Build Log · August 28, 2026
MedinaCHF — Onboarding Simplification, a Self-Hosted Invite Email, and a Live Production Outage Fixed
Courtney's live-member-test brief asked for less friction between invitation and Member Home. Building it surfaced that Clerk's invitation email needs a paid plan to customize, which led to a bigger decision (create Clerk accounts directly, send our own email) that a real account-deletion bug and a Crucible council review both caught and fixed before it shipped. A live production 500 (a missing table from an unrelated prior session) was found and fixed mid-session using the same evidence discipline. Two smaller features (RSVP manual correction, membership-progress event list) and two small bug fixes closed out the session.
- MedinaCHF
- Onboarding
- Clerk
- Crucible
- Production Incident
- real bugs found and fixed in the new account-creation logic before deploy (one could have deleted a real member's Clerk account)
- 2
- live production outage found via real Vercel logs and fixed (missing admin_intents table, unrelated to this session's own changes)
- 1
- separate feature/fix threads shipped and deployed: onboarding simplification, self-hosted invite email, RSVP manual correction, and two small UI bug fixes
- 4
real bugs found and fixed in the new account-creation logic before deploy (one could have deleted a real member's Clerk account)
live production outage found via real Vercel logs and fixed (missing admin_intents table, unrelated to this session's own changes)
separate feature/fix threads shipped and deployed: onboarding simplification, self-hosted invite email, RSVP manual correction, and two small UI bug fixes
Timeline
Start
Charge received from Courtney via Zeb: simplify onboarding after a live member test
Remove the /welcome install-choice screen and the first-login Getting Started card; route straight to Member Home
Build
Removed /welcome and GettingStartedCard, relocated Add-to-Phone into Help
Verified via real tsc + production build + live curl checks against the deployed routes
Scope growth
Zeb asked whether the invitation email could be customized — Clerk's template requires a paid plan
Investigated, then Zeb chose to create Clerk accounts directly and send ForgeKit's own email instead of upgrading Clerk
Bug found
A real Clerk account created with the notification email held back has no adults.clerkUserId until the member signs in
An earlier version of the shared helper treated that null as 'no account exists' and would have called the orphan-cleanup function, deleting the real account on a later retry
Crucible
Ran crucible:council (architect + qe) on the account-creation design before deploying
Council flagged the same fail-open pattern recurring in a second function (updateMemberOnboardingStatus) and called for one shared, fail-closed Clerk-lookup helper
Fix + deploy
Centralized the Clerk-existence check into resolveClerkAccountForEmail, fails closed on API uncertainty
tsc + production build re-verified clean, deployed to medinachf.forgekits.build
Live incident
Zeb reported /coordinator/settings throwing a live error mid-session
Pulled real Vercel production logs first — found relation "admin_intents" does not exist, a table defined in schema.ts by a prior session but never pushed to production
Fixed + verified
Pushed the missing table to production, independently confirmed via information_schema, confirmed the live page recovers
Root cause predates this session entirely — surfaced only because Courtney/Zeb happened to load that page
Feature
Added coordinator RSVP manual add/remove, mirroring the existing attendance-correction pattern
Mainly for correcting completed-event records — coordinator-only, org+event scoped
Close
Two small bug fixes along the way (a mislabeled button, the Add Member panel's width/required-field visibility)
All four feature threads verified and deployed to production before this retro was written
What shipped
products/medinaCHF/app/member/layout.tsx, app/member/page.tsx — removed the /welcome redirect and the Getting Started card; a newly onboarded member lands directly on normal Member Home
products/medinaCHF/app/welcome/page.tsx, components/GettingStartedCard.tsx — deleted entirely
products/medinaCHF/app/member/help/page.tsx — relocated AddToPhoneButton here as an optional resource
products/medinaCHF/lib/emails/member-account-ready.ts — new self-hosted HTML/text invitation email matching Courtney's copy
products/medinaCHF/lib/email.ts — added sendHtmlEmail
products/medinaCHF/lib/actions/member-management.ts — createMemberAccountDirect, createClerkAccountForAdult, resolveClerkAccountForEmail, updateMemberOnboardingStatus; createMemberManually now always creates the Clerk account inline with an optional sendAccountEmail flag
products/medinaCHF/components/coordinator/AddMemberButton.tsx — 'Send account email now' checkbox, wider panel, visible required-field markers
products/medinaCHF/components/coordinator/MemberDetailPanel.tsx — 'Send Account Email (ForgeKit)' button, manual onboarding-status override control
products/medinaCHF/tests/e2e/armory/coordinator-member-management.spec.ts — updated for the new Add Member button label/checkbox, added a held-back-email regression test
products/medinaCHF/lib/db/schema.ts — admin_intents table pushed to production (fix for a live outage; schema itself predates this session)
products/medinaCHF/lib/actions/rsvp.ts — recordRsvpForFamily, removeRsvpRecord
products/medinaCHF/components/coordinator/RsvpEditor.tsx — new coordinator RSVP add/remove UI
products/medinaCHF/app/coordinator/events/[id]/page.tsx — wired in RSVP add/remove, removed dead RSVP_LABEL constant
products/medinaCHF/lib/queries/attendance.ts — listCountedAttendanceEventsForFamily
products/medinaCHF/components/CountedEventsSection.tsx — 'Events That Counted This Year' on Plan Something
products/medinaCHF/app/member/planning-board/page.tsx, app/member/page.tsx — wired in the counted-events list and its Home deep-link; fixed 'View My Membership' button label to 'View My Profile'
“what the fuck. just delete it already. you have my permission.”