M29: polish recruiter engineering story
MobilityOps acceptance / backend (push) Canceled after 0s
MobilityOps acceptance / frontend (push) Canceled after 0s

This commit is contained in:
NuklearRabbit
2026-08-10 18:13:18 +02:00
parent 6365586e82
commit 29325b6c27
57 changed files with 717 additions and 349 deletions
+52 -47
View File
@@ -1,63 +1,68 @@
# MobilityOps — as-built architecture
# Fleet Ops — as-built architecture
```mermaid
flowchart TB
subgraph Browser
UI["MobilityOps Web<br/>React + TypeScript"]
end
UI["Fleet Ops Web\nReact + TypeScript + Vite"]
subgraph MobilityOps["MobilityOps (this repo)"]
API["FastAPI backend<br/>/api/v1/*"]
DISPATCH["Outbox dispatcher<br/>background thread"]
subgraph CORE["Fleet Ops this repository"]
API["FastAPI /api/v1\nRBAC + domain rules"]
OUT["Outbox dispatcher\nleases + bounded retry"]
DB[(PostgreSQL)]
OBS["Prometheus metrics\nGrafana dashboards"]
API --> DB
DISPATCH --> DB
OUT --> DB
API --> OBS
end
subgraph External["External central services"]
N8N["n8n<br/>return-processing workflow"]
RAGDEMO["Demo KnowledgeProvider<br/>TF-IDF extractive, local files"]
RAGCORE["RAGcore<br/>(adapter built, no live instance)"]
HUB["ITWorx MCP Hub<br/>(endpoints built, no live instance)"]
subgraph EXT["Existing external platforms"]
N8N["Central n8n\nsecondary orchestration"]
RAG["RAGcore\ngrounded procedure retrieval"]
HUB["ITWorx MCP Hub\ntool transport + publication"]
end
UI -->|session cookie| API
API -->|GroundedAnswer| RAGDEMO
API -.->|configurable, unavailable-safe| RAGCORE
DISPATCH -->|POST vehicle.returned.v1| N8N
N8N -->|callback, X-Service-Token| API
HUB -.->|X-Service-Token, read-only| API
classDef unverified stroke-dasharray: 5 5;
class RAGCORE,HUB unverified;
UI -->|secure session cookie| API
API -->|tenant/workspace adapter| RAG
OUT -->|vehicle.returned.v1| N8N
N8N -->|service-authenticated callback| API
HUB -->|service-authenticated read-only tools| API
```
Dashed boxes/arrows are implemented and unit/contract-tested but were never exercised
against a live instance in this environment (no reachable RAGcore or ITWorx MCP Hub).
Solid boxes were verified end-to-end, including a real n8n instance.
## Ownership and trust boundaries
## Component responsibility (unchanged from `docs/03-architecture.md`)
| Component | Owns | Explicitly does not own |
|---|---|---|
| Fleet Ops | vehicles, customers, bookings, inspections, quality issues, audit, permissions, outbox state | external workflow execution or procedure retrieval |
| RAGcore | indexing/retrieval and grounded procedure evidence | Fleet Ops database or business state |
| ITWorx MCP Hub | MCP transport, connector publication and central tool-call audit | Fleet Ops database or write actions |
| n8n | post-commit workflow orchestration | critical business rules or the source-of-truth transaction |
| Component | Owns |
|---|---|
| MobilityOps | vehicles, customers, bookings, inspections, data-quality issues, audit, outbox/delivery state |
| RAGcore | procedure retrieval and grounded answers (demo provider substitutes locally) |
| ITWorx MCP Hub | MCP transport, tool publication, central tool-call audit |
| n8n | post-commit secondary orchestration only — never the source of truth for vehicle state |
## End-to-end return trace
## Reliability boundaries verified in this build
```mermaid
sequenceDiagram
actor Operator
participant Web
participant API
participant DB
participant n8n
Operator->>Web: Review and confirm return
Web->>API: POST return with idempotency key
API->>DB: Lock booking and validate invariants
API->>DB: Commit inspection, state, audit and outbox atomically
API-->>Web: Result + correlation ID
Web-->>Operator: Human result and full processing trace
API->>n8n: Deliver persisted outbox event
n8n->>API: Authenticated status callback
API->>DB: Persist delivery/audit evidence
```
1. **Return commits atomically with its outbox event**`app/services/returns.py`, one
transaction; verified by `test_concurrent_returns_only_one_succeeds` (real Postgres row
locking, not mocked).
2. **Outbox delivery is at-least-once, idempotent by event ID** — verified live: the n8n
callback checks for an existing `AuditEvent` by event ID before recording a second time.
3. **RAGcore failure disables knowledge answers only**`RAGcoreKnowledgeProvider` degrades
to `unavailable`; the rest of the app is unaffected because the knowledge router is the
only consumer.
4. **MCP Hub failure does not affect the web application** — the four MCP provider
endpoints are a separate authenticated surface (`X-Service-Token`), invisible to the
browser-facing API/UI.
5. **n8n failure leaves events pending with bounded retries** — verified live: a seeded
`failed` event, retried through the UI, was picked up by the background dispatcher and
delivered through the real n8n instance within one poll cycle.
## Verified reliability properties
1. Concurrent returns serialize through PostgreSQL row locking; only one can commit.
2. Local return success is independent of n8n availability. Pending delivery remains persisted and retryable.
3. Outbox delivery is at-least-once and idempotent by event ID, with crash-recoverable leases and bounded backoff.
4. RAGcore failure affects knowledge answers only. The UI reports unavailable/insufficient evidence and does not invent an answer.
5. MCP endpoints are a separate tenant-bound, client-identity-validated, read-only surface; every call is audited with a correlation ID.
6. Browser authorization is enforced again on the API. Hiding a navigation item is never the security boundary.
The live deployment has exercised all three external boundaries. Local clean-checkout acceptance can use the deterministic extractive knowledge provider while reporting that mode honestly.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB