2 Commits

Author SHA1 Message Date
6034c08bad Alembic runs one transaction PER MIGRATION, not one for the whole chain
The 2026-08-21 crash at material_items printed 'Running upgrade' lines for
location_nodes and wp_files and then rolled all three back together - env.py
wrapped the entire run in a single transaction. The repair that followed
trusted those lines: material_items was hand-created, the version stamped to
head, and production ran for two days missing two tables it claimed to have.
Found 2026-08-23 when the locations import 500'd on UndefinedTable.

transaction_per_migration=True makes the log truthful: a crash keeps every
step that completed, and a stamp-to-head repair after a crash repairs ONE
migration, not an unknowable prefix of the chain. Verified: the full chain
still applies on a fresh scratch SQLite; the offline --sql render is
unchanged.

The production surgery (creating the two rolled-back tables from the offline
postgres render) is recorded in the session; no version stamp is needed
there - it is already, now truthfully, at head.

Items: BL-027's class, third finding; env.py infrastructure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 15:35:36 -07:00
39b48055ff Productionize WP Suite: auth, security hardening, sync, dashboard, PWA, email
Brings the Work Package Suite from a browser-local prototype to a
multi-tenant, SQL-backed deployment hardened for customer IP.

Auth & access control
- Local username/password login (bcrypt + JWT in an HttpOnly cookie),
  admin-managed users, per-project membership, and project-scoped API access.
- Admin console: change user roles, view the audit trail, manage settings.

Security hardening
- CSP / HSTS / X-Frame-Options / nosniff headers in nginx; Secure cookie via
  X-Forwarded-Proto; CSRF Origin check; attribute-safe output escaping.
- Login lockout, token_version session revocation, stronger password policy,
  fail-closed secret loading, encrypted (AES-256) database backups.

Persistence & schema
- SOPs and Work Packages are now DB-backed and shared across users, written
  through a durable client sync outbox that queues offline edits.
- Alembic migrations applied automatically on container start.

New capabilities
- Phase 2 dashboard (progress, gating, pagination, archive).
- Phase 3 PWA "Field View" with offline caching and auth fallback.
- WP owner assignment with OPTIONAL email notifications, OFF by default and
  toggled from the admin console. SMTP password is read only from the
  SMTP_PASSWORD env var (never stored); emails carry a WP number + deep link,
  never customer IP.

Also: IBM Carbon restyle, Help section, and DEPLOYMENT.md brought up to date.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:51:15 -07:00