mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
feat(cycle): user-defined custom symptoms
Mirror the v1.13 custom-mood-tag CRUD for cycle symptoms. A user can mint their own symptoms beyond the 15 seeded ones, picked from a label + icon popover via a dashed ghost-chip in the log-day sheet's symptom grid. - POST/GET /api/cycle/symptoms/custom and PATCH/DELETE on /[key]: mint a custom:<uuid> key, encrypt the free-text label at rest (AES-256-GCM), per-user cap, owner-scoped, gated behind requireCycleEnabled. Soft-hide by default, hard-purge on ?purge=true. - The day-log write already resolves a symptom key against the catalogue plus the caller's own rows, so a custom: key links by construction. - The log-day sheet fetches the user's customs and merges them under a new custom category in the chip grid; the ghost-chip + popover reuse the chip styling and the Lucide icon set. - Seed the global custom symptom category (migration 0134). - The purge route (DELETE /api/cycle/all) now drops the user's custom symptom rows too, so no intent-revealing label survives a purge. - The label is never logged: only the icon + counts reach annotate/auditLog. - i18n: cycle.symptom.custom.* across all six locales.
This commit is contained in:
1 parent
81ec98fc97
commit
985e197db4
18 files changed
+1233
-59
No files matched your search
@@ -37,6 +37,12 @@ export const DELETE = apiHandler(async (request: NextRequest) => {
|
||||
const dayLogs = await tx.cycleDayLog.deleteMany({
|
||||
where: { userId: user.id },
|
||||
});
|
||||
// Per-user custom symptoms carry an intent-revealing free-text label
|
||||
// (encrypted at rest). A purge that promises "nothing reproductive
|
||||
// persists" must drop them too; their links cascade off the row delete.
|
||||
const customSymptoms = await tx.cycleSymptom.deleteMany({
|
||||
where: { userId: user.id },
|
||||
});
|
||||
const predictions = await tx.cyclePrediction.deleteMany({
|
||||
where: { userId: user.id },
|
||||
});
|
||||
@@ -79,6 +85,7 @@ export const DELETE = apiHandler(async (request: NextRequest) => {
|
||||
});
|
||||
return {
|
||||
dayLogs: dayLogs.count,
|
||||
customSymptoms: customSymptoms.count,
|
||||
predictions: predictions.count,
|
||||
cycles: cycles.count,
|
||||
auditRows: auditRows.count,
|
||||
|
||||
Reference in new issue
Block a user