@agentsean/db 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/dist/client.d.ts +13 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +48 -0
- package/dist/client.js.map +1 -0
- package/dist/fts.d.ts +31 -0
- package/dist/fts.d.ts.map +1 -0
- package/dist/fts.js +69 -0
- package/dist/fts.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/pg/actions.d.ts +404 -0
- package/dist/pg/actions.d.ts.map +1 -0
- package/dist/pg/actions.js +54 -0
- package/dist/pg/actions.js.map +1 -0
- package/dist/pg/content.d.ts +642 -0
- package/dist/pg/content.d.ts.map +1 -0
- package/dist/pg/content.js +65 -0
- package/dist/pg/content.js.map +1 -0
- package/dist/pg/google.d.ts +2657 -0
- package/dist/pg/google.d.ts.map +1 -0
- package/dist/pg/google.js +250 -0
- package/dist/pg/google.js.map +1 -0
- package/dist/pg/hosted.d.ts +1075 -0
- package/dist/pg/hosted.d.ts.map +1 -0
- package/dist/pg/hosted.js +106 -0
- package/dist/pg/hosted.js.map +1 -0
- package/dist/pg/keywords.d.ts +962 -0
- package/dist/pg/keywords.d.ts.map +1 -0
- package/dist/pg/keywords.js +89 -0
- package/dist/pg/keywords.js.map +1 -0
- package/dist/pg/measure.d.ts +1343 -0
- package/dist/pg/measure.d.ts.map +1 -0
- package/dist/pg/measure.js +128 -0
- package/dist/pg/measure.js.map +1 -0
- package/dist/pg/schema.d.ts +2589 -0
- package/dist/pg/schema.d.ts.map +1 -0
- package/dist/pg/schema.js +243 -0
- package/dist/pg/schema.js.map +1 -0
- package/dist/pg/surfaces.d.ts +1187 -0
- package/dist/pg/surfaces.d.ts.map +1 -0
- package/dist/pg/surfaces.js +112 -0
- package/dist/pg/surfaces.js.map +1 -0
- package/dist/pg/vector.d.ts +4 -0
- package/dist/pg/vector.d.ts.map +1 -0
- package/dist/pg/vector.js +12 -0
- package/dist/pg/vector.js.map +1 -0
- package/dist/provider.d.ts +3 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +7 -0
- package/dist/provider.js.map +1 -0
- package/dist/schema.d.ts +11770 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +9 -0
- package/dist/schema.js.map +1 -0
- package/dist/sqlite/actions.d.ts +448 -0
- package/dist/sqlite/actions.d.ts.map +1 -0
- package/dist/sqlite/actions.js +54 -0
- package/dist/sqlite/actions.js.map +1 -0
- package/dist/sqlite/content.d.ts +708 -0
- package/dist/sqlite/content.d.ts.map +1 -0
- package/dist/sqlite/content.js +65 -0
- package/dist/sqlite/content.js.map +1 -0
- package/dist/sqlite/google.d.ts +2885 -0
- package/dist/sqlite/google.d.ts.map +1 -0
- package/dist/sqlite/google.js +250 -0
- package/dist/sqlite/google.js.map +1 -0
- package/dist/sqlite/hosted.d.ts +1183 -0
- package/dist/sqlite/hosted.d.ts.map +1 -0
- package/dist/sqlite/hosted.js +106 -0
- package/dist/sqlite/hosted.js.map +1 -0
- package/dist/sqlite/init-sql.d.ts +3 -0
- package/dist/sqlite/init-sql.d.ts.map +1 -0
- package/dist/sqlite/init-sql.js +963 -0
- package/dist/sqlite/init-sql.js.map +1 -0
- package/dist/sqlite/keywords.d.ts +1038 -0
- package/dist/sqlite/keywords.d.ts.map +1 -0
- package/dist/sqlite/keywords.js +89 -0
- package/dist/sqlite/keywords.js.map +1 -0
- package/dist/sqlite/measure.d.ts +1451 -0
- package/dist/sqlite/measure.d.ts.map +1 -0
- package/dist/sqlite/measure.js +128 -0
- package/dist/sqlite/measure.js.map +1 -0
- package/dist/sqlite/schema.d.ts +2849 -0
- package/dist/sqlite/schema.d.ts.map +1 -0
- package/dist/sqlite/schema.js +243 -0
- package/dist/sqlite/schema.js.map +1 -0
- package/dist/sqlite/surfaces.d.ts +1295 -0
- package/dist/sqlite/surfaces.d.ts.map +1 -0
- package/dist/sqlite/surfaces.js +112 -0
- package/dist/sqlite/surfaces.js.map +1 -0
- package/dist/tables.d.ts +30 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +106 -0
- package/dist/tables.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,963 @@
|
|
|
1
|
+
/** Hand-written SQLite DDL matching `sqlite/schema.ts`. Applied on boot. */
|
|
2
|
+
export const SQLITE_INIT_SQL = `
|
|
3
|
+
PRAGMA foreign_keys = ON;
|
|
4
|
+
PRAGMA journal_mode = WAL;
|
|
5
|
+
PRAGMA busy_timeout = 5000;
|
|
6
|
+
|
|
7
|
+
CREATE TABLE IF NOT EXISTS sites (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
origin TEXT NOT NULL,
|
|
10
|
+
name TEXT,
|
|
11
|
+
cms_kind TEXT,
|
|
12
|
+
autonomy_mode TEXT NOT NULL DEFAULT 'full_auto',
|
|
13
|
+
observe_until TEXT,
|
|
14
|
+
ymyl_category TEXT,
|
|
15
|
+
crawl_budget_pages INTEGER NOT NULL DEFAULT 5000,
|
|
16
|
+
crawl_rps REAL NOT NULL DEFAULT 1,
|
|
17
|
+
killswitch INTEGER NOT NULL DEFAULT 0,
|
|
18
|
+
never_touch_globs TEXT NOT NULL DEFAULT '[]',
|
|
19
|
+
created_at TEXT NOT NULL,
|
|
20
|
+
updated_at TEXT NOT NULL
|
|
21
|
+
);
|
|
22
|
+
CREATE UNIQUE INDEX IF NOT EXISTS sites_origin_uidx ON sites(origin);
|
|
23
|
+
CREATE INDEX IF NOT EXISTS sites_killswitch_idx ON sites(killswitch);
|
|
24
|
+
|
|
25
|
+
CREATE TABLE IF NOT EXISTS crawls (
|
|
26
|
+
id TEXT PRIMARY KEY,
|
|
27
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
28
|
+
started_at TEXT NOT NULL,
|
|
29
|
+
finished_at TEXT,
|
|
30
|
+
status TEXT NOT NULL,
|
|
31
|
+
pages_seen INTEGER NOT NULL DEFAULT 0,
|
|
32
|
+
pages_changed INTEGER NOT NULL DEFAULT 0,
|
|
33
|
+
error TEXT
|
|
34
|
+
);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS crawls_site_id_idx ON crawls(site_id);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS crawls_status_idx ON crawls(status);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS pages (
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
41
|
+
url TEXT NOT NULL,
|
|
42
|
+
url_hash TEXT NOT NULL,
|
|
43
|
+
status_code INTEGER,
|
|
44
|
+
content_hash TEXT,
|
|
45
|
+
title TEXT,
|
|
46
|
+
meta_description TEXT,
|
|
47
|
+
canonical TEXT,
|
|
48
|
+
h1 TEXT,
|
|
49
|
+
word_count INTEGER,
|
|
50
|
+
lang TEXT,
|
|
51
|
+
jsonld TEXT,
|
|
52
|
+
first_seen_at TEXT NOT NULL,
|
|
53
|
+
last_crawled_at TEXT,
|
|
54
|
+
last_changed_at TEXT,
|
|
55
|
+
last_audited_at TEXT,
|
|
56
|
+
inlink_count INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
outlink_count INTEGER NOT NULL DEFAULT 0
|
|
58
|
+
);
|
|
59
|
+
CREATE UNIQUE INDEX IF NOT EXISTS pages_site_url_hash_uidx ON pages(site_id, url_hash);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS pages_site_id_idx ON pages(site_id);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS pages_last_audited_idx ON pages(site_id, last_audited_at);
|
|
62
|
+
|
|
63
|
+
CREATE TABLE IF NOT EXISTS page_snapshots (
|
|
64
|
+
id TEXT PRIMARY KEY,
|
|
65
|
+
page_id TEXT NOT NULL REFERENCES pages(id) ON DELETE CASCADE,
|
|
66
|
+
crawl_id TEXT REFERENCES crawls(id) ON DELETE SET NULL,
|
|
67
|
+
fetched_at TEXT NOT NULL,
|
|
68
|
+
status_code INTEGER,
|
|
69
|
+
content_hash TEXT,
|
|
70
|
+
body TEXT,
|
|
71
|
+
headers TEXT
|
|
72
|
+
);
|
|
73
|
+
CREATE INDEX IF NOT EXISTS page_snapshots_page_id_idx ON page_snapshots(page_id);
|
|
74
|
+
CREATE INDEX IF NOT EXISTS page_snapshots_crawl_id_idx ON page_snapshots(crawl_id);
|
|
75
|
+
|
|
76
|
+
CREATE TABLE IF NOT EXISTS findings (
|
|
77
|
+
id TEXT PRIMARY KEY,
|
|
78
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
79
|
+
page_id TEXT REFERENCES pages(id) ON DELETE SET NULL,
|
|
80
|
+
rule_id TEXT NOT NULL,
|
|
81
|
+
severity TEXT NOT NULL,
|
|
82
|
+
autonomy_tier TEXT NOT NULL,
|
|
83
|
+
title TEXT NOT NULL,
|
|
84
|
+
explanation TEXT,
|
|
85
|
+
evidence TEXT,
|
|
86
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
87
|
+
fingerprint TEXT NOT NULL,
|
|
88
|
+
first_detected_at TEXT NOT NULL,
|
|
89
|
+
resolved_at TEXT
|
|
90
|
+
);
|
|
91
|
+
CREATE UNIQUE INDEX IF NOT EXISTS findings_fingerprint_uidx ON findings(fingerprint);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS findings_site_status_idx ON findings(site_id, status);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS findings_rule_id_idx ON findings(rule_id);
|
|
94
|
+
|
|
95
|
+
CREATE TABLE IF NOT EXISTS actions (
|
|
96
|
+
id TEXT PRIMARY KEY,
|
|
97
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
98
|
+
page_id TEXT REFERENCES pages(id) ON DELETE SET NULL,
|
|
99
|
+
finding_id TEXT REFERENCES findings(id) ON DELETE SET NULL,
|
|
100
|
+
action_type TEXT NOT NULL,
|
|
101
|
+
target_ref TEXT NOT NULL,
|
|
102
|
+
payload TEXT,
|
|
103
|
+
risk TEXT NOT NULL,
|
|
104
|
+
tier TEXT NOT NULL,
|
|
105
|
+
state TEXT NOT NULL,
|
|
106
|
+
approved_by TEXT,
|
|
107
|
+
approved_at TEXT,
|
|
108
|
+
applied_at TEXT,
|
|
109
|
+
error TEXT,
|
|
110
|
+
created_at TEXT NOT NULL
|
|
111
|
+
);
|
|
112
|
+
CREATE INDEX IF NOT EXISTS actions_site_state_idx ON actions(site_id, state);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS actions_finding_id_idx ON actions(finding_id);
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS changes (
|
|
116
|
+
id TEXT PRIMARY KEY,
|
|
117
|
+
action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,
|
|
118
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
119
|
+
applied_at TEXT NOT NULL,
|
|
120
|
+
actor TEXT NOT NULL,
|
|
121
|
+
summary TEXT NOT NULL,
|
|
122
|
+
revertible INTEGER NOT NULL DEFAULT 1,
|
|
123
|
+
reverted_at TEXT
|
|
124
|
+
);
|
|
125
|
+
CREATE INDEX IF NOT EXISTS changes_site_id_idx ON changes(site_id);
|
|
126
|
+
CREATE INDEX IF NOT EXISTS changes_action_id_idx ON changes(action_id);
|
|
127
|
+
|
|
128
|
+
CREATE TABLE IF NOT EXISTS change_snapshots (
|
|
129
|
+
id TEXT PRIMARY KEY,
|
|
130
|
+
change_id TEXT NOT NULL REFERENCES changes(id) ON DELETE CASCADE,
|
|
131
|
+
kind TEXT NOT NULL,
|
|
132
|
+
target_ref TEXT NOT NULL,
|
|
133
|
+
body TEXT NOT NULL,
|
|
134
|
+
content_type TEXT,
|
|
135
|
+
captured_at TEXT NOT NULL
|
|
136
|
+
);
|
|
137
|
+
CREATE INDEX IF NOT EXISTS change_snapshots_change_id_idx ON change_snapshots(change_id);
|
|
138
|
+
|
|
139
|
+
CREATE TABLE IF NOT EXISTS credentials (
|
|
140
|
+
id TEXT PRIMARY KEY,
|
|
141
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
142
|
+
provider TEXT NOT NULL,
|
|
143
|
+
keyring_account TEXT NOT NULL,
|
|
144
|
+
dek_id TEXT,
|
|
145
|
+
nonce TEXT,
|
|
146
|
+
scopes TEXT,
|
|
147
|
+
expires_at TEXT,
|
|
148
|
+
rotated_at TEXT,
|
|
149
|
+
created_at TEXT NOT NULL
|
|
150
|
+
);
|
|
151
|
+
CREATE INDEX IF NOT EXISTS credentials_site_id_idx ON credentials(site_id);
|
|
152
|
+
CREATE INDEX IF NOT EXISTS credentials_provider_idx ON credentials(provider);
|
|
153
|
+
|
|
154
|
+
CREATE TABLE IF NOT EXISTS cost_ledger (
|
|
155
|
+
id TEXT PRIMARY KEY,
|
|
156
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
157
|
+
ts TEXT NOT NULL,
|
|
158
|
+
provider TEXT NOT NULL,
|
|
159
|
+
model TEXT,
|
|
160
|
+
operation TEXT NOT NULL,
|
|
161
|
+
input_tokens INTEGER,
|
|
162
|
+
output_tokens INTEGER,
|
|
163
|
+
cost_usd REAL NOT NULL DEFAULT 0,
|
|
164
|
+
currency TEXT NOT NULL DEFAULT 'USD',
|
|
165
|
+
meta TEXT,
|
|
166
|
+
created_at TEXT NOT NULL
|
|
167
|
+
);
|
|
168
|
+
CREATE INDEX IF NOT EXISTS cost_ledger_site_ts_idx ON cost_ledger(site_id, ts);
|
|
169
|
+
CREATE INDEX IF NOT EXISTS cost_ledger_provider_idx ON cost_ledger(provider);
|
|
170
|
+
|
|
171
|
+
CREATE TABLE IF NOT EXISTS jobs (
|
|
172
|
+
id TEXT PRIMARY KEY,
|
|
173
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
174
|
+
kind TEXT NOT NULL,
|
|
175
|
+
status TEXT NOT NULL,
|
|
176
|
+
idempotency_key TEXT NOT NULL,
|
|
177
|
+
payload TEXT,
|
|
178
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
179
|
+
run_at TEXT,
|
|
180
|
+
heartbeat_at TEXT,
|
|
181
|
+
error TEXT,
|
|
182
|
+
created_at TEXT NOT NULL,
|
|
183
|
+
completed_at TEXT
|
|
184
|
+
);
|
|
185
|
+
CREATE UNIQUE INDEX IF NOT EXISTS jobs_idempotency_key_uidx ON jobs(idempotency_key);
|
|
186
|
+
CREATE INDEX IF NOT EXISTS jobs_status_run_at_idx ON jobs(status, run_at);
|
|
187
|
+
CREATE INDEX IF NOT EXISTS jobs_site_id_idx ON jobs(site_id);
|
|
188
|
+
|
|
189
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
190
|
+
key TEXT PRIMARY KEY,
|
|
191
|
+
value TEXT NOT NULL,
|
|
192
|
+
updated_at TEXT NOT NULL
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
196
|
+
id TEXT PRIMARY KEY,
|
|
197
|
+
ts TEXT NOT NULL,
|
|
198
|
+
site_id TEXT REFERENCES sites(id) ON DELETE SET NULL,
|
|
199
|
+
actor TEXT NOT NULL,
|
|
200
|
+
event TEXT NOT NULL,
|
|
201
|
+
subject_type TEXT,
|
|
202
|
+
subject_id TEXT,
|
|
203
|
+
payload TEXT,
|
|
204
|
+
prev_hash TEXT,
|
|
205
|
+
hash TEXT NOT NULL
|
|
206
|
+
);
|
|
207
|
+
CREATE INDEX IF NOT EXISTS audit_log_ts_idx ON audit_log(ts);
|
|
208
|
+
CREATE INDEX IF NOT EXISTS audit_log_site_id_idx ON audit_log(site_id);
|
|
209
|
+
CREATE INDEX IF NOT EXISTS audit_log_event_idx ON audit_log(event);
|
|
210
|
+
|
|
211
|
+
CREATE TABLE IF NOT EXISTS gsc_connections (
|
|
212
|
+
id TEXT PRIMARY KEY,
|
|
213
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
214
|
+
site_url TEXT NOT NULL,
|
|
215
|
+
permission_level TEXT,
|
|
216
|
+
account_email TEXT,
|
|
217
|
+
google_sub TEXT,
|
|
218
|
+
created_at TEXT NOT NULL,
|
|
219
|
+
updated_at TEXT NOT NULL
|
|
220
|
+
);
|
|
221
|
+
CREATE UNIQUE INDEX IF NOT EXISTS gsc_connections_site_uidx ON gsc_connections(site_id);
|
|
222
|
+
CREATE INDEX IF NOT EXISTS gsc_connections_site_url_idx ON gsc_connections(site_url);
|
|
223
|
+
|
|
224
|
+
CREATE TABLE IF NOT EXISTS ga4_connections (
|
|
225
|
+
id TEXT PRIMARY KEY,
|
|
226
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
227
|
+
property_id TEXT NOT NULL,
|
|
228
|
+
display_name TEXT,
|
|
229
|
+
time_zone TEXT,
|
|
230
|
+
currency_code TEXT,
|
|
231
|
+
account_id TEXT,
|
|
232
|
+
account_email TEXT,
|
|
233
|
+
created_at TEXT NOT NULL,
|
|
234
|
+
updated_at TEXT NOT NULL
|
|
235
|
+
);
|
|
236
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ga4_connections_site_uidx ON ga4_connections(site_id);
|
|
237
|
+
CREATE INDEX IF NOT EXISTS ga4_connections_property_idx ON ga4_connections(property_id);
|
|
238
|
+
|
|
239
|
+
CREATE TABLE IF NOT EXISTS gsc_daily (
|
|
240
|
+
id TEXT PRIMARY KEY,
|
|
241
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
242
|
+
date TEXT NOT NULL,
|
|
243
|
+
search_type TEXT NOT NULL,
|
|
244
|
+
clicks REAL NOT NULL DEFAULT 0,
|
|
245
|
+
impressions REAL NOT NULL DEFAULT 0,
|
|
246
|
+
ctr REAL,
|
|
247
|
+
position REAL,
|
|
248
|
+
data_state TEXT NOT NULL DEFAULT 'final',
|
|
249
|
+
first_incomplete_date TEXT
|
|
250
|
+
);
|
|
251
|
+
CREATE UNIQUE INDEX IF NOT EXISTS gsc_daily_uidx ON gsc_daily(site_id, date, search_type);
|
|
252
|
+
CREATE INDEX IF NOT EXISTS gsc_daily_site_date_idx ON gsc_daily(site_id, date);
|
|
253
|
+
|
|
254
|
+
CREATE TABLE IF NOT EXISTS gsc_page_daily (
|
|
255
|
+
id TEXT PRIMARY KEY,
|
|
256
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
257
|
+
date TEXT NOT NULL,
|
|
258
|
+
page TEXT NOT NULL,
|
|
259
|
+
search_type TEXT NOT NULL,
|
|
260
|
+
clicks REAL NOT NULL DEFAULT 0,
|
|
261
|
+
impressions REAL NOT NULL DEFAULT 0,
|
|
262
|
+
position REAL
|
|
263
|
+
);
|
|
264
|
+
CREATE UNIQUE INDEX IF NOT EXISTS gsc_page_daily_uidx ON gsc_page_daily(site_id, date, page, search_type);
|
|
265
|
+
CREATE INDEX IF NOT EXISTS gsc_page_daily_site_page_idx ON gsc_page_daily(site_id, page);
|
|
266
|
+
|
|
267
|
+
CREATE TABLE IF NOT EXISTS gsc_query_daily (
|
|
268
|
+
id TEXT PRIMARY KEY,
|
|
269
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
270
|
+
date TEXT NOT NULL,
|
|
271
|
+
query TEXT NOT NULL,
|
|
272
|
+
search_type TEXT NOT NULL,
|
|
273
|
+
clicks REAL NOT NULL DEFAULT 0,
|
|
274
|
+
impressions REAL NOT NULL DEFAULT 0,
|
|
275
|
+
position REAL
|
|
276
|
+
);
|
|
277
|
+
CREATE UNIQUE INDEX IF NOT EXISTS gsc_query_daily_uidx ON gsc_query_daily(site_id, date, query, search_type);
|
|
278
|
+
CREATE INDEX IF NOT EXISTS gsc_query_daily_site_date_idx ON gsc_query_daily(site_id, date);
|
|
279
|
+
|
|
280
|
+
CREATE TABLE IF NOT EXISTS gsc_url_inspections (
|
|
281
|
+
id TEXT PRIMARY KEY,
|
|
282
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
283
|
+
url TEXT NOT NULL,
|
|
284
|
+
inspected_at TEXT NOT NULL,
|
|
285
|
+
verdict TEXT,
|
|
286
|
+
coverage_state TEXT,
|
|
287
|
+
indexing_state TEXT,
|
|
288
|
+
google_canonical TEXT,
|
|
289
|
+
user_canonical TEXT,
|
|
290
|
+
robots_txt_state TEXT,
|
|
291
|
+
page_fetch_state TEXT,
|
|
292
|
+
crawled_as TEXT,
|
|
293
|
+
last_crawl_time TEXT,
|
|
294
|
+
inspection_link TEXT,
|
|
295
|
+
raw TEXT
|
|
296
|
+
);
|
|
297
|
+
CREATE INDEX IF NOT EXISTS gsc_url_inspections_site_url_idx ON gsc_url_inspections(site_id, url);
|
|
298
|
+
CREATE INDEX IF NOT EXISTS gsc_url_inspections_inspected_idx ON gsc_url_inspections(site_id, inspected_at);
|
|
299
|
+
|
|
300
|
+
CREATE TABLE IF NOT EXISTS ga4_daily (
|
|
301
|
+
id TEXT PRIMARY KEY,
|
|
302
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
303
|
+
date TEXT NOT NULL,
|
|
304
|
+
sessions REAL NOT NULL DEFAULT 0,
|
|
305
|
+
organic_sessions REAL NOT NULL DEFAULT 0,
|
|
306
|
+
engaged_sessions REAL NOT NULL DEFAULT 0,
|
|
307
|
+
conversions REAL NOT NULL DEFAULT 0
|
|
308
|
+
);
|
|
309
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ga4_daily_uidx ON ga4_daily(site_id, date);
|
|
310
|
+
CREATE INDEX IF NOT EXISTS ga4_daily_site_date_idx ON ga4_daily(site_id, date);
|
|
311
|
+
|
|
312
|
+
CREATE TABLE IF NOT EXISTS ga4_landing_daily (
|
|
313
|
+
id TEXT PRIMARY KEY,
|
|
314
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
315
|
+
date TEXT NOT NULL,
|
|
316
|
+
landing_page TEXT NOT NULL,
|
|
317
|
+
sessions REAL NOT NULL DEFAULT 0,
|
|
318
|
+
engaged_sessions REAL NOT NULL DEFAULT 0
|
|
319
|
+
);
|
|
320
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ga4_landing_daily_uidx ON ga4_landing_daily(site_id, date, landing_page);
|
|
321
|
+
CREATE INDEX IF NOT EXISTS ga4_landing_daily_page_idx ON ga4_landing_daily(site_id, landing_page);
|
|
322
|
+
|
|
323
|
+
CREATE TABLE IF NOT EXISTS crux_records (
|
|
324
|
+
id TEXT PRIMARY KEY,
|
|
325
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
326
|
+
identifier TEXT NOT NULL,
|
|
327
|
+
identifier_kind TEXT NOT NULL,
|
|
328
|
+
form_factor TEXT NOT NULL,
|
|
329
|
+
collection_date TEXT NOT NULL,
|
|
330
|
+
lcp_p75 REAL,
|
|
331
|
+
inp_p75 REAL,
|
|
332
|
+
cls_p75 REAL,
|
|
333
|
+
ttfb_p75 REAL,
|
|
334
|
+
fcp_p75 REAL,
|
|
335
|
+
source_api TEXT NOT NULL,
|
|
336
|
+
insufficient_traffic INTEGER NOT NULL DEFAULT 0,
|
|
337
|
+
raw TEXT
|
|
338
|
+
);
|
|
339
|
+
CREATE UNIQUE INDEX IF NOT EXISTS crux_records_uidx ON crux_records(site_id, identifier, form_factor, collection_date, source_api);
|
|
340
|
+
CREATE INDEX IF NOT EXISTS crux_records_site_idx ON crux_records(site_id);
|
|
341
|
+
|
|
342
|
+
CREATE TABLE IF NOT EXISTS psi_audits (
|
|
343
|
+
id TEXT PRIMARY KEY,
|
|
344
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
345
|
+
url TEXT NOT NULL,
|
|
346
|
+
strategy TEXT NOT NULL,
|
|
347
|
+
fetched_at TEXT NOT NULL,
|
|
348
|
+
performance_score REAL,
|
|
349
|
+
seo_score REAL,
|
|
350
|
+
lcp_ms REAL,
|
|
351
|
+
inp_ms REAL,
|
|
352
|
+
cls REAL,
|
|
353
|
+
lighthouse_version TEXT,
|
|
354
|
+
body TEXT
|
|
355
|
+
);
|
|
356
|
+
CREATE INDEX IF NOT EXISTS psi_audits_site_url_idx ON psi_audits(site_id, url);
|
|
357
|
+
CREATE INDEX IF NOT EXISTS psi_audits_fetched_idx ON psi_audits(site_id, fetched_at);
|
|
358
|
+
|
|
359
|
+
CREATE TABLE IF NOT EXISTS google_incidents (
|
|
360
|
+
id TEXT PRIMARY KEY,
|
|
361
|
+
number TEXT,
|
|
362
|
+
begin TEXT NOT NULL,
|
|
363
|
+
end TEXT,
|
|
364
|
+
created TEXT,
|
|
365
|
+
modified TEXT,
|
|
366
|
+
external_desc TEXT NOT NULL,
|
|
367
|
+
status_impact TEXT,
|
|
368
|
+
severity TEXT,
|
|
369
|
+
service_key TEXT NOT NULL,
|
|
370
|
+
service_name TEXT NOT NULL,
|
|
371
|
+
uri TEXT,
|
|
372
|
+
raw TEXT,
|
|
373
|
+
ingested_at TEXT NOT NULL
|
|
374
|
+
);
|
|
375
|
+
CREATE INDEX IF NOT EXISTS google_incidents_begin_idx ON google_incidents(begin);
|
|
376
|
+
CREATE INDEX IF NOT EXISTS google_incidents_service_idx ON google_incidents(service_key);
|
|
377
|
+
|
|
378
|
+
CREATE TABLE IF NOT EXISTS google_changepoints (
|
|
379
|
+
id TEXT PRIMARY KEY,
|
|
380
|
+
kind TEXT NOT NULL,
|
|
381
|
+
begin TEXT NOT NULL,
|
|
382
|
+
end TEXT,
|
|
383
|
+
title TEXT NOT NULL,
|
|
384
|
+
metric_impact TEXT NOT NULL DEFAULT '[]',
|
|
385
|
+
clicks_affected INTEGER NOT NULL DEFAULT 0,
|
|
386
|
+
impressions_affected INTEGER NOT NULL DEFAULT 0,
|
|
387
|
+
position_affected INTEGER NOT NULL DEFAULT 0,
|
|
388
|
+
source TEXT NOT NULL,
|
|
389
|
+
incident_id TEXT,
|
|
390
|
+
notes TEXT
|
|
391
|
+
);
|
|
392
|
+
CREATE UNIQUE INDEX IF NOT EXISTS google_changepoints_uidx ON google_changepoints(kind, begin, title);
|
|
393
|
+
CREATE INDEX IF NOT EXISTS google_changepoints_begin_idx ON google_changepoints(begin);
|
|
394
|
+
|
|
395
|
+
CREATE TABLE IF NOT EXISTS gsc_ga4_reconciliation (
|
|
396
|
+
id TEXT PRIMARY KEY,
|
|
397
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
398
|
+
date TEXT NOT NULL,
|
|
399
|
+
gsc_clicks REAL NOT NULL DEFAULT 0,
|
|
400
|
+
ga4_organic_sessions REAL NOT NULL DEFAULT 0,
|
|
401
|
+
residual REAL NOT NULL DEFAULT 0,
|
|
402
|
+
residual_pct REAL,
|
|
403
|
+
overlapping_incident_ids TEXT NOT NULL DEFAULT '[]',
|
|
404
|
+
notes TEXT
|
|
405
|
+
);
|
|
406
|
+
CREATE UNIQUE INDEX IF NOT EXISTS gsc_ga4_reconciliation_uidx ON gsc_ga4_reconciliation(site_id, date);
|
|
407
|
+
CREATE INDEX IF NOT EXISTS gsc_ga4_reconciliation_site_idx ON gsc_ga4_reconciliation(site_id);
|
|
408
|
+
|
|
409
|
+
CREATE TABLE IF NOT EXISTS site_verifications (
|
|
410
|
+
id TEXT PRIMARY KEY,
|
|
411
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
412
|
+
method TEXT NOT NULL,
|
|
413
|
+
identifier TEXT NOT NULL,
|
|
414
|
+
token TEXT,
|
|
415
|
+
token_path TEXT,
|
|
416
|
+
verified_at TEXT,
|
|
417
|
+
error TEXT,
|
|
418
|
+
created_at TEXT NOT NULL
|
|
419
|
+
);
|
|
420
|
+
CREATE UNIQUE INDEX IF NOT EXISTS site_verifications_uidx ON site_verifications(site_id, method, identifier);
|
|
421
|
+
|
|
422
|
+
CREATE TABLE IF NOT EXISTS quota_usage (
|
|
423
|
+
id TEXT PRIMARY KEY,
|
|
424
|
+
api TEXT NOT NULL,
|
|
425
|
+
scope_key TEXT NOT NULL,
|
|
426
|
+
window_kind TEXT NOT NULL,
|
|
427
|
+
window_start TEXT NOT NULL,
|
|
428
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
429
|
+
limit_count INTEGER NOT NULL,
|
|
430
|
+
updated_at TEXT NOT NULL
|
|
431
|
+
);
|
|
432
|
+
CREATE UNIQUE INDEX IF NOT EXISTS quota_usage_uidx ON quota_usage(api, scope_key, window_kind, window_start);
|
|
433
|
+
CREATE INDEX IF NOT EXISTS quota_usage_api_idx ON quota_usage(api, window_start);
|
|
434
|
+
|
|
435
|
+
CREATE TABLE IF NOT EXISTS adapter_connections (
|
|
436
|
+
id TEXT PRIMARY KEY,
|
|
437
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
438
|
+
kind TEXT NOT NULL,
|
|
439
|
+
config TEXT NOT NULL,
|
|
440
|
+
created_at TEXT NOT NULL,
|
|
441
|
+
updated_at TEXT NOT NULL
|
|
442
|
+
);
|
|
443
|
+
CREATE UNIQUE INDEX IF NOT EXISTS adapter_connections_site_kind_uidx ON adapter_connections(site_id, kind);
|
|
444
|
+
CREATE INDEX IF NOT EXISTS adapter_connections_site_idx ON adapter_connections(site_id);
|
|
445
|
+
|
|
446
|
+
CREATE TABLE IF NOT EXISTS url_allowlist (
|
|
447
|
+
id TEXT PRIMARY KEY,
|
|
448
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
449
|
+
url TEXT NOT NULL,
|
|
450
|
+
added_by TEXT NOT NULL,
|
|
451
|
+
created_at TEXT NOT NULL
|
|
452
|
+
);
|
|
453
|
+
CREATE UNIQUE INDEX IF NOT EXISTS url_allowlist_site_url_uidx ON url_allowlist(site_id, url);
|
|
454
|
+
CREATE INDEX IF NOT EXISTS url_allowlist_site_idx ON url_allowlist(site_id);
|
|
455
|
+
|
|
456
|
+
CREATE TABLE IF NOT EXISTS entity_sightings (
|
|
457
|
+
id TEXT PRIMARY KEY,
|
|
458
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
459
|
+
entity TEXT NOT NULL,
|
|
460
|
+
entity_kind TEXT NOT NULL,
|
|
461
|
+
source TEXT NOT NULL,
|
|
462
|
+
first_seen_at TEXT NOT NULL
|
|
463
|
+
);
|
|
464
|
+
CREATE UNIQUE INDEX IF NOT EXISTS entity_sightings_site_entity_uidx ON entity_sightings(site_id, entity);
|
|
465
|
+
CREATE INDEX IF NOT EXISTS entity_sightings_site_source_idx ON entity_sightings(site_id, source);
|
|
466
|
+
|
|
467
|
+
CREATE TABLE IF NOT EXISTS two_key_approvals (
|
|
468
|
+
id TEXT PRIMARY KEY,
|
|
469
|
+
action_id TEXT NOT NULL REFERENCES actions(id) ON DELETE CASCADE,
|
|
470
|
+
actor TEXT NOT NULL,
|
|
471
|
+
hmac TEXT NOT NULL,
|
|
472
|
+
created_at TEXT NOT NULL
|
|
473
|
+
);
|
|
474
|
+
CREATE UNIQUE INDEX IF NOT EXISTS two_key_approvals_action_actor_uidx ON two_key_approvals(action_id, actor);
|
|
475
|
+
CREATE INDEX IF NOT EXISTS two_key_approvals_action_idx ON two_key_approvals(action_id);
|
|
476
|
+
|
|
477
|
+
CREATE TABLE IF NOT EXISTS reports (
|
|
478
|
+
id TEXT PRIMARY KEY,
|
|
479
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
480
|
+
created_at TEXT NOT NULL,
|
|
481
|
+
title TEXT NOT NULL,
|
|
482
|
+
body_html TEXT NOT NULL,
|
|
483
|
+
payload_json TEXT NOT NULL,
|
|
484
|
+
hash TEXT NOT NULL,
|
|
485
|
+
white_label INTEGER NOT NULL DEFAULT 0
|
|
486
|
+
);
|
|
487
|
+
CREATE INDEX IF NOT EXISTS reports_site_id_idx ON reports(site_id);
|
|
488
|
+
|
|
489
|
+
CREATE TABLE IF NOT EXISTS style_profiles (
|
|
490
|
+
id TEXT PRIMARY KEY,
|
|
491
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
492
|
+
voice_json TEXT NOT NULL,
|
|
493
|
+
disclosure TEXT NOT NULL DEFAULT 'html_comment',
|
|
494
|
+
updated_at TEXT NOT NULL
|
|
495
|
+
);
|
|
496
|
+
CREATE UNIQUE INDEX IF NOT EXISTS style_profiles_site_uidx ON style_profiles(site_id);
|
|
497
|
+
|
|
498
|
+
CREATE TABLE IF NOT EXISTS content_briefs (
|
|
499
|
+
id TEXT PRIMARY KEY,
|
|
500
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
501
|
+
page_id TEXT REFERENCES pages(id) ON DELETE SET NULL,
|
|
502
|
+
playbook_id TEXT NOT NULL,
|
|
503
|
+
playbook_version TEXT NOT NULL,
|
|
504
|
+
kind TEXT NOT NULL,
|
|
505
|
+
target_url TEXT NOT NULL,
|
|
506
|
+
brief_json TEXT NOT NULL,
|
|
507
|
+
score REAL NOT NULL DEFAULT 0,
|
|
508
|
+
created_at TEXT NOT NULL
|
|
509
|
+
);
|
|
510
|
+
CREATE INDEX IF NOT EXISTS content_briefs_site_idx ON content_briefs(site_id);
|
|
511
|
+
CREATE INDEX IF NOT EXISTS content_briefs_page_idx ON content_briefs(page_id);
|
|
512
|
+
|
|
513
|
+
CREATE TABLE IF NOT EXISTS content_drafts (
|
|
514
|
+
id TEXT PRIMARY KEY,
|
|
515
|
+
brief_id TEXT NOT NULL REFERENCES content_briefs(id) ON DELETE CASCADE,
|
|
516
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
517
|
+
page_id TEXT REFERENCES pages(id) ON DELETE SET NULL,
|
|
518
|
+
action_id TEXT,
|
|
519
|
+
title TEXT,
|
|
520
|
+
body TEXT,
|
|
521
|
+
model TEXT,
|
|
522
|
+
model_class TEXT,
|
|
523
|
+
state TEXT NOT NULL,
|
|
524
|
+
gate_json TEXT,
|
|
525
|
+
evidence_tier TEXT NOT NULL DEFAULT 'E',
|
|
526
|
+
created_at TEXT NOT NULL,
|
|
527
|
+
published_at TEXT
|
|
528
|
+
);
|
|
529
|
+
CREATE INDEX IF NOT EXISTS content_drafts_site_idx ON content_drafts(site_id);
|
|
530
|
+
CREATE INDEX IF NOT EXISTS content_drafts_brief_idx ON content_drafts(brief_id);
|
|
531
|
+
CREATE INDEX IF NOT EXISTS content_drafts_state_idx ON content_drafts(site_id, state);
|
|
532
|
+
|
|
533
|
+
CREATE TABLE IF NOT EXISTS publish_gate_results (
|
|
534
|
+
id TEXT PRIMARY KEY,
|
|
535
|
+
draft_id TEXT NOT NULL REFERENCES content_drafts(id) ON DELETE CASCADE,
|
|
536
|
+
check_id INTEGER NOT NULL,
|
|
537
|
+
code TEXT NOT NULL,
|
|
538
|
+
ok INTEGER NOT NULL,
|
|
539
|
+
detail TEXT NOT NULL,
|
|
540
|
+
created_at TEXT NOT NULL
|
|
541
|
+
);
|
|
542
|
+
CREATE INDEX IF NOT EXISTS publish_gate_results_draft_idx ON publish_gate_results(draft_id);
|
|
543
|
+
|
|
544
|
+
CREATE TABLE IF NOT EXISTS keywords (
|
|
545
|
+
id TEXT PRIMARY KEY,
|
|
546
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
547
|
+
query TEXT NOT NULL,
|
|
548
|
+
source TEXT NOT NULL,
|
|
549
|
+
volume INTEGER,
|
|
550
|
+
volume_source TEXT,
|
|
551
|
+
difficulty REAL,
|
|
552
|
+
clicks REAL NOT NULL DEFAULT 0,
|
|
553
|
+
impressions REAL NOT NULL DEFAULT 0,
|
|
554
|
+
position REAL,
|
|
555
|
+
page TEXT,
|
|
556
|
+
cluster_id TEXT,
|
|
557
|
+
created_at TEXT NOT NULL,
|
|
558
|
+
updated_at TEXT NOT NULL
|
|
559
|
+
);
|
|
560
|
+
CREATE UNIQUE INDEX IF NOT EXISTS keywords_site_query_uidx ON keywords(site_id, query);
|
|
561
|
+
CREATE INDEX IF NOT EXISTS keywords_site_idx ON keywords(site_id);
|
|
562
|
+
CREATE INDEX IF NOT EXISTS keywords_cluster_idx ON keywords(cluster_id);
|
|
563
|
+
|
|
564
|
+
CREATE TABLE IF NOT EXISTS keyword_clusters (
|
|
565
|
+
id TEXT PRIMARY KEY,
|
|
566
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
567
|
+
label TEXT NOT NULL,
|
|
568
|
+
member_count INTEGER NOT NULL DEFAULT 0,
|
|
569
|
+
centroid_json TEXT,
|
|
570
|
+
serp_confirmed INTEGER NOT NULL DEFAULT 0,
|
|
571
|
+
created_at TEXT NOT NULL
|
|
572
|
+
);
|
|
573
|
+
CREATE INDEX IF NOT EXISTS keyword_clusters_site_idx ON keyword_clusters(site_id);
|
|
574
|
+
|
|
575
|
+
CREATE TABLE IF NOT EXISTS rank_snapshots (
|
|
576
|
+
id TEXT PRIMARY KEY,
|
|
577
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
578
|
+
query TEXT NOT NULL,
|
|
579
|
+
url TEXT,
|
|
580
|
+
position INTEGER,
|
|
581
|
+
date TEXT NOT NULL,
|
|
582
|
+
provider TEXT NOT NULL,
|
|
583
|
+
estimated_usd REAL NOT NULL DEFAULT 0,
|
|
584
|
+
actual_usd REAL NOT NULL DEFAULT 0,
|
|
585
|
+
created_at TEXT NOT NULL
|
|
586
|
+
);
|
|
587
|
+
CREATE UNIQUE INDEX IF NOT EXISTS rank_snapshots_uidx ON rank_snapshots(site_id, query, date, provider);
|
|
588
|
+
CREATE INDEX IF NOT EXISTS rank_snapshots_site_date_idx ON rank_snapshots(site_id, date);
|
|
589
|
+
|
|
590
|
+
CREATE TABLE IF NOT EXISTS serp_cache (
|
|
591
|
+
id TEXT PRIMARY KEY,
|
|
592
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
593
|
+
query TEXT NOT NULL,
|
|
594
|
+
provider TEXT NOT NULL,
|
|
595
|
+
results_json TEXT NOT NULL,
|
|
596
|
+
estimated_usd REAL NOT NULL DEFAULT 0,
|
|
597
|
+
fetched_at TEXT NOT NULL
|
|
598
|
+
);
|
|
599
|
+
CREATE UNIQUE INDEX IF NOT EXISTS serp_cache_uidx ON serp_cache(query, provider);
|
|
600
|
+
CREATE INDEX IF NOT EXISTS serp_cache_site_idx ON serp_cache(site_id);
|
|
601
|
+
|
|
602
|
+
CREATE TABLE IF NOT EXISTS provider_quotes (
|
|
603
|
+
id TEXT PRIMARY KEY,
|
|
604
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
605
|
+
provider TEXT NOT NULL,
|
|
606
|
+
capability TEXT NOT NULL,
|
|
607
|
+
operation TEXT NOT NULL,
|
|
608
|
+
units INTEGER NOT NULL DEFAULT 1,
|
|
609
|
+
estimated_usd REAL NOT NULL DEFAULT 0,
|
|
610
|
+
actual_usd REAL,
|
|
611
|
+
free INTEGER NOT NULL DEFAULT 0,
|
|
612
|
+
created_at TEXT NOT NULL
|
|
613
|
+
);
|
|
614
|
+
CREATE INDEX IF NOT EXISTS provider_quotes_site_idx ON provider_quotes(site_id);
|
|
615
|
+
CREATE INDEX IF NOT EXISTS provider_quotes_provider_idx ON provider_quotes(provider);
|
|
616
|
+
|
|
617
|
+
CREATE TABLE IF NOT EXISTS embedding_cache (
|
|
618
|
+
id TEXT PRIMARY KEY,
|
|
619
|
+
hash TEXT NOT NULL,
|
|
620
|
+
model TEXT NOT NULL,
|
|
621
|
+
dim INTEGER NOT NULL,
|
|
622
|
+
vector_json TEXT NOT NULL,
|
|
623
|
+
created_at TEXT NOT NULL
|
|
624
|
+
);
|
|
625
|
+
CREATE UNIQUE INDEX IF NOT EXISTS embedding_cache_uidx ON embedding_cache(hash, model);
|
|
626
|
+
|
|
627
|
+
CREATE TABLE IF NOT EXISTS experiments (
|
|
628
|
+
id TEXT PRIMARY KEY,
|
|
629
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
630
|
+
hypothesis TEXT NOT NULL,
|
|
631
|
+
intervention_kind TEXT NOT NULL,
|
|
632
|
+
status TEXT NOT NULL,
|
|
633
|
+
design TEXT NOT NULL,
|
|
634
|
+
unit TEXT NOT NULL,
|
|
635
|
+
randomisation_seed INTEGER NOT NULL,
|
|
636
|
+
cluster_key TEXT,
|
|
637
|
+
pre_start TEXT NOT NULL,
|
|
638
|
+
pre_end TEXT NOT NULL,
|
|
639
|
+
post_start TEXT NOT NULL,
|
|
640
|
+
planned_end TEXT NOT NULL,
|
|
641
|
+
primary_metric TEXT NOT NULL DEFAULT 'clicks',
|
|
642
|
+
secondary_metric TEXT,
|
|
643
|
+
planned_mde REAL NOT NULL,
|
|
644
|
+
power_target REAL NOT NULL DEFAULT 0.8,
|
|
645
|
+
alpha REAL NOT NULL DEFAULT 0.05,
|
|
646
|
+
evidence_tier TEXT,
|
|
647
|
+
peeking_blocked INTEGER NOT NULL DEFAULT 1,
|
|
648
|
+
created_at TEXT NOT NULL,
|
|
649
|
+
concluded_at TEXT
|
|
650
|
+
);
|
|
651
|
+
CREATE INDEX IF NOT EXISTS experiments_site_idx ON experiments(site_id);
|
|
652
|
+
CREATE INDEX IF NOT EXISTS experiments_status_idx ON experiments(site_id, status);
|
|
653
|
+
CREATE INDEX IF NOT EXISTS experiments_planned_end_idx ON experiments(planned_end);
|
|
654
|
+
|
|
655
|
+
CREATE TABLE IF NOT EXISTS cohorts (
|
|
656
|
+
id TEXT PRIMARY KEY,
|
|
657
|
+
experiment_id TEXT NOT NULL REFERENCES experiments(id) ON DELETE CASCADE,
|
|
658
|
+
arm TEXT NOT NULL
|
|
659
|
+
);
|
|
660
|
+
CREATE UNIQUE INDEX IF NOT EXISTS cohorts_experiment_arm_uidx ON cohorts(experiment_id, arm);
|
|
661
|
+
CREATE INDEX IF NOT EXISTS cohorts_experiment_idx ON cohorts(experiment_id);
|
|
662
|
+
|
|
663
|
+
CREATE TABLE IF NOT EXISTS cohort_members (
|
|
664
|
+
id TEXT PRIMARY KEY,
|
|
665
|
+
cohort_id TEXT NOT NULL REFERENCES cohorts(id) ON DELETE CASCADE,
|
|
666
|
+
url TEXT NOT NULL,
|
|
667
|
+
pre_clicks REAL NOT NULL DEFAULT 0,
|
|
668
|
+
pre_impressions REAL NOT NULL DEFAULT 0,
|
|
669
|
+
content_hash_at_start TEXT
|
|
670
|
+
);
|
|
671
|
+
CREATE UNIQUE INDEX IF NOT EXISTS cohort_members_uidx ON cohort_members(cohort_id, url);
|
|
672
|
+
CREATE INDEX IF NOT EXISTS cohort_members_cohort_idx ON cohort_members(cohort_id);
|
|
673
|
+
|
|
674
|
+
CREATE TABLE IF NOT EXISTS experiment_results (
|
|
675
|
+
experiment_id TEXT PRIMARY KEY REFERENCES experiments(id) ON DELETE CASCADE,
|
|
676
|
+
metric TEXT NOT NULL,
|
|
677
|
+
point_estimate REAL,
|
|
678
|
+
ci_low REAL,
|
|
679
|
+
ci_high REAL,
|
|
680
|
+
ci_level REAL,
|
|
681
|
+
prob_positive REAL,
|
|
682
|
+
realised_mde REAL,
|
|
683
|
+
n_boot INTEGER,
|
|
684
|
+
suppressed_by TEXT NOT NULL DEFAULT '[]',
|
|
685
|
+
evidence_tier TEXT NOT NULL,
|
|
686
|
+
statement TEXT NOT NULL,
|
|
687
|
+
causation_claimed INTEGER NOT NULL DEFAULT 0,
|
|
688
|
+
analysed_at TEXT NOT NULL
|
|
689
|
+
);
|
|
690
|
+
|
|
691
|
+
CREATE TABLE IF NOT EXISTS data_anomalies (
|
|
692
|
+
id TEXT PRIMARY KEY,
|
|
693
|
+
description TEXT NOT NULL,
|
|
694
|
+
start_date TEXT NOT NULL,
|
|
695
|
+
end_date TEXT,
|
|
696
|
+
affected_metrics TEXT NOT NULL DEFAULT '[]',
|
|
697
|
+
affected_surfaces TEXT NOT NULL DEFAULT '[]',
|
|
698
|
+
source TEXT NOT NULL
|
|
699
|
+
);
|
|
700
|
+
CREATE INDEX IF NOT EXISTS data_anomalies_start_idx ON data_anomalies(start_date);
|
|
701
|
+
|
|
702
|
+
CREATE TABLE IF NOT EXISTS claims (
|
|
703
|
+
id TEXT PRIMARY KEY,
|
|
704
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
705
|
+
change_id TEXT REFERENCES changes(id) ON DELETE SET NULL,
|
|
706
|
+
experiment_id TEXT REFERENCES experiments(id) ON DELETE SET NULL,
|
|
707
|
+
evidence_tier TEXT NOT NULL,
|
|
708
|
+
statement TEXT NOT NULL,
|
|
709
|
+
metric TEXT NOT NULL DEFAULT 'clicks',
|
|
710
|
+
causation_claimed INTEGER NOT NULL DEFAULT 0,
|
|
711
|
+
refused_reason TEXT,
|
|
712
|
+
created_at TEXT NOT NULL
|
|
713
|
+
);
|
|
714
|
+
CREATE INDEX IF NOT EXISTS claims_site_idx ON claims(site_id);
|
|
715
|
+
CREATE INDEX IF NOT EXISTS claims_change_idx ON claims(change_id);
|
|
716
|
+
CREATE INDEX IF NOT EXISTS claims_experiment_idx ON claims(experiment_id);
|
|
717
|
+
CREATE INDEX IF NOT EXISTS claims_tier_idx ON claims(site_id, evidence_tier);
|
|
718
|
+
|
|
719
|
+
CREATE TABLE IF NOT EXISTS reconciliation_waterfall (
|
|
720
|
+
id TEXT PRIMARY KEY,
|
|
721
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
722
|
+
date TEXT NOT NULL,
|
|
723
|
+
window_start TEXT NOT NULL,
|
|
724
|
+
window_end TEXT NOT NULL,
|
|
725
|
+
gsc_clicks REAL NOT NULL DEFAULT 0,
|
|
726
|
+
ga4_organic_sessions REAL NOT NULL DEFAULT 0,
|
|
727
|
+
residual REAL NOT NULL DEFAULT 0,
|
|
728
|
+
residual_pct REAL,
|
|
729
|
+
causes_json TEXT NOT NULL,
|
|
730
|
+
anonymized_query_share REAL,
|
|
731
|
+
eu_invisible_share REAL,
|
|
732
|
+
notes TEXT,
|
|
733
|
+
created_at TEXT NOT NULL
|
|
734
|
+
);
|
|
735
|
+
CREATE UNIQUE INDEX IF NOT EXISTS reconciliation_waterfall_uidx ON reconciliation_waterfall(site_id, window_start, window_end);
|
|
736
|
+
CREATE INDEX IF NOT EXISTS reconciliation_waterfall_site_idx ON reconciliation_waterfall(site_id);
|
|
737
|
+
|
|
738
|
+
CREATE TABLE IF NOT EXISTS ai_runs (
|
|
739
|
+
id TEXT PRIMARY KEY,
|
|
740
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
741
|
+
engine TEXT NOT NULL,
|
|
742
|
+
prompt_count INTEGER NOT NULL DEFAULT 0,
|
|
743
|
+
citation_share REAL NOT NULL DEFAULT 0,
|
|
744
|
+
share_of_voice REAL NOT NULL DEFAULT 0,
|
|
745
|
+
estimated_usd REAL NOT NULL DEFAULT 0,
|
|
746
|
+
ran_at TEXT NOT NULL
|
|
747
|
+
);
|
|
748
|
+
CREATE INDEX IF NOT EXISTS ai_runs_site_idx ON ai_runs(site_id);
|
|
749
|
+
CREATE INDEX IF NOT EXISTS ai_runs_ran_idx ON ai_runs(site_id, ran_at);
|
|
750
|
+
|
|
751
|
+
CREATE TABLE IF NOT EXISTS ai_citations (
|
|
752
|
+
id TEXT PRIMARY KEY,
|
|
753
|
+
run_id TEXT NOT NULL REFERENCES ai_runs(id) ON DELETE CASCADE,
|
|
754
|
+
engine TEXT NOT NULL,
|
|
755
|
+
prompt TEXT NOT NULL,
|
|
756
|
+
cited_url TEXT,
|
|
757
|
+
cited_domain TEXT,
|
|
758
|
+
is_ours INTEGER NOT NULL DEFAULT 0
|
|
759
|
+
);
|
|
760
|
+
CREATE INDEX IF NOT EXISTS ai_citations_run_idx ON ai_citations(run_id);
|
|
761
|
+
|
|
762
|
+
CREATE TABLE IF NOT EXISTS bing_ai_rows (
|
|
763
|
+
id TEXT PRIMARY KEY,
|
|
764
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
765
|
+
date TEXT NOT NULL,
|
|
766
|
+
grounding_query TEXT NOT NULL,
|
|
767
|
+
citations INTEGER NOT NULL DEFAULT 0,
|
|
768
|
+
citation_share REAL NOT NULL DEFAULT 0,
|
|
769
|
+
source TEXT NOT NULL DEFAULT 'csv'
|
|
770
|
+
);
|
|
771
|
+
CREATE INDEX IF NOT EXISTS bing_ai_rows_site_idx ON bing_ai_rows(site_id);
|
|
772
|
+
|
|
773
|
+
CREATE TABLE IF NOT EXISTS gbp_locations (
|
|
774
|
+
id TEXT PRIMARY KEY,
|
|
775
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
776
|
+
location_name TEXT NOT NULL,
|
|
777
|
+
title TEXT,
|
|
778
|
+
primary_category TEXT,
|
|
779
|
+
place_id TEXT,
|
|
780
|
+
approval_status TEXT NOT NULL DEFAULT 'none',
|
|
781
|
+
verified_at TEXT
|
|
782
|
+
);
|
|
783
|
+
CREATE INDEX IF NOT EXISTS gbp_locations_site_idx ON gbp_locations(site_id);
|
|
784
|
+
|
|
785
|
+
CREATE TABLE IF NOT EXISTS gbp_edits (
|
|
786
|
+
id TEXT PRIMARY KEY,
|
|
787
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
788
|
+
location_id TEXT NOT NULL,
|
|
789
|
+
kind TEXT NOT NULL,
|
|
790
|
+
payload TEXT NOT NULL DEFAULT '{}',
|
|
791
|
+
applied_at TEXT NOT NULL
|
|
792
|
+
);
|
|
793
|
+
CREATE INDEX IF NOT EXISTS gbp_edits_loc_idx ON gbp_edits(location_id, applied_at);
|
|
794
|
+
|
|
795
|
+
CREATE TABLE IF NOT EXISTS mentions (
|
|
796
|
+
id TEXT PRIMARY KEY,
|
|
797
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
798
|
+
url TEXT NOT NULL,
|
|
799
|
+
snippet TEXT NOT NULL,
|
|
800
|
+
linked INTEGER NOT NULL DEFAULT 0,
|
|
801
|
+
score REAL NOT NULL DEFAULT 0,
|
|
802
|
+
kind TEXT NOT NULL,
|
|
803
|
+
created_at TEXT NOT NULL
|
|
804
|
+
);
|
|
805
|
+
CREATE INDEX IF NOT EXISTS mentions_site_idx ON mentions(site_id);
|
|
806
|
+
CREATE UNIQUE INDEX IF NOT EXISTS mentions_uidx ON mentions(site_id, url, kind);
|
|
807
|
+
|
|
808
|
+
CREATE TABLE IF NOT EXISTS inbound_404s (
|
|
809
|
+
id TEXT PRIMARY KEY,
|
|
810
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
811
|
+
source_url TEXT NOT NULL,
|
|
812
|
+
target_url TEXT NOT NULL,
|
|
813
|
+
status INTEGER,
|
|
814
|
+
created_at TEXT NOT NULL
|
|
815
|
+
);
|
|
816
|
+
CREATE INDEX IF NOT EXISTS inbound_404s_site_idx ON inbound_404s(site_id);
|
|
817
|
+
|
|
818
|
+
CREATE TABLE IF NOT EXISTS outreach_drafts (
|
|
819
|
+
id TEXT PRIMARY KEY,
|
|
820
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
821
|
+
mention_id TEXT,
|
|
822
|
+
to_email TEXT,
|
|
823
|
+
subject TEXT NOT NULL,
|
|
824
|
+
body TEXT NOT NULL,
|
|
825
|
+
state TEXT NOT NULL DEFAULT 'draft',
|
|
826
|
+
created_at TEXT NOT NULL
|
|
827
|
+
);
|
|
828
|
+
CREATE INDEX IF NOT EXISTS outreach_drafts_site_idx ON outreach_drafts(site_id, state);
|
|
829
|
+
|
|
830
|
+
CREATE TABLE IF NOT EXISTS vertical_profiles (
|
|
831
|
+
id TEXT PRIMARY KEY,
|
|
832
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
833
|
+
preset TEXT NOT NULL,
|
|
834
|
+
confidence REAL NOT NULL DEFAULT 0,
|
|
835
|
+
signals_json TEXT NOT NULL DEFAULT '[]',
|
|
836
|
+
answers_json TEXT NOT NULL DEFAULT '{}',
|
|
837
|
+
suppressed_checks INTEGER NOT NULL DEFAULT 0,
|
|
838
|
+
updated_at TEXT NOT NULL
|
|
839
|
+
);
|
|
840
|
+
CREATE UNIQUE INDEX IF NOT EXISTS vertical_profiles_site_uidx ON vertical_profiles(site_id);
|
|
841
|
+
|
|
842
|
+
CREATE TABLE IF NOT EXISTS tenants (
|
|
843
|
+
id TEXT PRIMARY KEY,
|
|
844
|
+
name TEXT NOT NULL,
|
|
845
|
+
email TEXT NOT NULL,
|
|
846
|
+
plan TEXT NOT NULL DEFAULT 'cloud_starter',
|
|
847
|
+
status TEXT NOT NULL DEFAULT 'trialing',
|
|
848
|
+
stripe_customer_id TEXT,
|
|
849
|
+
stripe_subscription_id TEXT,
|
|
850
|
+
byok INTEGER NOT NULL DEFAULT 1,
|
|
851
|
+
created_at TEXT NOT NULL,
|
|
852
|
+
updated_at TEXT NOT NULL
|
|
853
|
+
);
|
|
854
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenants_email_uidx ON tenants(email);
|
|
855
|
+
|
|
856
|
+
CREATE TABLE IF NOT EXISTS tenant_seats (
|
|
857
|
+
id TEXT PRIMARY KEY,
|
|
858
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
859
|
+
email TEXT NOT NULL,
|
|
860
|
+
role TEXT NOT NULL DEFAULT 'owner',
|
|
861
|
+
created_at TEXT NOT NULL
|
|
862
|
+
);
|
|
863
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenant_seats_uidx ON tenant_seats(tenant_id, email);
|
|
864
|
+
CREATE INDEX IF NOT EXISTS tenant_seats_tenant_idx ON tenant_seats(tenant_id);
|
|
865
|
+
|
|
866
|
+
CREATE TABLE IF NOT EXISTS tenant_sites (
|
|
867
|
+
id TEXT PRIMARY KEY,
|
|
868
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
869
|
+
site_id TEXT NOT NULL REFERENCES sites(id) ON DELETE CASCADE,
|
|
870
|
+
created_at TEXT NOT NULL
|
|
871
|
+
);
|
|
872
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenant_sites_site_uidx ON tenant_sites(site_id);
|
|
873
|
+
CREATE UNIQUE INDEX IF NOT EXISTS tenant_sites_pair_uidx ON tenant_sites(tenant_id, site_id);
|
|
874
|
+
CREATE INDEX IF NOT EXISTS tenant_sites_tenant_idx ON tenant_sites(tenant_id);
|
|
875
|
+
|
|
876
|
+
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
877
|
+
id TEXT PRIMARY KEY,
|
|
878
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
879
|
+
plan TEXT NOT NULL,
|
|
880
|
+
interval TEXT NOT NULL DEFAULT 'month',
|
|
881
|
+
status TEXT NOT NULL,
|
|
882
|
+
current_period_end TEXT,
|
|
883
|
+
created_at TEXT NOT NULL,
|
|
884
|
+
updated_at TEXT NOT NULL
|
|
885
|
+
);
|
|
886
|
+
CREATE INDEX IF NOT EXISTS subscriptions_tenant_idx ON subscriptions(tenant_id);
|
|
887
|
+
|
|
888
|
+
CREATE TABLE IF NOT EXISTS stripe_events (
|
|
889
|
+
id TEXT PRIMARY KEY,
|
|
890
|
+
type TEXT NOT NULL,
|
|
891
|
+
payload TEXT NOT NULL DEFAULT '{}',
|
|
892
|
+
processed_at TEXT NOT NULL
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
CREATE TABLE IF NOT EXISTS metered_usage (
|
|
896
|
+
id TEXT PRIMARY KEY,
|
|
897
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
898
|
+
kind TEXT NOT NULL,
|
|
899
|
+
quantity INTEGER NOT NULL DEFAULT 1,
|
|
900
|
+
period TEXT NOT NULL,
|
|
901
|
+
created_at TEXT NOT NULL
|
|
902
|
+
);
|
|
903
|
+
CREATE INDEX IF NOT EXISTS metered_usage_tenant_idx ON metered_usage(tenant_id, period);
|
|
904
|
+
|
|
905
|
+
CREATE TABLE IF NOT EXISTS envelope_keys (
|
|
906
|
+
id TEXT PRIMARY KEY,
|
|
907
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
908
|
+
wrapped_dek TEXT NOT NULL,
|
|
909
|
+
created_at TEXT NOT NULL
|
|
910
|
+
);
|
|
911
|
+
CREATE UNIQUE INDEX IF NOT EXISTS envelope_keys_tenant_uidx ON envelope_keys(tenant_id);
|
|
912
|
+
|
|
913
|
+
CREATE TABLE IF NOT EXISTS quota_windows (
|
|
914
|
+
id TEXT PRIMARY KEY,
|
|
915
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
916
|
+
window_start TEXT NOT NULL,
|
|
917
|
+
jobs INTEGER NOT NULL DEFAULT 0,
|
|
918
|
+
crawl_pages INTEGER NOT NULL DEFAULT 0,
|
|
919
|
+
concurrent INTEGER NOT NULL DEFAULT 0
|
|
920
|
+
);
|
|
921
|
+
CREATE UNIQUE INDEX IF NOT EXISTS quota_windows_uidx ON quota_windows(tenant_id, window_start);
|
|
922
|
+
|
|
923
|
+
CREATE TABLE IF NOT EXISTS erasure_requests (
|
|
924
|
+
id TEXT PRIMARY KEY,
|
|
925
|
+
tenant_id TEXT NOT NULL,
|
|
926
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
927
|
+
requested_at TEXT NOT NULL,
|
|
928
|
+
completed_at TEXT,
|
|
929
|
+
notes TEXT
|
|
930
|
+
);
|
|
931
|
+
|
|
932
|
+
CREATE TABLE IF NOT EXISTS connector_pairings (
|
|
933
|
+
id TEXT PRIMARY KEY,
|
|
934
|
+
tenant_id TEXT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
935
|
+
site_id TEXT REFERENCES sites(id) ON DELETE CASCADE,
|
|
936
|
+
token_hash TEXT NOT NULL,
|
|
937
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
938
|
+
created_at TEXT NOT NULL
|
|
939
|
+
);
|
|
940
|
+
CREATE INDEX IF NOT EXISTS connector_pairings_tenant_idx ON connector_pairings(tenant_id);
|
|
941
|
+
|
|
942
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS findings_fts USING fts5(
|
|
943
|
+
id UNINDEXED,
|
|
944
|
+
title,
|
|
945
|
+
explanation,
|
|
946
|
+
rule_id,
|
|
947
|
+
tokenize = 'porter'
|
|
948
|
+
);
|
|
949
|
+
|
|
950
|
+
CREATE TRIGGER IF NOT EXISTS findings_fts_ai AFTER INSERT ON findings BEGIN
|
|
951
|
+
INSERT INTO findings_fts(id, title, explanation, rule_id)
|
|
952
|
+
VALUES (new.id, new.title, new.explanation, new.rule_id);
|
|
953
|
+
END;
|
|
954
|
+
CREATE TRIGGER IF NOT EXISTS findings_fts_ad AFTER DELETE ON findings BEGIN
|
|
955
|
+
DELETE FROM findings_fts WHERE id = old.id;
|
|
956
|
+
END;
|
|
957
|
+
CREATE TRIGGER IF NOT EXISTS findings_fts_au AFTER UPDATE ON findings BEGIN
|
|
958
|
+
DELETE FROM findings_fts WHERE id = old.id;
|
|
959
|
+
INSERT INTO findings_fts(id, title, explanation, rule_id)
|
|
960
|
+
VALUES (new.id, new.title, new.explanation, new.rule_id);
|
|
961
|
+
END;
|
|
962
|
+
`;
|
|
963
|
+
//# sourceMappingURL=init-sql.js.map
|