-- 0012_constructs.sql — the "construct" entity: a sequence + all its derived
-- artifacts (variant library, plasmid, CRISPR guides, primers) + its loop
-- phase. This is the grouping key the app was missing: plasmids /
-- crispr_designs / primer_analyses / libraries were silos with no backref to
-- their source sequence, so nothing tied a user's work together.
--
-- Run this in the Supabase SQL editor (Dashboard → SQL → New query → Run)
-- before/at deploy of the construct-centric UI (Mission Control + Bench).
-- Idempotent: safe to run more than once. Mirrors public.plasmids (0005)
-- exactly for the security posture — owner-only RLS, a TTL via expires_at
-- (NULL = keep forever, for future pro plans), and list/expiry indexes. The
-- Space backend writes/reads with the service-role key (bypasses RLS) and
-- also filters on user_id in code; the RLS policies are the defense-in-depth
-- layer for any direct anon-key client access.

create table if not exists public.constructs (
    id            uuid primary key default gen_random_uuid(),
    user_id       uuid not null references auth.users (id) on delete cascade,
    created_at    timestamptz not null default now(),
    updated_at    timestamptz not null default now(),
    expires_at    timestamptz,                          -- NULL = never expires
    name          text not null default 'Untitled construct',

    -- Sequence identity (the grouping key).
    sequence_hash text not null,                        -- sha256(seq)[:16], from _hash_sequence
    wt_identifier text,                                 -- e.g. ">MC1R" / gene symbol
    wt_protein    text not null default '',             -- amino-acid sequence
    sequence_dna  text not null default '',             -- full WT coding DNA

    -- Loop phase.
    phase         text not null default 'Design',       -- 'Design' | 'Build' | 'Edit' | 'Learn'

    -- Denormalised artifact references (nullable; populated as tools run).
    library_id    uuid,                                 -- latest DE library
    plasmid_ids   uuid[] not null default '{}',
    crispr_ids    uuid[] not null default '{}',
    primer_ids    uuid[] not null default '{}',

    meta          jsonb not null default '{}'::jsonb
);

comment on table public.constructs is
    'A sequence + all its derived artifacts + loop phase. Groups a user''s '
    'work by source sequence (sequence_hash). Owner-only RLS; TTL via expires_at.';

alter table public.constructs enable row level security;

drop policy if exists "constructs_select_own" on public.constructs;
create policy "constructs_select_own"
    on public.constructs for select
    using (auth.uid() = user_id);

drop policy if exists "constructs_insert_own" on public.constructs;
create policy "constructs_insert_own"
    on public.constructs for insert
    with check (auth.uid() = user_id);

drop policy if exists "constructs_update_own" on public.constructs;
create policy "constructs_update_own"
    on public.constructs for update
    using (auth.uid() = user_id);

drop policy if exists "constructs_delete_own" on public.constructs;
create policy "constructs_delete_own"
    on public.constructs for delete
    using (auth.uid() = user_id);

-- List query: a user's constructs, newest activity first.
create index if not exists constructs_user_updated_idx
    on public.constructs (user_id, updated_at desc);

-- Dedup / grouping lookup by source sequence.
create index if not exists constructs_user_seq_hash_idx
    on public.constructs (user_id, sequence_hash);

-- Lazy expiry sweep target.
create index if not exists constructs_expires_idx
    on public.constructs (expires_at)
    where expires_at is not null;
