Let a delegate add to the clinical record of a shared account

An allergy, a family-history entry, an illness episode and a custom-metric
value now resolve the record rather than the caller.

Two of them carry a consequence worth naming. The family-history row
describes the record's relatives, so it is the one admitted write where
third-party health information is present by design; it is stored as the
record's own, exactly as the read arm already serves it. The illness module
gate runs against the record before the write, so a delegate cannot open an
episode inside a record whose owner switched the module off, whatever they
set on their own account.

The custom-metric entry reaches its metric through the ownership hop, which
now resolves against the record: a delegate can only feed a definition the
owner made, and their own metric of the same name is unreachable from in
there. Its validation breadcrumb moves to auditLog().
This commit is contained in:
Marc-André Bombeck committed 2026-08-03 12:10:59 +02:00
1 parent c6be0778dc
commit 095aba095e
4 files changed
+30 -19

No files matched your search

+6 -2
View File
@@ -13,7 +13,7 @@
import { NextRequest } from "next/server";
import { prisma } from "@/lib/db";
import { apiHandler, requireAuth, requireRecordAuth } from "@/lib/api-handler";
import { apiHandler, requireRecordAuth } from "@/lib/api-handler";
import { annotate } from "@/lib/logging/context";
import { auditLog } from "@/lib/auth/audit";
import {
@@ -74,7 +74,11 @@ export const GET = apiHandler(async (request: NextRequest) => {
export const POST = apiHandler(withIdempotency<[NextRequest]>(postEpisode));
async function postEpisode(request: NextRequest): Promise<Response> {
const { user } = await requireAuth();
// v1.36.x — a delegated write. The module gate below follows the RECORD, not
// the caller: whether illness tracking exists is a property of the record, so
// a delegate who runs the module on their own account does not thereby gain
// an episode surface inside somebody else's.
const { user } = await requireRecordAuth("write");
const gate = await requireIllnessEnabled(user.id);
if (!gate.enabled) return gate.response;