chore: format data integrity fixes

This commit is contained in:
Marc-André Bombeck committed 2026-07-20 14:02:08 +02:00
1 parent a846bbc90d
commit d966355f83
5 files changed
+67 -87

No files matched your search

@@ -367,8 +367,7 @@ const handler = apiHandler(
adminCodexConnectedAt: settings.adminCodexConnectedAt
? new Date(settings.adminCodexConnectedAt)
: null,
adminCodexConnectionStatus:
settings.adminCodexConnectionStatus,
adminCodexConnectionStatus: settings.adminCodexConnectionStatus,
adminAiInsightsFeedbackSummary:
settings.adminAiInsightsFeedbackSummary as never,
defaultUserTimezone: settings.defaultUserTimezone,
@@ -381,8 +380,7 @@ const handler = apiHandler(
settings.assistantCorrelationsEnabled,
assistantHealthScoreExplainerEnabled:
settings.assistantHealthScoreExplainerEnabled,
moduleAvailabilityJson:
settings.moduleAvailabilityJson as never,
moduleAvailabilityJson: settings.moduleAvailabilityJson as never,
documentMaxFileBytes: settings.documentMaxFileBytes,
documentQuotaBytes: BigInt(settings.documentQuotaBytes),
};
@@ -492,9 +490,7 @@ const handler = apiHandler(
active: m.active ?? true,
notificationsEnabled: m.notificationsEnabled ?? true,
pausedAt: m.pausedAt ? new Date(m.pausedAt) : null,
snoozedUntil: m.snoozedUntil
? new Date(m.snoozedUntil)
: null,
snoozedUntil: m.snoozedUntil ? new Date(m.snoozedUntil) : null,
startsOn: m.startsOn ? new Date(m.startsOn) : null,
endsOn: m.endsOn ? new Date(m.endsOn) : null,
oneShot: m.oneShot ?? false,
+4 -13
View File
@@ -126,10 +126,8 @@ function stableFallbackMoodInstant(
const digest = createHash("sha256")
.update(`${fallbackMoodIdentity(entry)}:${occurrence}`)
.digest();
const initialOffset =
digest.readUInt32BE(0) % ENTRY_INSTANT_CLOCK_SKEW_MS;
const offset =
(initialOffset + probe) % ENTRY_INSTANT_CLOCK_SKEW_MS;
const initialOffset = digest.readUInt32BE(0) % ENTRY_INSTANT_CLOCK_SKEW_MS;
const offset = (initialOffset + probe) % ENTRY_INSTANT_CLOCK_SKEW_MS;
const dateStart = fallbackMoodDateStart(entry.date);
if (!dateStart) throw new Error("Invalid mood date");
return new Date(dateStart.getTime() + offset);
@@ -308,17 +306,10 @@ export const POST = apiHandler(async (request: NextRequest) => {
fallbackOccurrences.set(identity, occurrence + 1);
}
for (
let probe = 0;
probe < ENTRY_INSTANT_CLOCK_SKEW_MS;
probe++
) {
for (let probe = 0; probe < ENTRY_INSTANT_CLOCK_SKEW_MS; probe++) {
const loggedAt =
e.loggedAt ?? stableFallbackMoodInstant(e, occurrence, probe);
if (
!e.loggedAt &&
reservedFallbackInstants.has(loggedAt.getTime())
) {
if (!e.loggedAt && reservedFallbackInstants.has(loggedAt.getTime())) {
continue;
}
try {
+3 -5
View File
@@ -80,11 +80,9 @@ describe("buildCycleBackupSection disaster-recovery mode", () => {
},
};
const section = await buildCycleBackupSection(
prisma as never,
"user-1",
{ purpose: "disaster-recovery" },
);
const section = await buildCycleBackupSection(prisma as never, "user-1", {
purpose: "disaster-recovery",
});
expect(prisma.menstrualCycle.findMany).toHaveBeenCalledWith(
expect.objectContaining({ where: { userId: "user-1" } }),
+32 -30
View File
@@ -367,37 +367,39 @@ export async function upsertWhoopMeasurements(
chunkStart + WHOOP_MEASUREMENT_TRANSACTION_CHUNK_SIZE,
readings.length,
);
const verdicts = await prisma.$transaction(
async (tx) => {
const outcomes = [];
for (let index = chunkStart; index < chunkEnd; index++) {
const reading = readings[index]!;
const verdict = await reconcileExternalMeasurement(
tx,
{
userId,
type: reading.type as MeasurementType,
source: "WHOOP",
value: reading.value,
unit: reading.unit,
measuredAt: reading.measuredAt,
externalId: reading.externalId,
sleepStage: reading.sleepStage ?? null,
},
{ exactExternalMatch: "update" },
);
if (verdict.status === "failed") {
throw new MeasurementReconciliationError(verdict);
const verdicts = await prisma
.$transaction(
async (tx) => {
const outcomes = [];
for (let index = chunkStart; index < chunkEnd; index++) {
const reading = readings[index]!;
const verdict = await reconcileExternalMeasurement(
tx,
{
userId,
type: reading.type as MeasurementType,
source: "WHOOP",
value: reading.value,
unit: reading.unit,
measuredAt: reading.measuredAt,
externalId: reading.externalId,
sleepStage: reading.sleepStage ?? null,
},
{ exactExternalMatch: "update" },
);
if (verdict.status === "failed") {
throw new MeasurementReconciliationError(verdict);
}
outcomes.push(verdict);
}
outcomes.push(verdict);
}
return outcomes;
},
{ maxWait: 10_000, timeout: 60_000 },
).catch((err) => {
invalidateTouchedTypes();
throw err;
});
return outcomes;
},
{ maxWait: 10_000, timeout: 60_000 },
)
.catch((err) => {
invalidateTouchedTypes();
throw err;
});
const touched: Array<{ type: MeasurementType; measuredAt: Date }> = [];
const insertedRows: Array<
@@ -280,9 +280,7 @@ describe("canonical disaster-recovery backup round-trip", () => {
scheduleType: "CYCLIC",
cyclicOnWeeks: 3,
cyclicOffWeeks: 1,
doseWindows: [
{ timeOfDay: "08:00", start: "07:30", end: "09:00" },
],
doseWindows: [{ timeOfDay: "08:00", start: "07:30", end: "09:00" }],
},
},
},
@@ -340,8 +338,7 @@ describe("canonical disaster-recovery backup round-trip", () => {
deletedAt: tombstoneDeletedAt,
},
});
const cycleCategory =
await prisma.cycleSymptomCategory.findFirstOrThrow();
const cycleCategory = await prisma.cycleSymptomCategory.findFirstOrThrow();
const cycleSymptom = await prisma.cycleSymptom.create({
data: {
id: "cycle-symptom-dr",
@@ -542,7 +539,9 @@ describe("canonical disaster-recovery backup round-trip", () => {
);
await prisma.appSettings.deleteMany();
await prisma.medicationIntakeEvent.deleteMany({ where: { userId: ownerId } });
await prisma.medicationIntakeEvent.deleteMany({
where: { userId: ownerId },
});
await prisma.medication.deleteMany({ where: { userId: ownerId } });
await prisma.cycleDayLog.deleteMany({ where: { userId: ownerId } });
await prisma.menstrualCycle.deleteMany({ where: { userId: ownerId } });
@@ -880,9 +879,7 @@ describe("canonical disaster-recovery backup round-trip", () => {
type: "PULSE" as const,
value: 60 + (index % 20),
unit: "bpm",
measuredAt: new Date(
Date.UTC(2026, 6, 10, 0, 0, 0, index),
).toISOString(),
measuredAt: new Date(Date.UTC(2026, 6, 10, 0, 0, 0, index)).toISOString(),
source: "IMPORT" as const,
externalId: `external-${index}`,
syncVersion: 3,
@@ -907,29 +904,25 @@ describe("canonical disaster-recovery backup round-trip", () => {
options?: { maxWait?: number; timeout?: number },
) => Promise<unknown>;
const transactionSpy = vi.spyOn(prisma, "$transaction");
transactionSpy.mockImplementation(
(async (
callback: (tx: Prisma.TransactionClient) => Promise<unknown>,
options?: { maxWait?: number; timeout?: number },
) =>
originalTransaction(async (tx) => {
const originalUpsert = tx.measurement.upsert.bind(tx.measurement);
const originalCreateMany = tx.measurement.createMany.bind(
tx.measurement,
);
vi.spyOn(tx.measurement, "upsert").mockImplementation((args) => {
stableWriteQueries += 1;
return originalUpsert(args);
});
vi.spyOn(tx.measurement, "createMany").mockImplementation(
(args) => {
stableWriteQueries += 1;
return originalCreateMany(args);
},
);
return callback(tx);
}, options)) as never,
);
transactionSpy.mockImplementation((async (
callback: (tx: Prisma.TransactionClient) => Promise<unknown>,
options?: { maxWait?: number; timeout?: number },
) =>
originalTransaction(async (tx) => {
const originalUpsert = tx.measurement.upsert.bind(tx.measurement);
const originalCreateMany = tx.measurement.createMany.bind(
tx.measurement,
);
vi.spyOn(tx.measurement, "upsert").mockImplementation((args) => {
stableWriteQueries += 1;
return originalUpsert(args);
});
vi.spyOn(tx.measurement, "createMany").mockImplementation((args) => {
stableWriteQueries += 1;
return originalCreateMany(args);
});
return callback(tx);
}, options)) as never);
const response = await POST(
makeRequest(backup.id) as unknown as Parameters<typeof POST>[0],