diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 97bb09e..4716e95 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -1,5 +1,27 @@ # Project state +## Publication and Unraid deployment (2026-08-02) + +- Unraid deployment is live at `http://192.168.10.150:1236` from + `/mnt/user/appdata/mobilityops`, Compose project `mobilityops`. +- Deployment config commits: `07ab7a3`, `847cd05`, `e1a1c67`, `1e13943`. The accepted + baseline `4bf9afbeff44088864e0844769d4dd0e4089d85b` remains intact. +- All four services are healthy with zero restarts. Only web port 1236 is exposed to the + LAN; n8n is loopback-only on host port 15678; API and PostgreSQL are internal. +- Migrations are at `e7b08389f47f (head)` and deterministic seed counts match final + acceptance. A Chrome smoke test covered every requested page and a real return; its n8n + event succeeded on attempt 1. Browser console and recent service log scans were clean. +- RAGcore is disabled in favor of the honest local demo provider. MCP Hub registration is + disabled. n8n is initialized, published, healthy, and live-verified. +- Local post-change gates: 66 backend tests, Ruff, mypy (44 files), and frontend production + build all pass. Evidence is in `artifacts/deployment/unraid-summary.md`. +- Publication is blocked only because the requested Chrome session at + `https://gitea.itworx.tech` is signed out. Gitea SSH authentication as Jens succeeds. +- Exact next action: after the user signs in to Gitea in Chrome, create private uninitialized + `Jens/MobilityOps`, add the supplied SSH clone URL as `origin`, push `master` and tags, + verify history/default branch/hygiene in Git and the web UI, update the deployment + evidence to PASS, commit/push that update, and refresh `.deploy/source-revision`. + ## Current milestone M7 — complete. All milestones (M0–M7) done, plus a full post-M7 final-acceptance audit (see below). See `artifacts/final-acceptance/summary.md` for the definitive acceptance evidence (supersedes `artifacts/evidence/final-summary.md`, which is kept as historical M7 evidence). diff --git a/artifacts/deployment/unraid-summary.md b/artifacts/deployment/unraid-summary.md new file mode 100644 index 0000000..705b5ec --- /dev/null +++ b/artifacts/deployment/unraid-summary.md @@ -0,0 +1,131 @@ +# MobilityOps Unraid deployment evidence + +## Outcome + +- Deployment: **PASS** +- Gitea publication: **BLOCKED — Chrome session is signed out** +- Intended Gitea URL: `https://gitea.itworx.tech/Jens/MobilityOps` +- Requested visibility: private (not yet created or verified) +- Branch: `master` +- Verified baseline commit: `4bf9afbeff44088864e0844769d4dd0e4089d85b` +- Deployment implementation commit: `1e13943cffb2da8a328b5b1ea5e9b1fe73fdd774` +- Server: `192.168.10.150` +- Server directory: `/mnt/user/appdata/mobilityops` +- Compose project: `mobilityops` +- Application URL: `http://192.168.10.150:1236` +- Port mapping: LAN `0.0.0.0:1236` / `[::]:1236` to `web:80` + +## Services and health + +| Service | Runtime state | Health | Host exposure | +|---|---|---|---| +| `db` | running, 0 restarts | healthy | none (`5432/tcp` internal) | +| `api` | running, 0 restarts | healthy | none (`8000/tcp` internal) | +| `web` | running, 0 restarts | healthy | `1236:80` on LAN | +| `n8n` | running, 0 restarts | healthy | `127.0.0.1:15678:5678` only | + +No unrelated container was stopped, recreated, or modified. Port `1236` was confirmed +unused by listeners, Docker containers, and existing Compose projects before deployment. +The requested directory did not exist and was created specifically for MobilityOps. + +## Deployment commands + +The existing SSH aliases resolve to the requested hosts and keys (`gitea.itworx.tech` +for Gitea SSH and `unraid` for root access). No key was created, copied, or replaced. +The committed source was transferred from the workstation; Unraid has no Gitea key. + +```bash +git archive --format=tar.gz --output= +scp unraid:/mnt/user/appdata/mobilityops/.deploy/source.tar.gz +ssh unraid +cd /mnt/user/appdata/mobilityops +tar -xzf .deploy/source.tar.gz +./deploy/unraid/configure-env.sh http://192.168.10.150:1236 +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml up --build -d +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T api \ + python -m app.cli seed --reset +./deploy/unraid/setup-n8n.sh http://127.0.0.1:15678 +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T n8n \ + n8n import:workflow --input=//imports/mobilityops-return-processing.json +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T n8n \ + n8n publish:workflow --id=mobilityops-return-processing +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml restart n8n +``` + +The server `.env` was created from `.env.example`, is mode `0600`, and contains generated +runtime secrets. Secret values and n8n owner credentials remain server-only and are not +included here or in Git. + +## Validation evidence + +- Migration: `e7b08389f47f (head)`. +- Deterministic seed: users 2, customers 180, vehicles 50, bookings 246, inspections 75, + maintenance 40, data-quality issues 26, workflow runs 20. +- HTTP: `GET /` returned 200; `GET /health` returned + `{"status":"ok","service":"mobilityops-api"}` through the web proxy. +- Backend gates in an isolated local Compose project: 66 tests passed, Ruff clean, mypy + clean across 44 files. +- Frontend: `npm ci && npm run build` completed (`tsc -b && vite build`). +- Logs: no traceback, fatal, uncaught, or unresolved startup error in the deployment log + scan. Browser console had no warnings or errors during the smoke test. +- Browser smoke test in Chrome: Operations Manager demo login, Dashboard, Vehicles, + Bookings, Data Quality, Knowledge, Automation, and Audit all loaded from the LAN URL. +- Dashboard showed persisted seed metrics (21 available, 11 rented, 6 cleaning, + 5 maintenance, 7 blocked, 22 open issues, 1 pending/failed workflow). +- Return workflow: `BK-DEMO-RETURN` accepted 54,700 km, created `INSP-0076` and + `DQ-RET-0076`, preserved the 54,820 km canonical odometer, and changed the booking to + returned. +- n8n round trip: event prefix `250f6c0e` reached `succeeded` on attempt 1; the callback + and `return_registered` audit events were visible in the UI. +- Data quality: `DQ-RET-0076` displayed the persisted regression evidence and related + booking/inspection references. +- Knowledge: UI truthfully showed `Provider: demo · available · 10 procedures indexed`; + the damage question returned grounded excerpts and citations from the local procedures. + +## Integration status + +- RAGcore: disabled for this deployment; `KNOWLEDGE_PROVIDER=demo`. No claim of a live + RAGcore connection is shown. Operational functionality is unaffected. +- ITWorx MCP Hub: registration disabled with `MCP_HUB_REGISTRATION_ENABLED=false`; the + independently authenticated provider endpoints remain available internally to the web + proxy/API boundary, but no live Hub connection is claimed. +- n8n: deployed, healthy, editor loopback-only, owner initialized, workflow imported and + published, and a real return delivery succeeded. + +## Known limitations + +- Gitea repository creation and web verification remain blocked until the requested Chrome + session is authenticated. SSH authentication itself is verified for user `Jens`. +- RAGcore and ITWorx MCP Hub are intentionally not connected yet. +- Demo authentication remains the accepted HMAC-cookie PoC mechanism. +- The dependency advisories already documented in final acceptance remain unchanged. + +## Redeploy + +From the workstation, create an archive of the desired committed revision and transfer it +to `.deploy/source.tar.gz`. On Unraid, preserve `.env` and the named volumes, then run: + +```bash +cd /mnt/user/appdata/mobilityops +tar -xzf .deploy/source.tar.gz +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml up --build -d +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T api alembic current +curl -fsS http://127.0.0.1:1236/health +``` + +## Logs + +```bash +cd /mnt/user/appdata/mobilityops +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml ps +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml logs --tail=200 +docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml logs -f api web n8n +``` + +## Safe rollback + +Choose a known-good commit on the workstation, archive and transfer it as above, then on +Unraid extract it over the identifiable MobilityOps source directory and run the same +`up --build -d` command. Preserve `.env` and both named volumes; do not use `down -v`, +remove volumes, prune Docker, or modify unrelated containers. Check the target commit's +Alembic compatibility before rolling application code behind the current database schema.