diff --git a/PUBLIC_SOURCE_EXPORT.md b/PUBLIC_SOURCE_EXPORT.md
index 03af803..7202771 100644
--- a/PUBLIC_SOURCE_EXPORT.md
+++ b/PUBLIC_SOURCE_EXPORT.md
@@ -1,3 +1,3 @@
# Public source export
-This source snapshot was generated from the private canonical repository at revision `0458403e679d5e76f48b4b49d235476631fecf08`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
+This source snapshot was generated from the private canonical repository at revision `64b0a721955f10dfd1570b6b5933c0a0462ff442`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
diff --git a/PUBLIC_SOURCE_MANIFEST.json b/PUBLIC_SOURCE_MANIFEST.json
index 6953391..d5bca50 100644
--- a/PUBLIC_SOURCE_MANIFEST.json
+++ b/PUBLIC_SOURCE_MANIFEST.json
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
- "sourceRevision": "0458403e679d5e76f48b4b49d235476631fecf08",
+ "sourceRevision": "64b0a721955f10dfd1570b6b5933c0a0462ff442",
"files": [
{
"path": ".dockerignore",
@@ -39,8 +39,8 @@
},
{
"path": "README.md",
- "sha256": "3e6d0faf54046ae25087825fbe387fafb4aa37170762f94c0acf844daedc6e33",
- "bytes": 950
+ "sha256": "890585d90df05d0f2eeea563103fe6634a8352e5f28aec1007b413eb7225655f",
+ "bytes": 3624
},
{
"path": "SECURITY.md",
@@ -49,7 +49,7 @@
},
{
"path": "backend/Dockerfile",
- "sha256": "f2e98da6dc1bbcdf7c83c540208398c24ae1a34badcf2de4340c5a89eab579b9",
+ "sha256": "2406004823d76e1b0d85e5909253c56f75eaa10521c33a299cc48d43fd1d4ab8",
"bytes": 1386
},
{
@@ -629,8 +629,8 @@
},
{
"path": "frontend/Dockerfile",
- "sha256": "313f19ae47cb9771daa693224d6232b539657d90f43fc522ba358ade8c98d5c9",
- "bytes": 1157
+ "sha256": "878e7bf8aeee75cbaaf46fe8ff5c644f04fd19979dcce119247666ded6efe6f9",
+ "bytes": 1200
},
{
"path": "frontend/e2e-live/smoke.spec.ts",
@@ -789,7 +789,7 @@
},
{
"path": "frontend/package-lock.json",
- "sha256": "0b8dd7fc6285dd3539827fbf6c9aee4102eb1150cd7fa5ac6f9a8f013dede7e5",
+ "sha256": "2294303dcf1cdae97e5bf60d9d46621c477ef5de154d5d8c596a9e0e472e536f",
"bytes": 169491
},
{
diff --git a/README.md b/README.md
index b61fb56..3b1439f 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,60 @@
-# MobilityOps · public source
+# Fleet Ops
-MobilityOps (Fleet Ops) is a synthetic-data operations demo for vehicle rental and service teams. This repository is the reviewed public source snapshot. Development and deployment happen in a private canonical repository; each public update is generated from a committed revision with a fresh content review.
+
One operational workspace for a fictional vehicle rental fleet.
-## Run locally
+Try the demo · Features · Architecture · Deployment
-Copy `.env.example` to `.env`, then run `make demo`. Open . The demo uses fictional records and a local knowledge provider.
+Fleet Ops is the application in the `MobilityOps` repository. It brings vehicles, bookings, returns, data quality and procedures into one controlled workspace. This public edition uses **synthetic people, vehicles and activity** so you can explore the real workflows without exposing operational data.
-## Contents
+
-- `backend/` — FastAPI domain and API
-- `frontend/` — React interface and browser tests
-- `contracts/` — API and event contracts
-- `knowledge/` and `seed/` — synthetic procedures and records
+*The application supports English, Dutch and French. This demo capture shows the Dutch interface.*
-## Security
+## Try the demo
-Please report vulnerabilities through the contact in [SECURITY.md](SECURITY.md). No operational deployment state or private Git history is included in this repository.
+Requirements: Docker Engine with Compose and a recent `make` implementation.
-Licensed under the terms in [LICENSE](LICENSE).
+```bash
+cp .env.example .env
+make demo
+```
+
+Open . No demo password is required. Choose **Highlights in 90 seconds** for a short guided tour, or enter as an operations manager or rental employee. API readiness is available at .
+
+The demo includes a deterministic dataset and a local knowledge provider. It does not require a live external AI service or production n8n endpoint.
+
+## What you can do
+
+| Area | Workflow |
+| --- | --- |
+| Fleet and bookings | Inspect vehicle availability, booking state, returns and maintenance context. |
+| Controlled returns | Preview an inspection and commit the vehicle, booking, audit and outbox changes together. |
+| Data quality | Review rule-backed issues, assignments, deadlines and explicit customer merges. |
+| Knowledge | Ask procedural questions and inspect cited evidence; insufficient evidence stays unanswered. |
+| Integrations | See delivery state, bounded retries and correlated audit events. |
+| Administration | Manage roles, privacy exports, anonymisation and retention controls. |
+
+
+
+## How it works
+
+```mermaid
+flowchart LR
+ Web[React and TypeScript] --> API[FastAPI and role checks]
+ API --> DB[(PostgreSQL)]
+ API --> Knowledge[Grounded knowledge provider]
+ DB --> Outbox[Transactional outbox]
+ Outbox --> Automation[n8n integration]
+```
+
+The API owns operational state. Return processing is transactional; external automation receives an outbox event after the database commit. The demo can use bundled n8n, while a production installation can connect to an existing instance. The frontend is responsive and supports keyboard navigation.
+
+## Deployment notes
+
+The Compose stack includes the web app, API, database and a local automation fallback. Copy `.env.example`, set unique credentials and an appropriate `N8N_WEBHOOK_URL`, then mount persistent PostgreSQL storage. Put the web endpoint behind HTTPS, verify `/health/ready`, and test backup and restore before use. The public source intentionally contains no private deployment configuration.
+
+For development, use `make test`, `make lint`, `make e2e` and `npm run build --prefix frontend`. The main directories are `backend/` (API and migrations), `frontend/` (UI and browser tests), `contracts/` (integration schemas), and `knowledge/` plus `seed/` (fictional demo content).
+
+## About this public copy
+
+This repository is published from a reviewed private source commit. `PUBLIC_SOURCE_MANIFEST.json` records the source revision and file hashes. No private Git history is included. See [SECURITY.md](SECURITY.md) for vulnerability reporting and [LICENSE](LICENSE) for licensing.
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 8bbd9e0..57a73bb 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.12-slim-bookworm@sha256:a116514e19457bcb7af7efe9c3dd0b9b71e85b317694e7882a1c52aa15a78134 AS runtime-base
+FROM python:3.12-slim-bookworm@sha256:392307d22300de8b5986851a12d9176dfc0fc073e65bf6523ebd7dcbeb23564e AS runtime-base
ARG VCS_REF=development
ARG BUILD_DATE=unknown
LABEL org.opencontainers.image.title="Fleet Ops API" \
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
index 7289136..cb39118 100644
--- a/frontend/Dockerfile
+++ b/frontend/Dockerfile
@@ -13,7 +13,7 @@ RUN npm run build
FROM nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46
# The pinned upstream image can lag Alpine security rebuilds. Apply the current
# fixes from its pinned Alpine release before shipping the runtime image.
-RUN apk upgrade --no-cache
+RUN apk upgrade --no-cache && apk add --no-cache 'libexpat>=2.8.5-r0'
ARG VCS_REF=development
ARG BUILD_DATE=unknown
LABEL org.opencontainers.image.title="Fleet Ops Web" \
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 26dc768..e26d00e 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -3107,9 +3107,9 @@
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
- "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
+ "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
"dev": true,
"funding": [
{