Repository navigation
Expand file tree
/
Copy pathsupabase_schema.sql
More file actions
122 lines (112 loc) · 3.58 KB
/
Copy pathsupabase_schema.sql
File metadata and controls
122 lines (112 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
-- Enable pgvector extension
create extension if not exists vector;
-- Documents table
create table if not exists documents (
id uuid primary key default gen_random_uuid(),
filename text not null,
file_type text not null,
uploaded_at timestamp with time zone default now(),
status text not null check (status in ('processing', 'ready', 'failed')),
page_count integer
);
-- Chunks table
create table if not exists chunks (
id uuid primary key default gen_random_uuid(),
document_id uuid references documents(id) on delete cascade,
content text not null,
embedding vector(768), -- Gemini gemini-embedding-001 (outputDimensionality 768)
page_number integer,
chunk_index integer,
token_count integer
);
-- Index for vector similarity search
create index on chunks using hnsw (embedding vector_cosine_ops);
-- Full-text search column and index
alter table chunks add column if not exists fts tsvector generated always as (to_tsvector('english', content)) stored;
create index on chunks using gin (fts);
-- Conversations table
create table if not exists conversations (
id uuid primary key default gen_random_uuid(),
title text not null default 'New Conversation',
created_at timestamp with time zone default now()
);
-- Messages table
create table if not exists messages (
id uuid primary key default gen_random_uuid(),
conversation_id uuid references conversations(id) on delete cascade,
role text not null check (role in ('user', 'assistant')),
content text not null,
citations jsonb default '[]'::jsonb, -- array of {chunk_id, snippet, page}
grounding_score float,
created_at timestamp with time zone default now()
);
-- Eval runs table
create table if not exists eval_runs (
id uuid primary key default gen_random_uuid(),
run_at timestamp with time zone default now(),
faithfulness float,
context_precision float,
answer_relevancy float,
notes text
);
-- Per-query observability log (drives the /dashboard)
create table if not exists query_logs (
id uuid primary key default gen_random_uuid(),
conversation_id uuid references conversations(id) on delete set null,
query text,
rewritten_query text,
latency_ms jsonb default '{}'::jsonb, -- per-stage latency breakdown
tokens_in integer default 0,
tokens_out integer default 0,
rerank_fallback boolean default false,
created_at timestamp with time zone default now()
);
-- RPC: vector-only similarity search (cosine)
create or replace function vector_search(
query_embedding vector(768),
match_count int default 20,
min_similarity float default 0.0
) returns table (
id uuid,
document_id uuid,
content text,
page_number int,
chunk_index int,
similarity float
) language sql stable as $$
select
chunks.id,
chunks.document_id,
chunks.content,
chunks.page_number,
chunks.chunk_index,
1 - (chunks.embedding <=> query_embedding) as similarity
from chunks
where 1 - (chunks.embedding <=> query_embedding) >= min_similarity
order by chunks.embedding <=> query_embedding
limit match_count;
$$;
-- RPC: full-text keyword search
create or replace function full_text_search(
query_text text,
match_count int default 20
) returns table (
id uuid,
document_id uuid,
content text,
page_number int,
chunk_index int,
similarity float
) language sql stable as $$
select
chunks.id,
chunks.document_id,
chunks.content,
chunks.page_number,
chunks.chunk_index,
ts_rank_cd(chunks.fts, plainto_tsquery('english', query_text)) as similarity
from chunks
where chunks.fts @@ plainto_tsquery('english', query_text)
order by similarity desc
limit match_count;
$$;