Files
temetro/backend/src/routes/activity.ts
T
Khalid Abdi 3ee00fcf06 feat: per-patient record history + summary PDF export
Add GET /api/activity/patient/:fileNumber (every audited change on one chart,
newest first, readable by any clinic member) and surface it as a Record
history timeline in the patient detail sheet. Add a Download summary action
that builds a clean, printable one-page clinical summary in the browser
(Save as PDF) — no PDF dependency, nothing leaves the server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 21:33:31 +03:00

43 lines
1.3 KiB
TypeScript

import { Router } from "express";
import { requireAuth, requireOrg } from "../middleware/auth.js";
import * as service from "../services/activity.js";
export const activityRouter = Router();
// The audit feed is readable by any clinic member.
activityRouter.use(requireAuth, requireOrg);
// Whether the caller runs the clinic (owner/admin) and may therefore see the
// whole feed. Everyone else is scoped to their own actions.
function isClinicAdmin(memberRole: string | undefined): boolean {
return String(memberRole ?? "")
.split(",")
.map((s) => s.trim())
.some((r) => r === "owner" || r === "admin");
}
activityRouter.get("/", async (req, res, next) => {
try {
const actorId = isClinicAdmin(req.memberRole) ? undefined : req.user!.id;
res.json(await service.listActivity(req.organizationId!, { actorId }));
} catch (err) {
next(err);
}
});
// A single patient's record history (who added/changed what, when). Any clinic
// member can read it — it's the audit trail for that chart.
activityRouter.get("/patient/:fileNumber", async (req, res, next) => {
try {
res.json(
await service.listPatientActivity(
req.organizationId!,
req.params.fileNumber as string,
),
);
} catch (err) {
next(err);
}
});