docs: update OpenAPI contract, README branding, and PROJECT_STATE for the correction milestone

- contracts/openapi.yaml: title is now "Fleet Ops API"; documents the new
  status-recommendation preview endpoint and the apply endpoint's request body
  (recommendation_token) and full error-code set; notes the search endpoint's
  code+params response shape.
- README.md: title and intro now say Fleet Ops, with an explicit note on the
  Fleet Ops (visible)/MobilityOps (technical identifier) naming split; refreshed
  stale test counts (151 backend, 108 Playwright).
- PROJECT_STATE.md: full progress record for the in-progress correction milestone,
  including what's done, what bugs were found and fixed, and what's explicitly not
  yet done (i18n test-strengthening 11D/E/F, clean-checkout drill, Unraid deployment,
  merge to master).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
NuklearRabbit
2026-08-03 23:14:34 +02:00
co-authored by Claude Sonnet 5
parent 1e407754e6
commit a7ac5ed9d0
3 changed files with 136 additions and 10 deletions
+50 -6
View File
@@ -1,8 +1,11 @@
openapi: 3.1.0
info:
title: MobilityOps API
title: Fleet Ops API
version: 0.1.0
description: Contract baseline for the MobilityOps proof of concept.
description: >-
Contract baseline for the Fleet Ops demo. "Fleet Ops" is the visible product name;
"mobilityops" remains the technical identifier for the repository, deployment
directory, database, and internal service/health identifiers only.
servers:
- url: http://localhost:8128
paths:
@@ -181,26 +184,67 @@ paths:
description: Wrong rule type, issue not open, or overlap still present
'422':
description: booking_ref not one of the overlapping bookings
/api/v1/data-quality/issues/{public_ref}/status-recommendation:
post:
operationId: previewVehicleStatusRecommendation
description: >-
vehicle_status_conflict only. Non-mutating: computes the recommendation from
the same shared evaluator the scanner and apply endpoint use
(app.services.vehicle_status.evaluate_vehicle_status), without resolving the
issue, writing an audit event, or queuing automation. Safe to call repeatedly
-- see docs/fleet-ops-correction/vehicle-status-decision-table.md.
parameters:
- $ref: '#/components/parameters/PublicRef'
responses:
'200':
description: >-
Current/recommended status, recommendation code, safe_to_apply,
manual_review_required, the underlying facts, and a recommendation_token
the apply endpoint revalidates against.
'409':
description: Wrong rule type, issue not open, or vehicle not found
/api/v1/data-quality/issues/{public_ref}/apply-recommended-status:
post:
operationId: applyRecommendedVehicleStatus
description: >-
vehicle_status_conflict only. Applies the one authoritative recommendation
function's output and re-validates before resolving.
function's output within one transaction: locks the issue and vehicle,
recomputes the recommendation from fresh facts, rejects the request if the
supplied recommendation_token no longer matches (RECOMMENDATION_STALE), refuses
an unsafe/manual-review recommendation (MANUAL_REVIEW_REQUIRED) or a
recommendation with nothing to apply (NO_CONFLICT_DETECTED), then re-validates
the same evaluator post-write before resolving the issue.
parameters:
- $ref: '#/components/parameters/PublicRef'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [recommendation_token]
properties:
recommendation_token:
type: string
description: The token from the most recent status-recommendation preview call.
responses:
'200':
description: Applied status, reason and the resolved issue
description: Applied status, reason code and the resolved issue
'409':
description: Wrong rule type, issue not open, or no conflict detected
description: >-
Wrong rule type, issue not open, vehicle not found, stale recommendation
token, manual review required, no conflict detected, or the applied status
did not resolve the conflict on re-validation
/api/v1/search:
get:
operationId: search
description: >-
Bounded typed results (vehicle, booking, data_quality_issue, section).
Data-quality and manager-only sections are filtered server-side by role.
Customers are never returned -- no customer detail route exists.
Customers are never returned -- no customer detail route exists. Every result's
`label` is a stable public_ref/section id (never translatable prose); `detail_code`
(+ optional `detail_params` for data values like make/model/location) is what the
frontend localizes -- the backend never emits English/Dutch/French sentences here.
parameters:
- in: query
name: q