frontend: patient delete + complete sheet + Obsidian-style record graph

- deletePatient() lib fn (DELETE /api/patients/:fileNumber already existed)
- confirmed delete button in the patient sheet (full-clinician only)
- aggregate appointments/prescriptions/invoices into the sheet (by file #)
- new shared RecordGraph (@xyflow/react + d3-force) linking problems↔visits,
  added as a "Record graph" section + reusable by AI Graph mode
- i18n keys for delete + new sheet sections

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-17 19:02:32 +03:00
parent 705d4b5719
commit 3b4e1c7f61
7 changed files with 396 additions and 2 deletions
@@ -206,6 +206,16 @@
"successBody": "{{name}} is now with {{provider}}.",
"errorTitle": "Couldn't transfer patient",
"error": "Please try again."
},
"delete": {
"action": "Delete patient",
"title": "Delete patient?",
"body": "Permanently delete {{name}}'s chart and all of its records. This cannot be undone.",
"confirm": "Delete patient",
"cancel": "Cancel",
"doneTitle": "Patient deleted",
"failedTitle": "Couldn't delete patient",
"failedBody": "Please try again."
}
},
"appointments": {
@@ -1022,6 +1032,23 @@
"recent": "{{count}} recent",
"empty": "No visits yet."
},
"graph": {
"title": "Record graph",
"hint": "How this patient's problems and visits connect. Drag nodes; scroll to pan.",
"empty": "Not enough record data to graph yet."
},
"appointments": {
"title": "Appointments",
"empty": "No appointments on file."
},
"prescriptions": {
"title": "Prescriptions",
"empty": "No prescriptions on file."
},
"invoices": {
"title": "Invoices",
"empty": "No invoices on file."
},
"trend": {
"empty": "No trend data yet.",
"last": "{{label}} · last {{count}}",
+10
View File
@@ -130,6 +130,16 @@ export async function appendLabs(
);
}
// Permanently delete a patient's chart. Backed by DELETE
// /api/patients/:fileNumber (gated by `patient:delete` — the full-clinician
// marker). Resolves on 204; throws ApiError on failure.
export async function deletePatient(fileNumber: string): Promise<void> {
await apiFetch<void>(
`/api/patients/${encodeURIComponent(fileNumber.trim())}`,
{ method: "DELETE" },
);
}
// Reassign a patient to another clinician (sets their primary provider + PCP).
export async function transferPatient(
fileNumber: string,