A running log of architecture decisions and the reasoning behind them. New entries go at the top. Each entry: what we decided, why, what we considered, what would change our mind.
Decision: Next.js 15 (App Router) + TypeScript + Tailwind, with Supabase for auth/database/storage and Netlify for hosting.
Why:
Alternatives considered:
What would change our mind: A specific feature requirement Supabase can’t serve (real-time collaboration at scale, complex search, etc.) might push us to add a service alongside Supabase, but won’t replace it.
Decision: Support these four. Skip Facebook, GitHub, Discord, etc.
Why:
Decision: A “family” is the tenancy boundary. Every domain table in the
future will have family_id and RLS that joins to family_members.
Why:
family_members rather than checking a single family_id on
the user lets us model that without contortions.is_family_member(family_id) SQL helper means every future RLS policy
is one line, not five.Roles: owner, adult, child, elder. We’ll figure out what those
mean granularly when we hit the first feature that needs role-based
permissions.
getUser() not getSession() in middlewareDecision: Always use supabase.auth.getUser() to validate auth on the
server. Never use getSession() for security checks.
Why: getSession() reads the cookie and trusts it. getUser() validates
the JWT against Supabase Auth on every call. The latter is slightly slower
but is the only one that’s actually secure. The Supabase docs flag this and
several teams have shipped vulnerabilities by getting it wrong.
Decision: Use “Project Heirloom” as the GitHub repo name and internal working title. Brand name is unresolved.
Why: Naming is blocked on trademark/domain checks. Building under the
working name lets us start engineering without committing to a brand. The
real name lands in env vars, deployment URLs, and metadata.title once
chosen — minimal refactor cost.
What changes when we name it: Update metadata.title in app/layout.tsx,
update the Supabase project display name, update Netlify site name, register
the domain, transfer/rename the GitHub repo if desired.