Files
HealthLog/tests/fixtures/v137/sharing-matrix.ts
T

806 lines
16 KiB
TypeScript

export const SHARING_DOMAINS = [
"measurements",
"medications",
"labs",
"profile",
"illness",
"mind",
"cycle",
"documents",
] as const;
export type SharingDomain = (typeof SHARING_DOMAINS)[number];
export type SharingScope = SharingDomain | "record";
export type DelegatedLevel = "write" | "manage";
export type MutatingAction = "POST" | "PUT" | "PATCH" | "DELETE";
export type RecordKind = "shared" | "managed";
export type MutationEffect =
"create" | "update" | "delete" | "restore" | "upsert" | "export";
export interface MutatingHandlerContract {
readonly handlerModule: `app/api/${string}/route.ts`;
readonly route: `/api/${string}`;
readonly action: MutatingAction;
readonly recordKind: RecordKind;
readonly scope: SharingScope;
readonly level: DelegatedLevel;
readonly ownRecord: {
readonly actor: "record-owner";
readonly expected: "allow";
};
readonly deniedLevel: {
readonly actor: "delegate";
readonly level: "read" | "write";
readonly expected: "deny";
};
readonly admittedLevel: {
readonly actor: "delegate";
readonly expected: "allow";
};
readonly actorAttribution: {
readonly field: "actorUserId";
readonly expected: "acting-delegate";
};
readonly resultingEffect: {
readonly expected: "applied-once";
readonly mutation: MutationEffect;
};
readonly sideEffect: {
readonly recordTarget: "resolved-record";
readonly delegatedProviderEgress: "deny";
};
readonly encryptedFieldCarveOut: "never-assert-decrypted-field-content";
}
function handler(
handlerModule: `app/api/${string}/route.ts`,
route: `/api/${string}`,
action: MutatingAction,
scope: SharingScope,
level: DelegatedLevel,
mutation: MutationEffect,
): MutatingHandlerContract {
return {
handlerModule,
route,
action,
recordKind: "shared",
scope,
level,
ownRecord: { actor: "record-owner", expected: "allow" },
deniedLevel: {
actor: "delegate",
level: level === "write" ? "read" : "write",
expected: "deny",
},
admittedLevel: { actor: "delegate", expected: "allow" },
actorAttribution: {
field: "actorUserId",
expected: "acting-delegate",
},
resultingEffect: { expected: "applied-once", mutation },
sideEffect: {
recordTarget: "resolved-record",
delegatedProviderEgress: "deny",
},
encryptedFieldCarveOut: "never-assert-decrypted-field-content",
};
}
export const ADMITTED_MUTATING_HANDLERS = [
handler(
"app/api/measurements/route.ts",
"/api/measurements",
"POST",
"measurements",
"write",
"create",
),
handler(
"app/api/labs/route.ts",
"/api/labs",
"POST",
"labs",
"write",
"create",
),
handler(
"app/api/biomarkers/route.ts",
"/api/biomarkers",
"POST",
"labs",
"write",
"create",
),
handler(
"app/api/illness/episodes/route.ts",
"/api/illness/episodes",
"POST",
"illness",
"write",
"create",
),
handler(
"app/api/encounters/route.ts",
"/api/encounters",
"POST",
"profile",
"write",
"create",
),
handler(
"app/api/practitioners/route.ts",
"/api/practitioners",
"POST",
"profile",
"write",
"create",
),
handler(
"app/api/medications/[id]/side-effects/route.ts",
"/api/medications/[id]/side-effects",
"POST",
"medications",
"write",
"create",
),
handler(
"app/api/medications/route.ts",
"/api/medications",
"POST",
"medications",
"write",
"create",
),
handler(
"app/api/medications/intake/route.ts",
"/api/medications/intake",
"POST",
"medications",
"write",
"create",
),
handler(
"app/api/medications/[id]/intake/route.ts",
"/api/medications/[id]/intake",
"POST",
"medications",
"write",
"create",
),
handler(
"app/api/measurements/[id]/route.ts",
"/api/measurements/[id]",
"PUT",
"measurements",
"manage",
"update",
),
handler(
"app/api/measurements/[id]/route.ts",
"/api/measurements/[id]",
"DELETE",
"measurements",
"manage",
"delete",
),
handler(
"app/api/measurements/bulk-delete/route.ts",
"/api/measurements/bulk-delete",
"POST",
"measurements",
"manage",
"delete",
),
handler(
"app/api/measurements/restore/route.ts",
"/api/measurements/restore",
"POST",
"measurements",
"manage",
"restore",
),
handler(
"app/api/measurement-reminders/route.ts",
"/api/measurement-reminders",
"POST",
"measurements",
"manage",
"create",
),
handler(
"app/api/measurement-reminders/[id]/route.ts",
"/api/measurement-reminders/[id]",
"PATCH",
"measurements",
"manage",
"update",
),
handler(
"app/api/measurement-reminders/[id]/route.ts",
"/api/measurement-reminders/[id]",
"DELETE",
"measurements",
"manage",
"delete",
),
handler(
"app/api/measurement-reminders/[id]/complete/route.ts",
"/api/measurement-reminders/[id]/complete",
"POST",
"measurements",
"manage",
"update",
),
handler(
"app/api/measurement-reminders/[id]/satisfy/route.ts",
"/api/measurement-reminders/[id]/satisfy",
"POST",
"measurements",
"manage",
"update",
),
handler(
"app/api/measurement-reminders/[id]/skip/route.ts",
"/api/measurement-reminders/[id]/skip",
"POST",
"measurements",
"manage",
"update",
),
handler(
"app/api/measurement-reminders/[id]/snooze/route.ts",
"/api/measurement-reminders/[id]/snooze",
"POST",
"measurements",
"manage",
"update",
),
handler(
"app/api/labs/[id]/route.ts",
"/api/labs/[id]",
"PUT",
"labs",
"manage",
"update",
),
handler(
"app/api/labs/[id]/route.ts",
"/api/labs/[id]",
"DELETE",
"labs",
"manage",
"delete",
),
handler(
"app/api/labs/restore/route.ts",
"/api/labs/restore",
"POST",
"labs",
"manage",
"restore",
),
handler(
"app/api/biomarkers/[id]/route.ts",
"/api/biomarkers/[id]",
"PUT",
"labs",
"manage",
"update",
),
handler(
"app/api/biomarkers/[id]/route.ts",
"/api/biomarkers/[id]",
"DELETE",
"labs",
"manage",
"delete",
),
handler(
"app/api/allergies/route.ts",
"/api/allergies",
"POST",
"profile",
"manage",
"create",
),
handler(
"app/api/allergies/[id]/route.ts",
"/api/allergies/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/allergies/[id]/route.ts",
"/api/allergies/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/family-history/route.ts",
"/api/family-history",
"POST",
"profile",
"manage",
"create",
),
handler(
"app/api/family-history/[id]/route.ts",
"/api/family-history/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/family-history/[id]/route.ts",
"/api/family-history/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/illness/episodes/[id]/route.ts",
"/api/illness/episodes/[id]",
"PATCH",
"illness",
"manage",
"update",
),
handler(
"app/api/illness/episodes/[id]/route.ts",
"/api/illness/episodes/[id]",
"DELETE",
"illness",
"manage",
"delete",
),
handler(
"app/api/illness/episodes/[id]/resolve/route.ts",
"/api/illness/episodes/[id]/resolve",
"PATCH",
"illness",
"manage",
"update",
),
handler(
"app/api/illness/episodes/[id]/restore/route.ts",
"/api/illness/episodes/[id]/restore",
"POST",
"illness",
"manage",
"restore",
),
handler(
"app/api/encounters/[id]/route.ts",
"/api/encounters/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/encounters/[id]/route.ts",
"/api/encounters/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/encounters/[id]/restore/route.ts",
"/api/encounters/[id]/restore",
"POST",
"profile",
"manage",
"restore",
),
handler(
"app/api/practitioners/[id]/route.ts",
"/api/practitioners/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/practitioners/[id]/route.ts",
"/api/practitioners/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/practitioners/[id]/restore/route.ts",
"/api/practitioners/[id]/restore",
"POST",
"profile",
"manage",
"restore",
),
// v1.38.0 — the immunization log.
handler(
"app/api/vaccinations/route.ts",
"/api/vaccinations",
"POST",
"profile",
"write",
"create",
),
handler(
"app/api/vaccinations/[id]/route.ts",
"/api/vaccinations/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/vaccinations/[id]/route.ts",
"/api/vaccinations/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/vaccinations/[id]/restore/route.ts",
"/api/vaccinations/[id]/restore",
"POST",
"profile",
"manage",
"restore",
),
handler(
"app/api/vaccinations/[id]/booster/route.ts",
"/api/vaccinations/[id]/booster",
"POST",
"profile",
"write",
"upsert",
),
// v1.42 (#1005) — the record's own vaccine definitions.
handler(
"app/api/vaccinations/custom/route.ts",
"/api/vaccinations/custom",
"POST",
"profile",
"write",
"create",
),
handler(
"app/api/vaccinations/custom/[id]/route.ts",
"/api/vaccinations/custom/[id]",
"PATCH",
"profile",
"manage",
"update",
),
handler(
"app/api/vaccinations/custom/[id]/route.ts",
"/api/vaccinations/custom/[id]",
"DELETE",
"profile",
"manage",
"delete",
),
handler(
"app/api/illness/episodes/[id]/day-logs/route.ts",
"/api/illness/episodes/[id]/day-logs",
"POST",
"illness",
"manage",
"upsert",
),
handler(
"app/api/medications/[id]/route.ts",
"/api/medications/[id]",
"PUT",
"medications",
"manage",
"update",
),
handler(
"app/api/medications/[id]/schedule-revisions/route.ts",
"/api/medications/[id]/schedule-revisions",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/medications/[id]/schedule-revisions/[revisionId]/route.ts",
"/api/medications/[id]/schedule-revisions/[revisionId]",
"PATCH",
"medications",
"manage",
"update",
),
handler(
"app/api/medications/[id]/schedule-revisions/[revisionId]/route.ts",
"/api/medications/[id]/schedule-revisions/[revisionId]",
"DELETE",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/inventory/route.ts",
"/api/medications/[id]/inventory",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/medications/[id]/inventory/[itemId]/route.ts",
"/api/medications/[id]/inventory/[itemId]",
"PATCH",
"medications",
"manage",
"update",
),
handler(
"app/api/medications/[id]/inventory/[itemId]/route.ts",
"/api/medications/[id]/inventory/[itemId]",
"DELETE",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/side-effects/[logId]/route.ts",
"/api/medications/[id]/side-effects/[logId]",
"DELETE",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/ingredients/route.ts",
"/api/medications/[id]/ingredients",
"PUT",
"medications",
"manage",
"update",
),
handler(
"app/api/medications/[id]/glp1/route.ts",
"/api/medications/[id]/glp1",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/medications/[id]/intake/[eventId]/route.ts",
"/api/medications/[id]/intake/[eventId]",
"PUT",
"medications",
"manage",
"update",
),
handler(
"app/api/medications/[id]/intake/[eventId]/route.ts",
"/api/medications/[id]/intake/[eventId]",
"DELETE",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/intake/bulk-delete/route.ts",
"/api/medications/[id]/intake/bulk-delete",
"POST",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/intake/purge/route.ts",
"/api/medications/[id]/intake/purge",
"DELETE",
"medications",
"manage",
"delete",
),
handler(
"app/api/medications/[id]/intake/import/route.ts",
"/api/medications/[id]/intake/import",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/medications/intake/dose-history-import/route.ts",
"/api/medications/intake/dose-history-import",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/mood-entries/route.ts",
"/api/mood-entries",
"POST",
"mind",
"manage",
"create",
),
handler(
"app/api/mood-entries/[id]/route.ts",
"/api/mood-entries/[id]",
"PUT",
"mind",
"manage",
"update",
),
handler(
"app/api/mood-entries/[id]/route.ts",
"/api/mood-entries/[id]",
"DELETE",
"mind",
"manage",
"delete",
),
handler(
"app/api/mood-entries/bulk-delete/route.ts",
"/api/mood-entries/bulk-delete",
"POST",
"mind",
"manage",
"delete",
),
handler(
"app/api/mood-entries/restore/route.ts",
"/api/mood-entries/restore",
"POST",
"mind",
"manage",
"restore",
),
handler(
"app/api/mental-health/assessments/route.ts",
"/api/mental-health/assessments",
"POST",
"mind",
"manage",
"create",
),
handler(
"app/api/cycle/cycles/[id]/route.ts",
"/api/cycle/cycles/[id]",
"DELETE",
"cycle",
"manage",
"delete",
),
handler(
"app/api/cycle/day-logs/route.ts",
"/api/cycle/day-logs",
"POST",
"cycle",
"manage",
"upsert",
),
handler(
"app/api/cycle/day-logs/[id]/route.ts",
"/api/cycle/day-logs/[id]",
"PATCH",
"cycle",
"manage",
"update",
),
handler(
"app/api/cycle/day-logs/[id]/route.ts",
"/api/cycle/day-logs/[id]",
"DELETE",
"cycle",
"manage",
"delete",
),
handler(
"app/api/cycle/period/route.ts",
"/api/cycle/period",
"POST",
"cycle",
"manage",
"update",
),
handler(
"app/api/cycle/symptoms/custom/route.ts",
"/api/cycle/symptoms/custom",
"POST",
"cycle",
"manage",
"create",
),
handler(
"app/api/medications/categories/route.ts",
"/api/medications/categories",
"POST",
"medications",
"manage",
"create",
),
handler(
"app/api/nutrients/water/route.ts",
"/api/nutrients/water",
"POST",
"measurements",
"manage",
"upsert",
),
handler(
"app/api/insights/patterns/[id]/route.ts",
"/api/insights/patterns/[id]",
"PATCH",
"record",
"manage",
"update",
),
handler(
"app/api/export/health-record/route.ts",
"/api/export/health-record",
"POST",
"record",
"manage",
"export",
),
handler(
"app/api/symptoms/definitions/route.ts",
"/api/symptoms/definitions",
"POST",
"illness",
"manage",
"create",
),
handler(
"app/api/symptoms/definitions/[id]/route.ts",
"/api/symptoms/definitions/[id]",
"PATCH",
"illness",
"manage",
"update",
),
handler(
"app/api/symptoms/definitions/[id]/route.ts",
"/api/symptoms/definitions/[id]",
"DELETE",
"illness",
"manage",
"delete",
),
handler(
"app/api/symptoms/events/route.ts",
"/api/symptoms/events",
"POST",
"illness",
"write",
"create",
),
handler(
"app/api/symptoms/events/[id]/route.ts",
"/api/symptoms/events/[id]",
"PATCH",
"illness",
"manage",
"update",
),
handler(
"app/api/symptoms/events/[id]/route.ts",
"/api/symptoms/events/[id]",
"DELETE",
"illness",
"manage",
"delete",
),
] as const satisfies readonly MutatingHandlerContract[];