mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-20 11:19:56 +08:00
feat: add Supabase migration SQL for team data store
- 001_teams.sql: teams + team_members + RLS - 002_eval_runs.sql: eval results with universal format, indexes, upsert key - 003_data_tables.sql: retro, QA, ship, greptile, transcripts + RLS All tables use RLS: team members read/insert, admins delete. Transcript table has tighter policy (admin-only read). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
supabase/migrations/002_eval_runs.sql
Normal file
71
supabase/migrations/002_eval_runs.sql
Normal file
@@ -0,0 +1,71 @@
|
||||
-- 002_eval_runs.sql — Eval result storage.
|
||||
--
|
||||
-- Mirrors EvalResult from test/helpers/eval-store.ts.
|
||||
-- Supports both gstack's native eval format and the universal
|
||||
-- adapter format (any language pushes JSON results).
|
||||
|
||||
create table if not exists eval_runs (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
team_id uuid references teams(id) not null,
|
||||
user_id uuid references auth.users(id),
|
||||
repo_slug text not null,
|
||||
hostname text not null default '',
|
||||
|
||||
-- Eval metadata
|
||||
schema_version int not null default 1,
|
||||
version text not null default '',
|
||||
branch text not null default '',
|
||||
git_sha text not null default '',
|
||||
timestamp timestamptz not null default now(),
|
||||
tier text not null default 'e2e',
|
||||
|
||||
-- Summary stats
|
||||
total_tests int not null default 0,
|
||||
passed int not null default 0,
|
||||
failed int not null default 0,
|
||||
total_cost_usd numeric(10,4) not null default 0,
|
||||
total_duration_ms int not null default 0,
|
||||
|
||||
-- Universal format fields (adapter mode)
|
||||
label text, -- e.g. "dev_fix-terseness_standard"
|
||||
prompt_sha text, -- SHA of prompt source files
|
||||
by_category jsonb, -- { "post_generation": { passed: 16, total: 17 } }
|
||||
costs jsonb, -- [{ model, calls, input_tokens, output_tokens }]
|
||||
|
||||
-- Full test results (transcripts stripped for team sync)
|
||||
tests jsonb not null default '[]'::jsonb,
|
||||
|
||||
created_at timestamptz default now()
|
||||
);
|
||||
|
||||
-- Indexes for common queries
|
||||
create index if not exists idx_eval_runs_team on eval_runs(team_id);
|
||||
create index if not exists idx_eval_runs_repo on eval_runs(team_id, repo_slug);
|
||||
create index if not exists idx_eval_runs_branch on eval_runs(team_id, branch);
|
||||
create index if not exists idx_eval_runs_timestamp on eval_runs(team_id, timestamp desc);
|
||||
create index if not exists idx_eval_runs_label on eval_runs(team_id, label) where label is not null;
|
||||
|
||||
-- Upsert natural key: timestamp + hostname + repo_slug (idempotent pushes)
|
||||
create unique index if not exists idx_eval_runs_natural_key
|
||||
on eval_runs(team_id, timestamp, hostname, repo_slug);
|
||||
|
||||
-- RLS
|
||||
alter table eval_runs enable row level security;
|
||||
|
||||
create policy "team_read" on eval_runs
|
||||
for select using (
|
||||
team_id in (select team_id from team_members where user_id = auth.uid())
|
||||
);
|
||||
|
||||
create policy "team_insert" on eval_runs
|
||||
for insert with check (
|
||||
team_id in (select team_id from team_members where user_id = auth.uid())
|
||||
);
|
||||
|
||||
create policy "admin_delete" on eval_runs
|
||||
for delete using (
|
||||
team_id in (
|
||||
select team_id from team_members
|
||||
where user_id = auth.uid() and role in ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user