M28: complete production acceptance
This commit is contained in:
@@ -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 M21–M27 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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user