From a7ac5ed9d0522b5dac2b74cfaebe0b387d404a9e Mon Sep 17 00:00:00 2001 From: NuklearRabbit <145918611+NuklearRabbit@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:14:34 +0200 Subject: [PATCH] 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 --- PROJECT_STATE.md | 75 ++++++++++++++++++++++++++++++++++++++++++ README.md | 15 ++++++--- contracts/openapi.yaml | 56 +++++++++++++++++++++++++++---- 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 634a9d2..effdd3c 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -872,3 +872,78 @@ scenarios, demo manifest, About page). Gap audit: `docs/demo-release/current-dem test results, clean-checkout result, deployment evidence for both the feature branch and master, responsive/accessibility results, known limitations, rollback procedure) plus 10 screenshots in `artifacts/fleet-ops-release/screenshots/`. + +## Fleet Ops correction: safe status-recommendation flow, MO-016, message codes (2026-08-03) — IN PROGRESS on fix/fleet-ops-i18n-status-flow + +Branch `fix/fleet-ops-i18n-status-flow`, created from master's post-release head +(`18344bc`). Audit and rationale in `docs/fleet-ops-correction/` (gap audit, i18n +inventory, vehicle-status decision table). Not yet merged to master. + +- **Status-recommendation flow redesigned** per the brief: the old single opaque + "calculate and apply recommended status" action is replaced by a single shared, pure + evaluator (`backend/app/services/vehicle_status.py::evaluate_vehicle_status`) used + identically by the scanner, a new non-mutating preview endpoint + (`POST .../status-recommendation`), and a transactional apply endpoint + (`POST .../apply-recommended-status`) that locks the row, recomputes facts, rejects a + stale `recommendation_token` (optimistic concurrency), refuses unsafe/manual-review + recommendations, and re-validates post-write before resolving the issue. Frontend + `DataQualityIssueDetail.tsx` shows "Review recommendation" → a decision panel + (current/recommended status, why, evidence, consequences, localized in all 3 + languages) → an exact "Change status to " confirm action → result, with a + distinct "Manual review required" state offering no generic apply button. +- Fixed the real unsafe shortcut this evaluator exists to eliminate: "maintenance + + active booking" no longer auto-recommends "rented" (current status is itself now a + blocking fact), and "maintenance with nothing else wrong" no longer auto-clears to + "available" (no fact proves maintenance is actually finished — that release stays a + manual decision). +- **MO-016 order independence**: order independence does not mean "same final status + regardless of order" — resolving the booking overlap first genuinely removes the + conflict, correctly leaving nothing to apply. What must (and does) hold either way: + the recommendation always reflects real current facts, and nothing unsafe is ever + applied (never "rented"). Verified by both a backend test + (`test_mo_016_status_conflict_recommendation_is_order_independent`, explicitly scoped + to MO-016/DQ-DEMO-STATUS after finding the original version wasn't) and a browser-level + Playwright test in both orders. +- **"Fleet Ops" is a non-localizable brand constant** (`frontend/src/product.ts`, + backend `PRODUCT_NAME`), wired via `{{productName}}` interpolation everywhere the + brand appeared in locale prose; a permanent test fails the build if any locale file + ever defines the brand name or an `appName` key again. +- **Dynamic backend prose converted to message codes + params**: return status reasons, + audit field/actor-type labels, automation `last_error` (new `last_error_code` column, + migration `799d8800e241`), and search results (sections/vehicles/bookings/issues) all + now carry stable codes the frontend localizes; raw technical text is demoted to a + "Technical details" disclosure everywhere. +- **Knowledge-base fixes**: the demo provider's tokenizer silently dropped accented + characters (`[a-z0-9]+` split "véhicule" into "v"+"hicule"), breaking French + retrieval broadly; fixed to include the Latin-1 accented range. Also reweighted + section scoring so a body match (real substance) outranks a heading/title match (a + shallow structural hint) — the old weighting misranked the damage procedure behind + an unrelated document for the brief's exact validation question in all 3 languages. + Removed leftover "MobilityOps"/"PoC" mentions from 9 procedure documents (knowledge + prose is visible content, missed by the earlier rebrand). +- New `frontend/e2e/fleet-ops-correction.spec.ts` (14 tests) covers branding in 3 + languages, language persistence, the full status-recommendation flow (non-mutating + preview, exact confirm text, manual review, stale-token rejection), MO-016 order + independence, trilingual knowledge grounding, and localized audit/automation. Writing + it surfaced and fixed two real bugs: the frontend conflated "no conflict" with + "manual review required" (both carry `safe_to_apply: false`), and the original + MO-016 backend test never actually targeted MO-016's own issue. +- Added a keyboard/reduced-motion/no-color-only-status accessibility test for the new + status-decision panel; added `aria-live="polite"` to the panel so the applied + confirmation is announced. +- `contracts/openapi.yaml` and `README.md` updated: title is "Fleet Ops", the new + status-recommendation endpoint documented, apply-recommended-status's request body + and error codes documented, search endpoint's code+params shape documented, README + states the Fleet Ops/MobilityOps naming split explicitly and refreshes stale test + counts (151 backend, 108 Playwright). +- Gates green so far: 151 backend tests, Ruff, mypy, Alembic upgrade/downgrade + verified, frontend `tsc`/build, full 108-test Playwright suite (rebuilt `api`+`web` + containers each time before testing). +- **Not yet done**: sections 11D/E/F of the i18n test-strengthening brief (hardcoded- + JSX lint check, broader dynamic-content localization tests, a 3-language route + matrix), the clean-checkout drill, Unraid deployment + live 3-language validation, + and the final merge to master with `artifacts/fleet-ops-correction/final-summary.md` + evidence. Do not claim PASS on this correction until all of those are done. +- Commits so far on this branch: `6deb955` (status flow + brand constant + message + codes), `e6539d1` (knowledge fixes), `ac4b163` (Playwright spec updates for the new + flow), `1fdd2b3` (new E2E coverage + 2 bug fixes), `1e40775` (accessibility test). diff --git a/README.md b/README.md index 0a1b3cc..d9a44a6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,15 @@ -# MobilityOps +# Fleet Ops **Connected operations for vehicle rental and service teams.** -MobilityOps is a working proof of concept for a fictitious mobility company. It combines vehicle and booking operations, a controlled vehicle-return workflow, data-quality review, RAGcore-backed internal knowledge, n8n orchestration and read-only tools published through ITWorx MCP Hub. +Fleet Ops is a working proof of concept for a fictitious mobility company. It combines vehicle and booking operations, a controlled vehicle-return workflow, data-quality review, RAGcore-backed internal knowledge, n8n orchestration and read-only tools published through ITWorx MCP Hub. + +**Naming:** "Fleet Ops" is the product's visible name everywhere in the UI, the demo +knowledge base, and this documentation. "MobilityOps" remains the technical +identifier only — the repository name, local directory, package/module names, Docker +Compose project, deployment directory, and database names. The UI is fully trilingual +(nl-BE default, en-GB, fr-BE); see `docs/fleet-ops-correction/` for the localization +architecture, the vehicle-status decision table, and the correction evidence. The web application uses the premium responsive **Control Rail** interface: a compact operations-first workspace with persisted readiness metrics, evidence-led exceptions, @@ -114,9 +121,9 @@ All defaults are configurable via `.env` (see `.env.example`). ## Quality gates ```bash -make test # backend: pytest (127 tests) +make test # backend: pytest (151 tests) make lint # backend: ruff + mypy (strict, zero errors) -make e2e # frontend: Playwright end-to-end (56 tests, live stack required) +make e2e # frontend: Playwright end-to-end (108 tests, live stack required) ``` Frontend build/typecheck: `cd frontend && npm run build` (`tsc -b && vite build`). diff --git a/contracts/openapi.yaml b/contracts/openapi.yaml index e30e681..70ae0f3 100644 --- a/contracts/openapi.yaml +++ b/contracts/openapi.yaml @@ -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