mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
feat(documents): link a document to visits and vaccinations from its own sheet
A document could show its visits read-only and its vaccinations not at all, so a childhood record covering a dozen doses had to be attached from a dozen dose forms. The document's detail sheet now lists the visits and vaccinations it is filed against and, for someone who may manage the vault, links and unlinks them in one place, with the records dated near the document on top. Both ends write the same link tables through the link service, so the dose's form and the document's sheet cannot disagree about what is filed where. The document detail response carries the linked doses, named by catalogue slug or the person's own wording. It is null rather than empty for a grant that opens the vault but not the health background, so a shared page never claims to record no doses. The update route takes a replace-set of vaccination ids, up to 100 so one record can cover a whole primary schedule; ownership is re-checked, a foreign id answers 404 and the change lands in the audit log beside the other link fields. Linking from the dose suggestion now refreshes the sheet. Refs #1024, #1005
This commit is contained in:
1 parent
f46ed99def
commit
b480ac4543
23 files changed
+1012
-87
No files matched your search
@@ -128,6 +128,7 @@ export const ERROR_CODE_CATALOGUE: Readonly<Record<string, readonly string[]>> =
|
||||
"documents.inbound.restoreGone",
|
||||
"documents.inbound.uploadBusy",
|
||||
"documents.inbound.uploadTimeout",
|
||||
"documents.inbound.vaccinationNotFound",
|
||||
],
|
||||
encounter: [
|
||||
"encounter.invalid",
|
||||
|
||||
@@ -98,7 +98,7 @@ const inboundFactEditRequest = inboundFactEditSchema.meta({
|
||||
const documentUpdateRequest = documentUpdateSchema.meta({
|
||||
id: "DocumentUpdateRequest",
|
||||
description:
|
||||
"Metadata edit for a stored document: `title` (user label; null clears it), `kind` (category), `documentDate` (user filing date, YYYY-MM-DD; null clears it), `episodeIds` (REPLACE-SET of condition links — the document's links become exactly this set; an empty array unlinks everything; every id must be a live episode of the caller or the whole request answers 404), `encounterIds` (the same replace-set semantics over the caller's visits). At least one field required. No `userId` field — narrowed from the session and fed to the Prisma `where` with the row id.",
|
||||
"Metadata edit for a stored document: `title` (user label; null clears it), `kind` (category), `documentDate` (user filing date, YYYY-MM-DD; null clears it), `episodeIds` (REPLACE-SET of condition links — the document's links become exactly this set; an empty array unlinks everything; every id must be a live episode of the caller or the whole request answers 404), `encounterIds` (the same replace-set semantics over the caller's visits), `vaccinationIds` (the same replace-set semantics over the caller's vaccination doses, up to 100 so one childhood record can be filed against a whole primary schedule). At least one field required. No `userId` field — narrowed from the session and fed to the Prisma `where` with the row id.",
|
||||
});
|
||||
|
||||
const documentBulkRequest = documentBulkSchema.meta({
|
||||
@@ -156,6 +156,19 @@ const encounterLink = z
|
||||
"A link to one of the caller's visits — \"this letter belongs to that appointment\". `kind` is the visit-kind ENUM CONSTANT rather than a rendered name: unlike a condition label, which is the person's own words, a visit kind is one of eight closed values whose human name the reader's own bundle owns, so publishing the constant is what lets a German reader and an English one each see it named correctly.",
|
||||
});
|
||||
|
||||
const vaccinationLink = z
|
||||
.object({
|
||||
vaccinationId: z.string(),
|
||||
occurredAt: z.string().nullable(),
|
||||
catalogSlug: z.string().nullable(),
|
||||
vaccineName: z.string().nullable(),
|
||||
})
|
||||
.meta({
|
||||
id: "DocumentVaccinationLink",
|
||||
description:
|
||||
"A link to one of the caller's vaccination doses — \"this page records that dose\". `catalogSlug` is the catalogue entry when this release still knows the dose's slug, for the reader's own bundle to name; null is the signal to show `vaccineName`, the person's own wording. The same table the dose's own `/api/vaccinations/{id}/links` writes from the other end.",
|
||||
});
|
||||
|
||||
const inboundDocument = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
@@ -203,6 +216,10 @@ const inboundDocument = z
|
||||
const inboundDocumentDetail = inboundDocument
|
||||
.extend({
|
||||
facts: z.array(extractedFact),
|
||||
vaccinationLinks: z.array(vaccinationLink).nullable().meta({
|
||||
description:
|
||||
"Vaccination doses this document is filed against. Null when the caller acts inside somebody else's record under a grant that does not cover the health background the doses live in: the page is shared, the doses are not, and an empty list would claim the page records none.",
|
||||
}),
|
||||
summary: z.string().nullable(),
|
||||
summaryGeneratedAt: z.string().nullable(),
|
||||
summaryState: z.enum(DOCUMENT_SUMMARY_STATES),
|
||||
|
||||
Reference in new issue
Block a user