mirror of
https://github.com/temetro/temetro.git
synced 2026-08-28 19:37:33 +00:00
36461a5498
Patient record: - Add `bloodType` and `phone` to the patient model (schema, canonical types on both backend + frontend, zod validation). `phone` is a demographic field (reception can read/write); `bloodType` is clinical PHI, redacted for the reception role. Surface both in the record sheet, chat summary card, and the add/edit patient form. Migration 0033. Clinic location: - New org-scoped `clinic_settings` table (address/city/country + optional lat/long), service, and routes: GET /api/clinic/settings (any clinician) and PUT /api/clinic/location (owner/admin). Edited in Settings → Signing → Clinic location. Consumed later by the wallet app. Migration 0034. i18n: - Translate all new keys into every shipped locale (en/de/fr/ar/so) and document the "translate into every locale" rule in frontend/CLAUDE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { Router } from "express";
|
|
import { z } from "zod";
|
|
|
|
import {
|
|
requireAuth,
|
|
requireOrg,
|
|
requirePermission,
|
|
} from "../middleware/auth.js";
|
|
import { recordActivity } from "../services/activity.js";
|
|
import * as clinicSettings from "../services/clinic-settings.js";
|
|
|
|
export const clinicRouter = Router();
|
|
|
|
clinicRouter.use(requireAuth, requireOrg);
|
|
|
|
// The clinic's settings (currently just its location). Readable by any
|
|
// clinician so the app/UI can display the clinic address.
|
|
clinicRouter.get(
|
|
"/settings",
|
|
requirePermission({ patient: ["read"] }),
|
|
async (req, res, next) => {
|
|
try {
|
|
res.json(await clinicSettings.getClinicSettings(req.organizationId!));
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
},
|
|
);
|
|
|
|
// Set the clinic's location — owner/admin only (gated on the org-update
|
|
// statement, same as signing-key rotation / network toggle).
|
|
const locationSchema = z.object({
|
|
address: z.string().trim().max(200).default(""),
|
|
city: z.string().trim().max(120).default(""),
|
|
country: z.string().trim().max(120).default(""),
|
|
latitude: z.number().min(-90).max(90).nullable().default(null),
|
|
longitude: z.number().min(-180).max(180).nullable().default(null),
|
|
});
|
|
|
|
clinicRouter.put(
|
|
"/location",
|
|
requirePermission({ organization: ["update"] }),
|
|
async (req, res, next) => {
|
|
try {
|
|
const location = locationSchema.parse(req.body);
|
|
const view = await clinicSettings.setClinicLocation(
|
|
req.organizationId!,
|
|
location,
|
|
);
|
|
await recordActivity({
|
|
orgId: req.organizationId!,
|
|
actor: { id: req.user!.id, name: req.user!.name },
|
|
action: "Updated the clinic location",
|
|
entityType: "settings",
|
|
});
|
|
res.json(view);
|
|
} catch (err) {
|
|
next(err);
|
|
}
|
|
},
|
|
);
|