Phase 10: regression bench, hardening, archive location, native VM kit, go-live docs #55

Merged
spencerm merged 10 commits from phase-10 into main 2026-11-03 21:16:19 +00:00
2 changed files with 18 additions and 4 deletions
Showing only changes of commit c52edfa9b1 - Show all commits
+14
View File
@@ -25,12 +25,20 @@ All notable changes to this project are recorded here. The format follows [Keep
### Fixed
- The MTR viewer showed PDF certificates in a frame the server's own headers refuse, so Chrome showed nothing. It now draws them with the drawing viewer.
- Gitea issue 42: work-order text on the traveler stays inside its own box. Each line shrinks down to 70 percent of its size, then is cut with "...", so a long work order, operation or drawing no longer runs over the next QR code. The gap between work-order boxes is 18 pt, a quiet zone for the kiosk scanner. On the Work orders tab the card text wraps inside the card, the work order is 22 px and cards are at least 340 px wide, one per row on a narrow screen.
- Board columns are frames about three cards tall (700 px, never taller than the screen) that scroll on their own, with the column heading staying put, so a long column no longer pushes the next one far down the page. Narrow screens keep the plain one-column flow.
- Sign-in refused as cross-origin in Firefox: the app sent `Referrer-Policy: no-referrer`, under which Firefox sends `Origin: null` on same-origin POSTs. The policy is now `same-origin`, which still sends nothing to other sites.
### Changed
- Phase 10: the content security policy is final. Styles no longer need `'unsafe-inline'`, `data:` images and `blob:` workers are gone, and `frame-src` and `object-src` are `'none'` (a PDF opened in its own tab gets `object-src 'self'` so the browser can show it). The print area's rules moved into the theme stylesheet.
- Phase 10: backups and the restore run on the VM with `pg_dump` and `pg_restore` as the postgres user, with no `docker exec`. Same markers, 7 dumps and the 02:00 timer.
- Phase 10: security fixes in the pinned dependencies found by the CI scan: `pypdf` 6.21.2 to 6.21.4, `pyasn1` 0.6.4 to 0.6.5, and `certifi` to 2026.10.23.
- Phase 10: SECURITY.md is rewritten around the requirement ID table. O3, O4 and D6 are closed, S1 is tuned and S4 (the pentest) stays with IT.
- The env examples set `SITE_ID=PESCO` and leave `MFILES_CA_BUNDLE` unset, as DEPLOY.md says.
- Gitea issue 1 (change C1): over target follows the VISUAL ticket hours, not the station timer. A packet is over when its ticket hours are above its work-order target; a packet with no ticket hours is not over. The PM hours tables, the "Packets over target" table, the KPI, the summary line, the CSV and the report PDF follow. The columns read "Timer h", "Ticket h", "Target h", "Ticket variance h", "Ticket h / target" and "Over target (tickets)", and the over table ends with "Over by (tickets)". The timer is still shown.
- Gitea issue 24 (change C2): a Q.C. reject always needs a reason of at least 8 characters; an NCR number may go with it but no longer stands in for it. A packet rejected without an NCR number cannot be accepted, to complete or to another department, until Q.C. enters the NCR number (422 `ncr_required` "Enter the NCR number of the reject first."). The number is stored on the accepting inspection and in the log. The Q.C. bar shows the NCR field as required (`ncr_required` on the packet read). An NCR document added to the packet goes into section 5 of the data book.
- Gitea issue 25 (change C3): a packet cannot be filed while its unit's ITP is not complete (precondition `itp_complete`, "Complete the unit's ITP first. Q.C. signs it off on the ITP page."). A unit with no ITP does not block. The close panel shows the reason under File.
@@ -51,6 +59,12 @@ All notable changes to this project are recorded here. The format follows [Keep
### Added
- Phase 10: archive location (Gitea issue 7). With `ARCHIVE_ROOT` set, an Admin picks the archive folder under Admin, Storage, File locations. The folder must be under the root: `..`, absolute paths elsewhere and links that leave the root are refused, and nothing creates folders. Check writes, reads back and removes a probe file. Save runs the same check first. Each filing is copied to `<folder>/<project>/<unit>/<data book>-seal<id>/`: the sealed data book, the drawing pages, the packet documents, the unit's and project's Q.C. folder documents, the MTRs and a `manifest.json` with every file's sha256. The new `archive-copy` job runs every 15 minutes and right after each filing. A failed copy never blocks filing. It is retried after 5, 15 and 60 minutes, then hourly, and raises the critical `archive_failed` notification after 3 tries; "Retry now" asks for a run. Turning the archive on later also copies earlier filings. Nothing in the archive is overwritten or deleted. Every setting change, check and copy is audited. `packetstation doctor` checks the folder. Migration 0012 adds `archive_copies`.
- Phase 10: a banner tells everyone when the server was updated ("Packet Station was updated. Reload to get the new version.") with a Reload button. It checks on focus, on return to the tab, on an event-stream reconnect and every 5 minutes. It never reloads by itself.
- Phase 10: native VM install kit in `deploy/vm/` for production and test, each on its own Linux VM without Docker: systemd units for the app, the worker, the migration and a firewall that lets only NPM reach port 8000; a launcher that hands each unit only its own secrets; `install.sh` (PostgreSQL 16, ODBC Driver 18, the PESCO CA, the service user and folders) and `upgrade.sh` with rollback; `ps-run`, `ps-doctor`, env examples with explicit `VISUAL_SERVER` and `VISUAL_DATABASE`. DEPLOY.md has the steps, the NPM proxy hosts for the VMs and the archive NFS mount.
- Phase 10: regression bench. The old build's 38 scenarios are mapped to Playwright specs in `tests/e2e/BENCH.md`; the missing ones are new specs on synthetic fixtures, and every scenario fails on a CSP violation.
- Phase 10: GO-LIVE.md (date and feed boundary, groups, tablets, URL, cut-over, retiring M: as a read-only archive, production start, checklist, incident notes) and PAPER-FALLBACK.md (what each department does while the server is down and how paper is entered back).
- Gitea issue 18 (change C7): the department supervisor approves every received short, one receipt at a time, with a signature ("Approve a received short"), after checking the part and its heat number against what the warehouse issued. A lead is not enough. The Materials tab lists each receipt with who received it and who approved it, and an Approve button for the supervisor. A packet cannot be accepted as complete, or filed, until every short is received and approved ("Every short must be received and approved by the supervisor first."). Accept and route to another department does not wait. `POST /api/packets/{id}/shorts/receipts/{receipt_id}/approve`; the packet read gains `shorts` and `shorts_unapproved`. Migration 0011 adds the append-only `short_approvals` table.
- Gitea issue 23 (change C8): checklists per department. The Checklists screen (`/checklists`) lets a department supervisor edit their own department's checklist, and Admin any department's; a lead and Q.C. cannot. A department without its own list uses the default for its kind (weld or plain). A save needs a password session and the version it started from, and is audited (`checklists.dept_updated`). A stage keeps the list it had when work started (`packet_stages.checklist_template`, migration 0011), so a change reaches only stages not yet started. The Admin Checklists tab now edits department lists too. `GET /api/checklists`, `GET` and `PUT /api/checklists/{dept}`. The Q.C. check items are unchanged.
- Gitea issue 32 (change C9): the Stamp check screen (`/stamp-check`) for Admin, Q.C. and Clerical, in a password session. `POST /api/stamp-verify` and `POST /api/stamp-verify/pdf`; the `/api/admin` paths stay as aliases with the same rule.
+4 -4
View File
@@ -6,7 +6,7 @@ This repo is the rebuild of Packet Station as a server application: Docker Compo
## Status
**Rebuild in progress. Phase 9 done: the Admin page completed (departments, profiles with the CSV import, checklists, security settings and alerts, the access log, who is in, the stamp check), the nightly AD reconcile and the 15-minute role refresh, the integrity job, notifications by email with rules per event, nightly database backups with a rehearsed restore, and dependency scanning in CI. SethD's changes C1 to C11 (Gitea, 2026-10-26 and 2026-10-28) were built on 2026-10-30.**
**Rebuild built, go-live pending. Phase 10 done (2026-10-30): the regression bench, the final CSP and dependency scan, the build-version banner, the archive copy of every filing to the QNAP share, the native VM install kit, and the go-live, paper-fallback and security docs. Phase 9: the Admin page completed (departments, profiles with the CSV import, checklists, security settings and alerts, the access log, who is in, the stamp check), the nightly AD reconcile and the 15-minute role refresh, the integrity job, notifications by email with rules per event, nightly database backups with a rehearsed restore, and dependency scanning in CI. SethD's changes C1 to C11 (Gitea, 2026-10-26 and 2026-10-28) were built on 2026-10-30.**
People can sign in, set up projects and units, make hand drafts, attach a drawing, and send a packet to the warehouse, a department or Q.C. The worker reads released work orders from VISUAL on a schedule, makes and updates drafts, opens change orders on packets already in the shop, looks drawings up in M-Files and attaches them at the rev VISUAL calls. Clerical sees it all on the From VISUAL panel and in the Flagged and Changes to approve columns; Admin sets the feed up on the Feed tab. Warehouse works its task board (waiting, being pulled, on hold, pulled, released), pulls parts line by line with heat numbers, shorts, receipts and MTRs (the department supervisor then approves each received short with a signature), and releases to the supervisor once every line is pulled or short and every pulled line has a heat. A supervisor assigns the packet to a station and a welder. The welder's Stall screen lists the packets assigned to them, each at the station the supervisor picked. The welder starts the clock, marks welds on the drawing, places the heat table, finishes the checklist and submits with a PIN signature, and the supervisor sends it to Q.C. or routes it to another department with the marks carried. Department supervisors verify change orders with a signature. Q.C. inspects the packet on its own tab (the check items, a visual result per weld, NDE, hardness, notes), accepts it to the data book, to Shipping or on to another department with a PIN signature, or rejects it back to the supervisor with a reason and, when there is one, an NCR number. A packet rejected without an NCR number needs one at the accept, and a packet with a short not yet approved cannot be accepted as complete. Q.C. keeps project folders of documents per project and unit (ITP, WPS / PQR, procedures, certificates) where a new revision supersedes the old one and nothing is deleted, adds reports to a packet for the data book and takes them out with a reason, and works each unit's digital ITP from the Q.C. template through line initials, N/A, rejects with NCR numbers, section block signatures and a sign-off. Open hold and witness points show as a warning on the unit's packets. The feed marks a VISUAL packet closed in VISUAL when it sees every work order closed, and the packet moves to Clerical's "Ready for data book" column by itself; Clerical confirms a hand packet by hand. Clerical files the packet with a signature once VISUAL is closed, the unit's ITP is complete and every short is approved. Filing seals the packet with an HMAC and builds the manufacturing data book on the server, stored on the seal. The data book goes to the customer and has no history pages; the history stays in Packet Station. IT can reopen a filed packet with a reason and a signature, which keeps the broken seal and its data book. Anyone who can open a packet can view or download the data book, the job traveler with the work order QR codes, the ITP PDF and the traceability CSV, and print a stamped copy of the traveler, the drawings with the heat or weld map, the drawings without markup, the VOID sheets, the data book or any document. A print goes straight to the browser's print dialog. Every copy carries a stamp signed with the seal key, and every print and export is logged. Admin, Q.C. and Clerical check a copy's stamp on the Stamp check screen. Project Management and Admin read the PM reports. The ITP sign-off files the signed ITP PDF. Each department supervisor edits their department's checklist on the Checklists screen; a stage keeps the list it started with. An Admin manages departments and stations, welder stamps and station limits (one at a time or from a CSV), any department's checklist, the session and lockout settings, and who gets which email. The worker reconciles users with AD every night, re-reads each signed-in person's groups every 15 minutes, checks seals, files and the audit chain every night, and checks that the nightly backup ran. Problems and events reach people by email through app-03. Every packet write goes through the server policy. The old build on `M:\Production\Packet Station` stays the live system until go-live. The new system starts empty; nothing is migrated from M:.
@@ -24,7 +24,7 @@ People can sign in, set up projects and units, make hand drafts, attach a drawin
| Project Management screen (six tabs, periods, health, CSV and PDF reports), the find bar completed (search, filters, quick flags, Mine, Board and List, saved per browser), presence, motion, iPad layout | Yes (phase 8, verified in the CI stack on docker-1) |
| Admin completion (departments, profiles, checklists, Security, access log, who is in, stamp check, Notifications), AD reconcile and role refresh, integrity job, email notifications, backups and restore, CI dependency scan | Yes (phase 9) |
| SethD's changes C1 to C11: over target on VISUAL ticket hours, the Q.C. reject reason and the NCR on the accept, the ITP complete before filing, prints to the print dialog, filing blocked until VISUAL closes, no history pages in the data book, supervisor approval of received shorts, checklists per department (`/checklists`), the stamp check for Q.C. and Clerical (`/stamp-check`), PM reports for PM and Admin only, the Stall screen by assignment | Yes (2026-10-30) |
| Regression bench and go-live | No (phase 10) |
| Regression bench (the old build's 38 scenarios mapped in tests/e2e/BENCH.md), final CSP, version banner, archive location (Admin, Storage, File locations; `ARCHIVE_ROOT`; the `archive-copy` job), native VM install kit (`deploy/vm/`), backups and restore without Docker, GO-LIVE.md, PAPER-FALLBACK.md | Yes (phase 10). Go-live waits for the VMs and a date |
## Phases
@@ -52,9 +52,9 @@ docs/ the brief, the plan, security, deploy, feed, policy, sche
server/packetstation/ the Python package: app, worker, CLI, migrations, policy, domain, feed, drawings, PDFs
frontend/ Vite + React + TypeScript client
tests/ server tests (pytest), e2e scenarios (Playwright), synthetic fixture generator
deploy/ compose files (base, NPM overlay, CI overlay), PostgreSQL init, Samba AD for CI
deploy/ vm/ (native VM install), compose files (base, NPM overlay, CI overlay), PostgreSQL init, Samba AD for CI
docker/ the image entrypoint
scripts/ host backup and restore scripts, systemd timer
scripts/ backup and restore scripts for the VMs, systemd timer
.gitea/workflows/ CI
```