feat(reports): GET /reports registry + integration tests (PMS-146) #129

Merged
longjacksonle merged 1 commit from feat/pms-146-reports-registry-and-tests into main 2026-06-07 07:48:21 +02:00

What

Closes the two PMS-93 acceptance criteria that were left unmet despite the story being marked Done: there was no GET /api/v1/reports registry (AC1) and no integration tests (AC6).

Closes PMS-146 (subtask of PMS-93).

Registry (AC1)

GET /api/v1/reports returns the report types (dashboard, tickets, time, billing) with their parameter schemas - each descriptor has key, name, description, and a parameters list (name / kind / required). Gated by RequireReports, like the report endpoints. A client can now discover what it can run instead of hard-coding the list.

Tests (AC6) - tests/reports.rs

  • Aggregates reflect seeded data: seeds a company + ticket + a 120-minute time entry + a $1000 invoice, then asserts the dashboard counts the one open ticket, the tickets report counts the opened ticket, the time report sums to 120 minutes, and the billing report sums to the invoiced total.
  • Registry lists the four types (billing advertising its company_id param).
  • CSV export (/reports/tickets/export?format=csv) returns content (AC4).
  • Tenant isolation (AC5): a second tenant's $5000 invoice never appears in the first tenant's billing report, which sees only its own $1000.

Not changed (documented deviation)

The reports return stable typed JSON shapes rather than AC2's generic "columns/rows/totals" envelope. The client (MAPPS-130) already consumes the typed shapes, so this is a deliberate deviation, not a gap.

Verification

  • cargo test --test reports -> 2 passed; cargo test --lib -> 110 passed.
  • cargo fmt --check clean; cargo clippy --all-targets -- -D warnings clean.

🤖 Generated with Claude Code

## What Closes the two PMS-93 acceptance criteria that were left unmet despite the story being marked Done: there was no `GET /api/v1/reports` registry (AC1) and no integration tests (AC6). Closes PMS-146 (subtask of PMS-93). ## Registry (AC1) `GET /api/v1/reports` returns the report types (dashboard, tickets, time, billing) with their parameter schemas - each descriptor has `key`, `name`, `description`, and a `parameters` list (`name` / `kind` / `required`). Gated by `RequireReports`, like the report endpoints. A client can now discover what it can run instead of hard-coding the list. ## Tests (AC6) - `tests/reports.rs` - **Aggregates reflect seeded data:** seeds a company + ticket + a 120-minute time entry + a $1000 invoice, then asserts the dashboard counts the one open ticket, the tickets report counts the opened ticket, the time report sums to 120 minutes, and the billing report sums to the invoiced total. - **Registry** lists the four types (billing advertising its `company_id` param). - **CSV export** (`/reports/tickets/export?format=csv`) returns content (AC4). - **Tenant isolation (AC5):** a second tenant's $5000 invoice never appears in the first tenant's billing report, which sees only its own $1000. ## Not changed (documented deviation) The reports return stable typed JSON shapes rather than AC2's generic "columns/rows/totals" envelope. The client (MAPPS-130) already consumes the typed shapes, so this is a deliberate deviation, not a gap. ## Verification - `cargo test --test reports` -> 2 passed; `cargo test --lib` -> 110 passed. - `cargo fmt --check` clean; `cargo clippy --all-targets -- -D warnings` clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(reports): add GET /reports registry + integration tests (PMS-146, closes PMS-93 gaps)
All checks were successful
E2E (staging) / Playwright against staging (pull_request) Successful in 35s
Check / fmt + clippy + compile + tests (pull_request) Successful in 1m50s
Build OCI container / Build and push mokosh-api image (push) Successful in 3m9s
Create release / Create release from merged PR (pull_request) Has been skipped
73e8682087
PMS-93 was marked Done, but two story-level acceptance criteria were never closed: there was no registry endpoint (AC1) and no integration tests (AC6).

Adds GET /api/v1/reports: a registry of the report types (dashboard, tickets, time, billing) with their parameter schemas (key, name, description, and a list of parameter specs with name/kind/required), so a client can discover what it can run. Gated by RequireReports like the other report endpoints.

Adds tests/reports.rs: seeds a company + ticket + 120-minute time entry + a $1000 invoice and asserts each aggregate reflects the seeded data - the dashboard counts the one open ticket, the tickets report counts the opened ticket, the time report sums to 120 minutes, and the billing report sums to the invoiced total - plus the registry lists the four types (with billing advertising its company_id parameter) and CSV export returns content. A second test proves tenant scoping: a second tenant's $5000 invoice never appears in the first tenant's billing report (which sees only its own $1000).

Not changed: the reports return stable typed JSON shapes rather than the AC's generic columns/rows/totals envelope. That is an intentional, documented deviation - the client (MAPPS-130) already consumes the typed shapes - not a gap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/pms-146-reports-registry-and-tests 2026-06-07 07:48:21 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!129
No description provided.