fix(cycle): reset reproductive intent on the data purge

The hard-purge kept the CycleProfile row (so the gate + settings keep
working) but left the intent-revealing fields behind. Reset goal to
GENERAL_HEALTH and null the cycle/period/luteal priors inside the purge
transaction so no reproductive intent survives, matching the route's
"no reproductive trace persists" contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.8 committed 2026-06-06 13:41:49 +02:00
1 parent c21131e26e
commit d2da8d2657
1 file changed
+15 -1
+15 -1
View File
@@ -7,7 +7,9 @@
* menstrual cycles, predictions, the cycle audit trail, and the cycle
* reminder-delivery rows in the push-attempts ledger — so no dated
* reproductive trace survives in Postgres (the post-Dobbs threat model). The
* `CycleProfile` row is left in place (gate + settings keep working).
* `CycleProfile` row is left in place (gate + settings keep working) but its
* intent-revealing fields — goal + cycle/period/luteal priors — are reset to
* neutral defaults, so no reproductive intent survives either.
*
* Gated (`cycle.disabled` 403) and owner-scoped. The purge action itself IS
* audited (written after the transaction, so it survives) — its `details`
@@ -63,6 +65,18 @@ export const DELETE = apiHandler(async (request: NextRequest) => {
eventType: { in: ["CYCLE_PERIOD_SOON", "CYCLE_PERIOD_CONFIRM"] },
},
});
// Reset the reproductive INTENT carried on the profile (goal + cycle/period/
// luteal priors) to neutral defaults so a purge leaves no intent-revealing
// state, while keeping the row so the gate + settings keep working.
await tx.cycleProfile.updateMany({
where: { userId: user.id },
data: {
goal: "GENERAL_HEALTH",
typicalCycleLength: null,
typicalPeriodLength: null,
lutealPhaseLength: null,
},
});
return {
dayLogs: dayLogs.count,
predictions: predictions.count,