Files
wursor/supabase/migrations/012_artboard_phase0_columns.sql
T
2026-05-05 22:06:31 +01:00

74 lines
4.2 KiB
SQL

-- ═══════════════════════════════════════════════════════════════════════════
-- Migration 012: Phase 0 artboard schema additions
-- Adds first-class typed columns for canvas position, device preset, artboard
-- type, isolation metadata, drag-positioning flag, and thumbnail storage URL.
--
-- Spec reference: SOURCE-AWARE-CANVAS §3.7 (schema additions for Phase 0)
-- All changes use IF NOT EXISTS / DO $$ guards for idempotency.
-- ═══════════════════════════════════════════════════════════════════════════
-- ── artboards: Phase 0 spatial + type columns ─────────────────────────────────
-- Promote canvas position from metadata_jsonb to proper typed columns so they
-- can be indexed and compared without casting. Existing artboards keep their
-- metadata_jsonb values; new columns default to common presets.
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS canvas_x float8 DEFAULT 0;
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS canvas_y float8 DEFAULT 0;
-- Backfill canvas_x/canvas_y from metadata_jsonb for existing artboards.
UPDATE artboards
SET
canvas_x = (metadata_jsonb->>'x')::float8,
canvas_y = (metadata_jsonb->>'y')::float8
WHERE
canvas_x = 0 AND canvas_y = 0
AND (metadata_jsonb ? 'x' OR metadata_jsonb ? 'y');
-- Device preset: which physical screen size preset the artboard was sized for.
-- Possible values: 'desktop-hd' | 'desktop-4k' | 'laptop' | 'tablet' | 'mobile'
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS device_preset text DEFAULT 'desktop-hd';
-- Artboard type controls which content renderer is used.
-- 'route' → LiveArtboard iframe pointing at a dev-server route
-- 'isolation' → Isolation artboard wrapping a single component (Phase 3)
-- 'static' → Plain static HTML / no React detected
DO $$ BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'artboards' AND column_name = 'artboard_type'
) THEN
ALTER TABLE artboards ADD COLUMN artboard_type text NOT NULL DEFAULT 'route'
CHECK (artboard_type IN ('route', 'isolation', 'static'));
END IF;
END $$;
-- Isolation artboard metadata (populated when artboard_type = 'isolation').
-- isolation_component: exported symbol name, e.g. "Button"
-- isolation_file: workspace-relative path, e.g. "src/components/Button.tsx"
-- isolation_props: JSON props object fed to window.__OM_ISO_PROPS__
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS isolation_component text;
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS isolation_file text;
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS isolation_props jsonb DEFAULT '{}';
-- Drag-positioning flag: true once the user has manually moved this artboard
-- by ≥10 world-space pixels. Prevents the auto-arrange algorithm from
-- overwriting user-chosen positions.
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS manually_positioned boolean NOT NULL DEFAULT false;
-- Thumbnail URL: Supabase Storage public URL for the JPEG thumbnail captured
-- when the artboard transitions to 'far' viewport state.
-- The data URI itself is NEVER written here — only the Storage public URL.
-- Null until the first thumbnail is successfully uploaded.
ALTER TABLE artboards ADD COLUMN IF NOT EXISTS thumbnail_url text;
-- Index: quickly find all isolation artboards within a workspace
CREATE INDEX IF NOT EXISTS artboards_isolation_idx
ON artboards (workspace_id, artboard_type)
WHERE artboard_type = 'isolation';
-- ── intent_diffs: Phase 5 blocked_reason column ───────────────────────────────
-- Stores the agent-supplied reason when status = 'BLOCKED' (e.g. "merge conflict
-- in src/components/Button.tsx — please resolve manually before retrying").
-- Written by update_diff_status when status = 'BLOCKED'; null otherwise.
ALTER TABLE intent_diffs ADD COLUMN IF NOT EXISTS blocked_reason text;