Spaces:
Runtime error
Runtime error
| -- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| -- LabCard AI β Supabase Schema | |
| -- Run this once in Supabase SQL Editor: | |
| -- https://supabase.com β Your project β SQL Editor β New query | |
| -- βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| -- ββ Extensions ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| create extension if not exists "uuid-ossp"; | |
| create extension if not exists vector; -- for future RAG embeddings | |
| -- ββ Users (extends Supabase auth.users) ββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.profiles ( | |
| id uuid primary key references auth.users(id) on delete cascade, | |
| name text, | |
| age int, | |
| gender text, | |
| city text, | |
| phone text, | |
| created_at timestamptz default now(), | |
| updated_at timestamptz default now() | |
| ); | |
| -- ββ Reports βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.reports ( | |
| id uuid primary key default gen_random_uuid(), | |
| user_id uuid references public.profiles(id) on delete cascade, | |
| lab_name text, | |
| report_date date, | |
| health_score int check (health_score between 0 and 100), | |
| biological_age int, | |
| grade text, | |
| summary_en text, | |
| summary_hi text, | |
| doctor_note text, | |
| top_priority text, | |
| has_critical boolean default false, | |
| raw_text_hash text, -- SHA-256 of raw text β dedup without storing PII | |
| created_at timestamptz default now() | |
| ); | |
| create index if not exists idx_reports_user_date | |
| on public.reports (user_id, created_at desc); | |
| -- ββ Biomarkers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.biomarkers ( | |
| id bigserial primary key, | |
| report_id uuid references public.reports(id) on delete cascade, | |
| name text not null, | |
| std_name text, | |
| value numeric, | |
| unit text, | |
| normal_low numeric, | |
| normal_high numeric, | |
| status text, | |
| category text, | |
| explanation_en text, | |
| explanation_hi text, | |
| advice text, | |
| foods jsonb default '[]', | |
| created_at timestamptz default now() | |
| ); | |
| create index if not exists idx_biomarkers_report | |
| on public.biomarkers (report_id); | |
| create index if not exists idx_biomarkers_trend | |
| on public.biomarkers (report_id, std_name, created_at); | |
| -- ββ Reference Ranges βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.reference_ranges ( | |
| id bigserial primary key, | |
| biomarker text not null, | |
| std_name text, | |
| gender text default 'A', | |
| age_min int default 0, | |
| age_max int default 120, | |
| normal_low numeric, | |
| normal_high numeric, | |
| critical_low numeric, | |
| critical_high numeric, | |
| unit text, | |
| category text, | |
| notes text, | |
| updated_at timestamptz default now(), | |
| unique (biomarker, gender) | |
| ); | |
| -- ββ Chat Messages βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.chat_messages ( | |
| id bigserial primary key, | |
| report_id uuid references public.reports(id) on delete cascade, | |
| role text not null check (role in ('user','assistant')), | |
| content text not null, | |
| lang text default 'en', | |
| created_at timestamptz default now() | |
| ); | |
| create index if not exists idx_chat_report | |
| on public.chat_messages (report_id, created_at); | |
| -- ββ Medical Knowledge (for future RAG) βββββββββββββββββββββββββββββββββββββββ | |
| create table if not exists public.medical_knowledge ( | |
| id bigserial primary key, | |
| content text not null, | |
| embedding vector(1536), | |
| metadata jsonb default '{}', | |
| source text, | |
| created_at timestamptz default now() | |
| ); | |
| create index if not exists idx_medical_knowledge_embedding | |
| on public.medical_knowledge | |
| using hnsw (embedding vector_cosine_ops) | |
| with (m = 16, ef_construction = 64); | |
| -- Similarity search function | |
| create or replace function match_medical_knowledge ( | |
| query_embedding vector(1536), | |
| match_threshold float default 0.75, | |
| match_count int default 5 | |
| ) | |
| returns table (id bigint, content text, metadata jsonb, similarity float) | |
| language sql stable as $$ | |
| select id, content, metadata, | |
| 1 - (embedding <=> query_embedding) as similarity | |
| from public.medical_knowledge | |
| where 1 - (embedding <=> query_embedding) > match_threshold | |
| order by embedding <=> query_embedding | |
| limit match_count; | |
| $$; | |
| -- ββ Row Level Security ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| alter table public.profiles enable row level security; | |
| alter table public.reports enable row level security; | |
| alter table public.biomarkers enable row level security; | |
| alter table public.chat_messages enable row level security; | |
| -- Profiles: users can only see/edit their own profile | |
| create policy "profiles_own" on public.profiles | |
| for all using (auth.uid() = id); | |
| -- Reports: users can only see their own reports | |
| create policy "reports_own" on public.reports | |
| for all using (auth.uid() = user_id); | |
| -- Biomarkers: accessible through report ownership | |
| create policy "biomarkers_own" on public.biomarkers | |
| for all using ( | |
| report_id in ( | |
| select id from public.reports where user_id = auth.uid() | |
| ) | |
| ); | |
| -- Chat: accessible through report ownership | |
| create policy "chat_own" on public.chat_messages | |
| for all using ( | |
| report_id in ( | |
| select id from public.reports where user_id = auth.uid() | |
| ) | |
| ); | |
| -- Reference ranges: public read | |
| create policy "ref_ranges_read" on public.reference_ranges | |
| for select using (true); | |