backend: include appointments & invoices in the wallet push bundle

Appointments and invoices live in their own tables, not on the Patient
snapshot, so a clinic->wallet push previously sealed only the patient record
and the patient's appointments/invoices never reached the wallet app. Load and
attach them to the sealed bundle ({ patient, appointments, invoices, changes }).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-07-08 19:34:27 +03:00
parent fb9fa299c9
commit 1c5e71eb39
+18 -2
View File
@@ -13,6 +13,8 @@ import {
verifySignature,
} from "../lib/wallet-crypto.js";
import { ed25519PubToX25519Hex } from "../lib/wallet-x25519.js";
import { listAppointments } from "./appointments.js";
import { listInvoices } from "./invoices.js";
import { getPatient } from "./patients.js";
import { signWithClinicKey } from "./signing.js";
@@ -100,9 +102,23 @@ export async function createRecordUpdate(
const patient = await getPatient(orgId, fileNumber);
if (!patient) throw new HttpError(404, "Patient not found.");
// Appointments and invoices live in their own tables (not on the Patient
// snapshot), so pull the ones for this patient and ship them alongside — the
// wallet has no other way to see them and they'd otherwise silently vanish.
const [orgAppointments, orgInvoices] = await Promise.all([
listAppointments(orgId),
listInvoices(orgId),
]);
const appointments = orgAppointments.filter(
(a) => a.fileNumber === fileNumber,
);
const invoices = orgInvoices.filter((i) => i.fileNumber === fileNumber);
// The wallet opens this, verifies the signature over the same bytes, then
// replaces its on-device record with `patient`.
const bundle = utf8ToBytes(JSON.stringify({ patient, changes }));
// replaces its on-device record with `patient` (+ appointments/invoices).
const bundle = utf8ToBytes(
JSON.stringify({ patient, appointments, invoices, changes }),
);
const { signature, publicKey } = await signWithClinicKey(orgId, bundle);
const x25519Hex = ed25519PubToX25519Hex(decodeWalletNumber(walletNumber));
const sealed = seal(x25519Hex, bundle);