M28: complete production acceptance
MobilityOps acceptance / backend (push) Canceled after 0s
MobilityOps acceptance / frontend (push) Canceled after 0s

This commit is contained in:
NuklearRabbit
2026-08-10 16:34:56 +02:00
parent e1b700b10e
commit 6365586e82
2 changed files with 38 additions and 1 deletions
+36
View File
@@ -2611,3 +2611,39 @@ evidence yet."
vulnerabilities.
- Exact next action: commit/push, take a verified pre-deployment backup, redeploy to
Unraid, then run migration, health, browser and full Playwright acceptance.
## M27 — portable backup evidence (2026-08-10)
- Live restore-readiness validation found that scheduled checksum files named their dump
with the container-only `/backups` path. Dumps were structurally valid, but host-side
`sha256sum -c` could not resolve that path.
- Scheduled and on-demand backups now write basename-only checksum entries, so dump plus
sidecar remains verifiable after copying to the host or an independent secondary
destination.
- Evidence: Alpine shell syntax passed; the recreated live backup service produced
`mobilityops-20260810T141944Z.dump`; checksum validation and `pg_restore --list` both
passed through the documented host verification command.
## M28 — final production acceptance and hand-off (2026-08-10)
- Pushed milestones M21M27 to Gitea `master`, deployed committed source archives to
`/mnt/user/appdata/mobilityops`, and applied migration `b913a72e8c14 (head)`. Public
passwordless demo access remains enabled; OIDC remains an optional disabled addition.
- Activated the pinned internal Prometheus/Grafana profile with a server-generated
Grafana password and loopback-only ports. Prometheus reports the API target up; all six
alert rules evaluate healthy; Grafana 12.2.0 reports database `ok`. API, database, web,
scheduled backup, Prometheus and Grafana are running, while the existing shared n8n
remains the only n8n instance used by Fleet Ops.
- Live visual acceptance covered desktop dashboard and knowledge statistics plus Privacy
at desktop and a fresh 390 × 844 load. There was no horizontal overflow; the mobile
shell starts closed and the irreversible privacy action remains guarded.
- Complete live Playwright acceptance is **147 passed in 4.6 minutes**. A race in the new
privacy test login helper was removed by waiting for the authenticated dashboard; the
privacy pair also passed three consecutive repetitions before the full green run.
- Final demo reset restored **2 users / 180 customers / 50 vehicles / 254 bookings / 75
inspections / 40 maintenance records / 33 quality issues / 20 workflow runs**. API
readiness is `ready`, RAGcore is available with 11 authoritative NL sources and an
honestly unknown provider index count, and the latest backup verifies. No API/backup
error or traceback appears in post-deployment logs.
- Exact next action: none for the selected scope. Optional secret rotation and new n8n
execution evidence remain intentionally deferred by the user.
+2 -1
View File
@@ -5,13 +5,14 @@ async function resetAndLogin(request: APIRequestContext, page: Page) {
await request.post("/api/v1/demo/reset");
await page.goto("/login");
await page.getByRole("button", { name: "Verken als Operationsmanager" }).click();
await expect(page).toHaveURL(/\/dashboard$/);
}
test("privacy centre reports policy and produces an audited CSV export", async ({ page, request }) => {
await resetAndLogin(request, page);
await page.goto("/privacy");
await expect(page.getByRole("heading", { name: "Privacybeheer" })).toBeVisible();
await expect(page.getByText("30 dagen")).toBeVisible();
await expect(page.getByText("30 dagen", { exact: true })).toBeVisible();
const downloadPromise = page.waitForEvent("download");
await page.getByRole("link", { name: "Audit CSV downloaden" }).click();
const download = await downloadPromise;