feat(approvals): change_requests + quotes parent tables (PMS-484) #357

Merged
YousifShkara merged 1 commit from feat/PMS-484-approvals-parent-tables into main 2026-06-25 08:04:54 +02:00
Owner

PMS-470 widened the polymorphic approvals surface to accept
/change-requests/{id}/approvals and /quotes/{id}/approvals but
held the route handlers at 400 stubs because the parent tables that
assert_parent_exists needs did not exist. PMS-484 ships those parent
tables and flips the stubs into real round-trip handlers.

Migration 078 creates minimal change_requests + quotes tables:

  • change_requests: id PK, tenant_id FK, title, summary, requested_by_id,
    status CHECK ('draft' | 'submitted' | 'approved' | 'rejected'),
    timestamps + idx_change_requests_tenant.
  • quotes: same shape plus total_cents BIGINT + currency CHAR(3),
    same CHECK on status + idx_quotes_tenant.

Schema is deliberately minimal - just enough for the approval flow to
verify parent existence within the tenant and label rows in the SPA
approval timeline. A richer change-management / sales workflow is its
own follow-up.

Route handlers:

  • list_for_change_request / create_for_change_request use
    assert_parent_exists("change_requests", ...) then funnel into
    service.list_for_entity / service.create_for_entity with
    ApprovalTarget::ChangeRequest. Same pattern for the quote pair.

Tests:

  • change_request_approval_round_trip seeds a change_request row,
    creates an approval against it via /change-requests/{id}/approvals,
    asserts target=="change_request" + entity_id round-trips, lists
    approvals on the change_request, then decides approve.
  • quote_approval_round_trip mirrors the above for the quote prefix.
  • unknown_parent_returns_404 sweeps every polymorphic prefix
    (change-requests, quotes, time-entries) with a zero UUID and pins
    the 404 from the parent-existence check, replacing the prior
    "placeholder returns 400" test now that the placeholders are gone.

#PMS-484

PMS-470 widened the polymorphic approvals surface to accept `/change-requests/{id}/approvals` and `/quotes/{id}/approvals` but held the route handlers at 400 stubs because the parent tables that `assert_parent_exists` needs did not exist. PMS-484 ships those parent tables and flips the stubs into real round-trip handlers. Migration 078 creates minimal change_requests + quotes tables: - change_requests: id PK, tenant_id FK, title, summary, requested_by_id, status CHECK ('draft' | 'submitted' | 'approved' | 'rejected'), timestamps + idx_change_requests_tenant. - quotes: same shape plus total_cents BIGINT + currency CHAR(3), same CHECK on status + idx_quotes_tenant. Schema is deliberately minimal - just enough for the approval flow to verify parent existence within the tenant and label rows in the SPA approval timeline. A richer change-management / sales workflow is its own follow-up. Route handlers: - list_for_change_request / create_for_change_request use `assert_parent_exists("change_requests", ...)` then funnel into `service.list_for_entity` / `service.create_for_entity` with `ApprovalTarget::ChangeRequest`. Same pattern for the quote pair. Tests: - change_request_approval_round_trip seeds a change_request row, creates an approval against it via /change-requests/{id}/approvals, asserts target=="change_request" + entity_id round-trips, lists approvals on the change_request, then decides approve. - quote_approval_round_trip mirrors the above for the quote prefix. - unknown_parent_returns_404 sweeps every polymorphic prefix (change-requests, quotes, time-entries) with a zero UUID and pins the 404 from the parent-existence check, replacing the prior "placeholder returns 400" test now that the placeholders are gone. #PMS-484
feat(approvals): change_requests + quotes parent tables (PMS-484)
All checks were successful
E2E / Playwright against staging (pull_request) Successful in 1m6s
Check / fmt + clippy + build + tests (pull_request) Successful in 4m45s
Integration / integration tests (pull_request) Successful in 12m44s
Create release / Create release from merged PR (pull_request) Successful in 4s
d54fec4a44
PMS-470 widened the polymorphic approvals surface to accept
`/change-requests/{id}/approvals` and `/quotes/{id}/approvals` but
held the route handlers at 400 stubs because the parent tables that
`assert_parent_exists` needs did not exist. PMS-484 ships those parent
tables and flips the stubs into real round-trip handlers.

Migration 078 creates minimal change_requests + quotes tables:
- change_requests: id PK, tenant_id FK, title, summary, requested_by_id,
  status CHECK ('draft' | 'submitted' | 'approved' | 'rejected'),
  timestamps + idx_change_requests_tenant.
- quotes: same shape plus total_cents BIGINT + currency CHAR(3),
  same CHECK on status + idx_quotes_tenant.

Schema is deliberately minimal - just enough for the approval flow to
verify parent existence within the tenant and label rows in the SPA
approval timeline. A richer change-management / sales workflow is its
own follow-up.

Route handlers:
- list_for_change_request / create_for_change_request use
  `assert_parent_exists("change_requests", ...)` then funnel into
  `service.list_for_entity` / `service.create_for_entity` with
  `ApprovalTarget::ChangeRequest`. Same pattern for the quote pair.

Tests:
- change_request_approval_round_trip seeds a change_request row,
  creates an approval against it via /change-requests/{id}/approvals,
  asserts target=="change_request" + entity_id round-trips, lists
  approvals on the change_request, then decides approve.
- quote_approval_round_trip mirrors the above for the quote prefix.
- unknown_parent_returns_404 sweeps every polymorphic prefix
  (change-requests, quotes, time-entries) with a zero UUID and pins
  the 404 from the parent-existence check, replacing the prior
  "placeholder returns 400" test now that the placeholders are gone.

#PMS-484
YousifShkara deleted branch feat/PMS-484-approvals-parent-tables 2026-06-25 08:04:55 +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!357
No description provided.