@derwinjs/db 0.9.0 → 0.11.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 +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/milestone-event-store.d.ts +35 -0
- package/dist/milestone-event-store.d.ts.map +1 -0
- package/dist/milestone-event-store.js +221 -0
- package/dist/milestone-event-store.js.map +1 -0
- package/dist/rum-sample-store.d.ts +48 -0
- package/dist/rum-sample-store.d.ts.map +1 -0
- package/dist/rum-sample-store.js +155 -0
- package/dist/rum-sample-store.js.map +1 -0
- 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/migrations/20260508000100_sprint11_phase3_rum_samples/migration.sql +31 -0
- package/prisma/migrations/20260508000200_sprint11_phase5_milestone_events/migration.sql +42 -0
- package/prisma/schema.prisma +189 -0
- package/prisma-client/edge.js +63 -4
- package/prisma-client/index-browser.js +60 -1
- package/prisma-client/index.d.ts +10139 -1638
- package/prisma-client/index.js +63 -4
- package/prisma-client/package.json +1 -1
- package/prisma-client/schema.prisma +189 -0
- package/prisma-client/wasm.js +60 -1
|
@@ -148,6 +148,11 @@ model Project {
|
|
|
148
148
|
classificationOverrides ClassificationOverride[]
|
|
149
149
|
freezeWindows FreezeWindow[]
|
|
150
150
|
killSwitches KillSwitchState[]
|
|
151
|
+
visualBaselines VisualBaseline[]
|
|
152
|
+
contractBaselines ContractBaseline[]
|
|
153
|
+
tenantFuzzConfig TenantFuzzConfig?
|
|
154
|
+
rumSamples RumSample[]
|
|
155
|
+
milestoneEvents MilestoneEvent[]
|
|
151
156
|
|
|
152
157
|
@@map("projects")
|
|
153
158
|
@@schema("derwin")
|
|
@@ -982,3 +987,187 @@ enum QAUniformityStatus {
|
|
|
982
987
|
|
|
983
988
|
@@schema("derwin")
|
|
984
989
|
}
|
|
990
|
+
|
|
991
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
992
|
+
// QAP-105 (Sprint 10 Phase 2) — Visual baselines (pixel-diff regression)
|
|
993
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
994
|
+
//
|
|
995
|
+
// Stores the durable baseline screenshot bytes that VisualRegressionScanner
|
|
996
|
+
// pixel-diffs against on subsequent runs. One row per (projectId, scopeKey)
|
|
997
|
+
// — operator approves a new baseline by replacing the bytes via
|
|
998
|
+
// VisualBaselineStore.setBaseline. The Prisma-backed implementation lives
|
|
999
|
+
// at packages/db/src/visual-baseline-store.ts; the SDK contract is in
|
|
1000
|
+
// @derwinjs/sdk (VisualBaselineStore in
|
|
1001
|
+
// packages/sdk/src/types/visual-regression-scanner.ts).
|
|
1002
|
+
//
|
|
1003
|
+
// Stored as Postgres BYTEA so a small to mid-sized PNG fits inline. Rows
|
|
1004
|
+
// large enough to push past Postgres TOAST threshold get TOAST'd
|
|
1005
|
+
// transparently — no special handling required at this layer.
|
|
1006
|
+
|
|
1007
|
+
model VisualBaseline {
|
|
1008
|
+
id String @id @default(cuid())
|
|
1009
|
+
projectId String
|
|
1010
|
+
scopeKey String
|
|
1011
|
+
bytes Bytes
|
|
1012
|
+
createdAt DateTime @default(now())
|
|
1013
|
+
updatedAt DateTime @updatedAt
|
|
1014
|
+
|
|
1015
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1016
|
+
|
|
1017
|
+
@@unique([projectId, scopeKey])
|
|
1018
|
+
@@map("visual_baselines")
|
|
1019
|
+
@@schema("derwin")
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1023
|
+
// QAP-103 (Sprint 10 Phase 3) — Contract baselines (API contract diff)
|
|
1024
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1025
|
+
//
|
|
1026
|
+
// Stores the durable baseline OpenAPI / JSON-schema spec text that
|
|
1027
|
+
// ContractDiffer diffs candidates against on subsequent runs. One row per
|
|
1028
|
+
// (projectId, specKey) — operator approves a new baseline by replacing the
|
|
1029
|
+
// spec via ContractBaselineStore.setBaseline. Multiple specKeys are
|
|
1030
|
+
// allowed per project ('main-api', 'webhook-payloads', etc.).
|
|
1031
|
+
//
|
|
1032
|
+
// The Prisma-backed implementation lives at
|
|
1033
|
+
// packages/db/src/contract-baseline-store.ts; the SDK contract is in
|
|
1034
|
+
// @derwinjs/sdk (ContractBaselineStore in
|
|
1035
|
+
// packages/sdk/src/types/contract-baseline-store.ts).
|
|
1036
|
+
//
|
|
1037
|
+
// `format` is held as a String so adding new formats (proto, GraphQL SDL)
|
|
1038
|
+
// later does not require a migration. The factory validates the value
|
|
1039
|
+
// against the SDK union ('openapi' | 'json-schema') at runtime.
|
|
1040
|
+
|
|
1041
|
+
model ContractBaseline {
|
|
1042
|
+
id String @id @default(cuid())
|
|
1043
|
+
projectId String
|
|
1044
|
+
specKey String
|
|
1045
|
+
spec String @db.Text
|
|
1046
|
+
format String // 'openapi' | 'json-schema' — runtime-validated
|
|
1047
|
+
capturedAt DateTime @default(now())
|
|
1048
|
+
capturedBy String
|
|
1049
|
+
|
|
1050
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1051
|
+
|
|
1052
|
+
@@unique([projectId, specKey])
|
|
1053
|
+
@@index([projectId, capturedAt(sort: Desc)])
|
|
1054
|
+
@@map("contract_baselines")
|
|
1055
|
+
@@schema("derwin")
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1059
|
+
// QAP-104 (Sprint 10 Phase 4) — Tenant-isolation fuzz config
|
|
1060
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1061
|
+
//
|
|
1062
|
+
// Stores the operator-curated fuzz configuration that drives the
|
|
1063
|
+
// cross-tenant probing fuzzer (TenantFuzz). One row per project
|
|
1064
|
+
// (@unique projectId) — the fuzzer reads consentToFuzz, tenantSafeRoutes
|
|
1065
|
+
// and probePairs at run time. The store-side gate prevents probePairs
|
|
1066
|
+
// from being persisted unless consentToFuzz=true; the fuzzer itself
|
|
1067
|
+
// re-checks consent for defense-in-depth against stale config objects.
|
|
1068
|
+
//
|
|
1069
|
+
// The Prisma-backed implementation lives at
|
|
1070
|
+
// packages/db/src/tenant-fuzz-config-store.ts; the SDK contract is in
|
|
1071
|
+
// @derwinjs/sdk (TenantFuzzConfigStore in
|
|
1072
|
+
// packages/sdk/src/types/tenant-fuzz-config.ts).
|
|
1073
|
+
//
|
|
1074
|
+
// `tenantSafeRoutes` and `probePairs` are JSON columns — the route shape
|
|
1075
|
+
// (method/path/body templates) and pair shape (token/resourceId/label)
|
|
1076
|
+
// are runtime-validated at the SDK boundary on every read/write rather
|
|
1077
|
+
// than carved into the schema. This keeps the schema simple and lets new
|
|
1078
|
+
// optional fields land without migrations.
|
|
1079
|
+
|
|
1080
|
+
model TenantFuzzConfig {
|
|
1081
|
+
id String @id @default(cuid())
|
|
1082
|
+
projectId String @unique
|
|
1083
|
+
consentToFuzz Boolean @default(false)
|
|
1084
|
+
tenantSafeRoutes Json // TenantFuzzRoute[]
|
|
1085
|
+
probePairs Json // TenantFuzzPair[]
|
|
1086
|
+
updatedAt DateTime @updatedAt
|
|
1087
|
+
updatedBy String
|
|
1088
|
+
|
|
1089
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1090
|
+
|
|
1091
|
+
@@map("tenant_fuzz_configs")
|
|
1092
|
+
@@schema("derwin")
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1096
|
+
// QAP-113 (Sprint 11 Phase 3) — RUM / Web Vitals samples
|
|
1097
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1098
|
+
//
|
|
1099
|
+
// Stores consumer-pushed Real User Monitoring (RUM) samples emitted by the
|
|
1100
|
+
// consumer app's web-vitals hooks. Unlike Sprint 10/11 scanner surfaces this
|
|
1101
|
+
// is INGESTION — the data is pushed from client devices, not produced by a
|
|
1102
|
+
// Derwin-spawned scanner. One row per individual sample; baseline statistics
|
|
1103
|
+
// (p50/p75/p95) are derived on demand from this row set rather than
|
|
1104
|
+
// maintained as a rolling aggregate.
|
|
1105
|
+
//
|
|
1106
|
+
// The Prisma-backed implementation lives at
|
|
1107
|
+
// packages/db/src/rum-sample-store.ts; the SDK contract is in
|
|
1108
|
+
// @derwinjs/sdk (RumSampleStore in
|
|
1109
|
+
// packages/sdk/src/types/rum-sample-store.ts) and the ingest contract
|
|
1110
|
+
// (WebVitalsIngestor) in packages/sdk/src/types/web-vitals-ingestor.ts.
|
|
1111
|
+
//
|
|
1112
|
+
// `metric` and `rating` are held as String columns rather than Prisma enums
|
|
1113
|
+
// so consumers can emit custom metrics (alongside the canonical
|
|
1114
|
+
// CLS / FCP / INP / LCP / TTFB) without requiring a migration. The factory
|
|
1115
|
+
// validates the value at runtime where it matters.
|
|
1116
|
+
|
|
1117
|
+
model RumSample {
|
|
1118
|
+
id String @id @default(cuid())
|
|
1119
|
+
projectId String
|
|
1120
|
+
metric String // 'CLS' | 'FCP' | 'INP' | 'LCP' | 'TTFB' or custom
|
|
1121
|
+
value Float
|
|
1122
|
+
rating String // 'good' | 'needs-improvement' | 'poor'
|
|
1123
|
+
url String
|
|
1124
|
+
deviceType String?
|
|
1125
|
+
sessionId String?
|
|
1126
|
+
capturedAt DateTime @default(now())
|
|
1127
|
+
|
|
1128
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1129
|
+
|
|
1130
|
+
@@index([projectId, metric, capturedAt(sort: Desc)])
|
|
1131
|
+
@@map("rum_samples")
|
|
1132
|
+
@@schema("derwin")
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1136
|
+
// QAP-115 (Sprint 11 Phase 5) — Cross-product tracking timeline (MilestoneEvent)
|
|
1137
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1138
|
+
//
|
|
1139
|
+
// Foundation for the Tracking Timeline Gantt UI shipped in Sprint 11 Phase 6.
|
|
1140
|
+
// One row per scheduled or in-progress milestone; ranges (releases, freeze
|
|
1141
|
+
// windows) carry both `startsAt` + `endsAt`; point-in-time milestones (demos,
|
|
1142
|
+
// launches) carry only `startsAt`. `kind` is intentionally a free-form String
|
|
1143
|
+
// rather than a Prisma enum so consumers can emit custom kinds (the conflict-
|
|
1144
|
+
// detection helpers in @derwinjs/core treat unknown kinds as "no conflict
|
|
1145
|
+
// computed against this kind" rather than throwing).
|
|
1146
|
+
//
|
|
1147
|
+
// The Prisma-backed implementation lives at
|
|
1148
|
+
// packages/db/src/milestone-event-store.ts; the SDK contract is in
|
|
1149
|
+
// @derwinjs/sdk (MilestoneEventStore in
|
|
1150
|
+
// packages/sdk/src/types/milestone-event-store.ts).
|
|
1151
|
+
//
|
|
1152
|
+
// Indexes mirror the two read paths: chronological per project (for the
|
|
1153
|
+
// Gantt's primary read) and per-kind per project (for swimlane grouping).
|
|
1154
|
+
|
|
1155
|
+
model MilestoneEvent {
|
|
1156
|
+
id String @id @default(cuid())
|
|
1157
|
+
projectId String
|
|
1158
|
+
name String
|
|
1159
|
+
description String? @db.Text
|
|
1160
|
+
startsAt DateTime
|
|
1161
|
+
endsAt DateTime?
|
|
1162
|
+
kind String // 'release' | 'freeze' | 'demo' | 'launch' | custom
|
|
1163
|
+
createdBy String
|
|
1164
|
+
createdAt DateTime @default(now())
|
|
1165
|
+
updatedAt DateTime @updatedAt
|
|
1166
|
+
|
|
1167
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1168
|
+
|
|
1169
|
+
@@index([projectId, startsAt(sort: Asc)])
|
|
1170
|
+
@@index([projectId, kind])
|
|
1171
|
+
@@map("milestone_events")
|
|
1172
|
+
@@schema("derwin")
|
|
1173
|
+
}
|
package/prisma-client/wasm.js
CHANGED
|
@@ -450,6 +450,60 @@ exports.Prisma.QAUniformityScalarFieldEnum = {
|
|
|
450
450
|
createdAt: 'createdAt'
|
|
451
451
|
};
|
|
452
452
|
|
|
453
|
+
exports.Prisma.VisualBaselineScalarFieldEnum = {
|
|
454
|
+
id: 'id',
|
|
455
|
+
projectId: 'projectId',
|
|
456
|
+
scopeKey: 'scopeKey',
|
|
457
|
+
bytes: 'bytes',
|
|
458
|
+
createdAt: 'createdAt',
|
|
459
|
+
updatedAt: 'updatedAt'
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
exports.Prisma.ContractBaselineScalarFieldEnum = {
|
|
463
|
+
id: 'id',
|
|
464
|
+
projectId: 'projectId',
|
|
465
|
+
specKey: 'specKey',
|
|
466
|
+
spec: 'spec',
|
|
467
|
+
format: 'format',
|
|
468
|
+
capturedAt: 'capturedAt',
|
|
469
|
+
capturedBy: 'capturedBy'
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
exports.Prisma.TenantFuzzConfigScalarFieldEnum = {
|
|
473
|
+
id: 'id',
|
|
474
|
+
projectId: 'projectId',
|
|
475
|
+
consentToFuzz: 'consentToFuzz',
|
|
476
|
+
tenantSafeRoutes: 'tenantSafeRoutes',
|
|
477
|
+
probePairs: 'probePairs',
|
|
478
|
+
updatedAt: 'updatedAt',
|
|
479
|
+
updatedBy: 'updatedBy'
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
exports.Prisma.RumSampleScalarFieldEnum = {
|
|
483
|
+
id: 'id',
|
|
484
|
+
projectId: 'projectId',
|
|
485
|
+
metric: 'metric',
|
|
486
|
+
value: 'value',
|
|
487
|
+
rating: 'rating',
|
|
488
|
+
url: 'url',
|
|
489
|
+
deviceType: 'deviceType',
|
|
490
|
+
sessionId: 'sessionId',
|
|
491
|
+
capturedAt: 'capturedAt'
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
exports.Prisma.MilestoneEventScalarFieldEnum = {
|
|
495
|
+
id: 'id',
|
|
496
|
+
projectId: 'projectId',
|
|
497
|
+
name: 'name',
|
|
498
|
+
description: 'description',
|
|
499
|
+
startsAt: 'startsAt',
|
|
500
|
+
endsAt: 'endsAt',
|
|
501
|
+
kind: 'kind',
|
|
502
|
+
createdBy: 'createdBy',
|
|
503
|
+
createdAt: 'createdAt',
|
|
504
|
+
updatedAt: 'updatedAt'
|
|
505
|
+
};
|
|
506
|
+
|
|
453
507
|
exports.Prisma.SortOrder = {
|
|
454
508
|
asc: 'asc',
|
|
455
509
|
desc: 'desc'
|
|
@@ -658,7 +712,12 @@ exports.Prisma.ModelName = {
|
|
|
658
712
|
SpendLedger: 'SpendLedger',
|
|
659
713
|
QAPattern: 'QAPattern',
|
|
660
714
|
QARevert: 'QARevert',
|
|
661
|
-
QAUniformity: 'QAUniformity'
|
|
715
|
+
QAUniformity: 'QAUniformity',
|
|
716
|
+
VisualBaseline: 'VisualBaseline',
|
|
717
|
+
ContractBaseline: 'ContractBaseline',
|
|
718
|
+
TenantFuzzConfig: 'TenantFuzzConfig',
|
|
719
|
+
RumSample: 'RumSample',
|
|
720
|
+
MilestoneEvent: 'MilestoneEvent'
|
|
662
721
|
};
|
|
663
722
|
|
|
664
723
|
/**
|