- VISION, ARCHITECTURE, RBAC, COMPLIANCE
- Module specs (COMMS, GRIEVANCE, COLLEGE_BUMPING)
- DATA_MODELS, AGENTS.md
- Cursor rules split (platform, comms, grievance, bumping)
-
seed/reference-tenant-opseu-caat.json - ADRs 007–012
- Auth (Auth.js), MFA scaffold
- Module registry and hub nav
- Audit log foundation
- Refactor OPSEU/CAAT strings to tenant config
- Package rename:
local-union-hub - Multi-union onboarding UI (Phase 6 — memory overlay + invites)
- CRUD, timeline, notes, deadlines
- CAConfig per union
- Email draft templates
- Export grievance bundle
- PDF upload and compare view
- Committee sessions and notes
- Sector module flag per union
- Encrypted local export/import for grievance data
- Optional browser encrypted local slice (backup)
- Bumping cases included in hybrid slice when module enabled
- Officer handoff wizard
- CA clause snippet library (union-uploaded)
- Meeting scheduler (ICS export)
- Member communication log
- Overdue dashboard
- Union template marketplace (within-union sharing)
- Mobile steward read-only mode
- ADR-013 Collection / BargainingUnit under Local
- Multi-local + FT/PT reference seed (
locals,bargainingUnits) -
resolveGrievanceConfig(collection → union) - Hub context switcher (local + collection) + elevated cross-local access fix
- Brand Kit v2 profiles (FT/PT) + Comms copy
- Phase 7 scaffolds: audit UI, attachment API + scan stub, MFA fixed-code verify
- PostgreSQL + Row-Level Security (
unionId/localId/ optionalbargainingUnitId) — Drizzle migrations +unionops_approle; flip via*_DB_BACKEND=postgres - Replace memory adapters with DB-backed stores — per-module Drizzle adapters behind flags (default memory until operators flip)
-
ApiAdapterfor hub clients — opt-in server persistence for Brand Kit + preferences (/api/brand-kit,/api/preferences); default remainsLocalStorageAdapter - Multi-union tenant onboarding / invite UI (create locals + collections; runtime overlay;
/app/onboarding,/app/invites,/app/invite/[token]) - Hybrid live local data path (optional offline source of truth)
- Attachment metadata API + memory adapter + scan stub (
skipped_dev) - Audit log query UI (
/app/audit) for elevated officers - MFA no longer accepts arbitrary 6-digit codes —
AUTH_DEV_MFA_CODE/AUTH_MFA_CODE(default000000) - Object storage + real virus scanner — local FS + S3-compatible SSE-S3; ClamAV HTTP via
ATTACHMENT_SCANNER_URL - Grievance detail UI for attachments — list/upload/download panel in
GrievanceDetail, role-gated byuseStewardReadOnly - Server-side bumping attachments (light) —
AttachmentAdapter.createForBumping/listForBumping,/api/bumping/cases/[id]/attachments, UI panel inBumpingCaseDetail(canWritegated); client-side PDF text-extract on the New Case form is unchanged - TOTP enrollment UI (
/app/mfa/setup) — QR + manual secret, confirm-before-persist, demo-memory or Postgresuserstable depending onAUTH_USERS_BACKEND - Retire
shared_code_insecureas a viable production mode when MFA is on —AUTH_MFA_ENABLEDopt-in (default off for demos); when enabled, production requirestotpunlessAUTH_ALLOW_SHARED_MFA_IN_PROD=true; unenrolled users redirected to/app/mfa/setup
8-lite + 8-lite+ shipped — memory adapter; clock in/out, manual/retro ranges, bulk event groups, expected windows, entry-needed tracking, approvals, CSV + union-business report at /app/time.
- Module
"time"in registry + reference seed - Clock in/out for staff, release, duty bank, action, volunteer categories
- Manual past ranges + admin bulk union-business entries
- Expected windows + weekday gap “entry needed” board
- Submit/approve workflow + admin board + date-scoped CSV / union-business report
- Optional GPS punch tagging (client consent checkbox)
- Postgres + RLS persistence (
TIME_DB_BACKEND=postgres; memory default) - Sites / geofence admin + bulk approve + XLSX/PDF rollup (8b, 2026-07-24)
- Full workers directory, OT policies, shift recurrence, auto-accrual, groups, payroll hooks (8-full, 2026-07-26)
- Punch photo attachments + hybrid time slice v1.1 (8f, 2026-07-26)
Spec: docs/modules/WORKFORCE_TIME.md
Why: Stewards trust the on-screen preview. Playwright used to only visit tools — it did not assert PNG/PDF downloads. Flyer PDFs could ship multi‑MB uncompressed embeds; mobile preview scale() could bake into captures.
Shipped:
| Step | Outcome |
|---|---|
| 9a | Capture hardening — src/lib/export/capture.ts (unscale ancestors, inline computed styles, pinned box); Flyer inline aspectRatio + capture-safe header type; PDF pages re-encode PNG→JPEG |
| 9b | Fidelity helpers — src/lib/export/fidelity.ts + unit tests (capture.test.ts, fidelity.test.ts) |
| 9c | Playwright @smoke downloads — e2e/tools.export.smoke.spec.ts (Flyer PNG/PDF, Graphic PNG, Board Notice PDF) |
| 9d | Solidarity stretch — Solidarity Poster PNG output smoke |
Tickets TOOL-008 / TOOL-009 closed.
| Step | Outcome |
|---|---|
| 9e | Preview/capture ↔ download comparison — compareRasters + e2e/tools.export.fidelity.spec.ts (@export); data-export-root + ExportCaptureBridge; run npm run test:export |
Residual: optional CI job for @export if smoke runtime budget is tight; tighten PDF JPEG thresholds as capture improves.
-
LocalMeetingScheduleentity (unionId,localId, monthly/custom recurrence, time, location,publicBlurb, timezone,publicSlug); memory + optionalMEETINGS_DB_BACKEND=postgres, migration0018_local_meeting_schedule+ RLS - Hub
/app/meetings— configure schedule (president/exec/admin write, others read), computed next-meeting date,.icsdownload with optionalVALARM, copy public share link - Officer in-app reminder banner (
MeetingReminderBanner, reusesDemoSiteBannerlayout pattern) — shows within 7 days of the next meeting, no auto-email - Public "next meeting" page
/meetings/[slug]+ reusableNextMeetingSnippet— no PII, no union/local ids, for embed/share -
RRULE-equivalent recurrence math (src/lib/meetings/recurrence.ts) — monthly-by-date, monthly-by-nth-weekday, or custom date list - Phase B/R1+ (tokenized RSVP + transactional SMTP) —
UnionMeeting/RsvpToken/RsvpResponse,/r/[token],EMAIL_ENABLED+ nodemailer (ADR-016); seedocs/modules/CALENDAR_MEETINGS.md
OPSEU/CAAT launches first. Seed: seed/reference-tenant-opseu-caat.json.
Agent guidance: .cursor/rules/roadmap-next.mdc, .cursor/rules/hybrid-qol.mdc.