Calendar cert/invoice check marks (owner-only)
Added: 2026-08-10 (entirely-api a8b8931, entirely-portal de5f04f;
owner-gate + legend c5ff538 / 190414f)
Visibility: up_owner only (Dustin + Jacob), gated in BOTH layers — the
backend returns cert_emailed=False (and skips the lookup) for every other
role, and SubChecks returns null for non-owners. A legend row under the
branch legend (gold ✓ cert emailed / green ✓ invoice sent) is gated the same
way. Note: a future third up_owner account would inherit visibility.
Month, week, and day calendar views (plus the month-view day panel) show sub-workflow completion at the head of each project line, before the branch color dot:
- Gold ✓ (
#c9a227) — certification has been emailed - Green ✓ (
#5a8a5a) — invoice Sent - Black ✓ (
var(--ink)) — invoice Paid (replaces the green check;invoiceCheck()two-state resolver, portalffd1bdd)
Nothing renders until the sub-workflow completes. Colors match
SubTrackIndicator (cert gold / invoice green).
Data flow
- Invoice: already in every event’s description blob
(
Invoice Status: Sent|Paid), parsed client-side. No backend change. - Cert: new
cert_emailed+cert_emailed_atfields onGET /portal/calendar/events, computed by_cert_emailed_map()inroutes/intake.py. Merges three delivery sources, newest first:- email tracking DB (
/data/portal-auth/email_tracking.db) — one batch query viaemail_tracking_service.get_cert_delivery_info - portal state file (
cert_invoice_state/{record_id}.json,cert_state == "sent") CERTS/sent_log.jsonappend-only delivery log
- email tracking DB (
Backfill
No data migration: sources 2 and 3 predate the tracking DB, so historical sends surface automatically. At ship time: 257 projects show the gold check (246 from the tracking DB, 11 only from file sources). Certs delivered outside the portal pipeline (legacy blkhse-era manual Gmail sends) have no delivery record anywhere and stay unchecked — flipping those would require inference from project status, deliberately not done.
Frontend
portal-v2/src/pages/CalendarPage.tsx — SubChecks component + invoiceSent()
helper; render sites: month cell rows, day panel rows, WeekGridView,
DayGridView. CalendarEvent interface gained cert_emailed/cert_emailed_at.