@derwinjs/db 0.5.0 → 0.7.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.
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Default DriftDetector — QAP-Sprint7 Phase 6 / QAP-077.
3
+ *
4
+ * Stock implementation of the SDK DriftDetector contract
5
+ * (packages/sdk/src/types/drift-detector.ts). Compares per-(classification,
6
+ * surface) success rates over a recent CURRENT window against a longer
7
+ * BASELINE window (the period immediately preceding the current window) and
8
+ * emits a DriftAlarm[] for tuples whose current rate is materially worse
9
+ * than baseline.
10
+ *
11
+ * Window semantics:
12
+ * t0 = now
13
+ * currentStart = t0 - currentWindowDays
14
+ * baselineStart = currentStart - baselineWindowDays
15
+ *
16
+ * currentWindow = [currentStart, t0)
17
+ * baselineWindow = [baselineStart, currentStart)
18
+ *
19
+ * The two windows are NON-overlapping by construction so an attempt counts in
20
+ * exactly one window; the comparison is genuinely "recent vs prior" rather
21
+ * than "recent vs trailing-30-day-including-this-week".
22
+ *
23
+ * Sample selection mirrors LearningHealthReporter (Sprint 2 Group D-3):
24
+ * - dispatchStatus IN ('AUTO_MERGED', 'HUMAN_MERGED') — Lifeline's MERGED
25
+ * under Option β
26
+ * - mergedAt within the window
27
+ * - fixSuccessScore not null — only attempts that have been scored count
28
+ * toward the success rate; pending-outcome attempts are excluded from
29
+ * both numerator and denominator (otherwise a brand-new merge with no
30
+ * score yet would be miscounted as a failure).
31
+ *
32
+ * Success classification:
33
+ * fixSuccessScore > 0 → success (Layer F scoring tiers: +0.2 / +0.5 / +1.0)
34
+ * fixSuccessScore <= 0 → failure (-1.0 / -0.5 / 0.0)
35
+ *
36
+ * classification + surface live on QATicket, not QAFixAttempt, so the query
37
+ * pulls them via the `ticket` relation in a single findMany then aggregates
38
+ * in-memory. For Sprint 7 cron usage this is fine (tens to low-hundreds of
39
+ * MERGED attempts per project per 37-day span); a future scale-out could
40
+ * push the grouping into a raw SQL aggregate over the join.
41
+ *
42
+ * Failure semantics: throws DriftDetectorError('invalid_input') on malformed
43
+ * input (negative window, empty projectId). Empty projects return [].
44
+ *
45
+ * Tenant isolation: projectId flows directly into the Prisma `where` clause,
46
+ * matching the rest of Layer F.
47
+ */
48
+ import type { PrismaClient } from './prisma.js';
49
+ import { type DriftDetector } from '@derwinjs/sdk';
50
+ export interface PrismaDriftDetectorConfig {
51
+ /** Generated Prisma client. Pass an instance per process. */
52
+ prisma: PrismaClient;
53
+ }
54
+ /**
55
+ * Build a DriftDetector backed by Prisma over QAFixAttempt + QATicket.
56
+ *
57
+ * The returned `scan` is intended to be invoked from a periodic job
58
+ * (mirroring OutcomeRecorder + TrustScoreUpdater from QAP-075). Sprint 8
59
+ * may expose `GET /qa/drift-alarms` if operator-facing UI needs it; the
60
+ * scan itself stays cron-callable independent of an HTTP route.
61
+ */
62
+ export declare function createPrismaDriftDetector(config: PrismaDriftDetectorConfig): DriftDetector;
63
+ //# sourceMappingURL=drift-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.d.ts","sourceRoot":"","sources":["../src/drift-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,yBAAyB;IACxC,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AAYD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,GAAG,aAAa,CA6G1F"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-detector.js","sourceRoot":"","sources":["../src/drift-detector.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -23,5 +23,7 @@ export { createPrismaQAUniformityStore, type PrismaQAUniformityStoreConfig, } fr
23
23
  export { createPrismaAgentFindingsIngestor, type PrismaAgentFindingsIngestorConfig, } from './agent-findings-ingestor.js';
24
24
  export { createPrismaLearningHealthReporter, type PrismaLearningHealthReporterConfig, } from './learning-health-reporter.js';
25
25
  export { createPrismaCoverageGapReporter, type PrismaCoverageGapReporterConfig, } from './coverage-gap-reporter.js';
26
+ export { createPrismaRegressionDetector, type PrismaRegressionDetectorConfig, } from './regression-detector.js';
27
+ export { createPrismaDriftDetector, type PrismaDriftDetectorConfig } from './drift-detector.js';
26
28
  export * from './prisma.js';
27
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,KAAK,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,EAClC,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AA4BpC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,KAAK,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,EAClC,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,KAAK,8BAA8B,GACpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AA4BhG,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -24,6 +24,8 @@ export { createPrismaQAUniformityStore, } from './qa-uniformity-store.js';
24
24
  export { createPrismaAgentFindingsIngestor, } from './agent-findings-ingestor.js';
25
25
  export { createPrismaLearningHealthReporter, } from './learning-health-reporter.js';
26
26
  export { createPrismaCoverageGapReporter, } from './coverage-gap-reporter.js';
27
+ export { createPrismaRegressionDetector, } from './regression-detector.js';
28
+ export { createPrismaDriftDetector } from './drift-detector.js';
27
29
  // ─── Prisma client re-export ─────────────────────────────────────────────
28
30
  //
29
31
  // @derwinjs/db ships its OWN generated Prisma client (output: prisma-client/
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,cAAuB,CAAC;AAEpD,4EAA4E;AAE5E,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAmC,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,GAElC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,GAEnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,GAEhC,MAAM,4BAA4B,CAAC;AAEpC,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,sEAAsE;AACtE,wEAAwE;AACxE,wEAAwE;AACxE,gDAAgD;AAChD,EAAE;AACF,+DAA+D;AAC/D,0EAA0E;AAC1E,yCAAyC;AACzC,+EAA+E;AAC/E,yCAAyC;AACzC,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,+BAA+B;AAC/B,EAAE;AACF,oBAAoB;AACpB,8DAA8D;AAC9D,4CAA4C;AAC5C,qEAAqE;AACrE,QAAQ;AACR,gDAAgD;AAEhD,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,cAAuB,CAAC;AAEpD,4EAA4E;AAE5E,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAmC,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,GAElC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,GAEnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,GAEhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,GAE/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAkC,MAAM,qBAAqB,CAAC;AAEhG,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,sEAAsE;AACtE,wEAAwE;AACxE,wEAAwE;AACxE,gDAAgD;AAChD,EAAE;AACF,+DAA+D;AAC/D,0EAA0E;AAC1E,yCAAyC;AACzC,+EAA+E;AAC/E,yCAAyC;AACzC,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,+BAA+B;AAC/B,EAAE;AACF,oBAAoB;AACpB,8DAA8D;AAC9D,4CAA4C;AAC5C,qEAAqE;AACrE,QAAQ;AACR,gDAAgD;AAEhD,cAAc,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rag-retriever.d.ts","sourceRoot":"","sources":["../src/rag-retriever.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AASvB,MAAM,WAAW,wBAAwB;IACvC,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AAiBD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,YAAY,CAuGvF"}
1
+ {"version":3,"file":"rag-retriever.d.ts","sourceRoot":"","sources":["../src/rag-retriever.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAGL,KAAK,YAAY,EAIlB,MAAM,eAAe,CAAC;AASvB,MAAM,WAAW,wBAAwB;IACvC,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AAiBD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,wBAAwB,GAAG,YAAY,CAmIvF"}
@@ -122,6 +122,30 @@ export function createPrismaRAGRetriever(config) {
122
122
  }
123
123
  return { id };
124
124
  },
125
+ async updateOutcomeQuality(input) {
126
+ validateUpdateOutcomeQualityInput(input);
127
+ // Pattern D — tenant isolation. The WHERE clause scopes by both
128
+ // projectId AND fixAttemptId so a Sprint 7 Phase 5 update cannot
129
+ // bleed across tenants even if the caller mis-routes a fixAttemptId.
130
+ // Cross-tenant or missing-row → updateMany returns count=0; surface
131
+ // that as `{ updated: 0 }` per the contract (no throw).
132
+ //
133
+ // We deliberately use the typed `updateMany` (not raw SQL) because:
134
+ // (a) the `embedding` column is Unsupported but we're not touching
135
+ // it — we only set `outcomeQuality` (Float, fully typed); and
136
+ // (b) `updateMany` returns the affected-row count, which we need to
137
+ // hand back to the orchestrator for the audit trail.
138
+ const result = await prisma.rAGCorpus.updateMany({
139
+ where: {
140
+ projectId: input.projectId,
141
+ fixAttemptId: input.fixAttemptId,
142
+ },
143
+ data: {
144
+ outcomeQuality: input.outcomeQuality,
145
+ },
146
+ });
147
+ return { updated: result.count };
148
+ },
125
149
  };
126
150
  }
127
151
  // ─── Helpers ─────────────────────────────────────────────────────────────
@@ -147,6 +171,20 @@ function validateFindSimilarInput(input) {
147
171
  throw new RAGRetrieverError('invalid_embedding_length', `queryEmbedding must be ${String(EMBEDDING_DIM)}-dim, got ${actual}`);
148
172
  }
149
173
  }
174
+ function validateUpdateOutcomeQualityInput(input) {
175
+ if (typeof input.projectId !== 'string' || !input.projectId.trim()) {
176
+ throw new RAGRetrieverError('invalid_input', 'projectId is required');
177
+ }
178
+ if (typeof input.fixAttemptId !== 'string' || !input.fixAttemptId.trim()) {
179
+ throw new RAGRetrieverError('invalid_input', 'fixAttemptId is required');
180
+ }
181
+ if (typeof input.outcomeQuality !== 'number' ||
182
+ Number.isNaN(input.outcomeQuality) ||
183
+ input.outcomeQuality < 0 ||
184
+ input.outcomeQuality > 1) {
185
+ throw new RAGRetrieverError('invalid_input', 'outcomeQuality must be in [0, 1]');
186
+ }
187
+ }
150
188
  function validatePersistInput(input) {
151
189
  if (typeof input.projectId !== 'string' || !input.projectId.trim()) {
152
190
  throw new RAGRetrieverError('invalid_input', 'projectId is required');
@@ -1 +1 @@
1
- {"version":3,"file":"rag-retriever.js","sourceRoot":"","sources":["../src/rag-retriever.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rag-retriever.js","sourceRoot":"","sources":["../src/rag-retriever.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Default RegressionDetector — QAP-Sprint7 Phase 3 / QAP-071.
3
+ *
4
+ * Stock implementation of the SDK RegressionDetector callback type
5
+ * (packages/sdk/src/types/regression-detector.ts). Wires `QATicketStore.listQATickets`
6
+ * with (classification, surface, ageHours, status) filters to find newly-opened
7
+ * tickets matching the original ticket's classification + surface within
8
+ * `withinDays` of `sinceMergedAt`. Returns true iff at least one such ticket
9
+ * exists (excluding the original ticket itself).
10
+ *
11
+ * Why a callback factory in @derwinjs/db rather than a stateful adapter:
12
+ * The RegressionDetector contract is intentionally a function type — not
13
+ * every consumer reads QA tickets to decide regression. A telemetry-driven
14
+ * Datadog/OpenTelemetry impl would query metrics instead. This file provides
15
+ * the *default* QATicketStore-backed callback that runPostVerify wires when
16
+ * the consumer opts into Derwin's standard regression-detection rule.
17
+ *
18
+ * Tenant isolation: the projectId argument from the callback flows directly
19
+ * into ticketStore.getQATicket and ticketStore.listQATickets, both of which
20
+ * are tenant-scoped per QAP-018B. No cross-project leakage is possible at
21
+ * this layer.
22
+ *
23
+ * Failure semantics: the callback never throws. Defense-in-depth — if the
24
+ * original ticket cannot be resolved (missing or cross-tenant), return false
25
+ * (no original means no regression context). This mirrors the orchestrator's
26
+ * "regression detection MUST NOT abort the post-verify path" rule. The
27
+ * upstream caller (runPostVerify) additionally wraps the call in try/catch
28
+ * for the same defensive posture.
29
+ */
30
+ import type { QATicketStore, RegressionDetector } from '@derwinjs/sdk';
31
+ export interface PrismaRegressionDetectorConfig {
32
+ /**
33
+ * QATicketStore instance — the same instance the rest of the platform uses,
34
+ * so the lookups respect the same tenant scope and DB connection pool.
35
+ */
36
+ ticketStore: QATicketStore;
37
+ }
38
+ /**
39
+ * Build a RegressionDetector backed by QATicketStore.listQATickets.
40
+ *
41
+ * The returned callback is invoked by runPostVerify when post-verify reports
42
+ * failure signals after a merge — see packages/core/src/orchestrator/run-post-verify.ts.
43
+ */
44
+ export declare function createPrismaRegressionDetector(config: PrismaRegressionDetectorConfig): RegressionDetector;
45
+ //# sourceMappingURL=regression-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression-detector.d.ts","sourceRoot":"","sources":["../src/regression-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIvE,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,WAAW,EAAE,aAAa,CAAC;CAC5B;AAQD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,GACrC,kBAAkB,CAyCpB"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Default RegressionDetector — QAP-Sprint7 Phase 3 / QAP-071.
3
+ *
4
+ * Stock implementation of the SDK RegressionDetector callback type
5
+ * (packages/sdk/src/types/regression-detector.ts). Wires `QATicketStore.listQATickets`
6
+ * with (classification, surface, ageHours, status) filters to find newly-opened
7
+ * tickets matching the original ticket's classification + surface within
8
+ * `withinDays` of `sinceMergedAt`. Returns true iff at least one such ticket
9
+ * exists (excluding the original ticket itself).
10
+ *
11
+ * Why a callback factory in @derwinjs/db rather than a stateful adapter:
12
+ * The RegressionDetector contract is intentionally a function type — not
13
+ * every consumer reads QA tickets to decide regression. A telemetry-driven
14
+ * Datadog/OpenTelemetry impl would query metrics instead. This file provides
15
+ * the *default* QATicketStore-backed callback that runPostVerify wires when
16
+ * the consumer opts into Derwin's standard regression-detection rule.
17
+ *
18
+ * Tenant isolation: the projectId argument from the callback flows directly
19
+ * into ticketStore.getQATicket and ticketStore.listQATickets, both of which
20
+ * are tenant-scoped per QAP-018B. No cross-project leakage is possible at
21
+ * this layer.
22
+ *
23
+ * Failure semantics: the callback never throws. Defense-in-depth — if the
24
+ * original ticket cannot be resolved (missing or cross-tenant), return false
25
+ * (no original means no regression context). This mirrors the orchestrator's
26
+ * "regression detection MUST NOT abort the post-verify path" rule. The
27
+ * upstream caller (runPostVerify) additionally wraps the call in try/catch
28
+ * for the same defensive posture.
29
+ */
30
+ // ─── Constants ────────────────────────────────────────────────────────────
31
+ const HOURS_PER_DAY = 24;
32
+ // ─── Factory ─────────────────────────────────────────────────────────────
33
+ /**
34
+ * Build a RegressionDetector backed by QATicketStore.listQATickets.
35
+ *
36
+ * The returned callback is invoked by runPostVerify when post-verify reports
37
+ * failure signals after a merge — see packages/core/src/orchestrator/run-post-verify.ts.
38
+ */
39
+ export function createPrismaRegressionDetector(config) {
40
+ const { ticketStore } = config;
41
+ return async ({ projectId, qaTicketId, sinceMergedAt, withinDays }) => {
42
+ // (1) Fetch the original ticket. Both not-found and cross-tenant
43
+ // collisions return null per the QATicketStore contract — either way,
44
+ // returning false here is the correct defensive answer (no original →
45
+ // no regression context to evaluate).
46
+ const original = await ticketStore.getQATicket({ id: qaTicketId, projectId });
47
+ if (original === null) {
48
+ return false;
49
+ }
50
+ // (2) List candidate regression tickets via the store's existing filter
51
+ // shape. We narrow on (classification, surface) to scope to the same
52
+ // failure family, on ageHoursMax = withinDays * 24 to bound the search
53
+ // window, and on status: 'OPEN' so already-resolved historical tickets
54
+ // don't generate false positives. ageHoursMin: 0 is the floor.
55
+ const candidates = await ticketStore.listQATickets({
56
+ projectId,
57
+ classification: original.classification,
58
+ surface: original.surface,
59
+ ageHoursMin: 0,
60
+ ageHoursMax: withinDays * HOURS_PER_DAY,
61
+ status: 'OPEN',
62
+ });
63
+ // (3) Paranoia filter — listQATickets uses age (relative to "now"), not
64
+ // an absolute timestamp, and the original's age might place IT inside
65
+ // the window too. We exclude (a) tickets created at or before the merge
66
+ // moment and (b) the original ticket itself. The combination means:
67
+ // only tickets opened strictly AFTER the merge that are NOT the original
68
+ // count as regressions.
69
+ const mergedAtMs = sinceMergedAt.getTime();
70
+ const matches = candidates.tickets.filter((t) => {
71
+ if (t.id === qaTicketId)
72
+ return false;
73
+ return t.createdAt.getTime() > mergedAtMs;
74
+ });
75
+ return matches.length > 0;
76
+ };
77
+ }
78
+ //# sourceMappingURL=regression-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression-detector.js","sourceRoot":"","sources":["../src/regression-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAcH,6EAA6E;AAE7E,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB,4EAA4E;AAE5E;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAsC;IAEtC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAE/B,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,EAAE;QACpE,iEAAiE;QACjE,sEAAsE;QACtE,sEAAsE;QACtE,sCAAsC;QACtC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9E,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wEAAwE;QACxE,qEAAqE;QACrE,uEAAuE;QACvE,uEAAuE;QACvE,+DAA+D;QAC/D,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC;YACjD,SAAS;YACT,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,UAAU,GAAG,aAAa;YACvC,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,wEAAwE;QACxE,sEAAsE;QACtE,wEAAwE;QACxE,oEAAoE;QACpE,yEAAyE;QACzE,wBAAwB;QACxB,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC9C,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU;gBAAE,OAAO,KAAK,CAAC;YACtC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@derwinjs/db",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Prisma schema + migrations for Derwin's own Postgres. 14 models, project-namespaced. Per ADR-0005. Ships its own generated Prisma client (multi-platform binaries) for cross-consumer compatibility.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -33,8 +33,8 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@prisma/client": "^5.22.0",
36
- "@derwinjs/core": "0.5.0",
37
- "@derwinjs/sdk": "0.5.0"
36
+ "@derwinjs/core": "0.7.0",
37
+ "@derwinjs/sdk": "0.7.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@vitest/coverage-v8": "^2.1.9",