File size: 11,116 Bytes
9bd4388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
-- ============================================================
-- Aarogyan β€” Supabase Database Schema
-- Run this in your Supabase SQL Editor (in order)
-- ============================================================

-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "pgcrypto";

-- ────────────────────────────────────────────────────────────
-- 1. USERS
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS users (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email           TEXT UNIQUE NOT NULL,
    password_hash   TEXT NOT NULL,
    full_name       TEXT NOT NULL,
    created_at      TIMESTAMPTZ DEFAULT NOW(),
    updated_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_users_email ON users (email);

-- ────────────────────────────────────────────────────────────
-- 2. PROFILES
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS profiles (
    id                      UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id                 UUID UNIQUE NOT NULL REFERENCES users(id) ON DELETE CASCADE,

    -- Section 1: Personal
    full_name               TEXT,
    date_of_birth           DATE,
    biological_sex          TEXT CHECK (biological_sex IN ('Male', 'Female', 'Intersex')),
    height_cm               NUMERIC(5,1),
    weight_kg               NUMERIC(5,1),
    blood_group             TEXT,
    city                    TEXT,
    region_state            TEXT,
    preferred_language      TEXT DEFAULT 'English',
    emergency_contact_name  TEXT,
    emergency_contact_phone TEXT,

    -- Sections 2–9: stored as JSONB arrays/objects
    existing_conditions     JSONB DEFAULT '[]'::JSONB,
    allergies               JSONB DEFAULT '[]'::JSONB,
    current_medications     JSONB DEFAULT '[]'::JSONB,
    supplements             JSONB DEFAULT '[]'::JSONB,
    past_medical_history    JSONB DEFAULT '[]'::JSONB,
    family_medical_history  JSONB DEFAULT '[]'::JSONB,
    lifestyle               JSONB DEFAULT '{}'::JSONB,
    mental_health           JSONB DEFAULT '{}'::JSONB,

    created_at              TIMESTAMPTZ DEFAULT NOW(),
    updated_at              TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_profiles_user_id ON profiles (user_id);

-- ────────────────────────────────────────────────────────────
-- 3. CONSULTATIONS
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS consultations (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id     UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name        TEXT NOT NULL,
    start_date  DATE,
    notes       TEXT,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    updated_at  TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_consultations_user_id ON consultations (user_id);

-- ────────────────────────────────────────────────────────────
-- 4. SESSIONS
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS sessions (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    consultation_id     UUID NOT NULL REFERENCES consultations(id) ON DELETE CASCADE,
    visit_date          DATE NOT NULL,
    symptoms            TEXT,
    diagnosis           TEXT,
    medications         TEXT,
    doctor_notes        TEXT,
    created_at          TIMESTAMPTZ DEFAULT NOW(),
    updated_at          TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_sessions_consultation_id ON sessions (consultation_id);

-- ────────────────────────────────────────────────────────────
-- 5. SESSION DOCUMENTS
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS session_documents (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    session_id      UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
    file_name       TEXT NOT NULL,
    storage_path    TEXT NOT NULL,
    public_url      TEXT,
    content_type    TEXT,
    ocr_text        TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_session_documents_session_id ON session_documents (session_id);

-- ────────────────────────────────────────────────────────────
-- 6. CONVERSATIONS (Medical Assistant)
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS conversations (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id     UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    title       TEXT DEFAULT 'New Conversation',
    preview     TEXT,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    updated_at  TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_conversations_user_id ON conversations (user_id);

-- ────────────────────────────────────────────────────────────
-- 7. MESSAGES
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS messages (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id     UUID NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
    role                TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
    content             TEXT NOT NULL,
    created_at          TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_messages_conversation_id ON messages (conversation_id);

-- ────────────────────────────────────────────────────────────
-- 8. EMOTIONAL SESSIONS (Orbz / Buddy)
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS emotional_sessions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id         UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    user_text       TEXT,
    buddy_text      TEXT,
    mood_score      SMALLINT CHECK (mood_score BETWEEN 1 AND 10),
    emotion         TEXT,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_emotional_sessions_user_id ON emotional_sessions (user_id);
CREATE INDEX idx_emotional_sessions_created_at ON emotional_sessions (created_at);

-- ────────────────────────────────────────────────────────────
-- 9. STORAGE BUCKETS (run separately or via Supabase dashboard)
-- ────────────────────────────────────────────────────────────
-- Create a storage bucket called "documents" with:
--   Public: false (files accessed via signed URLs or backend proxy)
--   Max file size: 2097152 (2 MB)
--   Allowed MIME types: image/jpeg, image/png, application/pdf
--
-- Run this if the Supabase storage API supports SQL:
-- INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
-- VALUES (
--     'documents',
--     'documents',
--     true,
--     2097152,
--     ARRAY['image/jpeg', 'image/png', 'application/pdf']
-- )
-- ON CONFLICT (id) DO NOTHING;

-- ────────────────────────────────────────────────────────────
-- 10. UPDATED_AT TRIGGERS
-- ────────────────────────────────────────────────────────────
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_users_updated_at
    BEFORE UPDATE ON users
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER trg_profiles_updated_at
    BEFORE UPDATE ON profiles
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER trg_consultations_updated_at
    BEFORE UPDATE ON consultations
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER trg_sessions_updated_at
    BEFORE UPDATE ON sessions
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER trg_conversations_updated_at
    BEFORE UPDATE ON conversations
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- ────────────────────────────────────────────────────────────
-- 11. ROW LEVEL SECURITY (RLS) β€” Disable for service role key
-- ────────────────────────────────────────────────────────────
-- Since the backend uses the SERVICE ROLE key (bypasses RLS),
-- RLS is disabled. Enable RLS policies only if you switch to
-- the ANON key on the backend.
ALTER TABLE users DISABLE ROW LEVEL SECURITY;
ALTER TABLE profiles DISABLE ROW LEVEL SECURITY;
ALTER TABLE consultations DISABLE ROW LEVEL SECURITY;
ALTER TABLE sessions DISABLE ROW LEVEL SECURITY;
ALTER TABLE session_documents DISABLE ROW LEVEL SECURITY;
ALTER TABLE conversations DISABLE ROW LEVEL SECURITY;
ALTER TABLE messages DISABLE ROW LEVEL SECURITY;
ALTER TABLE emotional_sessions DISABLE ROW LEVEL SECURITY;