-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschema.sql
More file actions
237 lines (221 loc) · 8.68 KB
/
schema.sql
File metadata and controls
237 lines (221 loc) · 8.68 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
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
-- AskOzzy — Database Schema (v2 — with all enhancement tables)
-- Users table
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
full_name TEXT NOT NULL,
department TEXT DEFAULT '',
role TEXT DEFAULT 'civil_servant',
tier TEXT DEFAULT 'free',
referral_code TEXT UNIQUE,
referred_by TEXT DEFAULT NULL,
affiliate_tier TEXT DEFAULT 'starter',
total_referrals INTEGER DEFAULT 0,
affiliate_earnings REAL DEFAULT 0.0,
totp_secret TEXT DEFAULT NULL,
totp_enabled INTEGER DEFAULT 0,
auth_method TEXT DEFAULT 'access_code',
recovery_code_hash TEXT DEFAULT NULL,
referral_source TEXT DEFAULT 'organic',
submitted_referral_code TEXT DEFAULT NULL,
org_id TEXT DEFAULT NULL,
created_at TEXT DEFAULT (datetime('now')),
last_login TEXT DEFAULT (datetime('now')),
FOREIGN KEY (referred_by) REFERENCES users(id)
);
-- WebAuthn (passkey) credentials
CREATE TABLE IF NOT EXISTS webauthn_credentials (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
credential_id TEXT NOT NULL UNIQUE,
public_key TEXT NOT NULL,
sign_count INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_webauthn_user ON webauthn_credentials(user_id);
CREATE INDEX IF NOT EXISTS idx_webauthn_credential ON webauthn_credentials(credential_id);
-- Referrals tracking
CREATE TABLE IF NOT EXISTS referrals (
id TEXT PRIMARY KEY,
referrer_id TEXT NOT NULL,
referred_id TEXT NOT NULL,
status TEXT DEFAULT 'completed' CHECK (status IN ('pending', 'completed', 'paid')),
bonus_amount REAL DEFAULT 10.0,
recurring_rate REAL DEFAULT 0.05,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (referrer_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (referred_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Conversation folders
CREATE TABLE IF NOT EXISTS folders (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
color TEXT DEFAULT '#FCD116',
sort_order INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Conversations table
CREATE TABLE IF NOT EXISTS conversations (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT DEFAULT 'New Conversation',
template_id TEXT DEFAULT NULL,
model TEXT DEFAULT '@cf/meta/llama-4-scout-17b-16e-instruct',
folder_id TEXT DEFAULT NULL,
pinned INTEGER DEFAULT 0,
agent_id TEXT DEFAULT NULL,
share_token TEXT DEFAULT NULL,
shared_at TEXT DEFAULT NULL,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (folder_id) REFERENCES folders(id)
);
-- Messages table
CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY,
conversation_id TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('user', 'assistant', 'system')),
content TEXT NOT NULL,
model TEXT DEFAULT NULL,
tokens_used INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
);
-- Message ratings (thumbs up/down)
CREATE TABLE IF NOT EXISTS message_ratings (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
message_id TEXT NOT NULL,
conversation_id TEXT NOT NULL,
rating INTEGER NOT NULL CHECK (rating IN (-1, 1)),
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE,
UNIQUE(user_id, message_id)
);
-- Usage tracking
CREATE TABLE IF NOT EXISTS usage_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INTEGER DEFAULT 0,
output_tokens INTEGER DEFAULT 0,
date TEXT DEFAULT (date('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Broadcast announcements
CREATE TABLE IF NOT EXISTS announcements (
id TEXT PRIMARY KEY,
admin_id TEXT NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
type TEXT DEFAULT 'info' CHECK (type IN ('info', 'warning', 'success', 'maintenance')),
active INTEGER DEFAULT 1,
dismissible INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
expires_at TEXT DEFAULT NULL,
FOREIGN KEY (admin_id) REFERENCES users(id)
);
-- Audit log
CREATE TABLE IF NOT EXISTS audit_log (
id TEXT PRIMARY KEY,
admin_id TEXT NOT NULL,
action TEXT NOT NULL,
target_type TEXT NOT NULL,
target_id TEXT DEFAULT NULL,
details TEXT DEFAULT NULL,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (admin_id) REFERENCES users(id)
);
-- Content moderation flags
CREATE TABLE IF NOT EXISTS moderation_flags (
id TEXT PRIMARY KEY,
conversation_id TEXT NOT NULL,
message_id TEXT DEFAULT NULL,
user_id TEXT NOT NULL,
reason TEXT NOT NULL,
status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'reviewed', 'dismissed')),
reviewed_by TEXT DEFAULT NULL,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Organizations for team billing
CREATE TABLE IF NOT EXISTS organizations (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
owner_id TEXT NOT NULL,
tier TEXT DEFAULT 'free',
max_seats INTEGER DEFAULT 10,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (owner_id) REFERENCES users(id)
);
-- User memories (AI personalization)
CREATE TABLE IF NOT EXISTS user_memories (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL,
type TEXT DEFAULT 'preference' CHECK (type IN ('preference', 'fact', 'auto')),
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE(user_id, key)
);
-- Custom AI agents
CREATE TABLE IF NOT EXISTS agents (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT DEFAULT '',
system_prompt TEXT NOT NULL,
department TEXT DEFAULT '',
knowledge_category TEXT DEFAULT '',
icon TEXT DEFAULT '🤖',
active INTEGER DEFAULT 1,
created_by TEXT NOT NULL,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (created_by) REFERENCES users(id)
);
-- Push notification subscriptions
CREATE TABLE IF NOT EXISTS push_subscriptions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
endpoint TEXT NOT NULL UNIQUE,
p256dh TEXT NOT NULL,
auth TEXT NOT NULL,
notify_announcements INTEGER DEFAULT 1,
notify_queue_sync INTEGER DEFAULT 1,
notify_shared_chat INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_push_subs_user ON push_subscriptions(user_id);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_conversations_user ON conversations(user_id, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_conversations_folder ON conversations(folder_id);
CREATE INDEX IF NOT EXISTS idx_conversations_pinned ON conversations(user_id, pinned DESC, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id, created_at ASC);
CREATE INDEX IF NOT EXISTS idx_message_ratings_message ON message_ratings(message_id);
CREATE INDEX IF NOT EXISTS idx_message_ratings_user ON message_ratings(user_id);
CREATE INDEX IF NOT EXISTS idx_usage_user_date ON usage_log(user_id, date);
CREATE INDEX IF NOT EXISTS idx_referrals_referrer ON referrals(referrer_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_users_referral_code ON users(referral_code);
CREATE INDEX IF NOT EXISTS idx_users_org ON users(org_id);
CREATE INDEX IF NOT EXISTS idx_folders_user ON folders(user_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_announcements_active ON announcements(active, expires_at);
CREATE INDEX IF NOT EXISTS idx_audit_log_admin ON audit_log(admin_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_audit_log_target ON audit_log(target_type, target_id);
CREATE INDEX IF NOT EXISTS idx_moderation_flags_status ON moderation_flags(status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_organizations_owner ON organizations(owner_id);
CREATE INDEX IF NOT EXISTS idx_user_memories_user ON user_memories(user_id, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_user_memories_type ON user_memories(user_id, type);
CREATE INDEX IF NOT EXISTS idx_agents_active ON agents(active, name);
CREATE INDEX IF NOT EXISTS idx_agents_department ON agents(department);
CREATE INDEX IF NOT EXISTS idx_conversations_agent ON conversations(agent_id);
CREATE INDEX IF NOT EXISTS idx_conversations_share_token ON conversations(share_token) WHERE share_token IS NOT NULL;