import { and, 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 { systemIncidents } from "@/modules/core/server/schema"; import type { IncidentStatus } from "@/modules/core/types"; type RouteContext = { params: Promise<{ id: string; }>; }; const INCIDENT_STATUSES: IncidentStatus[] = ["open", "acknowledged", "resolved", "closed"]; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function readStatus(value: unknown): IncidentStatus | null { if (typeof value !== "string") { return null; } return INCIDENT_STATUSES.find((status) => status === value) ?? null; } export async function PATCH(request: Request, context: RouteContext): Promise { const { id } = await context.params; const auth = await requirePermission("incident:manage", { action: "incident.update", targetType: "incident", targetId: id, }); if (!auth.success) { return auth.response; } const body = await readJsonBody(request); if (!isRecord(body)) { return jsonFailure("请求数据格式无效"); } const status = readStatus(body.status); if (!status) { return jsonFailure("故障状态无效"); } const database = getDatabase(); const organizationId = auth.context.organization?.id; const updateValues = { status, updatedAt: new Date(), acknowledgedByAccountId: status === "acknowledged" ? auth.context.account.id : undefined, acknowledgedAt: status === "acknowledged" ? new Date() : undefined, resolvedByAccountId: status === "resolved" || status === "closed" ? auth.context.account.id : undefined, resolvedAt: status === "resolved" || status === "closed" ? new Date() : undefined, }; const rows = organizationId ? await database .update(systemIncidents) .set(updateValues) .where(and(eq(systemIncidents.id, id), eq(systemIncidents.organizationId, organizationId))) .returning() : await database.update(systemIncidents).set(updateValues).where(eq(systemIncidents.id, id)).returning(); const incident = rows[0]; if (!incident) { return jsonFailure("故障事件不存在", 404); } await recordAuditLog({ actor: auth.context.account, organizationId: incident.organizationId ?? undefined, action: "incident.update", targetType: "incident", targetId: incident.id, result: "success", reason: `故障状态更新为:${status}`, }); return jsonSuccess("故障事件已更新", { incident }); }