import { randomUUID } from "node:crypto"; import { and, desc, eq } from "drizzle-orm"; import { jsonFailure, jsonSuccess, readJsonBody } from "@/modules/core/server/api"; import { recordAuditLog } from "@/modules/core/server/audit"; import { requirePermission } from "@/modules/core/server/auth"; import { getDatabase } from "@/modules/core/server/db"; import { admissions, beds, elders } from "@/modules/core/server/schema"; import { validateElderInput } from "@/modules/elders/types"; import type { Elder } from "@/modules/elders/types"; function toElder(row: typeof elders.$inferSelect, bedLabel?: { room: string; bed: string; bedId: string }): Elder { return { id: row.id, organizationId: row.organizationId, name: row.name, gender: row.gender, age: row.age, careLevel: row.careLevel, room: bedLabel?.room ?? "", bed: bedLabel?.bed ?? "", bedId: bedLabel?.bedId, status: row.status, primaryContact: row.primaryContact, phone: row.phone, medicalNotes: row.medicalNotes, createdAt: row.createdAt.toISOString(), updatedAt: row.updatedAt.toISOString(), }; } export async function GET(): Promise { const auth = await requirePermission("elder:read", { action: "elder.list", targetType: "elder", }); if (!auth.success) { return auth.response; } const organizationId = auth.context.organization?.id; if (!organizationId) { return jsonFailure("请选择机构后查看老人档案", 400); } const database = getDatabase(); const rows = await database .select() .from(elders) .where(eq(elders.organizationId, organizationId)) .orderBy(desc(elders.createdAt)); return jsonSuccess("老人档案已加载", { elders: rows.map((row) => toElder(row)) }); } export async function POST(request: Request): Promise { const auth = await requirePermission("elder:create", { action: "elder.create", targetType: "elder", }); if (!auth.success) { return auth.response; } const organizationId = auth.context.organization?.id; if (!organizationId) { return jsonFailure("请选择机构后新增老人档案", 400); } const input = validateElderInput(await readJsonBody(request)); if (!input.success) { return jsonFailure(input.reason); } const database = getDatabase(); const created = await database.transaction(async (transaction) => { const elderId = randomUUID(); const elderRows = await transaction .insert(elders) .values({ id: elderId, organizationId, name: input.data.name, gender: input.data.gender, age: input.data.age, careLevel: input.data.careLevel, status: input.data.status, primaryContact: input.data.primaryContact, phone: input.data.phone, medicalNotes: input.data.medicalNotes, }) .returning(); const elder = elderRows[0]; if (!elder) { throw new Error("老人档案创建失败"); } if (input.data.bedId) { const bedRows = await transaction .select() .from(beds) .where(and(eq(beds.id, input.data.bedId), eq(beds.organizationId, organizationId))) .limit(1); const bed = bedRows[0]; if (!bed) { throw new Error("床位不存在"); } if (bed.status !== "available") { throw new Error("床位不可分配"); } await transaction .insert(admissions) .values({ organizationId, elderId: elder.id, bedId: bed.id, status: "active", notes: "新增档案时办理入住", }); await transaction.update(beds).set({ status: "occupied", updatedAt: new Date() }).where(eq(beds.id, bed.id)); } return elder; }); const elder = toElder(created); await recordAuditLog({ actor: auth.context.account, organizationId, action: "elder.create", targetType: "elder", targetId: elder.id, result: "success", reason: `新增老人档案:${elder.name}`, }); return jsonSuccess("老人档案已创建", { elder }, 201); }