# Master Public Release Gate 29 - Scheduled Report Delivery Foundation

Date: 2026-06-17

## Decision

Gate 29 local slice: APPROVED.

Reports now support a tenant-scoped scheduled report delivery queue for saved report presets. This closes the local scheduling foundation without claiming live email/PDF delivery, hosted worker execution, or provider-backed report distribution.

## Scope

Implemented:

- `report_delivery_jobs` schema and migration.
- Database and demo/session repositories for report delivery jobs.
- `ReportDeliveryService` queueing for saved reports with weekly/monthly cadence.
- Duplicate prevention per tenant, saved report, and scheduled run time.
- `/reports` scheduled delivery panel and delivery queue visibility.
- `POST /reports/deliveries/queue` route under the existing Reports area.
- `manage_reports` RBAC permission for saved preset and delivery mutations.
- Audit entry for scheduled report delivery queue actions.
- Regression coverage for service queueing, duplicate prevention, UI visibility, route registration, audit logging, and database tenant isolation.

Not implemented:

- Live email/PDF delivery provider integration.
- Background hosted worker runner.
- Report file generation/storage.
- Delivery retry/backoff worker.
- Customer/user subscription preferences for emailed reports.

## Verification

Commands:

```powershell
php -l src\Reports\Repository\ReportDeliveryJobRepository.php
php -l src\Reports\Repository\DatabaseReportDeliveryJobRepository.php
php -l src\Reports\Repository\DemoReportDeliveryJobSessionRepository.php
php -l src\Reports\Service\ReportDeliveryService.php
php -l src\Demo\Controller\OperationsController.php
php -l public\index.php
php -l templates\reports\index.php
php -l tests\run.php
composer test
composer check
composer validate --no-check-publish
composer audit --locked
composer release-gate
composer mysql-isolation-smoke
composer mysql-volume-profile
FIELDOPS_RELEASE_GATE_MYSQL=1 composer release-gate
XAMPP composer check
XAMPP composer release-gate
XAMPP FIELDOPS_RELEASE_GATE_MYSQL=1 composer release-gate
XAMPP browser-smoke
XAMPP role-interaction-smoke
XAMPP accessibility-smoke
```

Current result:

- Syntax checks: PASS.
- `composer test`: PASS.
- `composer check`: PASS.
- `composer validate --no-check-publish`: PASS.
- `composer audit --locked`: PASS.
- `composer release-gate`: PASS.
- `composer mysql-isolation-smoke`: PASS.
- `composer mysql-volume-profile`: PASS.
- MySQL-enabled `composer release-gate`: PASS.
- XAMPP served-copy `composer check`: PASS.
- XAMPP served-copy `composer release-gate`: PASS.
- XAMPP served-copy MySQL-enabled `composer release-gate`: PASS.
- XAMPP browser smoke: PASS with `failureCount: 0`.
- XAMPP high-risk role interaction smoke: PASS with `failureCount: 0`.
- XAMPP accessibility smoke: PASS with `failureCount: 0` and `warningCount: 0`.
- Full gate verification: PASS.

Regression assertions added:

- RBAC separates report viewing from report management.
- Reports page renders scheduled delivery and delivery queue UI.
- Delivery service queues scheduled saved presets once and decorates provider status.
- Delivery queue action redirects and writes an audit event.
- Delivery route is registered.
- Database saved report and delivery repositories enforce tenant-scoped lookup.

## Security and Data Notes

- Delivery jobs are tenant-scoped by `tenant_id`.
- Duplicate checks include tenant id, saved report id, and scheduled run timestamp.
- Mutating routes require `manage_reports`, CSRF, and authenticated session state.
- Audit logs record queue actions without storing report contents.
- Provider-missing status is explicit when `FIELDOPS_REPORT_DELIVERY_ENABLED` is not enabled.

## Remaining Blockers

- Live report delivery still requires provider credentials, a background worker, retry policy, generated files, and hosted worker evidence.
- Hosted BI/report performance proof remains required before public launch.
- Material-cost-backed profitability is covered by Gate 30, direct job cost capture is covered by Gate 31, contract profitability rollups are covered by Gate 32, purchase-order accrual is covered by Gate 33, supplier-invoice matching is covered by Gate 34, and payroll/time-sheet import is covered by Gate 35; full profitability still requires live cost import evidence.
