> For the complete documentation index, see [llms.txt](https://seekspeed.gitbook.io/seekspeed-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://seekspeed.gitbook.io/seekspeed-docs/architecture/data-model.md).

# Data Model

Every entity lives in its own table with row-level security gated on `workspaces.owner_id = auth.uid()`. The schema is intentionally relational rather than a JSONB blob so that exports, share tokens, and analytics can be expressed as plain SQL.

## Tables

```sql
create table public.workspaces (
  id          uuid primary key default gen_random_uuid(),
  owner_id    uuid not null references auth.users(id) on delete cascade,
  name        text not null,
  created_at  timestamptz not null default now()
);

create table public.connectors (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  name          text not null,
  base_url      text not null,
  api_key       text,                -- server-side only
  model         text not null,
  preset        text,
  headers       jsonb not null default '{}'::jsonb,
  created_at    timestamptz not null default now()
);

create table public.agents (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  name          text not null,
  system_prompt text not null default '',
  connector_id  uuid references public.connectors(id) on delete set null,
  tools         jsonb not null default '[]'::jsonb,
  memory        text not null default 'ephemeral',
  token_budget  integer not null default 2048,
  tags          text[] not null default '{}'
);

create table public.benchmark_runs (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  agent_id      uuid not null references public.agents(id) on delete cascade,
  prompts       jsonb not null,
  iterations    integer not null default 1,
  concurrency   integer not null default 1,
  status        text not null default 'pending',
  results       jsonb not null default '[]'::jsonb,
  stats         jsonb not null default '{}'::jsonb,
  created_at    timestamptz not null default now()
);

create table public.recommendations (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  run_id        uuid references public.benchmark_runs(id) on delete cascade,
  title         text not null,
  rationale     text not null,
  expected      text not null,
  difficulty    text not null,
  confidence    real not null,
  status        text not null default 'open',     -- open|applied|measured|accepted|rejected
  variant_id    uuid references public.agents(id),
  measured_run  uuid references public.benchmark_runs(id),
  p_value       real,
  delta_ms      real
);

create table public.spec_jobs (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  adapter       text not null,           -- 'vllm' | 'tgi' | 'llamacpp' | 'stub'
  endpoint      text not null,
  baseline      text,
  target_model  text not null,
  draft_model   text not null,
  sample_count  integer not null,
  metrics       jsonb,
  logs          jsonb not null default '[]'::jsonb,
  status        text not null default 'queued'
);

create table public.reports (
  id            uuid primary key default gen_random_uuid(),
  workspace_id  uuid not null references public.workspaces(id) on delete cascade,
  title         text not null,
  notes         text,
  run_ids       uuid[] not null,
  share_token   text unique,
  created_at    timestamptz not null default now()
);
```

## GRANT + RLS pattern

Every public-schema table follows the same four-step pattern:

```sql
GRANT SELECT, INSERT, UPDATE, DELETE ON public.connectors TO authenticated;
GRANT ALL ON public.connectors TO service_role;
ALTER TABLE public.connectors ENABLE ROW LEVEL SECURITY;

CREATE POLICY "owner can rw connectors"
  ON public.connectors FOR ALL TO authenticated
  USING (workspace_id IN (SELECT id FROM public.workspaces WHERE owner_id = auth.uid()))
  WITH CHECK (workspace_id IN (SELECT id FROM public.workspaces WHERE owner_id = auth.uid()));
```

`anon` is granted **only** on the `reports` table and only for `SELECT`, and even then a policy requires the `x-share-token` header to match the row's `share_token`. Everything else requires an authenticated session.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://seekspeed.gitbook.io/seekspeed-docs/architecture/data-model.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
