docs(release): update contracts and docs for functional-completion changes

Add the new endpoints to contracts/openapi.yaml and docs/05-api-contract.md
(return-preview, the four rule-specific data-quality resolution endpoints,
search, integration status, scheduled-scan), document the role matrix and
the audit before/after exposure in docs/12-security-and-audit.md, document
each rule type's actual resolution flow in docs/07-data-quality.md
(including the deliberate evidence-fingerprint simplification and the
reopened_from/previous_decision recurrence link), document the preview/
commit relationship in docs/08-return-workflow.md, and update README.md's
scope/integration-status/quality-gate sections to match what's actually
implemented and verified now. Also drops docs/05-api-contract.md's mention
of GET /api/v1/system/status, which was never implemented.
This commit is contained in:
NuklearRabbit
2026-08-02 07:10:37 +02:00
parent e115031a57
commit c981aad2a3
6 changed files with 266 additions and 21 deletions
+40 -7
View File
@@ -11,9 +11,10 @@ The demo may use signed server-issued sessions or short-lived JWTs. Demo-role bu
### System and demo
- `GET /health`
- `GET /api/v1/system/status`
- `POST /api/v1/demo/login`
- `POST /api/v1/demo/reset` — Operations Manager only
- `GET /api/v1/demo/session` — confirms the current session; `Cache-Control: no-store`
- `POST /api/v1/demo/logout` — safe to call without a session
- `POST /api/v1/demo/reset` — Operations Manager only; invalidates the caller's own session
### Dashboard
@@ -28,17 +29,37 @@ The demo may use signed server-issued sessions or short-lived JWTs. Demo-role bu
- `GET /api/v1/bookings`
- `GET /api/v1/bookings/{public_ref}`
- `POST /api/v1/bookings/{public_ref}/return-preview` — non-mutating; shares its domain
evaluation with the commit endpoint below so the two cannot drift apart
- `POST /api/v1/bookings/{public_ref}/return`
Return commands require an `Idempotency-Key` header and optimistic version where relevant.
Return commands require an `Idempotency-Key` header. Concurrency safety is row-lock based
(`SELECT ... FOR UPDATE` on the booking and vehicle); no optimistic-version field is
accepted or needed on top of that.
### Data quality
All Operations Manager only.
- `GET /api/v1/data-quality/issues`
- `GET /api/v1/data-quality/issues/{public_ref}`
- `POST /api/v1/data-quality/scan` — manual trigger for the deterministic five-rule scan
- `POST /api/v1/data-quality/issues/{public_ref}/defer`
- `POST /api/v1/data-quality/issues/{public_ref}/reject`
- `POST /api/v1/data-quality/issues/{public_ref}/merge-customers`
- `POST /api/v1/data-quality/issues/{public_ref}/merge-customers` — possible_duplicate_customer
- `POST /api/v1/data-quality/issues/{public_ref}/provide-fields` — missing_required_field
- `POST /api/v1/data-quality/issues/{public_ref}/resolve-odometer-regression` — odometer_regression
- `POST /api/v1/data-quality/issues/{public_ref}/resolve-overlap` — booking_overlap
- `POST /api/v1/data-quality/issues/{public_ref}/apply-recommended-status` — vehicle_status_conflict
Each of the five rule types has exactly one bounded resolution path above (plus
defer/reject, which apply to any open issue).
### Search
- `GET /api/v1/search?q=...` — bounded typed results (vehicle, booking,
data_quality_issue, section); role-filtered server-side; customers are never returned
(no customer detail route exists in this PoC)
### Knowledge
@@ -47,9 +68,21 @@ Return commands require an `Idempotency-Key` header and optimistic version where
### Automation and audit
- `GET /api/v1/workflows`
- `POST /api/v1/workflows/{event_id}/retry`
- `GET /api/v1/audit`
- `GET /api/v1/workflows` — Operations Manager only
- `POST /api/v1/workflows/{event_id}/retry` — Operations Manager only
- `GET /api/v1/audit` — Operations Manager only; each event includes `before`/`after`
plus a resolved `entity_ref`/`entity_link` where the entity type supports one
- `GET /api/v1/integrations/status` — Operations Manager only; truthful aggregate n8n
state from outbox delivery counts (not just the most recent event), and the actual
MCP Hub `registration_enabled` setting
### n8n-service endpoints
Service-token protected (`X-Service-Token`, same shared secret as the return callback):
- `POST /api/v1/integrations/n8n/return-callback`
- `POST /api/v1/integrations/n8n/scheduled-scan` — triggered by the scheduled
quality-scan workflow; runs the same domain scan the manual UI action uses
### MCP-provider endpoints
+26 -1
View File
@@ -25,14 +25,29 @@ Merge rewires booking references, preserves the loser as a tombstone and audits
Required for active customers: first name, last name and at least one of email or phone. Required for active vehicles: registration number, make, model and location.
Resolution: `POST /provide-fields` accepts only the fields the entity type actually
requires (rejects anything else), applies them, and re-runs the same missing-field check.
The issue resolves only once nothing required remains missing; a partial submission
updates the record and its evidence but leaves the issue open.
## DQ-03 Odometer regression
Flag an inspection or maintenance reading below the canonical odometer. Never lower the canonical value automatically.
Resolution: `POST /resolve-odometer-regression` offers exactly two bounded decisions —
`retain_canonical` (the submitted reading is treated as erroneous; canonical is
untouched) or `correct_reading` (updates a named related booking's reading and the
vehicle's canonical odometer together). A `correct_reading` value below the current
canonical is rejected, since it would not resolve the regression, not silently applied.
## DQ-04 Booking overlap
Flag overlapping `reserved` or `active` bookings for one vehicle. Normal write APIs reject new overlaps; the seed/import path may create one controlled legacy conflict.
Resolution: `POST /resolve-overlap` blocks one of the two named overlapping bookings
(minimal safe resolution, not a scheduling calendar) and re-verifies no
reserved/active overlap remains among the issue's related bookings before resolving.
## DQ-05 Vehicle status conflict
Examples:
@@ -42,6 +57,16 @@ Examples:
- status `available` while critical open quality issue exists;
- status `maintenance` with an active booking.
Resolution: `POST /apply-recommended-status` computes a recommendation from one
authoritative function mirroring the conditions above, applies it, and re-runs the same
function to confirm the conflict is actually gone before resolving.
## Lifecycle
Detection is idempotent by `(rule_type, entity_type, entity_id, evidence fingerprint)` while open. Resolved issues remain historical. Reintroduced evidence creates a new issue linked to the prior issue where useful.
Detection is idempotent by `(rule_type, entity_type, entity_id)` while open — the CSV
seed rows don't carry a stable evidence fingerprint, so the literal
`(..., evidence fingerprint)` scheme from an earlier draft of this rule was dropped as
unworkable for seeded data; re-implementing it would need to reconcile with that. Resolved
issues remain historical. Reintroduced evidence creates a new issue whose evidence carries
`reopened_from` (the prior issue's reference) and `previous_decision` (its resolved
status), so a repeat problem is never presented as if no decision was ever made.
+11
View File
@@ -1,5 +1,16 @@
# Vehicle-return workflow
## Preview
`POST /api/v1/bookings/{public_ref}/return-preview` takes the same request body as the
commit endpoint below and runs the identical evaluation (`evaluate_return()`) with no
writes, no audit event and no outbox event — it exists so the UI's review step shows the
server's actual answer instead of guessing the outcome client-side. It returns the
canonical and submitted odometer readings, whether the submission is a regression, the
resulting vehicle status with a human-readable reason, whether a quality issue would be
created, and next-booking risk. `register_vehicle_return` (below) calls the same
`evaluate_return()` function, so preview and commit cannot drift apart.
## Input
- booking public reference;
+31
View File
@@ -4,6 +4,30 @@
Role buttons may create a session for a seeded demo identity. All API routes still enforce authorization. Demo reset and customer merge require Operations Manager.
The browser never treats its own cached copy of the logged-in user as authoritative:
`AuthContext` re-verifies against `GET /api/v1/demo/session` on every app load (that
response is `Cache-Control: no-store`, so a stale cached "authenticated" response can't
survive a logout), and a central 401 listener on the API client clears local auth state
from any endpoint, not just the session check. `POST /api/v1/demo/logout` and
`POST /api/v1/demo/reset` both invalidate the session cookie server-side.
## Role matrix
| Capability | Rental Employee | Operations Manager |
|---|---|---|
| Dashboard, fleet, vehicle detail, bookings, booking detail | yes | yes |
| Register a vehicle return | yes | yes |
| Knowledge assistant | yes | yes |
| Data-quality workbench (view, scan, all resolutions) | no | yes |
| Integrations / automation status and retry | no | yes |
| Audit trail | no | yes |
| Demo reset | no | yes |
Enforced server-side (every listed manager-only action returns `403` for Rental
Employee, verified by direct API tests, not just a hidden button) and mirrored in the
frontend nav (manager-only items are not rendered, not merely disabled) and route guards
(direct URL access shows a restricted message rather than partial data).
## Service authentication
Use separate scoped credentials for:
@@ -42,6 +66,13 @@ Required actions:
Audit is append-only through the application. Provide filters by actor, action, entity and correlation ID.
`GET /api/v1/audit` (Operations Manager only) returns `before`/`after` for every event
(the columns already existed but were not serialized until this pass) plus a resolved
`entity_ref`/`entity_link` for vehicle, booking and data-quality-issue entities (no
customer link exists — no customer detail route). The UI shows a human-readable
before/after summary per row by default, with the raw before/after/metadata JSON behind
a `<details>` disclosure rather than shown unconditionally.
## Confirmation
No write-capable MCP actions exist in this PoC. Destructive UI actions such as demo reset and customer merge require explicit confirmation.