mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
refactor(db): extract the P2002 predicate into one shared helper
The Prisma unique-constraint (P2002) narrowing predicate had been hand-copied into five call sites. Fold them into a single isP2002 in src/lib/prisma-errors.ts and import it everywhere (the two step-drain sites keep their local isUniqueConstraintViolation name via an import alias). Behaviour-identical; one place to chase a future P2002-semantics change instead of five. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
9c39afa352
commit
ba4349eda0
6 files changed
+29
-51
No files matched your search
@@ -38,6 +38,7 @@
|
||||
* `rollup-full-backfill` boot-time converging-backfill pattern.
|
||||
*/
|
||||
import type { PrismaClient } from "@/generated/prisma/client";
|
||||
import { isP2002 as isUniqueConstraintViolation } from "@/lib/prisma-errors";
|
||||
|
||||
import { dailyStatsExternalId } from "./apple-health-mapping";
|
||||
import {
|
||||
@@ -100,15 +101,6 @@ export interface StepConsolidationSummary {
|
||||
};
|
||||
}
|
||||
|
||||
/** True for a Prisma unique-constraint violation (P2002). */
|
||||
function isUniqueConstraintViolation(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code?: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
|
||||
export interface StepConsolidationOptions {
|
||||
/** Limit the pass to a single user. Default = every user. */
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
* production standalone image strips `tsx`, so this can never be a CLI.
|
||||
*/
|
||||
import type { MeasurementType, PrismaClient } from "@/generated/prisma/client";
|
||||
import { isP2002 as isUniqueConstraintViolation } from "@/lib/prisma-errors";
|
||||
|
||||
import {
|
||||
dailyStatsExternalId,
|
||||
@@ -77,19 +78,6 @@ export const DENSE_INTRADAY_RETENTION_DAYS = 14;
|
||||
/** The daily-stats externalId prefix marks an already-collapsed row. */
|
||||
const DAILY_STATS_PREFIX = "stats:";
|
||||
|
||||
/**
|
||||
* True for a Prisma unique-constraint violation (P2002). Mirrors the
|
||||
* `consolidate-legacy-steps.ts` precedent verbatim so the two drains
|
||||
* classify the same error the same way.
|
||||
*/
|
||||
function isUniqueConstraintViolation(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code?: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
|
||||
export interface DenseIntradayRetentionSummary {
|
||||
dryRun: boolean;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
* unregistered queue silently never drains.
|
||||
*/
|
||||
import { prisma } from "@/lib/db";
|
||||
import { isP2002 } from "@/lib/prisma-errors";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { getGlobalBoss } from "@/lib/jobs/boss-instance";
|
||||
import { DEFAULT_TIMEZONE } from "@/lib/tz/format";
|
||||
@@ -53,16 +54,6 @@ import { recomputeMedicationComplianceForEvent } from "@/lib/rollups/medication-
|
||||
|
||||
export const INTAKE_SLOT_DEDUP_QUEUE = "intake-slot-dedup";
|
||||
|
||||
/** Narrow a thrown Prisma error to the P2002 unique-constraint code. */
|
||||
function isP2002(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serial concurrency — the populator walks a user's intake events and
|
||||
* writes per slot; concurrency-1 keeps it from crowding the request
|
||||
|
||||
@@ -17,21 +17,13 @@
|
||||
import type { PrismaClient } from "@/generated/prisma/client";
|
||||
|
||||
import { prisma as defaultPrisma } from "@/lib/db";
|
||||
import { isP2002 } from "@/lib/prisma-errors";
|
||||
import { resolveCanonicalSlotInstant } from "@/lib/medications/scheduling/resolve-slot-instant";
|
||||
import type { WorkerScheduleRow } from "@/lib/medications/scheduling/worker-helpers";
|
||||
import type { InjectionSiteKey } from "@/lib/medications/injection-sites";
|
||||
|
||||
type PrismaLike = Pick<PrismaClient, "medication" | "medicationIntakeEvent">;
|
||||
|
||||
/** Narrow a thrown Prisma error to the P2002 unique-constraint code. */
|
||||
function isP2002(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
|
||||
/** The minimal intake-row shape the slot upsert reads + returns. */
|
||||
export interface SlotIntakeRow {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Shared Prisma error narrowing helpers.
|
||||
*
|
||||
* The P2002 (unique-constraint violation) predicate was hand-copied into
|
||||
* five call sites (rollup persist, intake-slot dedup, slot upsert, legacy
|
||||
* step consolidation, dense-intraday retention). v1.11.2 folds them into
|
||||
* this single helper so a future change to the P2002 semantics has one
|
||||
* place to live instead of five.
|
||||
*
|
||||
* Deliberately structural (`typeof === "object"` + `"code" in err` +
|
||||
* `code === "P2002"`) rather than `instanceof Prisma.PrismaClientKnownRequestError`
|
||||
* so it survives client-bundling quirks while staying specific to the
|
||||
* unique-constraint code.
|
||||
*/
|
||||
|
||||
/** Narrow a thrown Prisma error to the P2002 unique-constraint code. */
|
||||
export function isP2002(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
import { prisma } from "@/lib/db";
|
||||
import { getGlobalBoss } from "@/lib/jobs/boss-instance";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import { isP2002 } from "@/lib/prisma-errors";
|
||||
import {
|
||||
collapseRollupRowsBySource,
|
||||
loadUserSourcePriority,
|
||||
@@ -437,16 +438,6 @@ async function runRollupAggregate(input: {
|
||||
* with `ON CONFLICT DO UPDATE` so the round-trip count is bounded
|
||||
* regardless of fan-out width.
|
||||
*/
|
||||
/** Narrow a thrown Prisma error to the P2002 unique-constraint code. */
|
||||
function isP2002(err: unknown): boolean {
|
||||
return (
|
||||
typeof err === "object" &&
|
||||
err !== null &&
|
||||
"code" in err &&
|
||||
(err as { code: unknown }).code === "P2002"
|
||||
);
|
||||
}
|
||||
|
||||
async function persistRollupRows(
|
||||
userId: string,
|
||||
granularity: RollupGranularity,
|
||||
|
||||
Reference in new issue
Block a user