From 4fc4a3d3b9f75da40bf7b4775b575c3634d50df4 Mon Sep 17 00:00:00 2001 From: lorentz Date: Sun, 10 May 2026 07:22:26 -0400 Subject: [PATCH] feat(09-01): add theme column to user table + Better Auth additionalField - migrations/084_add_user_theme.sql: ALTER TABLE user ADD COLUMN theme TEXT NOT NULL DEFAULT 'system' - Defensive backfill UPDATE for in-flight NULL rows on managed Postgres - COMMENT ON COLUMN documents allowed values (light|dark|system) - lib/auth.ts: adds theme additionalField with defaultValue 'system' after timezone - session.user.theme now exposed via Better Auth same as session.user.timezone --- lib/auth.ts | 4 ++++ migrations/084_add_user_theme.sql | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 migrations/084_add_user_theme.sql diff --git a/lib/auth.ts b/lib/auth.ts index f8eea01..9b3275c 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -96,6 +96,10 @@ export const auth = betterAuth({ type: "string", defaultValue: process.env.DEFAULT_TIMEZONE || "UTC", }, + theme: { + type: "string", + defaultValue: "system", + }, }, }, }); diff --git a/migrations/084_add_user_theme.sql b/migrations/084_add_user_theme.sql new file mode 100644 index 0000000..0b7f788 --- /dev/null +++ b/migrations/084_add_user_theme.sql @@ -0,0 +1,20 @@ +-- ============================================================================= +-- Per-user theme preference (Phase 9 — THEME-01, THEME-05) +-- ============================================================================= +-- Adds a `theme` column to the Better Auth "user" table so light/dark/system +-- preference persists server-side and applies on sign-in across devices. +-- +-- Allowed values: 'light' | 'dark' | 'system' (validated in API layer). +-- Default 'system' means next-themes detects OS preference at render time — +-- zero behavior change for existing signed-in users. +-- ============================================================================= + +ALTER TABLE "user" + ADD COLUMN IF NOT EXISTS theme TEXT NOT NULL DEFAULT 'system'; + +-- Defensive backfill (DEFAULT covers new inserts, but on managed Postgres a +-- column added with DEFAULT may briefly show NULL in flight on some replicas). +UPDATE "user" SET theme = 'system' WHERE theme IS NULL; + +COMMENT ON COLUMN "user".theme IS + 'User theme preference: light | dark | system. Applied app-wide via next-themes; server is canonical.';