# n8n workflow manifest Source of truth for the four canonical Fleet Ops n8n workflows. Definitions in this directory are cleaned exports of the live workflows on `https://n8n.itworx.tech` — credential values are never embedded; nodes reference named n8n credentials instead. Run `n8n/workflows/check_drift.py` to compare a live workflow against its repo definition. ## 1. Fleet Ops — Vehicle Return Orchestration | Field | Value | |---|---| | File | `fleet-ops-vehicle-return.json` | | Purpose | Orchestrate the post-return follow-up (cleaning vs. attention-required) once Fleet Ops emits a `vehicle.returned.v1` outbox event, and report the result back to Fleet Ops. | | Trigger | Production webhook, `POST /webhook/mobilityops-return`, Header Auth (`Fleet Ops Webhook Trigger Token`) | | Event contract | `contracts/events.schema.json`, `event_type: vehicle.returned.v1` (envelope: `event_id`, `event_type`, `occurred_at`, `correlation_id`, `aggregate`, `data`) | | Required credentials | `Fleet Ops Webhook Trigger Token` (Header Auth, on the trigger); `Fleet Ops Service Token` (Header Auth, on the outbound HTTP call) | | Live workflow ID | `mobilityops-return-processing` | | Active status (as of 2026-08-04) | Active / Published | | Error Workflow | `Fleet Ops — Workflow Error Handler` (wired) | | Timeouts / bounded retries | `Record follow-up` HTTP node: 15s timeout, retry on fail (3 tries, 1000ms wait) | | Checksum (sha256) | `e5b6ba02a7824867620ceaf214224521d52de76337604b947f26f1b0b5432358` (updated 2026-08-05 — the committed file had invalid JSON, a missing `},` between two node objects; fixed, no live workflow change) | ## 2. Fleet Ops — Scheduled Data Quality Scan | Field | Value | |---|---| | File | `fleet-ops-data-quality-scan.json` | | Purpose | Periodically (and on-demand) run the Fleet Ops data-quality scan and summarize created-issue counts per rule. | | Trigger | Schedule Trigger (hourly, Europe/Brussels instance timezone) + Manual Trigger for on-demand test runs | | Event contract | N/A — HTTP-triggered scan call, no inbound event envelope. Request: `POST /api/v1/integrations/n8n/scheduled-scan`, Header Auth. | | Required credentials | `Fleet Ops Service Token` (Header Auth, on the scan HTTP call) | | Live workflow ID | `mobilityops-scheduled-quality-scan` | | Active status (as of 2026-08-04) | Active / Published | | Error Workflow | `Fleet Ops — Workflow Error Handler` (wired) | | Timeouts / bounded retries | `Run quality scan` HTTP node: 15s timeout, retry on fail (3 tries, 1000ms wait) | | Checksum (sha256) | `c0d46e0519118e6336e35c4ea2a67edb2f14bd007909ccf9256c93733751244a` | ## 3. Fleet Ops — RAGcore Procedure Sync Fully built and saved live (6 real nodes: Schedule Trigger → List procedures → Prepare uploads → Upload to RAGcore → Summarize sync result → Report sync result to Fleet Ops), but **deliberately not published/active** — the Schedule Trigger runs daily at midnight, so activating it starts real, unattended runs against production RAGcore and Fleet Ops; that is a separate, explicit go-live decision, not something to flip silently. While validating this workflow (2026-08-05), found and fixed a real defect: the "Report sync result to Fleet Ops" node's three body-parameter expressions each had a stray trailing `}}` (e.g. `={{ $json.execution_id }} }}` instead of `={{ $json.execution_id }}`), which would have sent malformed values on every real run. Fixed via `n8n import:workflow` (the safe CLI path — not the REST API, which caused a prior wipe incident in this environment) against the same live workflow ID, keeping it inactive; re-exported and verified the fix applied with no other change (still 6 real nodes, `active: false`). Also found and fixed a second gap: `settings.errorWorkflow` was unset (workflows 1-2 wire `"errorWorkflow": "Xppn2rAEqUuyiCJF"`, workflow 3 did not) — wired it the same way via the same CLI import path, re-verified. | Field | Value | |---|---| | File | `fleet-ops-ragcore-procedure-sync.json` | | Purpose | Sync the trilingual procedure documents from Fleet Ops into RAGcore as source documents, keeping stable per-document IDs and skipping unchanged content. | | Trigger | Schedule Trigger (daily at midnight) | | Event contract | N/A — HTTP-triggered sync. Reads `GET /api/v1/integrations/n8n/procedures`, uploads via RAGcore's `POST /v1/uploads`, reports via `POST /api/v1/integrations/n8n/procedures-sync-result`. | | Required credentials | `Fleet Ops Service Token` (Header Auth, on the procedures-list and result-report calls); `RAGcore Sync Token` (Header Auth, `sources:sync` scope, on the upload call) | | Live workflow ID | `6wbkc4d1AouGpmWT` | | Active status (as of 2026-08-05) | Built / Saved / **Inactive** (not published — daily unattended runs require a separate explicit go-live decision) | | Error Workflow | `Fleet Ops — Workflow Error Handler` (wired) | | Checksum (sha256) | `643c0515a50fed3d35e28f0b8cb17841f6f8d91699944980b5c56e619d5bf2a6` | ## 4. Fleet Ops — Workflow Error Handler Central technical workflow attached to all three other Fleet Ops workflows (1, 2, 3) via n8n's per-workflow "Error Workflow" setting. Receives n8n's standard Error Trigger payload, derives a bounded/secret-free failure report (safe error category, truncated summary, no stack trace, no headers/tokens), and POSTs it to Fleet Ops, which registers an audit event idempotently keyed on `execution_id`. | Field | Value | |---|---| | File | `fleet-ops-error-handler.json` | | Purpose | Central error notification target for all other Fleet Ops n8n workflows | | Trigger | Error Trigger (fired by n8n when an attached workflow's execution fails) | | Event contract | None inbound (n8n's built-in error-trigger payload); outbound `POST /api/v1/integrations/n8n/workflow-error`, Header Auth, body: `workflow_id, workflow_name, execution_id, failed_at, error_category (timeout\|authError\|connectionError\|httpError\|validationError\|unknown), error_summary, trigger_context, correlation_id, attempt, retry_action` | | Required credentials | `Fleet Ops Service Token` (Header Auth, on the outbound HTTP call — same credential workflows 1-2 use) | | Live workflow ID | `Xppn2rAEqUuyiCJF` | | Active status (as of 2026-08-04) | Active / Published | | Error Workflow (on itself) | `- No Workflow -` (deliberately unset — prevents a recursive error loop) | | Checksum (sha256) | `d9e2795b917a89a9b4a733e435661585f8011bc97f134d3643dee93ea05b0be6` | Validated this round: mock-data run (Error Trigger pinned to a realistic payload) produced a real `200 {"status":"registered", ...}` from the live Fleet Ops server; re-running the identical payload produced `"status":"already_registered"`, confirming execution_id idempotency. A genuine induced failure (temporarily pointing workflow 2's HTTP node at a nonexistent path, then reverting) confirmed workflow 2 itself fails correctly against a broken endpoint and recovers cleanly once reverted; n8n's Error Workflow trigger did not fire for that *manual* "Execute workflow" editor run — n8n only invokes Error Workflow for unattended/production trigger executions, not manual test runs from the editor. This is a known limitation of the live-validation evidence for this round: the mock-data path exercises the same nodes/logic and the real Fleet Ops endpoint, but a fully automatic (schedule- or webhook-triggered) failure cascading into this handler was not observed live.