-- t-paliad-219 Slice C: firm-wide dashboard default layout. -- -- Design: docs/design-dashboard-configurable-2026-05-20.md ยง8.2 (firm-wide -- admin default, deferred to v1.1 โ€” now activated by m's Slice C brief). -- -- A single optional row that holds the firm's preferred dashboard layout. -- DashboardLayoutService.GetOrSeed reads this on first call for a new user -- (falling back to the code-resident FactoryDefaultLayout when null); -- ResetToDefault similarly prefers the firm default. Admins promote their -- own current layout into this row via POST /api/me/dashboard-layout/promote. -- -- Single-row design via CHECK (id = 1) so there's no ambiguity about which -- row is "the default". RLS lets any authenticated user SELECT (so the -- service can read it during seed); only the application (service-role -- connection) writes โ€” the admin gate sits on the HTTP handler. CREATE TABLE paliad.firm_dashboard_default ( id smallint PRIMARY KEY DEFAULT 1 CHECK (id = 1), layout_json jsonb NOT NULL, updated_by uuid REFERENCES paliad.users(id) ON DELETE SET NULL, updated_at timestamptz NOT NULL DEFAULT now() ); ALTER TABLE paliad.firm_dashboard_default ENABLE ROW LEVEL SECURITY; -- All authenticated users can SELECT โ€” the dashboard seed path needs to -- read it for every new user. The HTTP handler enforces admin-only on the -- PUT/DELETE paths; the service runs under service-role so writes bypass -- RLS anyway. No INSERT/UPDATE policy means no Supabase-JWT-authenticated -- client can write, which is the desired posture. CREATE POLICY firm_dashboard_default_read ON paliad.firm_dashboard_default FOR SELECT USING (true);