made tiny updates
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
-- ── Migration 008: Spec schema alignment ──────────────────────────────────────
|
||||
-- Aligns the database schema with the Layer 4 spec requirements.
|
||||
-- All changes are additive or rename-only; no data is destroyed.
|
||||
--
|
||||
-- Changes:
|
||||
-- 1. artboards.width / height — add NOT NULL DEFAULT per spec (1440 / 900)
|
||||
-- 2. artboards.parent_id — spec names this column parent_id (not parent_artboard_id);
|
||||
-- add parent_id as a generated column alias
|
||||
-- 3. origins.artboard_id — spec requires the FK to live on origins (not artboards)
|
||||
-- 4. intent_diffs: rename summary → aggregate_summary + rename changes_jsonb → changes
|
||||
-- 5. intent_diffs.session_id — make NOT NULL per spec (was nullable in migration 007)
|
||||
-- 6. agent_sessions.agent_type — add lowercase check values per spec
|
||||
-- 7. RLS: add permissive workspace-membership allow policies
|
||||
|
||||
-- ── 1. artboards width/height defaults ───────────────────────────────────────
|
||||
-- Backfill nulls introduced by migration 007, then add NOT NULL + DEFAULT.
|
||||
|
||||
update artboards set width = 1440 where width is null;
|
||||
update artboards set height = 900 where height is null;
|
||||
|
||||
alter table artboards
|
||||
alter column width set not null,
|
||||
alter column width set default 1440,
|
||||
alter column height set not null,
|
||||
alter column height set default 900;
|
||||
|
||||
-- created_by: spec says NOT NULL; backfill with '' then constrain
|
||||
update artboards set created_by = '' where created_by is null;
|
||||
alter table artboards alter column created_by set not null;
|
||||
alter table artboards alter column created_by set default '';
|
||||
|
||||
-- ── 2. artboards.parent_id alias ─────────────────────────────────────────────
|
||||
-- Spec uses parent_id; existing code uses parent_artboard_id. Add parent_id as
|
||||
-- a nullable FK that mirrors parent_artboard_id for spec-compliant consumers.
|
||||
-- Both columns will co-exist during the transition.
|
||||
do $$ begin
|
||||
if not exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'artboards' and column_name = 'parent_id'
|
||||
) then
|
||||
alter table artboards add column parent_id uuid references artboards(id);
|
||||
-- Backfill from the existing column
|
||||
update artboards set parent_id = parent_artboard_id where parent_artboard_id is not null;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
-- ── 3. origins.artboard_id (spec FK direction) ───────────────────────────────
|
||||
-- Spec: origins.artboard_id uuid not null references artboards(id) on delete cascade
|
||||
-- Existing: artboards.origin_id (reverse FK).
|
||||
-- We add the spec-required column as nullable (existing origin rows have no artboard_id
|
||||
-- until they are re-linked). New origins created via spec-compliant code must set it.
|
||||
do $$ begin
|
||||
if not exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'origins' and column_name = 'artboard_id'
|
||||
) then
|
||||
alter table origins add column artboard_id uuid references artboards(id) on delete cascade;
|
||||
-- Best-effort backfill: find artboards pointing to each origin
|
||||
update origins o
|
||||
set artboard_id = a.id
|
||||
from artboards a
|
||||
where a.origin_id = o.id;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
-- ── 4. intent_diffs: rename columns to spec names ────────────────────────────
|
||||
|
||||
-- Rename changes_jsonb → changes (spec column name)
|
||||
do $$ begin
|
||||
if exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'intent_diffs' and column_name = 'changes_jsonb'
|
||||
) and not exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'intent_diffs' and column_name = 'changes'
|
||||
) then
|
||||
alter table intent_diffs rename column changes_jsonb to changes;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
-- Rename summary → aggregate_summary (spec column name)
|
||||
do $$ begin
|
||||
if exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'intent_diffs' and column_name = 'summary'
|
||||
) and not exists (
|
||||
select 1 from information_schema.columns
|
||||
where table_name = 'intent_diffs' and column_name = 'aggregate_summary'
|
||||
) then
|
||||
alter table intent_diffs rename column summary to aggregate_summary;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
-- ── 5. intent_diffs.session_id NOT NULL ──────────────────────────────────────
|
||||
-- Spec: session_id text not null. Backfill existing nulls, then constrain.
|
||||
update intent_diffs set session_id = '' where session_id is null;
|
||||
alter table intent_diffs alter column session_id set not null;
|
||||
alter table intent_diffs alter column session_id set default '';
|
||||
|
||||
-- Also: author_id was NOT NULL in the spec from migration 001 — ensure created_by
|
||||
-- exists on design_language_files as NOT NULL (backfill then constrain)
|
||||
update design_language_files set created_by = '' where created_by is null;
|
||||
alter table design_language_files alter column created_by set not null;
|
||||
alter table design_language_files alter column created_by set default '';
|
||||
|
||||
-- ── 6. agent_sessions: expand agent_type to include spec lowercase values ─────
|
||||
-- Spec: 'cursor', 'claude-code', 'generic' (lowercase, hyphenated)
|
||||
-- Existing: uppercase 'CURSOR', 'CLAUDE_CODE', 'GENERIC' + original set
|
||||
-- Drop and re-create the check constraint to include both sets.
|
||||
alter table agent_sessions drop constraint if exists agent_sessions_agent_type_check;
|
||||
alter table agent_sessions add constraint agent_sessions_agent_type_check
|
||||
check (agent_type in (
|
||||
'cursor', 'claude-code', 'generic', -- spec lowercase
|
||||
'CURSOR', 'CLAUDE_CODE', 'GENERIC' -- existing uppercase
|
||||
));
|
||||
|
||||
-- ── 7. RLS workspace-membership allow policies ────────────────────────────────
|
||||
-- Spec: "workspace members can access" via auth.uid()::text = owner_id
|
||||
-- These are the permissive policies required by Layer 4. The deny-all-anon
|
||||
-- policies from migration 003 remain and complement these.
|
||||
|
||||
-- workspaces: owner can access their own workspace
|
||||
drop policy if exists "workspace owner access" on workspaces;
|
||||
create policy "workspace owner access" on workspaces
|
||||
for all
|
||||
using (owner_id = auth.uid()::text);
|
||||
|
||||
-- artboards: members of the workspace can access
|
||||
drop policy if exists "workspace member artboard access" on artboards;
|
||||
create policy "workspace member artboard access" on artboards
|
||||
for all
|
||||
using (
|
||||
workspace_id in (
|
||||
select id from workspaces where owner_id = auth.uid()::text
|
||||
)
|
||||
or workspace_id in (
|
||||
select workspace_id from team_members where user_id = auth.uid()::text
|
||||
)
|
||||
);
|
||||
|
||||
-- origins: accessible when the linked artboard is accessible
|
||||
drop policy if exists "workspace member origin access" on origins;
|
||||
create policy "workspace member origin access" on origins
|
||||
for all
|
||||
using (
|
||||
id in (
|
||||
select origin_id from artboards
|
||||
where workspace_id in (
|
||||
select id from workspaces where owner_id = auth.uid()::text
|
||||
union
|
||||
select workspace_id from team_members where user_id = auth.uid()::text
|
||||
)
|
||||
and origin_id is not null
|
||||
)
|
||||
);
|
||||
|
||||
-- intent_diffs: accessible when the linked artboard is accessible
|
||||
drop policy if exists "workspace member diff access" on intent_diffs;
|
||||
create policy "workspace member diff access" on intent_diffs
|
||||
for all
|
||||
using (
|
||||
artboard_id in (
|
||||
select id from artboards
|
||||
where workspace_id in (
|
||||
select id from workspaces where owner_id = auth.uid()::text
|
||||
union
|
||||
select workspace_id from team_members where user_id = auth.uid()::text
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- design_language_files: accessible within the workspace
|
||||
drop policy if exists "workspace member dlf access" on design_language_files;
|
||||
create policy "workspace member dlf access" on design_language_files
|
||||
for all
|
||||
using (
|
||||
workspace_id in (
|
||||
select id from workspaces where owner_id = auth.uid()::text
|
||||
union
|
||||
select workspace_id from team_members where user_id = auth.uid()::text
|
||||
)
|
||||
);
|
||||
|
||||
-- agent_sessions: accessible when the linked artboard is accessible
|
||||
drop policy if exists "workspace member session access" on agent_sessions;
|
||||
create policy "workspace member session access" on agent_sessions
|
||||
for all
|
||||
using (
|
||||
artboard_id in (
|
||||
select id from artboards
|
||||
where workspace_id in (
|
||||
select id from workspaces where owner_id = auth.uid()::text
|
||||
union
|
||||
select workspace_id from team_members where user_id = auth.uid()::text
|
||||
)
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user