M29: polish recruiter engineering story
@@ -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.
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 303 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 39 KiB |