@derwinjs/db 0.9.0 → 0.10.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/dist/contract-baseline-store.d.ts +21 -0
- package/dist/contract-baseline-store.d.ts.map +1 -0
- package/dist/contract-baseline-store.js +103 -0
- package/dist/contract-baseline-store.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/scripts/smoke-auto-fix.js +1 -1
- package/dist/scripts/smoke-auto-fix.js.map +1 -1
- package/dist/tenant-fuzz-config-store.d.ts +28 -0
- package/dist/tenant-fuzz-config-store.d.ts.map +1 -0
- package/dist/tenant-fuzz-config-store.js +173 -0
- package/dist/tenant-fuzz-config-store.js.map +1 -0
- package/dist/visual-baseline-store.d.ts +21 -0
- package/dist/visual-baseline-store.d.ts.map +1 -0
- package/dist/visual-baseline-store.js +87 -0
- package/dist/visual-baseline-store.js.map +1 -0
- package/package.json +3 -3
- package/prisma/migrations/20260501165631_init/migration.sql +407 -0
- package/prisma/migrations/20260503051425_0002_qap018b_qaticket_crosslink_fields/migration.sql +6 -0
- package/prisma/migrations/20260507130000_sprint10_visual_baselines/migration.sql +27 -0
- package/prisma/migrations/20260507130100_sprint10_phase3_contract_baselines/migration.sql +32 -0
- package/prisma/migrations/20260507130200_sprint10_phase4_tenant_fuzz/migration.sql +34 -0
- package/prisma/schema.prisma +107 -0
- package/prisma-client/edge.js +36 -4
- package/prisma-client/index-browser.js +33 -1
- package/prisma-client/index.d.ts +15602 -10678
- package/prisma-client/index.js +36 -4
- package/prisma-client/package.json +1 -1
- package/prisma-client/schema.prisma +107 -0
- package/prisma-client/wasm.js +33 -1
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
-- CreateEnum
|
|
2
|
+
CREATE TYPE "ProjectType" AS ENUM ('SAAS', 'ECOMMERCE', 'MARKETING', 'ERP', 'ANALYTICS', 'INFRA', 'CONTENT');
|
|
3
|
+
|
|
4
|
+
-- CreateEnum
|
|
5
|
+
CREATE TYPE "ProjectMode" AS ENUM ('OBSERVE', 'TICKET_ONLY', 'AUTHOR', 'AUTO');
|
|
6
|
+
|
|
7
|
+
-- CreateEnum
|
|
8
|
+
CREATE TYPE "RunTrigger" AS ENUM ('CRON', 'OPERATOR_ON_DEMAND', 'WEBHOOK', 'CONTINUOUS');
|
|
9
|
+
|
|
10
|
+
-- CreateEnum
|
|
11
|
+
CREATE TYPE "RunStatus" AS ENUM ('IN_PROGRESS', 'COMPLETED', 'FAILED', 'CANCELLED');
|
|
12
|
+
|
|
13
|
+
-- CreateEnum
|
|
14
|
+
CREATE TYPE "SurfaceCategory" AS ENUM ('CODE_HEALTH', 'FUNCTIONAL_CORRECTNESS', 'UI_UX_INTEGRITY', 'PERF_RESILIENCE', 'SECURITY', 'COMPLIANCE_AUDIT', 'MULTI_TENANT_SAFETY', 'OPERATIONAL_HEALTH');
|
|
15
|
+
|
|
16
|
+
-- CreateEnum
|
|
17
|
+
CREATE TYPE "Severity" AS ENUM ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW');
|
|
18
|
+
|
|
19
|
+
-- CreateEnum
|
|
20
|
+
CREATE TYPE "RiskTier" AS ENUM ('LOW', 'MEDIUM', 'HIGH', 'NEVER');
|
|
21
|
+
|
|
22
|
+
-- CreateEnum
|
|
23
|
+
CREATE TYPE "TicketStatus" AS ENUM ('OPEN', 'INVESTIGATING', 'AUTHORING', 'PR_OPEN', 'MERGED', 'REGRESSED_REVERTED', 'CLOSED_WONTFIX', 'CLOSED_RESOLVED', 'ESCALATED');
|
|
24
|
+
|
|
25
|
+
-- CreateEnum
|
|
26
|
+
CREATE TYPE "ReviewBucket" AS ENUM ('PASS', 'FAIL', 'ESCALATION');
|
|
27
|
+
|
|
28
|
+
-- CreateEnum
|
|
29
|
+
CREATE TYPE "AttemptStatus" AS ENUM ('AUTHORING', 'PRE_VERIFY_FAILED', 'PRE_VERIFY_PASSED', 'PR_OPENED', 'AUTO_MERGED', 'HUMAN_MERGED', 'REJECTED', 'REGRESSED_REVERTED', 'FAILED');
|
|
30
|
+
|
|
31
|
+
-- CreateEnum
|
|
32
|
+
CREATE TYPE "ArtifactType" AS ENUM ('SCREENSHOT', 'VIDEO', 'DOM_SNAPSHOT', 'CONSOLE_LOG', 'NETWORK_LOG', 'TELEMETRY_SLICE', 'CODE_SNAPSHOT', 'PROMPT_TEXT', 'DIFF', 'REASONING_TRACE', 'REVIEWER_OUTPUT', 'REPLAY_BUNDLE');
|
|
33
|
+
|
|
34
|
+
-- CreateEnum
|
|
35
|
+
CREATE TYPE "ArtifactStage" AS ENUM ('DETECTION', 'INVESTIGATION', 'TICKET_CREATION', 'AUTHORING', 'PRE_MERGE_VERIFICATION', 'POST_MERGE_VERIFICATION', 'ARCHIVAL');
|
|
36
|
+
|
|
37
|
+
-- CreateEnum
|
|
38
|
+
CREATE TYPE "PolicyType" AS ENUM ('RISK_TIER', 'CONCURRENCY', 'TRUST_THRESHOLD', 'ESCALATION');
|
|
39
|
+
|
|
40
|
+
-- CreateTable
|
|
41
|
+
CREATE TABLE "projects" (
|
|
42
|
+
"id" TEXT NOT NULL,
|
|
43
|
+
"name" TEXT NOT NULL,
|
|
44
|
+
"slug" TEXT NOT NULL,
|
|
45
|
+
"type" "ProjectType" NOT NULL,
|
|
46
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
48
|
+
"mode" "ProjectMode" NOT NULL DEFAULT 'OBSERVE',
|
|
49
|
+
"modeChangedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
50
|
+
"modeChangedBy" TEXT,
|
|
51
|
+
"monthlyBudgetCents" INTEGER NOT NULL DEFAULT 10000,
|
|
52
|
+
"dailyDispatchLimit" INTEGER NOT NULL DEFAULT 50,
|
|
53
|
+
|
|
54
|
+
CONSTRAINT "projects_pkey" PRIMARY KEY ("id")
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
-- CreateTable
|
|
58
|
+
CREATE TABLE "project_profiles" (
|
|
59
|
+
"id" TEXT NOT NULL,
|
|
60
|
+
"projectId" TEXT NOT NULL,
|
|
61
|
+
"type" "ProjectType" NOT NULL,
|
|
62
|
+
"domainOntology" JSONB NOT NULL,
|
|
63
|
+
"riskProfile" JSONB NOT NULL,
|
|
64
|
+
"criticalFlows" JSONB NOT NULL,
|
|
65
|
+
"glossary" JSONB NOT NULL,
|
|
66
|
+
"dependencies" JSONB NOT NULL,
|
|
67
|
+
"complianceTags" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
|
68
|
+
"ingestedDocsHash" TEXT NOT NULL,
|
|
69
|
+
"lastIngestedAt" TIMESTAMP(3) NOT NULL,
|
|
70
|
+
"lastEvolvedAt" TIMESTAMP(3) NOT NULL,
|
|
71
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
72
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
73
|
+
|
|
74
|
+
CONSTRAINT "project_profiles_pkey" PRIMARY KEY ("id")
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- CreateTable
|
|
78
|
+
CREATE TABLE "ingested_docs" (
|
|
79
|
+
"id" TEXT NOT NULL,
|
|
80
|
+
"projectId" TEXT NOT NULL,
|
|
81
|
+
"source" TEXT NOT NULL,
|
|
82
|
+
"sourcePath" TEXT NOT NULL,
|
|
83
|
+
"contentHash" TEXT NOT NULL,
|
|
84
|
+
"contentSize" INTEGER NOT NULL,
|
|
85
|
+
"ingestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
86
|
+
"ontologyDelta" JSONB,
|
|
87
|
+
|
|
88
|
+
CONSTRAINT "ingested_docs_pkey" PRIMARY KEY ("id")
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
-- CreateTable
|
|
92
|
+
CREATE TABLE "profile_evolution_log" (
|
|
93
|
+
"id" TEXT NOT NULL,
|
|
94
|
+
"profileId" TEXT NOT NULL,
|
|
95
|
+
"triggerType" TEXT NOT NULL,
|
|
96
|
+
"delta" JSONB NOT NULL,
|
|
97
|
+
"rationale" TEXT NOT NULL,
|
|
98
|
+
"appliedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
99
|
+
"appliedBy" TEXT NOT NULL,
|
|
100
|
+
|
|
101
|
+
CONSTRAINT "profile_evolution_log_pkey" PRIMARY KEY ("id")
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
-- CreateTable
|
|
105
|
+
CREATE TABLE "qa_runs" (
|
|
106
|
+
"id" TEXT NOT NULL,
|
|
107
|
+
"projectId" TEXT NOT NULL,
|
|
108
|
+
"triggeredBy" TEXT NOT NULL,
|
|
109
|
+
"triggerType" "RunTrigger" NOT NULL,
|
|
110
|
+
"scope" JSONB NOT NULL,
|
|
111
|
+
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
112
|
+
"completedAt" TIMESTAMP(3),
|
|
113
|
+
"status" "RunStatus" NOT NULL DEFAULT 'IN_PROGRESS',
|
|
114
|
+
"signalsRaised" INTEGER NOT NULL DEFAULT 0,
|
|
115
|
+
"ticketsCreated" INTEGER NOT NULL DEFAULT 0,
|
|
116
|
+
"attemptsLaunched" INTEGER NOT NULL DEFAULT 0,
|
|
117
|
+
|
|
118
|
+
CONSTRAINT "qa_runs_pkey" PRIMARY KEY ("id")
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
-- CreateTable
|
|
122
|
+
CREATE TABLE "raw_signals" (
|
|
123
|
+
"id" TEXT NOT NULL,
|
|
124
|
+
"qaRunId" TEXT NOT NULL,
|
|
125
|
+
"routeName" TEXT NOT NULL,
|
|
126
|
+
"signalType" TEXT NOT NULL,
|
|
127
|
+
"rawData" JSONB NOT NULL,
|
|
128
|
+
"rawArtifactRefs" JSONB NOT NULL,
|
|
129
|
+
"qaTicketId" TEXT,
|
|
130
|
+
"investigatedAt" TIMESTAMP(3),
|
|
131
|
+
"capturedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
132
|
+
|
|
133
|
+
CONSTRAINT "raw_signals_pkey" PRIMARY KEY ("id")
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
-- CreateTable
|
|
137
|
+
CREATE TABLE "qa_tickets" (
|
|
138
|
+
"id" TEXT NOT NULL,
|
|
139
|
+
"projectId" TEXT NOT NULL,
|
|
140
|
+
"qaRunId" TEXT NOT NULL,
|
|
141
|
+
"externalRef" TEXT,
|
|
142
|
+
"externalSystem" TEXT,
|
|
143
|
+
"originatingTicketRef" TEXT,
|
|
144
|
+
"surface" "SurfaceCategory" NOT NULL,
|
|
145
|
+
"classification" TEXT NOT NULL,
|
|
146
|
+
"severity" "Severity" NOT NULL,
|
|
147
|
+
"riskTier" "RiskTier" NOT NULL,
|
|
148
|
+
"status" "TicketStatus" NOT NULL DEFAULT 'OPEN',
|
|
149
|
+
"title" TEXT NOT NULL,
|
|
150
|
+
"reproSteps" JSONB NOT NULL,
|
|
151
|
+
"suspectedRootCause" TEXT NOT NULL,
|
|
152
|
+
"blastRadius" JSONB NOT NULL,
|
|
153
|
+
"proposedFixApproach" TEXT NOT NULL,
|
|
154
|
+
"autoMergeEligible" BOOLEAN NOT NULL DEFAULT false,
|
|
155
|
+
"autoMergeRationale" TEXT,
|
|
156
|
+
"finalBucket" "ReviewBucket",
|
|
157
|
+
"bucketReason" TEXT,
|
|
158
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
159
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
160
|
+
"closedAt" TIMESTAMP(3),
|
|
161
|
+
|
|
162
|
+
CONSTRAINT "qa_tickets_pkey" PRIMARY KEY ("id")
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
-- CreateTable
|
|
166
|
+
CREATE TABLE "qa_fix_attempts" (
|
|
167
|
+
"id" TEXT NOT NULL,
|
|
168
|
+
"qaTicketId" TEXT NOT NULL,
|
|
169
|
+
"projectId" TEXT NOT NULL,
|
|
170
|
+
"attemptNumber" INTEGER NOT NULL,
|
|
171
|
+
"promptText" TEXT NOT NULL,
|
|
172
|
+
"diff" TEXT,
|
|
173
|
+
"diffSizeBytes" INTEGER,
|
|
174
|
+
"modelName" TEXT,
|
|
175
|
+
"modelVersion" TEXT,
|
|
176
|
+
"inputTokens" INTEGER,
|
|
177
|
+
"outputTokens" INTEGER,
|
|
178
|
+
"costCents" INTEGER,
|
|
179
|
+
"preVerifyResult" JSONB,
|
|
180
|
+
"preVerifyPassed" BOOLEAN,
|
|
181
|
+
"branchName" TEXT,
|
|
182
|
+
"prUrl" TEXT,
|
|
183
|
+
"prNumber" INTEGER,
|
|
184
|
+
"dispatchStatus" "AttemptStatus" NOT NULL DEFAULT 'AUTHORING',
|
|
185
|
+
"mergedAt" TIMESTAMP(3),
|
|
186
|
+
"postVerifyResult" JSONB,
|
|
187
|
+
"regressionDetected" BOOLEAN NOT NULL DEFAULT false,
|
|
188
|
+
"autoRevertedAt" TIMESTAMP(3),
|
|
189
|
+
"humanEditLines" INTEGER,
|
|
190
|
+
"fixSuccessScore" DOUBLE PRECISION,
|
|
191
|
+
"attemptedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
192
|
+
"closedAt" TIMESTAMP(3),
|
|
193
|
+
|
|
194
|
+
CONSTRAINT "qa_fix_attempts_pkey" PRIMARY KEY ("id")
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
-- CreateTable
|
|
198
|
+
CREATE TABLE "classification_trust" (
|
|
199
|
+
"id" TEXT NOT NULL,
|
|
200
|
+
"projectId" TEXT NOT NULL,
|
|
201
|
+
"classification" TEXT NOT NULL,
|
|
202
|
+
"surface" "SurfaceCategory" NOT NULL,
|
|
203
|
+
"attemptsLast30d" INTEGER NOT NULL DEFAULT 0,
|
|
204
|
+
"mergedClean" INTEGER NOT NULL DEFAULT 0,
|
|
205
|
+
"mergedWithEdits" INTEGER NOT NULL DEFAULT 0,
|
|
206
|
+
"regressed" INTEGER NOT NULL DEFAULT 0,
|
|
207
|
+
"reverted" INTEGER NOT NULL DEFAULT 0,
|
|
208
|
+
"successScore" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
209
|
+
"trustPercent" INTEGER NOT NULL DEFAULT 0,
|
|
210
|
+
"autoMergeEligible" BOOLEAN NOT NULL DEFAULT false,
|
|
211
|
+
"lastComputedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
212
|
+
|
|
213
|
+
CONSTRAINT "classification_trust_pkey" PRIMARY KEY ("id")
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
-- CreateTable
|
|
217
|
+
CREATE TABLE "rag_corpus" (
|
|
218
|
+
"id" TEXT NOT NULL,
|
|
219
|
+
"projectId" TEXT NOT NULL,
|
|
220
|
+
"classification" TEXT NOT NULL,
|
|
221
|
+
"surface" "SurfaceCategory" NOT NULL,
|
|
222
|
+
"promptText" TEXT NOT NULL,
|
|
223
|
+
"diff" TEXT NOT NULL,
|
|
224
|
+
"embedding" BYTEA,
|
|
225
|
+
"fixAttemptId" TEXT NOT NULL,
|
|
226
|
+
"outcomeQuality" DOUBLE PRECISION NOT NULL,
|
|
227
|
+
"addedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
228
|
+
|
|
229
|
+
CONSTRAINT "rag_corpus_pkey" PRIMARY KEY ("id")
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
-- CreateTable
|
|
233
|
+
CREATE TABLE "audit_artifacts" (
|
|
234
|
+
"id" TEXT NOT NULL,
|
|
235
|
+
"projectId" TEXT NOT NULL,
|
|
236
|
+
"qaTicketId" TEXT,
|
|
237
|
+
"qaFixAttemptId" TEXT,
|
|
238
|
+
"artifactType" "ArtifactType" NOT NULL,
|
|
239
|
+
"stage" "ArtifactStage" NOT NULL,
|
|
240
|
+
"storageBackend" TEXT NOT NULL,
|
|
241
|
+
"storageKey" TEXT NOT NULL,
|
|
242
|
+
"contentType" TEXT NOT NULL,
|
|
243
|
+
"sizeBytes" INTEGER NOT NULL,
|
|
244
|
+
"contentHash" TEXT NOT NULL,
|
|
245
|
+
"meta" JSONB NOT NULL,
|
|
246
|
+
"retentionUntil" TIMESTAMP(3),
|
|
247
|
+
"capturedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
248
|
+
|
|
249
|
+
CONSTRAINT "audit_artifacts_pkey" PRIMARY KEY ("id")
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
-- CreateTable
|
|
253
|
+
CREATE TABLE "policies" (
|
|
254
|
+
"id" TEXT NOT NULL,
|
|
255
|
+
"projectId" TEXT NOT NULL,
|
|
256
|
+
"policyType" "PolicyType" NOT NULL,
|
|
257
|
+
"pathRules" JSONB NOT NULL,
|
|
258
|
+
"classificationOverrides" JSONB NOT NULL,
|
|
259
|
+
"autoMergeTrustThreshold" INTEGER NOT NULL DEFAULT 70,
|
|
260
|
+
"autoMergeMediumThreshold" INTEGER NOT NULL DEFAULT 85,
|
|
261
|
+
"dailyDispatchLimit" INTEGER NOT NULL DEFAULT 50,
|
|
262
|
+
"perTicketAttemptLimit" INTEGER NOT NULL DEFAULT 3,
|
|
263
|
+
"freezeWindowsCron" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
|
264
|
+
"escalationTriggers" JSONB NOT NULL,
|
|
265
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
266
|
+
"updatedBy" TEXT NOT NULL,
|
|
267
|
+
|
|
268
|
+
CONSTRAINT "policies_pkey" PRIMARY KEY ("id")
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
-- CreateTable
|
|
272
|
+
CREATE TABLE "project_mode_log" (
|
|
273
|
+
"id" TEXT NOT NULL,
|
|
274
|
+
"projectId" TEXT NOT NULL,
|
|
275
|
+
"fromMode" "ProjectMode" NOT NULL,
|
|
276
|
+
"toMode" "ProjectMode" NOT NULL,
|
|
277
|
+
"reason" TEXT NOT NULL,
|
|
278
|
+
"changedBy" TEXT NOT NULL,
|
|
279
|
+
"changedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
280
|
+
|
|
281
|
+
CONSTRAINT "project_mode_log_pkey" PRIMARY KEY ("id")
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
-- CreateTable
|
|
285
|
+
CREATE TABLE "spend_ledger" (
|
|
286
|
+
"id" TEXT NOT NULL,
|
|
287
|
+
"projectId" TEXT NOT NULL,
|
|
288
|
+
"qaFixAttemptId" TEXT,
|
|
289
|
+
"vendor" TEXT NOT NULL,
|
|
290
|
+
"eventType" TEXT NOT NULL,
|
|
291
|
+
"costCents" INTEGER NOT NULL,
|
|
292
|
+
"meta" JSONB NOT NULL,
|
|
293
|
+
"occurredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
294
|
+
|
|
295
|
+
CONSTRAINT "spend_ledger_pkey" PRIMARY KEY ("id")
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
-- CreateIndex
|
|
299
|
+
CREATE UNIQUE INDEX "projects_slug_key" ON "projects"("slug");
|
|
300
|
+
|
|
301
|
+
-- CreateIndex
|
|
302
|
+
CREATE UNIQUE INDEX "project_profiles_projectId_key" ON "project_profiles"("projectId");
|
|
303
|
+
|
|
304
|
+
-- CreateIndex
|
|
305
|
+
CREATE INDEX "ingested_docs_projectId_sourcePath_idx" ON "ingested_docs"("projectId", "sourcePath");
|
|
306
|
+
|
|
307
|
+
-- CreateIndex
|
|
308
|
+
CREATE UNIQUE INDEX "ingested_docs_projectId_sourcePath_contentHash_key" ON "ingested_docs"("projectId", "sourcePath", "contentHash");
|
|
309
|
+
|
|
310
|
+
-- CreateIndex
|
|
311
|
+
CREATE INDEX "profile_evolution_log_profileId_appliedAt_idx" ON "profile_evolution_log"("profileId", "appliedAt" DESC);
|
|
312
|
+
|
|
313
|
+
-- CreateIndex
|
|
314
|
+
CREATE INDEX "qa_runs_projectId_startedAt_idx" ON "qa_runs"("projectId", "startedAt" DESC);
|
|
315
|
+
|
|
316
|
+
-- CreateIndex
|
|
317
|
+
CREATE UNIQUE INDEX "raw_signals_qaTicketId_key" ON "raw_signals"("qaTicketId");
|
|
318
|
+
|
|
319
|
+
-- CreateIndex
|
|
320
|
+
CREATE INDEX "raw_signals_qaRunId_idx" ON "raw_signals"("qaRunId");
|
|
321
|
+
|
|
322
|
+
-- CreateIndex
|
|
323
|
+
CREATE INDEX "raw_signals_routeName_capturedAt_idx" ON "raw_signals"("routeName", "capturedAt" DESC);
|
|
324
|
+
|
|
325
|
+
-- CreateIndex
|
|
326
|
+
CREATE INDEX "qa_tickets_projectId_status_idx" ON "qa_tickets"("projectId", "status");
|
|
327
|
+
|
|
328
|
+
-- CreateIndex
|
|
329
|
+
CREATE INDEX "qa_tickets_projectId_finalBucket_idx" ON "qa_tickets"("projectId", "finalBucket");
|
|
330
|
+
|
|
331
|
+
-- CreateIndex
|
|
332
|
+
CREATE INDEX "qa_tickets_projectId_createdAt_idx" ON "qa_tickets"("projectId", "createdAt" DESC);
|
|
333
|
+
|
|
334
|
+
-- CreateIndex
|
|
335
|
+
CREATE INDEX "qa_fix_attempts_qaTicketId_attemptNumber_idx" ON "qa_fix_attempts"("qaTicketId", "attemptNumber");
|
|
336
|
+
|
|
337
|
+
-- CreateIndex
|
|
338
|
+
CREATE INDEX "qa_fix_attempts_projectId_attemptedAt_idx" ON "qa_fix_attempts"("projectId", "attemptedAt" DESC);
|
|
339
|
+
|
|
340
|
+
-- CreateIndex
|
|
341
|
+
CREATE UNIQUE INDEX "classification_trust_projectId_classification_surface_key" ON "classification_trust"("projectId", "classification", "surface");
|
|
342
|
+
|
|
343
|
+
-- CreateIndex
|
|
344
|
+
CREATE INDEX "rag_corpus_projectId_classification_surface_idx" ON "rag_corpus"("projectId", "classification", "surface");
|
|
345
|
+
|
|
346
|
+
-- CreateIndex
|
|
347
|
+
CREATE INDEX "audit_artifacts_qaTicketId_idx" ON "audit_artifacts"("qaTicketId");
|
|
348
|
+
|
|
349
|
+
-- CreateIndex
|
|
350
|
+
CREATE INDEX "audit_artifacts_projectId_capturedAt_idx" ON "audit_artifacts"("projectId", "capturedAt" DESC);
|
|
351
|
+
|
|
352
|
+
-- CreateIndex
|
|
353
|
+
CREATE INDEX "policies_projectId_idx" ON "policies"("projectId");
|
|
354
|
+
|
|
355
|
+
-- CreateIndex
|
|
356
|
+
CREATE INDEX "project_mode_log_projectId_changedAt_idx" ON "project_mode_log"("projectId", "changedAt" DESC);
|
|
357
|
+
|
|
358
|
+
-- CreateIndex
|
|
359
|
+
CREATE INDEX "spend_ledger_projectId_occurredAt_idx" ON "spend_ledger"("projectId", "occurredAt" DESC);
|
|
360
|
+
|
|
361
|
+
-- CreateIndex
|
|
362
|
+
CREATE INDEX "spend_ledger_projectId_vendor_occurredAt_idx" ON "spend_ledger"("projectId", "vendor", "occurredAt");
|
|
363
|
+
|
|
364
|
+
-- AddForeignKey
|
|
365
|
+
ALTER TABLE "project_profiles" ADD CONSTRAINT "project_profiles_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
366
|
+
|
|
367
|
+
-- AddForeignKey
|
|
368
|
+
ALTER TABLE "profile_evolution_log" ADD CONSTRAINT "profile_evolution_log_profileId_fkey" FOREIGN KEY ("profileId") REFERENCES "project_profiles"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
369
|
+
|
|
370
|
+
-- AddForeignKey
|
|
371
|
+
ALTER TABLE "qa_runs" ADD CONSTRAINT "qa_runs_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
372
|
+
|
|
373
|
+
-- AddForeignKey
|
|
374
|
+
ALTER TABLE "raw_signals" ADD CONSTRAINT "raw_signals_qaRunId_fkey" FOREIGN KEY ("qaRunId") REFERENCES "qa_runs"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
375
|
+
|
|
376
|
+
-- AddForeignKey
|
|
377
|
+
ALTER TABLE "raw_signals" ADD CONSTRAINT "raw_signals_qaTicketId_fkey" FOREIGN KEY ("qaTicketId") REFERENCES "qa_tickets"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
378
|
+
|
|
379
|
+
-- AddForeignKey
|
|
380
|
+
ALTER TABLE "qa_tickets" ADD CONSTRAINT "qa_tickets_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
381
|
+
|
|
382
|
+
-- AddForeignKey
|
|
383
|
+
ALTER TABLE "qa_tickets" ADD CONSTRAINT "qa_tickets_qaRunId_fkey" FOREIGN KEY ("qaRunId") REFERENCES "qa_runs"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
384
|
+
|
|
385
|
+
-- AddForeignKey
|
|
386
|
+
ALTER TABLE "qa_fix_attempts" ADD CONSTRAINT "qa_fix_attempts_qaTicketId_fkey" FOREIGN KEY ("qaTicketId") REFERENCES "qa_tickets"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
387
|
+
|
|
388
|
+
-- AddForeignKey
|
|
389
|
+
ALTER TABLE "qa_fix_attempts" ADD CONSTRAINT "qa_fix_attempts_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
390
|
+
|
|
391
|
+
-- AddForeignKey
|
|
392
|
+
ALTER TABLE "classification_trust" ADD CONSTRAINT "classification_trust_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
393
|
+
|
|
394
|
+
-- AddForeignKey
|
|
395
|
+
ALTER TABLE "audit_artifacts" ADD CONSTRAINT "audit_artifacts_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
396
|
+
|
|
397
|
+
-- AddForeignKey
|
|
398
|
+
ALTER TABLE "audit_artifacts" ADD CONSTRAINT "audit_artifacts_qaTicketId_fkey" FOREIGN KEY ("qaTicketId") REFERENCES "qa_tickets"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
399
|
+
|
|
400
|
+
-- AddForeignKey
|
|
401
|
+
ALTER TABLE "audit_artifacts" ADD CONSTRAINT "audit_artifacts_qaFixAttemptId_fkey" FOREIGN KEY ("qaFixAttemptId") REFERENCES "qa_fix_attempts"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
402
|
+
|
|
403
|
+
-- AddForeignKey
|
|
404
|
+
ALTER TABLE "policies" ADD CONSTRAINT "policies_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
405
|
+
|
|
406
|
+
-- AddForeignKey
|
|
407
|
+
ALTER TABLE "project_mode_log" ADD CONSTRAINT "project_mode_log_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Sprint 10 Phase 2 (QAP-105) — Visual regression baselines.
|
|
2
|
+
--
|
|
3
|
+
-- Stores durable baseline screenshots that the visual-regression scanner
|
|
4
|
+
-- pixel-diffs against. One row per (projectId, scopeKey) — operator
|
|
5
|
+
-- approves a new baseline by replacing the bytes via
|
|
6
|
+
-- VisualBaselineStore.setBaseline.
|
|
7
|
+
--
|
|
8
|
+
-- Idempotent (IF NOT EXISTS) — safe to re-run on environments where the
|
|
9
|
+
-- table or index already exists.
|
|
10
|
+
|
|
11
|
+
CREATE TABLE IF NOT EXISTS "derwin"."visual_baselines" (
|
|
12
|
+
"id" TEXT NOT NULL,
|
|
13
|
+
"projectId" TEXT NOT NULL,
|
|
14
|
+
"scopeKey" TEXT NOT NULL,
|
|
15
|
+
"bytes" BYTEA NOT NULL,
|
|
16
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
17
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
18
|
+
CONSTRAINT "visual_baselines_pkey" PRIMARY KEY ("id")
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "visual_baselines_projectId_scopeKey_key"
|
|
22
|
+
ON "derwin"."visual_baselines"("projectId", "scopeKey");
|
|
23
|
+
|
|
24
|
+
ALTER TABLE "derwin"."visual_baselines"
|
|
25
|
+
ADD CONSTRAINT "visual_baselines_projectId_fkey"
|
|
26
|
+
FOREIGN KEY ("projectId") REFERENCES "derwin"."projects"("id")
|
|
27
|
+
ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Sprint 10 Phase 3 (QAP-103) — API contract baselines.
|
|
2
|
+
--
|
|
3
|
+
-- Stores durable baseline spec text (OpenAPI / JSON Schema) that the
|
|
4
|
+
-- contract differ compares candidate specs against. One row per
|
|
5
|
+
-- (projectId, specKey) — operator approves a new baseline by replacing
|
|
6
|
+
-- the spec via ContractBaselineStore.setBaseline. Multiple specKeys
|
|
7
|
+
-- per project are allowed ('main-api', 'webhook-payloads', etc.).
|
|
8
|
+
--
|
|
9
|
+
-- Idempotent (IF NOT EXISTS) — safe to re-run on environments where the
|
|
10
|
+
-- table or index already exists.
|
|
11
|
+
|
|
12
|
+
CREATE TABLE IF NOT EXISTS "derwin"."contract_baselines" (
|
|
13
|
+
"id" TEXT NOT NULL,
|
|
14
|
+
"projectId" TEXT NOT NULL,
|
|
15
|
+
"specKey" TEXT NOT NULL,
|
|
16
|
+
"spec" TEXT NOT NULL,
|
|
17
|
+
"format" TEXT NOT NULL,
|
|
18
|
+
"capturedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
19
|
+
"capturedBy" TEXT NOT NULL,
|
|
20
|
+
CONSTRAINT "contract_baselines_pkey" PRIMARY KEY ("id")
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "contract_baselines_projectId_specKey_key"
|
|
24
|
+
ON "derwin"."contract_baselines"("projectId", "specKey");
|
|
25
|
+
|
|
26
|
+
CREATE INDEX IF NOT EXISTS "contract_baselines_projectId_capturedAt_idx"
|
|
27
|
+
ON "derwin"."contract_baselines"("projectId", "capturedAt" DESC);
|
|
28
|
+
|
|
29
|
+
ALTER TABLE "derwin"."contract_baselines"
|
|
30
|
+
ADD CONSTRAINT "contract_baselines_projectId_fkey"
|
|
31
|
+
FOREIGN KEY ("projectId") REFERENCES "derwin"."projects"("id")
|
|
32
|
+
ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Sprint 10 Phase 4 (QAP-104) — Tenant-isolation fuzz configuration.
|
|
2
|
+
--
|
|
3
|
+
-- Stores the operator-curated fuzz configuration consumed by the
|
|
4
|
+
-- cross-tenant probing fuzzer (TenantFuzz). One row per project — the
|
|
5
|
+
-- fuzzer reads `consentToFuzz`, `tenantSafeRoutes` and `probePairs` at
|
|
6
|
+
-- run time. The store-side gate prevents probePairs from being persisted
|
|
7
|
+
-- unless consentToFuzz=true; the fuzzer itself re-checks consent for
|
|
8
|
+
-- defense-in-depth against stale config objects.
|
|
9
|
+
--
|
|
10
|
+
-- `tenantSafeRoutes` and `probePairs` are JSONB columns — the route shape
|
|
11
|
+
-- (method/path/body templates) and pair shape (token/resourceId/label)
|
|
12
|
+
-- are validated at the SDK boundary on every read/write.
|
|
13
|
+
--
|
|
14
|
+
-- Idempotent (IF NOT EXISTS) — safe to re-run on environments where the
|
|
15
|
+
-- table or index already exists.
|
|
16
|
+
|
|
17
|
+
CREATE TABLE IF NOT EXISTS "derwin"."tenant_fuzz_configs" (
|
|
18
|
+
"id" TEXT NOT NULL,
|
|
19
|
+
"projectId" TEXT NOT NULL,
|
|
20
|
+
"consentToFuzz" BOOLEAN NOT NULL DEFAULT false,
|
|
21
|
+
"tenantSafeRoutes" JSONB NOT NULL,
|
|
22
|
+
"probePairs" JSONB NOT NULL,
|
|
23
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
24
|
+
"updatedBy" TEXT NOT NULL,
|
|
25
|
+
CONSTRAINT "tenant_fuzz_configs_pkey" PRIMARY KEY ("id")
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "tenant_fuzz_configs_projectId_key"
|
|
29
|
+
ON "derwin"."tenant_fuzz_configs"("projectId");
|
|
30
|
+
|
|
31
|
+
ALTER TABLE "derwin"."tenant_fuzz_configs"
|
|
32
|
+
ADD CONSTRAINT "tenant_fuzz_configs_projectId_fkey"
|
|
33
|
+
FOREIGN KEY ("projectId") REFERENCES "derwin"."projects"("id")
|
|
34
|
+
ON DELETE CASCADE ON UPDATE CASCADE;
|
package/prisma/schema.prisma
CHANGED
|
@@ -148,6 +148,9 @@ model Project {
|
|
|
148
148
|
classificationOverrides ClassificationOverride[]
|
|
149
149
|
freezeWindows FreezeWindow[]
|
|
150
150
|
killSwitches KillSwitchState[]
|
|
151
|
+
visualBaselines VisualBaseline[]
|
|
152
|
+
contractBaselines ContractBaseline[]
|
|
153
|
+
tenantFuzzConfig TenantFuzzConfig?
|
|
151
154
|
|
|
152
155
|
@@map("projects")
|
|
153
156
|
@@schema("derwin")
|
|
@@ -982,3 +985,107 @@ enum QAUniformityStatus {
|
|
|
982
985
|
|
|
983
986
|
@@schema("derwin")
|
|
984
987
|
}
|
|
988
|
+
|
|
989
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
990
|
+
// QAP-105 (Sprint 10 Phase 2) — Visual baselines (pixel-diff regression)
|
|
991
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
992
|
+
//
|
|
993
|
+
// Stores the durable baseline screenshot bytes that VisualRegressionScanner
|
|
994
|
+
// pixel-diffs against on subsequent runs. One row per (projectId, scopeKey)
|
|
995
|
+
// — operator approves a new baseline by replacing the bytes via
|
|
996
|
+
// VisualBaselineStore.setBaseline. The Prisma-backed implementation lives
|
|
997
|
+
// at packages/db/src/visual-baseline-store.ts; the SDK contract is in
|
|
998
|
+
// @derwinjs/sdk (VisualBaselineStore in
|
|
999
|
+
// packages/sdk/src/types/visual-regression-scanner.ts).
|
|
1000
|
+
//
|
|
1001
|
+
// Stored as Postgres BYTEA so a small to mid-sized PNG fits inline. Rows
|
|
1002
|
+
// large enough to push past Postgres TOAST threshold get TOAST'd
|
|
1003
|
+
// transparently — no special handling required at this layer.
|
|
1004
|
+
|
|
1005
|
+
model VisualBaseline {
|
|
1006
|
+
id String @id @default(cuid())
|
|
1007
|
+
projectId String
|
|
1008
|
+
scopeKey String
|
|
1009
|
+
bytes Bytes
|
|
1010
|
+
createdAt DateTime @default(now())
|
|
1011
|
+
updatedAt DateTime @updatedAt
|
|
1012
|
+
|
|
1013
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1014
|
+
|
|
1015
|
+
@@unique([projectId, scopeKey])
|
|
1016
|
+
@@map("visual_baselines")
|
|
1017
|
+
@@schema("derwin")
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1021
|
+
// QAP-103 (Sprint 10 Phase 3) — Contract baselines (API contract diff)
|
|
1022
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1023
|
+
//
|
|
1024
|
+
// Stores the durable baseline OpenAPI / JSON-schema spec text that
|
|
1025
|
+
// ContractDiffer diffs candidates against on subsequent runs. One row per
|
|
1026
|
+
// (projectId, specKey) — operator approves a new baseline by replacing the
|
|
1027
|
+
// spec via ContractBaselineStore.setBaseline. Multiple specKeys are
|
|
1028
|
+
// allowed per project ('main-api', 'webhook-payloads', etc.).
|
|
1029
|
+
//
|
|
1030
|
+
// The Prisma-backed implementation lives at
|
|
1031
|
+
// packages/db/src/contract-baseline-store.ts; the SDK contract is in
|
|
1032
|
+
// @derwinjs/sdk (ContractBaselineStore in
|
|
1033
|
+
// packages/sdk/src/types/contract-baseline-store.ts).
|
|
1034
|
+
//
|
|
1035
|
+
// `format` is held as a String so adding new formats (proto, GraphQL SDL)
|
|
1036
|
+
// later does not require a migration. The factory validates the value
|
|
1037
|
+
// against the SDK union ('openapi' | 'json-schema') at runtime.
|
|
1038
|
+
|
|
1039
|
+
model ContractBaseline {
|
|
1040
|
+
id String @id @default(cuid())
|
|
1041
|
+
projectId String
|
|
1042
|
+
specKey String
|
|
1043
|
+
spec String @db.Text
|
|
1044
|
+
format String // 'openapi' | 'json-schema' — runtime-validated
|
|
1045
|
+
capturedAt DateTime @default(now())
|
|
1046
|
+
capturedBy String
|
|
1047
|
+
|
|
1048
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1049
|
+
|
|
1050
|
+
@@unique([projectId, specKey])
|
|
1051
|
+
@@index([projectId, capturedAt(sort: Desc)])
|
|
1052
|
+
@@map("contract_baselines")
|
|
1053
|
+
@@schema("derwin")
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1057
|
+
// QAP-104 (Sprint 10 Phase 4) — Tenant-isolation fuzz config
|
|
1058
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1059
|
+
//
|
|
1060
|
+
// Stores the operator-curated fuzz configuration that drives the
|
|
1061
|
+
// cross-tenant probing fuzzer (TenantFuzz). One row per project
|
|
1062
|
+
// (@unique projectId) — the fuzzer reads consentToFuzz, tenantSafeRoutes
|
|
1063
|
+
// and probePairs at run time. The store-side gate prevents probePairs
|
|
1064
|
+
// from being persisted unless consentToFuzz=true; the fuzzer itself
|
|
1065
|
+
// re-checks consent for defense-in-depth against stale config objects.
|
|
1066
|
+
//
|
|
1067
|
+
// The Prisma-backed implementation lives at
|
|
1068
|
+
// packages/db/src/tenant-fuzz-config-store.ts; the SDK contract is in
|
|
1069
|
+
// @derwinjs/sdk (TenantFuzzConfigStore in
|
|
1070
|
+
// packages/sdk/src/types/tenant-fuzz-config.ts).
|
|
1071
|
+
//
|
|
1072
|
+
// `tenantSafeRoutes` and `probePairs` are JSON columns — the route shape
|
|
1073
|
+
// (method/path/body templates) and pair shape (token/resourceId/label)
|
|
1074
|
+
// are runtime-validated at the SDK boundary on every read/write rather
|
|
1075
|
+
// than carved into the schema. This keeps the schema simple and lets new
|
|
1076
|
+
// optional fields land without migrations.
|
|
1077
|
+
|
|
1078
|
+
model TenantFuzzConfig {
|
|
1079
|
+
id String @id @default(cuid())
|
|
1080
|
+
projectId String @unique
|
|
1081
|
+
consentToFuzz Boolean @default(false)
|
|
1082
|
+
tenantSafeRoutes Json // TenantFuzzRoute[]
|
|
1083
|
+
probePairs Json // TenantFuzzPair[]
|
|
1084
|
+
updatedAt DateTime @updatedAt
|
|
1085
|
+
updatedBy String
|
|
1086
|
+
|
|
1087
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1088
|
+
|
|
1089
|
+
@@map("tenant_fuzz_configs")
|
|
1090
|
+
@@schema("derwin")
|
|
1091
|
+
}
|