diff --git a/src/app/api/medications/intake-summary/route.ts b/src/app/api/medications/intake-summary/route.ts deleted file mode 100644 index 3a2d0d1d5..000000000 --- a/src/app/api/medications/intake-summary/route.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { NextRequest } from "next/server"; -import { z } from "zod/v4"; -import { prisma } from "@/lib/db"; -import { apiHandler, requireAuth } from "@/lib/api-handler"; -import { annotate } from "@/lib/logging/context"; -import { apiError, apiSuccess } from "@/lib/api-response"; - -const querySchema = z.object({ - from: z.iso - .datetime({ offset: true }) - .transform((value) => new Date(value)) - .optional(), - to: z.iso - .datetime({ offset: true }) - .transform((value) => new Date(value)) - .optional(), -}); - -function toBerlinDayKey(date: Date): string { - return new Intl.DateTimeFormat("sv-SE", { - timeZone: "Europe/Berlin", - year: "numeric", - month: "2-digit", - day: "2-digit", - }).format(date); -} - -interface DailySummary { - date: string; - total: number; - medications: Record; -} - -export const GET = apiHandler(async (request: NextRequest) => { - const { user } = await requireAuth(); - - const parsed = querySchema.safeParse( - Object.fromEntries(request.nextUrl.searchParams), - ); - if (!parsed.success) { - return apiError(parsed.error.issues[0].message, 422); - } - - const { from, to } = parsed.data; - - const events = await prisma.medicationIntakeEvent.findMany({ - where: { - userId: user.id, - skipped: false, - takenAt: { - not: null, - ...(from && { gte: from }), - ...(to && { lte: to }), - }, - }, - select: { - takenAt: true, - medication: { - select: { - name: true, - }, - }, - }, - orderBy: { takenAt: "asc" }, - }); - - const medicationNames = new Set(); - const byDay = new Map(); - - for (const event of events) { - if (!event.takenAt) continue; - - const medicationName = event.medication.name; - const dayKey = toBerlinDayKey(event.takenAt); - medicationNames.add(medicationName); - - const existing = byDay.get(dayKey) ?? { - date: dayKey, - total: 0, - medications: {}, - }; - - existing.total += 1; - existing.medications[medicationName] = - (existing.medications[medicationName] ?? 0) + 1; - byDay.set(dayKey, existing); - } - - const points = [...byDay.values()].sort((a, b) => - a.date.localeCompare(b.date), - ); - - annotate({ - action: { name: "medication.intake_summary" }, - meta: { - point_count: points.length, - medication_count: medicationNames.size, - }, - }); - - return apiSuccess({ - points, - medications: [...medicationNames].sort((a, b) => a.localeCompare(b, "de")), - }); -}); diff --git a/src/components/dashboard/medication-intake-quick-add.tsx b/src/components/dashboard/medication-intake-quick-add.tsx index 73ba8c451..26e4446ed 100644 --- a/src/components/dashboard/medication-intake-quick-add.tsx +++ b/src/components/dashboard/medication-intake-quick-add.tsx @@ -58,7 +58,7 @@ import { * shaped the same as `MoodForm`). * * On success: invalidate `medicationDependentKeys` (medications + - * analytics + insights + intake-summary + achievements) PLUS the + * analytics + insights + achievements) PLUS the * inline per-medication compliance chart key so the detail page tile * refreshes if it happens to be mounted elsewhere in the app. * diff --git a/src/lib/query-keys.ts b/src/lib/query-keys.ts index b367dab5b..df8155542 100644 --- a/src/lib/query-keys.ts +++ b/src/lib/query-keys.ts @@ -87,7 +87,6 @@ export const queryKeys = { ["dashboard-medication-compliance", days] as const, medicationPhaseConfig: (medicationId: string) => ["phase-config", medicationId] as const, - medicationIntakeSummary: () => ["medications", "intake-summary"] as const, gamificationAchievements: () => ["gamification", "achievements"] as const, @@ -217,7 +216,6 @@ export const medicationDependentKeys = [ queryKeys.analytics(), queryKeys.insightsRoot(), queryKeys.insightsTargets(), - queryKeys.medicationIntakeSummary(), queryKeys.gamificationAchievements(), ["dashboard-medication-compliance"] as const, ];