feat(reports): add project + client report types end to end (PMS-179) #147
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pms-179-project-client-reports"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Add two new tenant-scoped report types, projects and clients, end to end. Subtask of PMS-93: the SPA reports landing page advertises Projects and Clients report categories that previously had no backend, so those surfaces rendered an honest "not available yet" notice.
Endpoints
GET /api/v1/reports/projects- project-delivery aggregate: projects grouped by status; total budget hours / amount vs actual hours / amount (actuals summed fromtime_entrieslinked to a project); task completion (total vs completed viatask_statuses.is_completed); overdue project count (target_end_datein the past, status not completed / cancelled).GET /api/v1/reports/clients- CMDB / contract aggregate: company counts (all / active); asset totals with breakdown by type and by status; assets whose warranty expires within 90 days; active and renewing-within-90-days contract counts.Both are added to the
GET /reportsregistry so a client can discover them, gain CSV export through the existing generic/reports/{report}/exportpath, and are guarded byRequireReports(same as the tickets and time reports).Tests
tests/reports.rsgainsprojects_report_aggregates,clients_report_aggregates, andclients_report_is_tenant_scoped. All five reports tests pass; 115 lib tests,clippy --all-targets -- -D warnings, andcargo fmt --checkare clean.Out of scope
The custom report builder stays unimplemented. PMS-93 explicitly rejected an ad-hoc query builder for v1 (injection / performance risk).
🤖 Generated with Claude Code
PMS-93 shipped the ticket / time / billing reports, but the SPA reports landing page also advertises Projects and Clients report categories that had no backend behind them, so those surfaces rendered an honest "not available yet" notice. This adds the two missing report types. GET /api/v1/reports/projects returns a tenant-scoped project-delivery aggregate: projects grouped by status, total budget hours / amount vs actual hours / amount (actuals summed from time_entries linked to a project), task completion (total vs completed via task_statuses.is_completed), and overdue project count (target_end_date in the past, not completed or cancelled). GET /api/v1/reports/clients returns a tenant-scoped CMDB / contract aggregate: company counts (all / active), asset totals with breakdown by type and by status, assets whose warranty expires within 90 days, and active / renewing-within-90-days contract counts. Both are added to the GET /reports registry so clients can discover them, gain CSV export via the existing generic /reports/{report}/export path, and are guarded by RequireReports like the tickets and time reports. Tests: tests/reports.rs gains projects_report_aggregates and clients_report_aggregates (assert each figure against seeded data, plus the registry advertises both keys and CSV export returns content) and clients_report_is_tenant_scoped (a second tenant's assets never leak into this tenant's counts). All five reports tests pass; 115 lib tests, clippy --all-targets, and fmt are clean. Out of scope: the custom report builder stays unimplemented. PMS-93 explicitly rejected an ad-hoc query builder for v1 (injection / performance risk). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>