@littlebearapps/create-platform 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.
Files changed (31) hide show
  1. package/dist/index.d.ts +11 -0
  2. package/dist/index.js +59 -0
  3. package/dist/prompts.d.ts +15 -0
  4. package/dist/prompts.js +58 -0
  5. package/dist/scaffold.d.ts +5 -0
  6. package/dist/scaffold.js +65 -0
  7. package/dist/templates.d.ts +16 -0
  8. package/dist/templates.js +53 -0
  9. package/package.json +46 -0
  10. package/templates/full/migrations/006_pattern_discovery.sql +199 -0
  11. package/templates/full/migrations/007_notifications_search.sql +127 -0
  12. package/templates/full/wrangler.alert-router.jsonc.hbs +34 -0
  13. package/templates/full/wrangler.notifications.jsonc.hbs +23 -0
  14. package/templates/full/wrangler.pattern-discovery.jsonc.hbs +33 -0
  15. package/templates/full/wrangler.search.jsonc.hbs +16 -0
  16. package/templates/full/wrangler.settings.jsonc.hbs +23 -0
  17. package/templates/shared/README.md.hbs +69 -0
  18. package/templates/shared/config/budgets.yaml.hbs +72 -0
  19. package/templates/shared/config/services.yaml.hbs +45 -0
  20. package/templates/shared/migrations/001_core_tables.sql +117 -0
  21. package/templates/shared/migrations/002_usage_warehouse.sql +830 -0
  22. package/templates/shared/migrations/003_feature_tracking.sql +250 -0
  23. package/templates/shared/migrations/004_settings_alerts.sql +452 -0
  24. package/templates/shared/migrations/seed.sql.hbs +4 -0
  25. package/templates/shared/package.json.hbs +21 -0
  26. package/templates/shared/scripts/sync-config.ts +242 -0
  27. package/templates/shared/tsconfig.json +12 -0
  28. package/templates/shared/wrangler.usage.jsonc.hbs +58 -0
  29. package/templates/standard/migrations/005_error_collection.sql +162 -0
  30. package/templates/standard/wrangler.error-collector.jsonc.hbs +44 -0
  31. package/templates/standard/wrangler.sentinel.jsonc.hbs +45 -0
@@ -0,0 +1,250 @@
1
+ -- =============================================================================
2
+ -- 003_feature_tracking.sql — Feature-level tracking and circuit breakers
3
+ -- =============================================================================
4
+ -- Consolidated from original migrations: 017, 018, 020, 021, 024, 025
5
+ --
6
+ -- Tables:
7
+ -- feature_usage_daily — Daily usage rollups per feature
8
+ -- feature_circuit_breaker_events — Trip/reset events for feature circuit breakers
9
+ -- feature_registry — Feature definitions synced from config
10
+ -- system_health_checks — SDK heartbeat probes for feature connectivity
11
+ -- feature_error_events — Real-time error event logging per feature
12
+ -- error_alerts — Alert history for deduplication
13
+ -- feature_ai_model_usage — Per-feature, per-model AI usage
14
+ -- =============================================================================
15
+
16
+
17
+ -- =============================================================================
18
+ -- FEATURE USAGE DAILY (from 017, with error columns from 024)
19
+ -- =============================================================================
20
+ -- Stores aggregated daily usage per feature (from Analytics Engine nightly).
21
+ -- Enables feature-level budget tracking and historical trend analysis.
22
+
23
+ CREATE TABLE IF NOT EXISTS feature_usage_daily (
24
+ id TEXT PRIMARY KEY,
25
+ feature_key TEXT NOT NULL, -- 'my-project:scanner:github'
26
+ usage_date TEXT NOT NULL, -- 'YYYY-MM-DD'
27
+
28
+ -- Resource metrics (aggregated daily totals)
29
+ d1_writes INTEGER DEFAULT 0,
30
+ d1_reads INTEGER DEFAULT 0,
31
+ kv_reads INTEGER DEFAULT 0,
32
+ kv_writes INTEGER DEFAULT 0,
33
+ do_requests INTEGER DEFAULT 0,
34
+ do_gb_seconds REAL DEFAULT 0,
35
+ r2_class_a INTEGER DEFAULT 0,
36
+ r2_class_b INTEGER DEFAULT 0,
37
+ ai_neurons INTEGER DEFAULT 0,
38
+ queue_messages INTEGER DEFAULT 0,
39
+ requests INTEGER DEFAULT 0,
40
+ cpu_ms INTEGER DEFAULT 0,
41
+
42
+ -- Circuit breaker events
43
+ times_disabled INTEGER DEFAULT 0,
44
+
45
+ -- Error tracking (from 024)
46
+ error_count INTEGER DEFAULT 0,
47
+ error_categories TEXT, -- JSON array of categories
48
+
49
+ -- Metadata
50
+ created_at INTEGER DEFAULT (unixepoch()),
51
+
52
+ UNIQUE(feature_key, usage_date)
53
+ );
54
+
55
+ CREATE INDEX IF NOT EXISTS idx_feature_usage_daily_key
56
+ ON feature_usage_daily(feature_key);
57
+ CREATE INDEX IF NOT EXISTS idx_feature_usage_daily_date
58
+ ON feature_usage_daily(usage_date DESC);
59
+ CREATE INDEX IF NOT EXISTS idx_feature_usage_daily_key_date
60
+ ON feature_usage_daily(feature_key, usage_date DESC);
61
+
62
+
63
+ -- =============================================================================
64
+ -- FEATURE CIRCUIT BREAKER EVENTS (from 018)
65
+ -- =============================================================================
66
+ -- Tracks trip/reset events for feature-level circuit breakers.
67
+
68
+ CREATE TABLE IF NOT EXISTS feature_circuit_breaker_events (
69
+ id TEXT PRIMARY KEY,
70
+ feature_key TEXT NOT NULL,
71
+ event_type TEXT NOT NULL, -- 'trip', 'reset', 'manual_disable', 'manual_enable'
72
+ reason TEXT,
73
+
74
+ -- Violation details (for 'trip' events)
75
+ violated_resource TEXT,
76
+ current_value REAL,
77
+ budget_limit REAL,
78
+
79
+ -- Metadata
80
+ auto_reset INTEGER DEFAULT 0,
81
+ alert_sent INTEGER DEFAULT 0,
82
+ created_at INTEGER DEFAULT (unixepoch())
83
+ );
84
+
85
+ CREATE INDEX IF NOT EXISTS idx_fcb_feature_key
86
+ ON feature_circuit_breaker_events(feature_key, created_at DESC);
87
+ CREATE INDEX IF NOT EXISTS idx_fcb_created_at
88
+ ON feature_circuit_breaker_events(created_at DESC);
89
+ CREATE INDEX IF NOT EXISTS idx_fcb_event_type
90
+ ON feature_circuit_breaker_events(event_type, created_at DESC);
91
+
92
+
93
+ -- =============================================================================
94
+ -- FEATURE REGISTRY (from 020)
95
+ -- =============================================================================
96
+ -- Stores feature definitions synced from services.yaml/budgets.yaml config.
97
+
98
+ CREATE TABLE IF NOT EXISTS feature_registry (
99
+ feature_key TEXT PRIMARY KEY, -- 'my-project:scanner:github'
100
+ project_id TEXT NOT NULL,
101
+ category TEXT NOT NULL,
102
+ feature TEXT NOT NULL,
103
+
104
+ -- Display
105
+ display_name TEXT NOT NULL,
106
+ description TEXT,
107
+
108
+ -- Budget
109
+ cost_tier TEXT DEFAULT 'medium', -- 'low', 'medium', 'high', 'critical'
110
+ daily_limits_json TEXT, -- JSON: { d1_writes: 5000, kv_reads: 10000, ... }
111
+
112
+ -- Circuit breaker
113
+ circuit_breaker_enabled INTEGER DEFAULT 0,
114
+ auto_reset_seconds INTEGER DEFAULT 3600,
115
+ cooldown_seconds INTEGER DEFAULT 300,
116
+ max_consecutive_trips INTEGER DEFAULT 3,
117
+
118
+ -- Thresholds
119
+ warning_threshold INTEGER DEFAULT 70,
120
+ critical_threshold INTEGER DEFAULT 90,
121
+
122
+ -- Metadata
123
+ sources_json TEXT, -- JSON array of source identifiers
124
+ synced_at INTEGER,
125
+ created_at INTEGER DEFAULT (unixepoch()),
126
+ updated_at INTEGER DEFAULT (unixepoch()),
127
+
128
+ FOREIGN KEY (project_id) REFERENCES project_registry(project_id)
129
+ );
130
+
131
+ CREATE INDEX IF NOT EXISTS idx_feature_registry_project
132
+ ON feature_registry(project_id);
133
+ CREATE INDEX IF NOT EXISTS idx_feature_registry_project_category
134
+ ON feature_registry(project_id, category);
135
+ CREATE INDEX IF NOT EXISTS idx_feature_registry_cb_enabled
136
+ ON feature_registry(circuit_breaker_enabled)
137
+ WHERE circuit_breaker_enabled = 1;
138
+ CREATE INDEX IF NOT EXISTS idx_feature_registry_cost_tier
139
+ ON feature_registry(cost_tier);
140
+
141
+
142
+ -- =============================================================================
143
+ -- SYSTEM HEALTH CHECKS (from 021)
144
+ -- =============================================================================
145
+ -- Tracks heartbeat probes from SDK health() function.
146
+
147
+ CREATE TABLE IF NOT EXISTS system_health_checks (
148
+ id TEXT PRIMARY KEY,
149
+ project_id TEXT NOT NULL,
150
+ feature_id TEXT NOT NULL,
151
+ last_heartbeat INTEGER NOT NULL,
152
+ status TEXT DEFAULT 'healthy',
153
+ consecutive_failures INTEGER DEFAULT 0,
154
+ last_failure_reason TEXT,
155
+ created_at INTEGER DEFAULT (unixepoch()),
156
+ updated_at INTEGER DEFAULT (unixepoch()),
157
+ UNIQUE(project_id, feature_id)
158
+ );
159
+
160
+ CREATE INDEX IF NOT EXISTS idx_health_checks_project ON system_health_checks(project_id);
161
+ CREATE INDEX IF NOT EXISTS idx_health_checks_status ON system_health_checks(status) WHERE status != 'healthy';
162
+ CREATE INDEX IF NOT EXISTS idx_health_checks_stale ON system_health_checks(last_heartbeat);
163
+
164
+
165
+ -- =============================================================================
166
+ -- FEATURE ERROR EVENTS (from 024)
167
+ -- =============================================================================
168
+ -- Real-time error event logging for alerting and debugging.
169
+ -- Supports P0/P1/P2 alerting tiers. 7-day retention.
170
+
171
+ CREATE TABLE IF NOT EXISTS feature_error_events (
172
+ id TEXT PRIMARY KEY,
173
+ feature_key TEXT NOT NULL,
174
+
175
+ -- Error classification
176
+ error_category TEXT NOT NULL,
177
+ error_code TEXT,
178
+ error_message TEXT, -- Truncated to max 500 chars
179
+
180
+ -- Context
181
+ correlation_id TEXT,
182
+ worker TEXT,
183
+
184
+ -- Alerting
185
+ priority TEXT DEFAULT 'P2',
186
+ alert_sent INTEGER DEFAULT 0,
187
+
188
+ created_at INTEGER DEFAULT (unixepoch())
189
+ );
190
+
191
+ CREATE INDEX IF NOT EXISTS idx_fee_feature_key
192
+ ON feature_error_events(feature_key, created_at DESC);
193
+ CREATE INDEX IF NOT EXISTS idx_fee_alert_pending
194
+ ON feature_error_events(alert_sent, priority, created_at DESC);
195
+ CREATE INDEX IF NOT EXISTS idx_fee_created_at
196
+ ON feature_error_events(created_at);
197
+ CREATE INDEX IF NOT EXISTS idx_fee_category
198
+ ON feature_error_events(error_category, created_at DESC);
199
+ CREATE INDEX IF NOT EXISTS idx_fee_correlation_id
200
+ ON feature_error_events(correlation_id);
201
+
202
+
203
+ -- =============================================================================
204
+ -- ERROR ALERTS HISTORY (from 024)
205
+ -- =============================================================================
206
+ -- Stores alert history for analysis and deduplication.
207
+
208
+ CREATE TABLE IF NOT EXISTS error_alerts (
209
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
210
+ feature_key TEXT NOT NULL,
211
+ alert_type TEXT NOT NULL, -- 'p0_immediate', 'p1_digest', 'p2_summary'
212
+ error_category TEXT,
213
+ error_code TEXT,
214
+ error_count INTEGER DEFAULT 1,
215
+ error_rate REAL,
216
+ correlation_id TEXT,
217
+ worker TEXT,
218
+ created_at INTEGER DEFAULT (unixepoch())
219
+ );
220
+
221
+ CREATE INDEX IF NOT EXISTS idx_ea_feature_key
222
+ ON error_alerts(feature_key, created_at DESC);
223
+ CREATE INDEX IF NOT EXISTS idx_ea_alert_type
224
+ ON error_alerts(alert_type, created_at DESC);
225
+ CREATE INDEX IF NOT EXISTS idx_ea_created_at
226
+ ON error_alerts(created_at);
227
+
228
+
229
+ -- =============================================================================
230
+ -- FEATURE AI MODEL USAGE (from 025)
231
+ -- =============================================================================
232
+ -- Per-feature, per-model AI usage from SDK telemetry.
233
+
234
+ CREATE TABLE IF NOT EXISTS feature_ai_model_usage (
235
+ id TEXT PRIMARY KEY,
236
+ feature_key TEXT NOT NULL,
237
+ model TEXT NOT NULL,
238
+ usage_date TEXT NOT NULL, -- YYYY-MM-DD
239
+ invocations INTEGER DEFAULT 0,
240
+ created_at INTEGER DEFAULT (unixepoch()),
241
+ updated_at INTEGER DEFAULT (unixepoch()),
242
+ UNIQUE(feature_key, model, usage_date)
243
+ );
244
+
245
+ CREATE INDEX IF NOT EXISTS idx_feature_ai_model_feature
246
+ ON feature_ai_model_usage(feature_key, usage_date DESC);
247
+ CREATE INDEX IF NOT EXISTS idx_feature_ai_model_model
248
+ ON feature_ai_model_usage(model, usage_date DESC);
249
+ CREATE INDEX IF NOT EXISTS idx_feature_ai_model_date
250
+ ON feature_ai_model_usage(usage_date DESC);
@@ -0,0 +1,452 @@
1
+ -- =============================================================================
2
+ -- 004_settings_alerts.sql — Settings, billing, DLQ, error budgets, audit
3
+ -- =============================================================================
4
+ -- Consolidated from original migrations: 023, 026, 029, 030, 031, 032, 033,
5
+ -- 034, 035, 052
6
+ --
7
+ -- Tables:
8
+ -- billing_settings — Billing cycle and plan limit configuration
9
+ -- dead_letter_queue — Failed telemetry messages for replay
10
+ -- error_budget_windows — 5-minute request/error windows for SLA tracking
11
+ -- sla_thresholds — SLA targets per feature or project
12
+ -- audit_results — SDK integration audit results
13
+ -- health_trends — Composite health score tracking over time
14
+ -- audit_file_hotspots — Files that change frequently (audit targets)
15
+ -- audit_sdk_regressions — Commits that removed SDK patterns
16
+ -- audit_file_hashes — File content hashes for delta detection
17
+ -- audit_delta_log — Files changed between audits
18
+ --
19
+ -- Views:
20
+ -- v_project_health_latest — Latest health status per project
21
+ -- v_unacknowledged_regressions — Summary of unacknowledged regressions
22
+ -- =============================================================================
23
+
24
+
25
+ -- =============================================================================
26
+ -- BILLING SETTINGS (from 023, with plan limits from 026)
27
+ -- =============================================================================
28
+ -- Billing cycle configuration and plan allowances.
29
+ -- All plan limit columns merged from migration 026 ALTER TABLEs.
30
+
31
+ CREATE TABLE IF NOT EXISTS billing_settings (
32
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ account_id TEXT NOT NULL DEFAULT 'default',
34
+ plan_type TEXT NOT NULL DEFAULT 'paid', -- 'free' | 'paid' | 'enterprise'
35
+ billing_cycle_day INTEGER NOT NULL DEFAULT 1, -- 1-28 or 0 for calendar month
36
+ billing_currency TEXT NOT NULL DEFAULT 'USD',
37
+ base_cost_monthly REAL NOT NULL DEFAULT 5.00, -- Workers Paid Plan base
38
+ notes TEXT,
39
+
40
+ -- Workers Paid Plan: $5/month includes 10M requests (from 026)
41
+ workers_included_requests INTEGER DEFAULT 10000000,
42
+ workers_overage_rate REAL DEFAULT 0.30,
43
+
44
+ -- D1: 25B reads + 50M writes included (from 026)
45
+ d1_included_reads INTEGER DEFAULT 25000000000,
46
+ d1_included_writes INTEGER DEFAULT 50000000,
47
+ d1_read_overage_rate REAL DEFAULT 0.001,
48
+ d1_write_overage_rate REAL DEFAULT 1.00,
49
+
50
+ -- KV: 10M reads + 1M writes included (from 026)
51
+ kv_included_reads INTEGER DEFAULT 10000000,
52
+ kv_included_writes INTEGER DEFAULT 1000000,
53
+ kv_read_overage_rate REAL DEFAULT 0.50,
54
+ kv_write_overage_rate REAL DEFAULT 5.00,
55
+
56
+ -- R2: 10GB storage + 1M Class A + 10M Class B ops included (from 026)
57
+ r2_included_storage_bytes INTEGER DEFAULT 10000000000,
58
+ r2_included_class_a INTEGER DEFAULT 1000000,
59
+ r2_included_class_b INTEGER DEFAULT 10000000,
60
+
61
+ -- Durable Objects: 3M requests + 400K GB-seconds included (from 026)
62
+ do_included_requests INTEGER DEFAULT 3000000,
63
+ do_included_gb_seconds INTEGER DEFAULT 400000,
64
+ do_request_overage_rate REAL DEFAULT 0.15,
65
+
66
+ created_at TEXT DEFAULT (datetime('now')),
67
+ updated_at TEXT DEFAULT (datetime('now')),
68
+ UNIQUE(account_id)
69
+ );
70
+
71
+ CREATE INDEX IF NOT EXISTS idx_billing_settings_account
72
+ ON billing_settings(account_id);
73
+
74
+
75
+ -- =============================================================================
76
+ -- DEAD LETTER QUEUE (from 029)
77
+ -- =============================================================================
78
+ -- Stores telemetry messages that failed processing after max retries.
79
+ -- Supports inspection, replay, and poison pill detection.
80
+ -- Retention: 30 days.
81
+
82
+ CREATE TABLE IF NOT EXISTS dead_letter_queue (
83
+ id TEXT PRIMARY KEY,
84
+
85
+ -- Original message content
86
+ message_payload TEXT NOT NULL,
87
+ feature_key TEXT NOT NULL,
88
+ project TEXT NOT NULL,
89
+ category TEXT,
90
+ feature TEXT,
91
+
92
+ -- Error context
93
+ error_message TEXT,
94
+ error_category TEXT,
95
+ error_code TEXT,
96
+ error_fingerprint TEXT,
97
+ retry_count INTEGER NOT NULL,
98
+
99
+ -- Tracing
100
+ correlation_id TEXT,
101
+ original_timestamp INTEGER,
102
+
103
+ -- DLQ management
104
+ status TEXT DEFAULT 'pending', -- 'pending', 'replayed', 'discarded'
105
+ replayed_at INTEGER,
106
+ replayed_by TEXT,
107
+ discard_reason TEXT,
108
+
109
+ created_at INTEGER DEFAULT (unixepoch()),
110
+ updated_at INTEGER DEFAULT (unixepoch())
111
+ );
112
+
113
+ CREATE INDEX IF NOT EXISTS idx_dlq_status
114
+ ON dead_letter_queue(status, created_at DESC);
115
+ CREATE INDEX IF NOT EXISTS idx_dlq_feature_key
116
+ ON dead_letter_queue(feature_key, created_at DESC);
117
+ CREATE INDEX IF NOT EXISTS idx_dlq_project
118
+ ON dead_letter_queue(project, created_at DESC);
119
+ CREATE INDEX IF NOT EXISTS idx_dlq_fingerprint
120
+ ON dead_letter_queue(error_fingerprint, created_at DESC);
121
+ CREATE INDEX IF NOT EXISTS idx_dlq_created_at
122
+ ON dead_letter_queue(created_at);
123
+ CREATE INDEX IF NOT EXISTS idx_dlq_correlation_id
124
+ ON dead_letter_queue(correlation_id);
125
+
126
+
127
+ -- =============================================================================
128
+ -- ERROR BUDGET WINDOWS (from 030)
129
+ -- =============================================================================
130
+ -- Tracks success/error counts in 5-minute windows per feature.
131
+ -- Enables rolling error rate calculation for SLO monitoring.
132
+ -- Retention: 30 days.
133
+
134
+ CREATE TABLE IF NOT EXISTS error_budget_windows (
135
+ id TEXT PRIMARY KEY,
136
+
137
+ -- Feature identification
138
+ feature_key TEXT NOT NULL,
139
+ project TEXT NOT NULL,
140
+
141
+ -- Window timing
142
+ window_start INTEGER NOT NULL,
143
+ window_end INTEGER NOT NULL,
144
+
145
+ -- Request counts
146
+ success_count INTEGER DEFAULT 0,
147
+ error_count INTEGER DEFAULT 0,
148
+ total_count INTEGER DEFAULT 0,
149
+
150
+ -- Error breakdown by category
151
+ timeout_count INTEGER DEFAULT 0,
152
+ validation_count INTEGER DEFAULT 0,
153
+ internal_count INTEGER DEFAULT 0,
154
+ external_count INTEGER DEFAULT 0,
155
+ other_count INTEGER DEFAULT 0,
156
+
157
+ -- Latency stats (percentiles in ms)
158
+ p50_latency_ms INTEGER,
159
+ p95_latency_ms INTEGER,
160
+ p99_latency_ms INTEGER,
161
+ max_latency_ms INTEGER,
162
+
163
+ created_at INTEGER DEFAULT (unixepoch()),
164
+ updated_at INTEGER DEFAULT (unixepoch())
165
+ );
166
+
167
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_error_budget_feature_window
168
+ ON error_budget_windows(feature_key, window_start);
169
+ CREATE INDEX IF NOT EXISTS idx_error_budget_project
170
+ ON error_budget_windows(project, window_start DESC);
171
+ CREATE INDEX IF NOT EXISTS idx_error_budget_window_start
172
+ ON error_budget_windows(window_start);
173
+ CREATE INDEX IF NOT EXISTS idx_error_budget_recent
174
+ ON error_budget_windows(feature_key, window_end DESC);
175
+
176
+
177
+ -- =============================================================================
178
+ -- SLA THRESHOLDS (from 030)
179
+ -- =============================================================================
180
+ -- SLA targets per feature or project.
181
+
182
+ CREATE TABLE IF NOT EXISTS sla_thresholds (
183
+ id TEXT PRIMARY KEY,
184
+
185
+ target_type TEXT NOT NULL CHECK (target_type IN ('feature', 'project')),
186
+ target_key TEXT NOT NULL,
187
+
188
+ -- SLA targets (error rate thresholds)
189
+ sla_target_pct REAL NOT NULL,
190
+ warning_threshold_pct REAL NOT NULL,
191
+ critical_threshold_pct REAL NOT NULL,
192
+
193
+ -- Window configuration
194
+ evaluation_window_hours INTEGER DEFAULT 24,
195
+
196
+ -- Status tracking
197
+ current_sla_pct REAL,
198
+ budget_remaining_pct REAL,
199
+ status TEXT DEFAULT 'healthy', -- 'healthy', 'warning', 'critical', 'exhausted'
200
+ last_evaluated_at INTEGER,
201
+
202
+ created_at INTEGER DEFAULT (unixepoch()),
203
+ updated_at INTEGER DEFAULT (unixepoch())
204
+ );
205
+
206
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sla_target
207
+ ON sla_thresholds(target_type, target_key);
208
+ CREATE INDEX IF NOT EXISTS idx_sla_status
209
+ ON sla_thresholds(status);
210
+
211
+
212
+ -- =============================================================================
213
+ -- AUDIT RESULTS (from 031, with columns from 032, 033, 052)
214
+ -- =============================================================================
215
+ -- SDK integration audit results from weekly triangulation audits.
216
+ -- All ALTER TABLE columns merged into CREATE TABLE.
217
+
218
+ CREATE TABLE IF NOT EXISTS audit_results (
219
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
220
+ audit_id TEXT NOT NULL,
221
+ project TEXT NOT NULL,
222
+ status TEXT NOT NULL, -- HEALTHY, ZOMBIE, UNTRACKED, BROKEN, NOT_INTEGRATED
223
+
224
+ status_message TEXT,
225
+
226
+ -- Config checks (from wrangler.jsonc)
227
+ has_platform_cache BOOLEAN,
228
+ has_platform_telemetry BOOLEAN,
229
+ observability_enabled BOOLEAN,
230
+ logs_enabled BOOLEAN,
231
+ config_issues TEXT, -- JSON array
232
+
233
+ -- Code smell tests
234
+ has_sdk_folder BOOLEAN,
235
+ has_with_feature_budget BOOLEAN,
236
+ has_tracked_env BOOLEAN,
237
+ has_circuit_breaker_error BOOLEAN,
238
+ has_error_logging BOOLEAN,
239
+
240
+ -- Runtime checks (D1 system_health_checks)
241
+ has_recent_heartbeat BOOLEAN,
242
+ hours_since_heartbeat INTEGER,
243
+
244
+ -- AI Judge results
245
+ ai_judge_score INTEGER, -- 0-100
246
+ ai_judge_summary TEXT,
247
+ ai_judge_issues TEXT, -- JSON array (legacy)
248
+ ai_cached_at TEXT,
249
+
250
+ -- Worker identification (from 032, for multi-worker projects)
251
+ worker_name TEXT DEFAULT NULL,
252
+
253
+ -- Traces configuration (from 032)
254
+ traces_enabled BOOLEAN DEFAULT NULL,
255
+ trace_sampling_rate REAL DEFAULT NULL,
256
+
257
+ -- Logs configuration extended (from 032)
258
+ log_sampling_rate REAL DEFAULT NULL,
259
+ invocation_logs_enabled BOOLEAN DEFAULT NULL,
260
+
261
+ -- Source maps (from 032)
262
+ source_maps_enabled BOOLEAN DEFAULT NULL,
263
+
264
+ -- AI observability scoring (from 032)
265
+ ai_observability_score INTEGER DEFAULT NULL,
266
+ ai_observability_issues TEXT DEFAULT NULL,
267
+
268
+ -- Rubric scores 1-5 per dimension (from 033)
269
+ rubric_sdk INTEGER DEFAULT NULL,
270
+ rubric_observability INTEGER DEFAULT NULL,
271
+ rubric_cost_protection INTEGER DEFAULT NULL,
272
+ rubric_security INTEGER DEFAULT NULL,
273
+
274
+ -- Evidence and reasoning (from 033)
275
+ rubric_evidence TEXT DEFAULT NULL, -- JSON object
276
+ ai_reasoning TEXT DEFAULT NULL,
277
+ ai_categorised_issues TEXT DEFAULT NULL, -- JSON array with severity
278
+
279
+ -- Validation metadata (from 033)
280
+ ai_validation_retries INTEGER DEFAULT 0,
281
+ ai_schema_version TEXT DEFAULT 'v1',
282
+
283
+ -- Scan type (from 052)
284
+ scan_type TEXT DEFAULT 'full' CHECK (scan_type IN ('full', 'focused')),
285
+ focused_dimensions TEXT, -- JSON array for focused scans
286
+
287
+ -- Metadata
288
+ created_at TEXT DEFAULT (datetime('now')),
289
+ UNIQUE(audit_id, project)
290
+ );
291
+
292
+ CREATE INDEX IF NOT EXISTS idx_audit_results_project ON audit_results(project);
293
+ CREATE INDEX IF NOT EXISTS idx_audit_results_status ON audit_results(status);
294
+ CREATE INDEX IF NOT EXISTS idx_audit_results_created ON audit_results(created_at);
295
+ CREATE INDEX IF NOT EXISTS idx_audit_results_ai_score ON audit_results(ai_judge_score) WHERE ai_judge_score IS NOT NULL;
296
+ CREATE INDEX IF NOT EXISTS idx_audit_results_audit_worker ON audit_results(audit_id, project, worker_name);
297
+ CREATE INDEX IF NOT EXISTS idx_audit_results_traces ON audit_results(traces_enabled) WHERE traces_enabled IS NOT NULL;
298
+ CREATE INDEX IF NOT EXISTS idx_audit_results_trace_sampling ON audit_results(trace_sampling_rate) WHERE trace_sampling_rate IS NOT NULL;
299
+ CREATE INDEX IF NOT EXISTS idx_audit_results_source_maps ON audit_results(source_maps_enabled) WHERE source_maps_enabled IS NOT NULL;
300
+ CREATE INDEX IF NOT EXISTS idx_audit_rubric_sdk ON audit_results(rubric_sdk) WHERE rubric_sdk IS NOT NULL;
301
+ CREATE INDEX IF NOT EXISTS idx_audit_rubric_observability ON audit_results(rubric_observability) WHERE rubric_observability IS NOT NULL;
302
+ CREATE INDEX IF NOT EXISTS idx_audit_rubric_cost ON audit_results(rubric_cost_protection) WHERE rubric_cost_protection IS NOT NULL;
303
+ CREATE INDEX IF NOT EXISTS idx_audit_rubric_security ON audit_results(rubric_security) WHERE rubric_security IS NOT NULL;
304
+ CREATE INDEX IF NOT EXISTS idx_audit_rubric_composite ON audit_results(project, rubric_sdk, rubric_observability, rubric_cost_protection, rubric_security) WHERE rubric_sdk IS NOT NULL;
305
+ CREATE INDEX IF NOT EXISTS idx_audit_results_scan_type ON audit_results(scan_type);
306
+
307
+
308
+ -- =============================================================================
309
+ -- HEALTH TRENDS (from 034, with scan_type from 052)
310
+ -- =============================================================================
311
+ -- Track composite health scores over time for trend analysis.
312
+
313
+ CREATE TABLE IF NOT EXISTS health_trends (
314
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
315
+ project TEXT NOT NULL,
316
+ audit_id TEXT NOT NULL,
317
+ audit_date TEXT NOT NULL, -- YYYY-MM-DD
318
+
319
+ -- Composite score (0-100 scale)
320
+ composite_score INTEGER NOT NULL,
321
+
322
+ -- Individual rubric scores (1-5 scale)
323
+ sdk_score INTEGER,
324
+ observability_score INTEGER,
325
+ cost_score INTEGER,
326
+ security_score INTEGER,
327
+
328
+ -- Trend direction
329
+ trend TEXT DEFAULT 'stable' CHECK (trend IN ('improving', 'stable', 'declining')),
330
+ score_delta INTEGER DEFAULT 0,
331
+
332
+ -- Scan type (from 052)
333
+ scan_type TEXT DEFAULT 'full' CHECK (scan_type IN ('full', 'focused')),
334
+
335
+ created_at TEXT DEFAULT (datetime('now')),
336
+ UNIQUE(project, audit_id)
337
+ );
338
+
339
+ CREATE INDEX IF NOT EXISTS idx_health_trends_project_date ON health_trends(project, audit_date DESC);
340
+ CREATE INDEX IF NOT EXISTS idx_health_trends_date ON health_trends(audit_date DESC);
341
+ CREATE INDEX IF NOT EXISTS idx_health_trends_trend ON health_trends(trend) WHERE trend = 'declining';
342
+ CREATE INDEX IF NOT EXISTS idx_health_trends_scan_type ON health_trends(scan_type);
343
+
344
+ -- View: Latest health status per project
345
+ CREATE VIEW IF NOT EXISTS v_project_health_latest AS
346
+ SELECT
347
+ ht.*,
348
+ (SELECT composite_score FROM health_trends
349
+ WHERE project = ht.project
350
+ AND audit_date < ht.audit_date
351
+ ORDER BY audit_date DESC LIMIT 1) as previous_score
352
+ FROM health_trends ht
353
+ WHERE ht.id IN (
354
+ SELECT MAX(id) FROM health_trends GROUP BY project
355
+ );
356
+
357
+
358
+ -- =============================================================================
359
+ -- BEHAVIOURAL ANALYSIS (from 035)
360
+ -- =============================================================================
361
+
362
+ -- File change hotspots — priority audit targets
363
+ CREATE TABLE IF NOT EXISTS audit_file_hotspots (
364
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
365
+ project TEXT NOT NULL,
366
+ file_path TEXT NOT NULL,
367
+ change_count INTEGER DEFAULT 0,
368
+ last_changed TEXT,
369
+ authors TEXT, -- JSON array
370
+ has_sdk_patterns BOOLEAN DEFAULT FALSE,
371
+ sdk_patterns_found TEXT, -- JSON array
372
+ hotspot_score INTEGER DEFAULT 0,
373
+ audit_date TEXT NOT NULL,
374
+ created_at TEXT DEFAULT (datetime('now')),
375
+ UNIQUE(project, file_path, audit_date)
376
+ );
377
+
378
+ CREATE INDEX IF NOT EXISTS idx_hotspots_project_score
379
+ ON audit_file_hotspots(project, hotspot_score DESC);
380
+ CREATE INDEX IF NOT EXISTS idx_hotspots_audit_date
381
+ ON audit_file_hotspots(audit_date DESC);
382
+
383
+ -- SDK regressions — commits that removed SDK patterns
384
+ CREATE TABLE IF NOT EXISTS audit_sdk_regressions (
385
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
386
+ project TEXT NOT NULL,
387
+ commit_sha TEXT NOT NULL,
388
+ commit_message TEXT,
389
+ commit_author TEXT,
390
+ commit_date TEXT,
391
+ file_path TEXT NOT NULL,
392
+ regression_type TEXT NOT NULL,
393
+ description TEXT,
394
+ severity TEXT DEFAULT 'medium' CHECK (severity IN ('critical', 'high', 'medium', 'low')),
395
+ acknowledged BOOLEAN DEFAULT FALSE,
396
+ acknowledged_at TEXT,
397
+ acknowledged_by TEXT,
398
+ audit_date TEXT NOT NULL,
399
+ created_at TEXT DEFAULT (datetime('now')),
400
+ UNIQUE(project, commit_sha, file_path, regression_type)
401
+ );
402
+
403
+ CREATE INDEX IF NOT EXISTS idx_regressions_project_date
404
+ ON audit_sdk_regressions(project, audit_date DESC);
405
+ CREATE INDEX IF NOT EXISTS idx_regressions_unacknowledged
406
+ ON audit_sdk_regressions(acknowledged, audit_date DESC)
407
+ WHERE acknowledged = FALSE;
408
+
409
+ -- File hashes — delta detection between audits
410
+ CREATE TABLE IF NOT EXISTS audit_file_hashes (
411
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
412
+ project TEXT NOT NULL,
413
+ file_path TEXT NOT NULL,
414
+ content_hash TEXT NOT NULL,
415
+ content_length INTEGER,
416
+ first_seen TEXT NOT NULL,
417
+ last_seen TEXT NOT NULL,
418
+ created_at TEXT DEFAULT (datetime('now')),
419
+ updated_at TEXT DEFAULT (datetime('now')),
420
+ UNIQUE(project, file_path)
421
+ );
422
+
423
+ CREATE INDEX IF NOT EXISTS idx_file_hashes_project
424
+ ON audit_file_hashes(project);
425
+
426
+ -- Delta audit log — files changed between audits
427
+ CREATE TABLE IF NOT EXISTS audit_delta_log (
428
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
429
+ audit_id TEXT NOT NULL,
430
+ project TEXT NOT NULL,
431
+ files_changed INTEGER DEFAULT 0,
432
+ files_added INTEGER DEFAULT 0,
433
+ files_removed INTEGER DEFAULT 0,
434
+ changed_files TEXT, -- JSON array
435
+ delta_issues_found INTEGER DEFAULT 0,
436
+ created_at TEXT DEFAULT (datetime('now'))
437
+ );
438
+
439
+ CREATE INDEX IF NOT EXISTS idx_delta_log_project_date
440
+ ON audit_delta_log(project, created_at DESC);
441
+
442
+ -- View: Unacknowledged regressions summary
443
+ CREATE VIEW IF NOT EXISTS v_unacknowledged_regressions AS
444
+ SELECT
445
+ project,
446
+ COUNT(*) as regression_count,
447
+ SUM(CASE WHEN severity = 'critical' THEN 1 ELSE 0 END) as critical_count,
448
+ SUM(CASE WHEN severity = 'high' THEN 1 ELSE 0 END) as high_count,
449
+ MAX(commit_date) as latest_regression_date
450
+ FROM audit_sdk_regressions
451
+ WHERE acknowledged = FALSE
452
+ GROUP BY project;
@@ -0,0 +1,4 @@
1
+ -- Seed data: register your project in the platform
2
+ INSERT INTO project_registry (project_id, display_name, status, tier, repository)
3
+ VALUES ('{{projectSlug}}', '{{projectName}}', 'active', 'paid', '{{githubOrg}}/{{projectSlug}}')
4
+ ON CONFLICT (project_id) DO NOTHING;