Phase 9: Admin completion, reconcile, notifications, integrity, backups
Admin: Departments (name and stations; add shows the three groups IT must create), Profiles (welder stamp, station limits, active) with a CSV import that previews and applies only when clean, Checklists (weld and plain), Security (session, lockout and rate-limit settings with bounds, alerts for the last 24 hours, the integrity result), Access log with filters and a guarded CSV, Who is in, Stamp check, Notifications, and the employeeID flags. Every Admin change is audited. Worker: ad-reconcile (nightly and on "refresh from AD now"), session-refresh (15 minutes), integrity (seals, asset hashes, missing and orphan files, the audit chain), backup-check, notify-send and notify-digest. Notifications route per event type to AD groups, users, mailboxes or the department Supervisor group, immediately or in a daily digest, over STARTTLS verified against the PESCO CA, with dry run on the test stack. Backups: scripts/backup/ps-backup.sh and ps-restore.sh with a systemd timer at 02:00 America/Denver. Restore rehearsed on the test stack 2026-10-21. CI: pip-audit and npm audit. pypdf 6.21.1 and certifi 2026.10.19. Migration 0010. Closes the app part of I6, M3, O1, O2 and S3. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -19,12 +19,38 @@ All notable changes to this project are recorded here. The format follows [Keep
|
||||
|
||||
### Changed
|
||||
|
||||
- Security fixes in the pinned dependencies, found by the new CI scan: `pypdf` 6.21.0 to 6.21.1 (GHSA-5hx5-vpf9-5wcv, a crafted PDF could reach the image parsers) and `certifi` 2026.7.22 to 2026.10.19 (PYSEC-2026-4320, a distrusted root removed). The image must be rebuilt for both to reach the stacks.
|
||||
- `POST /api/admin/ad/refresh` no longer runs the AD refresh in the request. It asks the worker for an `ad-reconcile` run and answers 202 `{requested, pending, job}`; `GET /api/admin/ad/reconcile` gives the latest report.
|
||||
- The storage quota alert is now mailed through the Notifications rules (to PS-Admins by default), with a "Cleared" message when usage drops back.
|
||||
- The session, lock and sign-in limit settings can be overridden on the Admin Security tab; the environment values are the defaults.
|
||||
- `deploy/env/prod.env.example` sets `BACKUP_DIR=/var/backups/packetstation/prod`, as the brief and the docs say.
|
||||
- Gitea issue 44: the packet tabs put Materials before Heat map.
|
||||
- Gitea issue 45: Admin and Clerical sessions wait 60 idle minutes before the screen lock and before signing out (`SESSION_DESK_MINUTES`, default 60; it never shortens `SESSION_LOCK_MINUTES` or `SESSION_IDLE_MINUTES`). Everyone else keeps 3 and 15. `GET /api/auth/me` answers the session's `lock_minutes` and the browser's idle lock follows it. The hidden-tab lock after a minute is unchanged.
|
||||
- VISUAL is the source of truth for the drawing rev. When M-Files' Effective rev differs from the rev VISUAL calls but M-Files still holds that rev as Retired (or Effective), the drawing job attaches it to the draft with no flag and no Clerical approval, and the packet page says the drawing is retired in M-Files. Any other M-Files status, or no document at that rev, still flags `rev_mismatch`; Packet Station only ever attaches Effective or Retired drawings. This replaces the "Use rev V as VISUAL calls it" choice from issue 41. Needs MFilesKit 0.1.3 (`DrawingLookup.revision`) and migration 0009.
|
||||
|
||||
### Added
|
||||
|
||||
- Phase 9: Admin completion, AD reconcile, integrity, notifications, backups. The Admin page gains eight tabs: Departments, Profiles, Checklists, Security, Access log, Who is in, Stamp check and Notifications. The tab list wraps into rows on a narrow screen.
|
||||
- Departments tab: every department with its AD groups (and whether each is in the OU) and its stations. Edit a department's name, turn it on or off, rename, reorder, add or hide stations. Stations are never deleted, since station limits and packets point at them. The code and the short name cannot change. "New department" adds a shop department with its stations and shows the three AD groups IT must create (`PS-<code>-<short name>-Worker`, `-Lead`, `-Supervisor`) before it is saved. Only shop departments can be added; the support departments are fixed.
|
||||
- Profiles tab: a person's welder stamp (1 to 12 letters, numbers or dashes, unique), whether their profile is active, and their station limits per department. An inactive profile drops out of the welder picker and the worker filter; it changes nothing the person may do. A CSV import by employee ID (columns `employee_id`, `welder_stamp`, `active`, `stations`; an empty cell leaves a value, `-` clears it; the `stations` cell is the person's whole list) shows a preview with every change and every error, and applies only when the preview has no errors, in one go. The Directory flags panel lists active users with no employee ID and employee IDs shared by more than one account.
|
||||
- Checklists tab: edit the weld and plain station checklists (group, key, text, order; at most 40 items; the placeholders `{drawing}`, `{rev}` and `{wps}`). A saved key cannot be renamed. A removed item drops out of new checklists only; open stages keep their answers. "Use the default list" restores the old build's list.
|
||||
- Security tab: the session, lock and sign-in limit settings with their bounds (the per-account failure limit stays at 15 or under, below AD's 20), applied without a restart. Security alerts for the last 24, 72 or 168 hours: account cooldowns, repeated wrong PINs, wrong PINs or passwords at unlock or signature, denied actions, sign-in bursts, Admin changes, IT edits and integrity findings, with a filter per kind. The last integrity run and its findings.
|
||||
- Access log tab: every sign-in attempt and every sign-in, session, PIN, device and signature audit row for everyone, filtered by time, person or account, kind, result and address (or address range), 200 rows at a time, and downloaded as CSV (at most 50,000 rows, with the formula guard, logged in the print log and the audit).
|
||||
- Who is in tab: the live sessions, with the kind, device, address, when seen, locked or active, and the screen and packet the person has open. Refreshes every 30 seconds.
|
||||
- Stamp check tab: paste a stamp line from a printed or exported copy, or just its 16-character code, or upload the PDF, and the server says whether it is genuine, does not verify, or was never printed, with who printed what and when.
|
||||
- Notifications tab: one rule per event type (13 of them), each on or off, sent at once or in a daily digest at a set time, to AD groups (found with a directory search), single users, mailboxes, or the Supervisor group of the event's department. People can be left out of a rule, except on the three security event types. A test send goes to the rule's recipients or to one address, even on the test stack. The sent log lists every message with its recipients and the result. Every rule starts on, sent at once, to PS-Admins.
|
||||
- Account settings: a Notifications section that shows each event that reaches the person and why (a group, the Supervisor group of a department, a mailbox, by name), with an opt-out per event in a password session. Security events cannot be turned off.
|
||||
- Email through app-03 with STARTTLS and the PESCO CA, never in plain text. Subjects start `[Packet Station]` on production and `[Packet Station TEST]` elsewhere. Recipients are in the envelope only, so nobody sees the list. The test stack records messages without sending them (`NOTIFY_DRY_RUN`), except a test send. Standing problems (feed failed or degraded, drawing lookups failing, change order waiting, group missing, backup stale, integrity failure, storage quota) send once when they start and a "Cleared" message when they end.
|
||||
- Events raised: account cooldowns, a PIN disabled, a session ended after wrong PINs, sign-in bursts (one address over its limit, or 20 failed sign-ins across accounts in 5 minutes), integrity failures, failed and degraded feed runs, drawing lookups failing for more than 24 hours, change orders waiting for review more than 3 days, Q.C. and ITP rejects (to the department), the AD reconcile report, groups missing from the OU, a stale backup, a new version deployed and the storage quota (Gitea issue 20).
|
||||
- The AD reconcile every night at 01:30, and on "Refresh from AD now", which now asks the worker for a run and shows "Refresh requested" and the latest report: groups missing from or extra in the OU, users seen, added, updated and deactivated, sessions ended, and employee ID problems. A user disabled or gone in AD is marked inactive and signed out; a user left with no group is signed out. The reconcile refuses to change anything when no mapped group is in the OU, or when every group is empty while active users exist. A run that fails or refuses sends one "AD reconcile did not run" notice until a run succeeds.
|
||||
- The role refresh every 15 minutes (a Security setting): every signed-in person's groups and account state are read again from AD, their roles and sessions updated, and anyone disabled, gone or left with no role signed out. AD down changes nothing.
|
||||
- The integrity job every night at 04:00: every seal of a filed packet checked with the seal key, asset files rehashed (uploads of the last 7 days every night, all of them on Sundays), asset rows with no file, files with no asset row (reported, never deleted) and the audit hash chain. Findings are kept and raise an alert; a clean run clears it.
|
||||
- Nightly database backups on docker-1: `scripts/backup/ps-backup.sh` with a systemd timer at 02:00 Denver time, an hour before the Proxmox backup. Each stack's database is dumped with `pg_dump -Fc` plus the roles without passwords, checked with `pg_restore --list`, 7 kept, with `last-success` and `last-failure` markers. The worker's backup-check job at 07:15 raises an alert when the newest dump is missing, empty, older than 26 hours or followed by a failure. `scripts/backup/ps-restore.sh` restores a dump into a fresh database, copies assets back without overwriting, checks every asset hash and prints row counts. The restore was rehearsed on the test stack on 2026-10-21: every table's row count and all 189 asset hashes matched.
|
||||
- Denied actions are audited (`policy.denied`, method, path and code only), as are account cooldowns (`auth.lockout`) and sign-in bursts (`auth.signin_burst`). Every Admin change is audited with before and after.
|
||||
- CI dependency scanning: `pip-audit` over `server/requirements.txt` fails on any known vulnerability; `npm audit --audit-level=high` fails on a high or critical one.
|
||||
- Migration 0010: notification rules, recipients, exclusions, outbox and the sent log, the event columns for delivery, `integrity_findings`, `users.profile_active`, `assets.hash_checked_at` and `hash_ok`, `departments.created_at` and `created_by`.
|
||||
- Tests: every new Admin endpoint as every role (Admin password session 200, Admin PIN session 403, every other role 403, anonymous 401), departments, profiles and the CSV import, checklists, security settings and their effect on the limits, alerts, the access log and its CSV, presence and the stamp check; event raising, recovery, routing, the SMTP path against a local relay with STARTTLS, digests and directory failures; the reconcile, the role refresh, the integrity job (a tampered seal, a changed, missing and orphan file, an edited audit row) and the backup check; the backup script with a fake `docker`; frontend tests for every new tab and the Account section; Playwright scenarios for Departments, Notifications, Security, the access log, the stamp check and Who is in.
|
||||
- docs/SCHEMA.md, POLICY.md, SECURITY.md (I6 app part, M3, O1, O2 and S3 closed), DEPLOY.md and FEED.md updated; PLAN.md open questions 43 to 50.
|
||||
|
||||
- Phase 8: Project Management, the find bar, presence and motion. The Project Management screen (`/pm`, view only) with the tabs Overview (the headline numbers, a plain-words summary, the pipeline by step with the slowest step in pink, the units late or at risk), Projects & units (every project with its units, due date, days left, packets by step, % done and health: On track, At risk, Late, Complete, No packets yet; a project is as healthy as its worst unit; tap a project for its units and a unit for its jobs), Bottlenecks & aging (time in the current step, every open packet longest waiting first with over 3 days flagged, average time per step for completed moves), Hours vs target (station timer hours and VISUAL ticket hours side by side against the work-order target by department, worker and project, plus every packet over target), Quality & issues (Q.C. rejects, open shorts, open change orders, warehouse holds, sent back) and Find jobs. The period picker (30 days, 90 days, 12 months, all) sets the window for history figures. Every table has Excel (CSV); "Excel (CSV) — all" saves every report; "PDF report" builds the PESCO production status report (cover with the headline numbers, summary and pipeline, projects, flow, labor, issues) on the server with the controlled-copy stamp. Every export is logged as "report exported" in the audit and the print log.
|
||||
- The find bar on every home screen: search over project number or name, lot, operation, drawing and rev, WPS, customer, PO, old project numbers, work orders, heat numbers, part IDs, welder name or stamp, change order and ECN numbers, with several words narrowing and Esc clearing; the project then unit picker; Filters with Department, Status (including At a station and Everything not filed), Station, Worker and, for Clerical and Project Management, the flag kind; the quick flags Change order open, Shorts open, Project overdue, Due within 7 days and Mine (what that screen is responsible for; hidden on the station and Project Management screens); Board or List with the list sortable by last updated, project / lot, due date, status or department. Filters and the view are saved per browser (`ps.flt`); the search text is not. Tapping a number tile shows only those jobs; tapping again clears. The numbers follow the project pick but not the other filters.
|
||||
|
||||
Reference in New Issue
Block a user