mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
Merge the health-data route group
Two groups created environment.ts independently; one carried all six paths, the other only the overview read, so the fuller side stands and the barrel keeps one import.
This commit is contained in:
commit
50b483d8d1
18 files changed
+4136
-54
No files matched your search
@@ -9,9 +9,11 @@
|
||||
* keeps its neutral greeting — never a fabricated opener.
|
||||
*
|
||||
* The signal is selected SERVER-SIDE; the client renders the resolved DTO
|
||||
* and never recomputes it (server-authoritative parity). This is an
|
||||
* INTERNAL same-origin route — it is deliberately NOT registered in the
|
||||
* OpenAPI contract the iOS client consumes.
|
||||
* and never recomputes it (server-authoritative parity). It IS registered in
|
||||
* the OpenAPI contract. This comment said the opposite until the route was
|
||||
* published — it shipped as a same-origin web surface and the sentence was
|
||||
* never revisited. A comment that contradicts the registry is worse than no
|
||||
* comment, because the next reader believes it instead of checking.
|
||||
*
|
||||
* Mirrors the sibling derived routes: `apiHandler` wrapper, `requireAuth`
|
||||
* (userId narrowed from the session/Bearer, never a body/query field),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { prisma } from "@/lib/db";
|
||||
import { apiHandler, requireAuth, requireRecordAuth } from "@/lib/api-handler";
|
||||
import { apiHandler, requireRecordAuth } from "@/lib/api-handler";
|
||||
import { auditLog } from "@/lib/auth/audit";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import {
|
||||
@@ -53,7 +53,16 @@ const POST_WINDOW_MS = 60_000;
|
||||
|
||||
export const GET = apiHandler(
|
||||
async (_request: NextRequest, { params }: RouteParams) => {
|
||||
const { user } = await requireAuth();
|
||||
// The read resolves the RECORD, at the level its siblings use. It did not
|
||||
// until the route was published, and the asymmetry that produced is the
|
||||
// reason it is written down here: the POST below has resolved the record
|
||||
// since v1.37.0, so a manager could add a titration step to a medication
|
||||
// whose history the GET refused them — may write, may not read, which is
|
||||
// not a shape any reading of the sharing model produces. `read` rather
|
||||
// than the POST's `manage` because that is what `/inventory`,
|
||||
// `/side-effects` and `/cadence` ask for the same medication's data, and
|
||||
// this read is strictly narrower than the write already permitted.
|
||||
const { user } = await requireRecordAuth("read", "medications");
|
||||
const { id } = await params;
|
||||
|
||||
// v1.5.5 F-1 C-4 — close the §10 invariant 24 gap. The destructive
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
* Updates the named MedicationIntakeEvent and returns the updated row.
|
||||
*/
|
||||
import { NextRequest } from "next/server";
|
||||
import { z } from "zod/v4";
|
||||
import { apiHandler, requireRecordAuth } from "@/lib/api-handler";
|
||||
import {
|
||||
apiError,
|
||||
@@ -46,7 +45,8 @@ import {
|
||||
restoreForIntake,
|
||||
} from "@/lib/medications/inventory/consumption";
|
||||
import {
|
||||
injectionSiteEnum,
|
||||
intakeAggregateQuerySchema,
|
||||
intakeStatusUpdateSchema,
|
||||
type InjectionSiteValue,
|
||||
} from "@/lib/validations/medication";
|
||||
import { queueMedicationIntakeSync } from "@/lib/notifications/medication-intake-sync";
|
||||
@@ -54,40 +54,15 @@ import { dispatchMedicationIntakeWebClear } from "@/lib/notifications/web-push-c
|
||||
import { notifyDelegatedIntake } from "@/lib/notifications/delegated-intake";
|
||||
import { countOutstandingDosesToday } from "@/lib/medications/outstanding-doses";
|
||||
|
||||
const querySchema = z.object({
|
||||
scope: z.enum(["today", "compliance"]),
|
||||
days: z.coerce.number().int().min(1).max(365).optional().default(30),
|
||||
});
|
||||
|
||||
const updateSchema = z.object({
|
||||
intakeId: z.string().min(1),
|
||||
status: z.enum(["taken", "skipped", "snoozed"]),
|
||||
takenAt: z.iso
|
||||
.datetime({ offset: true })
|
||||
.transform((s) => new Date(s))
|
||||
.optional(),
|
||||
snoozedUntil: z.iso
|
||||
.datetime({ offset: true })
|
||||
.transform((s) => new Date(s))
|
||||
.optional(),
|
||||
// v1.8.5 — optional injection site captured alongside a "taken"
|
||||
// status toggle. Validated server-side against the medication's
|
||||
// effective allowed set; ignored for skipped / snoozed.
|
||||
injectionSite: injectionSiteEnum.optional(),
|
||||
// v1.15.18 — late-take "attribute anyway" pin. When a "taken" toggle lands
|
||||
// outside every dose window the UI can offer to pin the take onto a chosen
|
||||
// real slot ("diesem Slot zuordnen?"); the server validates the instant is
|
||||
// a real slot of the medication (422 otherwise). Ignored for skip / snooze.
|
||||
forceSlotInstant: z.iso
|
||||
.datetime({ offset: true })
|
||||
.transform((s) => new Date(s))
|
||||
.optional(),
|
||||
});
|
||||
// The query + body schemas moved to `@/lib/validations/medication` when this
|
||||
// endpoint joined the published contract: the OpenAPI registry generates from
|
||||
// the validation modules, and a schema that only exists inside a handler is
|
||||
// one the spec has to restate — which is a second copy to keep in step.
|
||||
|
||||
export const GET = apiHandler(async (request: NextRequest) => {
|
||||
const { user } = await requireRecordAuth("read", "medications");
|
||||
|
||||
const parsed = querySchema.safeParse(
|
||||
const parsed = intakeAggregateQuerySchema.safeParse(
|
||||
Object.fromEntries(request.nextUrl.searchParams),
|
||||
);
|
||||
if (!parsed.success) {
|
||||
@@ -233,7 +208,7 @@ export const POST = apiHandler(async (request: NextRequest) => {
|
||||
});
|
||||
if (error) return error;
|
||||
|
||||
const parsed = updateSchema.safeParse(body);
|
||||
const parsed = intakeStatusUpdateSchema.safeParse(body);
|
||||
if (!parsed.success) {
|
||||
// v1.4.43 W6 — intake-event update hot path; multi-issue 422 +
|
||||
// audit breadcrumb keyed `medications.intake.update.validation-failed`.
|
||||
|
||||
Reference in new issue
Block a user