@bluefields/db 0.2.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.
Files changed (76) hide show
  1. package/LICENSE +202 -0
  2. package/dist/client.d.ts +6 -0
  3. package/dist/client.js +13 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/index.d.ts +19 -0
  6. package/dist/index.js +20 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/migrate.d.ts +11 -0
  9. package/dist/migrate.js +48 -0
  10. package/dist/migrate.js.map +1 -0
  11. package/dist/schema/api-keys.d.ts +145 -0
  12. package/dist/schema/api-keys.js +18 -0
  13. package/dist/schema/api-keys.js.map +1 -0
  14. package/dist/schema/audit-log.d.ts +228 -0
  15. package/dist/schema/audit-log.js +49 -0
  16. package/dist/schema/audit-log.js.map +1 -0
  17. package/dist/schema/cost-records.d.ts +190 -0
  18. package/dist/schema/cost-records.js +55 -0
  19. package/dist/schema/cost-records.js.map +1 -0
  20. package/dist/schema/crawl-job-pages.d.ts +186 -0
  21. package/dist/schema/crawl-job-pages.js +31 -0
  22. package/dist/schema/crawl-job-pages.js.map +1 -0
  23. package/dist/schema/crawl-jobs.d.ts +271 -0
  24. package/dist/schema/crawl-jobs.js +40 -0
  25. package/dist/schema/crawl-jobs.js.map +1 -0
  26. package/dist/schema/customers.d.ts +145 -0
  27. package/dist/schema/customers.js +19 -0
  28. package/dist/schema/customers.js.map +1 -0
  29. package/dist/schema/event-feedback.d.ts +170 -0
  30. package/dist/schema/event-feedback.js +35 -0
  31. package/dist/schema/event-feedback.js.map +1 -0
  32. package/dist/schema/events.d.ts +291 -0
  33. package/dist/schema/events.js +58 -0
  34. package/dist/schema/events.js.map +1 -0
  35. package/dist/schema/extractions.d.ts +327 -0
  36. package/dist/schema/extractions.js +56 -0
  37. package/dist/schema/extractions.js.map +1 -0
  38. package/dist/schema/host-extractors.d.ts +131 -0
  39. package/dist/schema/host-extractors.js +18 -0
  40. package/dist/schema/host-extractors.js.map +1 -0
  41. package/dist/schema/host-records.d.ts +237 -0
  42. package/dist/schema/host-records.js +42 -0
  43. package/dist/schema/host-records.js.map +1 -0
  44. package/dist/schema/notification-preferences.d.ts +195 -0
  45. package/dist/schema/notification-preferences.js +49 -0
  46. package/dist/schema/notification-preferences.js.map +1 -0
  47. package/dist/schema/scrape-cache.d.ts +136 -0
  48. package/dist/schema/scrape-cache.js +23 -0
  49. package/dist/schema/scrape-cache.js.map +1 -0
  50. package/dist/schema/sessions.d.ts +153 -0
  51. package/dist/schema/sessions.js +27 -0
  52. package/dist/schema/sessions.js.map +1 -0
  53. package/dist/schema/snapshots.d.ts +382 -0
  54. package/dist/schema/snapshots.js +60 -0
  55. package/dist/schema/snapshots.js.map +1 -0
  56. package/dist/schema/subscriptions.d.ts +604 -0
  57. package/dist/schema/subscriptions.js +79 -0
  58. package/dist/schema/subscriptions.js.map +1 -0
  59. package/dist/schema/usage-periods.d.ts +446 -0
  60. package/dist/schema/usage-periods.js +71 -0
  61. package/dist/schema/usage-periods.js.map +1 -0
  62. package/dist/tsconfig.tsbuildinfo +1 -0
  63. package/package.json +54 -0
  64. package/src/migrations/0001_initial.sql +398 -0
  65. package/src/migrations/0002_pg_cron.sql +109 -0
  66. package/src/migrations/0003_webhook_secret_cleanup.sql +55 -0
  67. package/src/migrations/0004_events_pg_notify.sql +39 -0
  68. package/src/migrations/0005_subscription_consecutive_failures.sql +19 -0
  69. package/src/migrations/0006_notification_preferences.sql +27 -0
  70. package/src/migrations/0007_crawl_jobs.sql +65 -0
  71. package/src/migrations/0008_sessions.sql +38 -0
  72. package/src/migrations/0009_scrape_cache.sql +34 -0
  73. package/src/migrations/0010_neon_defaults.sql +99 -0
  74. package/src/migrations/0011_credits_consumed_numeric.sql +12 -0
  75. package/src/migrations/0012_crawl_page_attestation.sql +10 -0
  76. package/src/migrations/0013_customer_deleted_at.sql +5 -0
@@ -0,0 +1,604 @@
1
+ export declare const subscriptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "subscriptions";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "id";
7
+ tableName: "subscriptions";
8
+ dataType: "string";
9
+ columnType: "PgUUID";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: true;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: undefined;
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {}>;
22
+ customerId: import("drizzle-orm/pg-core").PgColumn<{
23
+ name: "customer_id";
24
+ tableName: "subscriptions";
25
+ dataType: "string";
26
+ columnType: "PgUUID";
27
+ data: string;
28
+ driverParam: string;
29
+ notNull: true;
30
+ hasDefault: false;
31
+ isPrimaryKey: false;
32
+ isAutoincrement: false;
33
+ hasRuntimeDefault: false;
34
+ enumValues: undefined;
35
+ baseColumn: never;
36
+ identity: undefined;
37
+ generated: undefined;
38
+ }, {}, {}>;
39
+ url: import("drizzle-orm/pg-core").PgColumn<{
40
+ name: "url";
41
+ tableName: "subscriptions";
42
+ dataType: "string";
43
+ columnType: "PgText";
44
+ data: string;
45
+ driverParam: string;
46
+ notNull: true;
47
+ hasDefault: false;
48
+ isPrimaryKey: false;
49
+ isAutoincrement: false;
50
+ hasRuntimeDefault: false;
51
+ enumValues: [string, ...string[]];
52
+ baseColumn: never;
53
+ identity: undefined;
54
+ generated: undefined;
55
+ }, {}, {}>;
56
+ urlCanonical: import("drizzle-orm/pg-core").PgColumn<{
57
+ name: "url_canonical";
58
+ tableName: "subscriptions";
59
+ dataType: "string";
60
+ columnType: "PgText";
61
+ data: string;
62
+ driverParam: string;
63
+ notNull: true;
64
+ hasDefault: false;
65
+ isPrimaryKey: false;
66
+ isAutoincrement: false;
67
+ hasRuntimeDefault: false;
68
+ enumValues: [string, ...string[]];
69
+ baseColumn: never;
70
+ identity: undefined;
71
+ generated: undefined;
72
+ }, {}, {}>;
73
+ canonVersion: import("drizzle-orm/pg-core").PgColumn<{
74
+ name: "canon_version";
75
+ tableName: "subscriptions";
76
+ dataType: "number";
77
+ columnType: "PgSmallInt";
78
+ data: number;
79
+ driverParam: string | number;
80
+ notNull: true;
81
+ hasDefault: true;
82
+ isPrimaryKey: false;
83
+ isAutoincrement: false;
84
+ hasRuntimeDefault: false;
85
+ enumValues: undefined;
86
+ baseColumn: never;
87
+ identity: undefined;
88
+ generated: undefined;
89
+ }, {}, {}>;
90
+ schema: import("drizzle-orm/pg-core").PgColumn<{
91
+ name: "schema";
92
+ tableName: "subscriptions";
93
+ dataType: "json";
94
+ columnType: "PgJsonb";
95
+ data: unknown;
96
+ driverParam: unknown;
97
+ notNull: false;
98
+ hasDefault: false;
99
+ isPrimaryKey: false;
100
+ isAutoincrement: false;
101
+ hasRuntimeDefault: false;
102
+ enumValues: undefined;
103
+ baseColumn: never;
104
+ identity: undefined;
105
+ generated: undefined;
106
+ }, {}, {}>;
107
+ webhookUrl: import("drizzle-orm/pg-core").PgColumn<{
108
+ name: "webhook_url";
109
+ tableName: "subscriptions";
110
+ dataType: "string";
111
+ columnType: "PgText";
112
+ data: string;
113
+ driverParam: string;
114
+ notNull: false;
115
+ hasDefault: false;
116
+ isPrimaryKey: false;
117
+ isAutoincrement: false;
118
+ hasRuntimeDefault: false;
119
+ enumValues: [string, ...string[]];
120
+ baseColumn: never;
121
+ identity: undefined;
122
+ generated: undefined;
123
+ }, {}, {}>;
124
+ webhookSecretCurrent: import("drizzle-orm/pg-core").PgColumn<{
125
+ name: "webhook_secret_current";
126
+ tableName: "subscriptions";
127
+ dataType: "string";
128
+ columnType: "PgText";
129
+ data: string;
130
+ driverParam: string;
131
+ notNull: false;
132
+ hasDefault: false;
133
+ isPrimaryKey: false;
134
+ isAutoincrement: false;
135
+ hasRuntimeDefault: false;
136
+ enumValues: [string, ...string[]];
137
+ baseColumn: never;
138
+ identity: undefined;
139
+ generated: undefined;
140
+ }, {}, {}>;
141
+ webhookSecretPrevious: import("drizzle-orm/pg-core").PgColumn<{
142
+ name: "webhook_secret_previous";
143
+ tableName: "subscriptions";
144
+ dataType: "string";
145
+ columnType: "PgText";
146
+ data: string;
147
+ driverParam: string;
148
+ notNull: false;
149
+ hasDefault: false;
150
+ isPrimaryKey: false;
151
+ isAutoincrement: false;
152
+ hasRuntimeDefault: false;
153
+ enumValues: [string, ...string[]];
154
+ baseColumn: never;
155
+ identity: undefined;
156
+ generated: undefined;
157
+ }, {}, {}>;
158
+ webhookSecretRotatedAt: import("drizzle-orm/pg-core").PgColumn<{
159
+ name: "webhook_secret_rotated_at";
160
+ tableName: "subscriptions";
161
+ dataType: "date";
162
+ columnType: "PgTimestamp";
163
+ data: Date;
164
+ driverParam: string;
165
+ notNull: false;
166
+ hasDefault: false;
167
+ isPrimaryKey: false;
168
+ isAutoincrement: false;
169
+ hasRuntimeDefault: false;
170
+ enumValues: undefined;
171
+ baseColumn: never;
172
+ identity: undefined;
173
+ generated: undefined;
174
+ }, {}, {}>;
175
+ webhookUrlState: import("drizzle-orm/pg-core").PgColumn<{
176
+ name: "webhook_url_state";
177
+ tableName: "subscriptions";
178
+ dataType: "string";
179
+ columnType: "PgText";
180
+ data: string;
181
+ driverParam: string;
182
+ notNull: true;
183
+ hasDefault: true;
184
+ isPrimaryKey: false;
185
+ isAutoincrement: false;
186
+ hasRuntimeDefault: false;
187
+ enumValues: [string, ...string[]];
188
+ baseColumn: never;
189
+ identity: undefined;
190
+ generated: undefined;
191
+ }, {}, {}>;
192
+ webhookConsecutiveFailures: import("drizzle-orm/pg-core").PgColumn<{
193
+ name: "webhook_consecutive_failures";
194
+ tableName: "subscriptions";
195
+ dataType: "number";
196
+ columnType: "PgInteger";
197
+ data: number;
198
+ driverParam: string | number;
199
+ notNull: true;
200
+ hasDefault: true;
201
+ isPrimaryKey: false;
202
+ isAutoincrement: false;
203
+ hasRuntimeDefault: false;
204
+ enumValues: undefined;
205
+ baseColumn: never;
206
+ identity: undefined;
207
+ generated: undefined;
208
+ }, {}, {}>;
209
+ consecutiveFailures: import("drizzle-orm/pg-core").PgColumn<{
210
+ name: "consecutive_failures";
211
+ tableName: "subscriptions";
212
+ dataType: "number";
213
+ columnType: "PgInteger";
214
+ data: number;
215
+ driverParam: string | number;
216
+ notNull: true;
217
+ hasDefault: true;
218
+ isPrimaryKey: false;
219
+ isAutoincrement: false;
220
+ hasRuntimeDefault: false;
221
+ enumValues: undefined;
222
+ baseColumn: never;
223
+ identity: undefined;
224
+ generated: undefined;
225
+ }, {}, {}>;
226
+ minIntervalSeconds: import("drizzle-orm/pg-core").PgColumn<{
227
+ name: "min_interval_seconds";
228
+ tableName: "subscriptions";
229
+ dataType: "number";
230
+ columnType: "PgInteger";
231
+ data: number;
232
+ driverParam: string | number;
233
+ notNull: true;
234
+ hasDefault: true;
235
+ isPrimaryKey: false;
236
+ isAutoincrement: false;
237
+ hasRuntimeDefault: false;
238
+ enumValues: undefined;
239
+ baseColumn: never;
240
+ identity: undefined;
241
+ generated: undefined;
242
+ }, {}, {}>;
243
+ maxIntervalSeconds: import("drizzle-orm/pg-core").PgColumn<{
244
+ name: "max_interval_seconds";
245
+ tableName: "subscriptions";
246
+ dataType: "number";
247
+ columnType: "PgInteger";
248
+ data: number;
249
+ driverParam: string | number;
250
+ notNull: true;
251
+ hasDefault: true;
252
+ isPrimaryKey: false;
253
+ isAutoincrement: false;
254
+ hasRuntimeDefault: false;
255
+ enumValues: undefined;
256
+ baseColumn: never;
257
+ identity: undefined;
258
+ generated: undefined;
259
+ }, {}, {}>;
260
+ currentIntervalSeconds: import("drizzle-orm/pg-core").PgColumn<{
261
+ name: "current_interval_seconds";
262
+ tableName: "subscriptions";
263
+ dataType: "number";
264
+ columnType: "PgInteger";
265
+ data: number;
266
+ driverParam: string | number;
267
+ notNull: true;
268
+ hasDefault: true;
269
+ isPrimaryKey: false;
270
+ isAutoincrement: false;
271
+ hasRuntimeDefault: false;
272
+ enumValues: undefined;
273
+ baseColumn: never;
274
+ identity: undefined;
275
+ generated: undefined;
276
+ }, {}, {}>;
277
+ status: import("drizzle-orm/pg-core").PgColumn<{
278
+ name: "status";
279
+ tableName: "subscriptions";
280
+ dataType: "string";
281
+ columnType: "PgText";
282
+ data: string;
283
+ driverParam: string;
284
+ notNull: true;
285
+ hasDefault: true;
286
+ isPrimaryKey: false;
287
+ isAutoincrement: false;
288
+ hasRuntimeDefault: false;
289
+ enumValues: [string, ...string[]];
290
+ baseColumn: never;
291
+ identity: undefined;
292
+ generated: undefined;
293
+ }, {}, {}>;
294
+ nextPollAt: import("drizzle-orm/pg-core").PgColumn<{
295
+ name: "next_poll_at";
296
+ tableName: "subscriptions";
297
+ dataType: "date";
298
+ columnType: "PgTimestamp";
299
+ data: Date;
300
+ driverParam: string;
301
+ notNull: true;
302
+ hasDefault: true;
303
+ isPrimaryKey: false;
304
+ isAutoincrement: false;
305
+ hasRuntimeDefault: false;
306
+ enumValues: undefined;
307
+ baseColumn: never;
308
+ identity: undefined;
309
+ generated: undefined;
310
+ }, {}, {}>;
311
+ inngestEventId: import("drizzle-orm/pg-core").PgColumn<{
312
+ name: "inngest_event_id";
313
+ tableName: "subscriptions";
314
+ dataType: "string";
315
+ columnType: "PgText";
316
+ data: string;
317
+ driverParam: string;
318
+ notNull: false;
319
+ hasDefault: false;
320
+ isPrimaryKey: false;
321
+ isAutoincrement: false;
322
+ hasRuntimeDefault: false;
323
+ enumValues: [string, ...string[]];
324
+ baseColumn: never;
325
+ identity: undefined;
326
+ generated: undefined;
327
+ }, {}, {}>;
328
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
329
+ name: "created_at";
330
+ tableName: "subscriptions";
331
+ dataType: "date";
332
+ columnType: "PgTimestamp";
333
+ data: Date;
334
+ driverParam: string;
335
+ notNull: true;
336
+ hasDefault: true;
337
+ isPrimaryKey: false;
338
+ isAutoincrement: false;
339
+ hasRuntimeDefault: false;
340
+ enumValues: undefined;
341
+ baseColumn: never;
342
+ identity: undefined;
343
+ generated: undefined;
344
+ }, {}, {}>;
345
+ lastPolledAt: import("drizzle-orm/pg-core").PgColumn<{
346
+ name: "last_polled_at";
347
+ tableName: "subscriptions";
348
+ dataType: "date";
349
+ columnType: "PgTimestamp";
350
+ data: Date;
351
+ driverParam: string;
352
+ notNull: false;
353
+ hasDefault: false;
354
+ isPrimaryKey: false;
355
+ isAutoincrement: false;
356
+ hasRuntimeDefault: false;
357
+ enumValues: undefined;
358
+ baseColumn: never;
359
+ identity: undefined;
360
+ generated: undefined;
361
+ }, {}, {}>;
362
+ lastChangeAt: import("drizzle-orm/pg-core").PgColumn<{
363
+ name: "last_change_at";
364
+ tableName: "subscriptions";
365
+ dataType: "date";
366
+ columnType: "PgTimestamp";
367
+ data: Date;
368
+ driverParam: string;
369
+ notNull: false;
370
+ hasDefault: false;
371
+ isPrimaryKey: false;
372
+ isAutoincrement: false;
373
+ hasRuntimeDefault: false;
374
+ enumValues: undefined;
375
+ baseColumn: never;
376
+ identity: undefined;
377
+ generated: undefined;
378
+ }, {}, {}>;
379
+ pollCount: import("drizzle-orm/pg-core").PgColumn<{
380
+ name: "poll_count";
381
+ tableName: "subscriptions";
382
+ dataType: "number";
383
+ columnType: "PgInteger";
384
+ data: number;
385
+ driverParam: string | number;
386
+ notNull: true;
387
+ hasDefault: true;
388
+ isPrimaryKey: false;
389
+ isAutoincrement: false;
390
+ hasRuntimeDefault: false;
391
+ enumValues: undefined;
392
+ baseColumn: never;
393
+ identity: undefined;
394
+ generated: undefined;
395
+ }, {}, {}>;
396
+ changeCount: import("drizzle-orm/pg-core").PgColumn<{
397
+ name: "change_count";
398
+ tableName: "subscriptions";
399
+ dataType: "number";
400
+ columnType: "PgInteger";
401
+ data: number;
402
+ driverParam: string | number;
403
+ notNull: true;
404
+ hasDefault: true;
405
+ isPrimaryKey: false;
406
+ isAutoincrement: false;
407
+ hasRuntimeDefault: false;
408
+ enumValues: undefined;
409
+ baseColumn: never;
410
+ identity: undefined;
411
+ generated: undefined;
412
+ }, {}, {}>;
413
+ intent: import("drizzle-orm/pg-core").PgColumn<{
414
+ name: "intent";
415
+ tableName: "subscriptions";
416
+ dataType: "string";
417
+ columnType: "PgText";
418
+ data: string;
419
+ driverParam: string;
420
+ notNull: false;
421
+ hasDefault: false;
422
+ isPrimaryKey: false;
423
+ isAutoincrement: false;
424
+ hasRuntimeDefault: false;
425
+ enumValues: [string, ...string[]];
426
+ baseColumn: never;
427
+ identity: undefined;
428
+ generated: undefined;
429
+ }, {}, {}>;
430
+ diffRules: import("drizzle-orm/pg-core").PgColumn<{
431
+ name: "diff_rules";
432
+ tableName: "subscriptions";
433
+ dataType: "json";
434
+ columnType: "PgJsonb";
435
+ data: unknown;
436
+ driverParam: unknown;
437
+ notNull: true;
438
+ hasDefault: true;
439
+ isPrimaryKey: false;
440
+ isAutoincrement: false;
441
+ hasRuntimeDefault: false;
442
+ enumValues: undefined;
443
+ baseColumn: never;
444
+ identity: undefined;
445
+ generated: undefined;
446
+ }, {}, {}>;
447
+ lastMeaningfulExtractionId: import("drizzle-orm/pg-core").PgColumn<{
448
+ name: "last_meaningful_extraction_id";
449
+ tableName: "subscriptions";
450
+ dataType: "string";
451
+ columnType: "PgUUID";
452
+ data: string;
453
+ driverParam: string;
454
+ notNull: false;
455
+ hasDefault: false;
456
+ isPrimaryKey: false;
457
+ isAutoincrement: false;
458
+ hasRuntimeDefault: false;
459
+ enumValues: undefined;
460
+ baseColumn: never;
461
+ identity: undefined;
462
+ generated: undefined;
463
+ }, {}, {}>;
464
+ detectionLatencyTargetSeconds: import("drizzle-orm/pg-core").PgColumn<{
465
+ name: "detection_latency_target_seconds";
466
+ tableName: "subscriptions";
467
+ dataType: "number";
468
+ columnType: "PgInteger";
469
+ data: number;
470
+ driverParam: string | number;
471
+ notNull: false;
472
+ hasDefault: false;
473
+ isPrimaryKey: false;
474
+ isAutoincrement: false;
475
+ hasRuntimeDefault: false;
476
+ enumValues: undefined;
477
+ baseColumn: never;
478
+ identity: undefined;
479
+ generated: undefined;
480
+ }, {}, {}>;
481
+ verticalHint: import("drizzle-orm/pg-core").PgColumn<{
482
+ name: "vertical_hint";
483
+ tableName: "subscriptions";
484
+ dataType: "string";
485
+ columnType: "PgText";
486
+ data: string;
487
+ driverParam: string;
488
+ notNull: false;
489
+ hasDefault: false;
490
+ isPrimaryKey: false;
491
+ isAutoincrement: false;
492
+ hasRuntimeDefault: false;
493
+ enumValues: [string, ...string[]];
494
+ baseColumn: never;
495
+ identity: undefined;
496
+ generated: undefined;
497
+ }, {}, {}>;
498
+ ewmaChangeIntervalSeconds: import("drizzle-orm/pg-core").PgColumn<{
499
+ name: "ewma_change_interval_seconds";
500
+ tableName: "subscriptions";
501
+ dataType: "number";
502
+ columnType: "PgInteger";
503
+ data: number;
504
+ driverParam: string | number;
505
+ notNull: false;
506
+ hasDefault: false;
507
+ isPrimaryKey: false;
508
+ isAutoincrement: false;
509
+ hasRuntimeDefault: false;
510
+ enumValues: undefined;
511
+ baseColumn: never;
512
+ identity: undefined;
513
+ generated: undefined;
514
+ }, {}, {}>;
515
+ lastChangeObservedAt: import("drizzle-orm/pg-core").PgColumn<{
516
+ name: "last_change_observed_at";
517
+ tableName: "subscriptions";
518
+ dataType: "date";
519
+ columnType: "PgTimestamp";
520
+ data: Date;
521
+ driverParam: string;
522
+ notNull: false;
523
+ hasDefault: false;
524
+ isPrimaryKey: false;
525
+ isAutoincrement: false;
526
+ hasRuntimeDefault: false;
527
+ enumValues: undefined;
528
+ baseColumn: never;
529
+ identity: undefined;
530
+ generated: undefined;
531
+ }, {}, {}>;
532
+ consecutiveNoChangePolls: import("drizzle-orm/pg-core").PgColumn<{
533
+ name: "consecutive_no_change_polls";
534
+ tableName: "subscriptions";
535
+ dataType: "number";
536
+ columnType: "PgInteger";
537
+ data: number;
538
+ driverParam: string | number;
539
+ notNull: true;
540
+ hasDefault: true;
541
+ isPrimaryKey: false;
542
+ isAutoincrement: false;
543
+ hasRuntimeDefault: false;
544
+ enumValues: undefined;
545
+ baseColumn: never;
546
+ identity: undefined;
547
+ generated: undefined;
548
+ }, {}, {}>;
549
+ averageObservedIntervalSeconds: import("drizzle-orm/pg-core").PgColumn<{
550
+ name: "average_observed_interval_seconds";
551
+ tableName: "subscriptions";
552
+ dataType: "number";
553
+ columnType: "PgInteger";
554
+ data: number;
555
+ driverParam: string | number;
556
+ notNull: false;
557
+ hasDefault: false;
558
+ isPrimaryKey: false;
559
+ isAutoincrement: false;
560
+ hasRuntimeDefault: false;
561
+ enumValues: undefined;
562
+ baseColumn: never;
563
+ identity: undefined;
564
+ generated: undefined;
565
+ }, {}, {}>;
566
+ httpValidator: import("drizzle-orm/pg-core").PgColumn<{
567
+ name: "http_validator";
568
+ tableName: "subscriptions";
569
+ dataType: "json";
570
+ columnType: "PgJsonb";
571
+ data: unknown;
572
+ driverParam: unknown;
573
+ notNull: false;
574
+ hasDefault: false;
575
+ isPrimaryKey: false;
576
+ isAutoincrement: false;
577
+ hasRuntimeDefault: false;
578
+ enumValues: undefined;
579
+ baseColumn: never;
580
+ identity: undefined;
581
+ generated: undefined;
582
+ }, {}, {}>;
583
+ cyclicPatternHint: import("drizzle-orm/pg-core").PgColumn<{
584
+ name: "cyclic_pattern_hint";
585
+ tableName: "subscriptions";
586
+ dataType: "json";
587
+ columnType: "PgJsonb";
588
+ data: unknown;
589
+ driverParam: unknown;
590
+ notNull: false;
591
+ hasDefault: false;
592
+ isPrimaryKey: false;
593
+ isAutoincrement: false;
594
+ hasRuntimeDefault: false;
595
+ enumValues: undefined;
596
+ baseColumn: never;
597
+ identity: undefined;
598
+ generated: undefined;
599
+ }, {}, {}>;
600
+ };
601
+ dialect: "pg";
602
+ }>;
603
+ export type Subscription = typeof subscriptions.$inferSelect;
604
+ export type NewSubscription = typeof subscriptions.$inferInsert;
@@ -0,0 +1,79 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { sql } from 'drizzle-orm';
3
+ import { index, integer, jsonb, pgTable, smallint, text, timestamp, uuid, } from 'drizzle-orm/pg-core';
4
+ import { customers } from './customers.js';
5
+ export const subscriptions = pgTable('subscriptions', {
6
+ id: uuid('id').primaryKey().defaultRandom(),
7
+ customerId: uuid('customer_id')
8
+ .notNull()
9
+ .references(() => customers.id),
10
+ // as submitted, preserved verbatim
11
+ url: text('url').notNull(),
12
+ // normalized per the canon_version rules (Review #2)
13
+ urlCanonical: text('url_canonical').notNull(),
14
+ // which canonicalization rule set produced url_canonical (Review #2)
15
+ canonVersion: smallint('canon_version').notNull().default(1),
16
+ // null = markdown-only
17
+ schema: jsonb('schema'),
18
+ webhookUrl: text('webhook_url'),
19
+ // Dual-key webhook secret scheme (Review #7): rotation pattern with 24h overlap.
20
+ // _current signs outgoing webhooks; _previous accepted by customer during overlap.
21
+ webhookSecretCurrent: text('webhook_secret_current'),
22
+ webhookSecretPrevious: text('webhook_secret_previous'),
23
+ // when _current was last rotated; nightly job nulls _previous after 24h
24
+ webhookSecretRotatedAt: timestamp('webhook_secret_rotated_at', { withTimezone: true }),
25
+ // 'unverified' | 'verified' | 'disabled' (Review #7)
26
+ webhookUrlState: text('webhook_url_state').notNull().default('unverified'),
27
+ // resets on success, auto-disables at 10 (Review #7)
28
+ webhookConsecutiveFailures: integer('webhook_consecutive_failures').notNull().default(0),
29
+ // Poll-side failures (chunk 21 follow-up). Separate from webhook
30
+ // failures: this counts fetch/extract/diff exceptions, and trips
31
+ // status='paused' at 10. Migration: 0005.
32
+ consecutiveFailures: integer('consecutive_failures').notNull().default(0),
33
+ minIntervalSeconds: integer('min_interval_seconds').notNull().default(3600),
34
+ maxIntervalSeconds: integer('max_interval_seconds').notNull().default(86400),
35
+ currentIntervalSeconds: integer('current_interval_seconds').notNull().default(3600),
36
+ // active, paused, failing, expired
37
+ status: text('status').notNull().default('active'),
38
+ // pg_cron dispatcher finds rows where this <= now()
39
+ nextPollAt: timestamp('next_poll_at', { withTimezone: true }).notNull().defaultNow(),
40
+ // last poll's Inngest run for debugging
41
+ inngestEventId: text('inngest_event_id'),
42
+ createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
43
+ lastPolledAt: timestamp('last_polled_at', { withTimezone: true }),
44
+ lastChangeAt: timestamp('last_change_at', { withTimezone: true }),
45
+ pollCount: integer('poll_count').notNull().default(0),
46
+ changeCount: integer('change_count').notNull().default(0),
47
+ // one-sentence customer intent; fed into LLM judge prompt (Review #5)
48
+ intent: text('intent'),
49
+ // customer-configurable diff filtering rules (Review #5)
50
+ diffRules: jsonb('diff_rules').notNull().default(sql `'{"rules":[]}'::jsonb`),
51
+ // pointer for baseline-drift detection (Review #5); maintained by diff engine. No FK by design (extractions partitioning would force composite FK; the column is logically a reference but not enforced at the DB).
52
+ lastMeaningfulExtractionId: uuid('last_meaningful_extraction_id'),
53
+ // Adaptive polling state and configuration (Review #9)
54
+ // customer-stated SLA: "alert me within N seconds of a change"; null = use vertical default
55
+ detectionLatencyTargetSeconds: integer('detection_latency_target_seconds'),
56
+ // 'status_page' | 'pricing' | 'regulatory' | 'news' | 'general'; drives initial bounds
57
+ verticalHint: text('vertical_hint'),
58
+ // EWMA of inter-change intervals; updated on each meaningful change
59
+ ewmaChangeIntervalSeconds: integer('ewma_change_interval_seconds'),
60
+ // when we last classified a poll as meaningful
61
+ lastChangeObservedAt: timestamp('last_change_observed_at', { withTimezone: true }),
62
+ // counter for cold-start ramp and back-off
63
+ consecutiveNoChangePolls: integer('consecutive_no_change_polls').notNull().default(0),
64
+ // rolling 100-poll window; used for pricing-assumption validation dashboards
65
+ averageObservedIntervalSeconds: integer('average_observed_interval_seconds'),
66
+ // { etag, last_modified } from most recent fetch; null until first fetch, { unsupported: true } if site doesn't support conditional GET
67
+ httpValidator: jsonb('http_validator'),
68
+ // v1.1+: schedule-driven polling; null in v1
69
+ cyclicPatternHint: jsonb('cyclic_pattern_hint'),
70
+ }, (table) => [
71
+ index('idx_subs_customer').on(table.customerId),
72
+ index('idx_subs_canonical').on(table.urlCanonical).where(sql `${table.status} = 'active'`),
73
+ index('idx_subs_status').on(table.status).where(sql `${table.status} != 'expired'`),
74
+ // Critical: pg_cron dispatcher query hits this every minute
75
+ index('idx_subs_due')
76
+ .on(table.nextPollAt)
77
+ .where(sql `${table.status} = 'active'`),
78
+ ]);
79
+ //# sourceMappingURL=subscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../../src/schema/subscriptions.ts"],"names":[],"mappings":"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"}