Hub #3: explicit is_primary flag + shared getPrimarySite() (DRY)
The "oldest site = primary site" assumption was duplicated independently in
resolveSite, hub.js, account.js and admin.js (fragile: if the oldest happened
to be an artist site, the hub home would be wrong). Now:
- sites.is_primary column + backfill (marks the oldest if none is primary yet;
ensurePrimarySite sets it on fresh installs) → existing behaviour exactly
preserved.
- one getPrimarySite() helper (is_primary, fallback oldest) replaces the 4 copies.
- god can CHOOSE the primary/main site: ★ button + "primary" badge on /admin/sites
(exactly one primary via a transaction).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@…>