From ff118dd66d6333e008b76e5052a728d46721b10d Mon Sep 17 00:00:00 2001 From: NuklearRabbit <145918611+NuklearRabbit@users.noreply.github.com> Date: Sun, 2 Aug 2026 07:23:08 +0200 Subject: [PATCH] docs(state): record Batch 5 completion --- PROJECT_STATE.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 83f1eca..341b408 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -460,3 +460,50 @@ any change at `docs/functional-completion/server-baseline.md`. - Exact next action: Batch 5 — bounded outbox delivery-lease recovery for stale `delivering` events, a second (scheduled quality-scan) n8n workflow, final documentation/contract updates and acceptance evidence. + +### Batch 5 — complete (commits `ec8f809`, `e115031`, `c981aad`, `824048b`) + +- Fixed a real gap: `_claim_due_events` flipped rows to `delivering` and committed + before the HTTP call, with no reclaim path if the process died before the outcome was + recorded. Each claim now gets a lease deadline (`n8n_delivery_lease_seconds`, default + 120s, reusing the `next_attempt_at` column) and `run_dispatch_cycle()` sweeps expired + leases back to `pending` before claiming new work; `attempts` is preserved, and a + still-alive worker's unexpired lease is never touched. +- Added the second n8n workflow: `POST /api/v1/integrations/n8n/scheduled-scan` + (service-token protected, same pattern as the return callback) running the same + `run_scan()` the manual UI action uses, audited with `actor_type=service`. + `n8n/mobilityops-scheduled-quality-scan.json` (hourly + manual-test trigger) ships + `"active": false`. Live-verified twice: executed end-to-end via the Manual test + trigger against the **local** n8n instance (full green execution, confirmed via the + resulting `data_quality_scan_run` audit event), and published + directly + curl-round-tripped against the **shared Unraid n8n** and its live API + (`deploy/unraid/setup-scheduled-scan.sh`). The shared instance's own UI could not be + browser-tested directly — it runs `N8N_SECURE_COOKIE=true` and refuses login over the + plain-HTTP LAN URL, which is correct/expected shared-infrastructure behaviour, not + something this task should change. +- Updated `contracts/openapi.yaml` and `docs/05-api-contract.md` with every endpoint + added across all five batches; `docs/07-data-quality.md`, `docs/08-return-workflow.md` + and `docs/12-security-and-audit.md` now describe the actual resolution flows, the + preview/commit relationship, the role matrix and the audit before/after exposure. + Corrected `docs/07-data-quality.md`'s lifecycle description to match the + already-implemented `(rule_type, entity_type, entity_id)` idempotency key (no evidence + fingerprint) and documented the `reopened_from`/`previous_decision` recurrence link. + `README.md`'s scope/integration-status/quality-gate sections updated to match. +- Local evidence: `pytest` **117 passed**, `ruff check .` clean, `mypy app` 0 issues/46 + files, `npx tsc -b` clean, `npm run build` clean, `npx playwright test` **37 passed**. +- **Clean-checkout drill** (section 14): fresh `git clone` of this branch into an + isolated scratch directory, `.env` from `.env.example`, isolated Compose project name + and remapped host ports (no shared state with the working stack), `up --build -d` + from empty volumes → migrations ran automatically → seed → full backend gate (117 + passed, ruff clean, mypy clean) → `npm ci` (clean; the pre-existing esbuild-moderate/ + react-router-RSC-high advisories are unchanged, not new) → `tsc -b`/`vite build` clean + → full Playwright suite **37 passed** against the isolated stack. Torn down afterward + (`down -v` on the isolated project only; the working dev stack was never touched). +- Deployed to Unraid; migrations unchanged at `e7b08389f47f (head)`. Full 37-test + Playwright suite re-run against `http://192.168.10.150:1236` — **37 passed**. Demo + data reset afterward. +- Exact next action: none — all five batches are implemented, tested locally (including + a genuine clean-checkout drill), committed, pushed, deployed to Unraid and + re-verified against the live server after every batch. See + `artifacts/functional-completion/final-summary.md` for the definitive acceptance + evidence.