/**
* ★`error_list_id`(エラー内容)を書ける経路はエラー一覧の PATCH だけ★であることを固定する(指示書BD §2。D-184)。
*
* - D-Sec アラート画面(`components/features/ds-alerts/DsAlertsScreen.tsx`)は `PATCH /errors/{error_id}/status` を使うが、
* 本文は `saveDrafts()` → `patchRequestFromDraft()`(`lib/prechecks/edit-drafts.ts`)で作る。
* ★その本文に `error_list_id` が入らないこと★を見る(`ResolutionDraft` に余計なキーが紛れても写さない)。
* サーバー側の歯止め(D-Sec の行は `error_list_selectable=false` → 送れば422)は
* `app/api/errors/[error_id]/status/__tests__/route.test.ts` の「選べない行」が見る。
* - 事前チェック(`PATCH /prechecks/{id}/status`)の歯止めは `lib/db/__tests__/robot-error-write-sql.test.ts`
* (4列の写しが `error_list_id` で例外)と `app/api/prechecks/[id]/status/__tests__/route.test.ts`(本文から捨てる)。
*
* ★エラー一覧の画面で `error_list_id` を送れるようにするとき(次の指示書)も、D-Sec の経路はこのテストのまま通ること★。
*/
import { describe, expect, it } from "vitest";
import { patchRequestFromDraft, saveDrafts, type ResolutionDraft } from "@/lib/prechecks/edit-drafts";
import type { DsAlert, PrecheckStatusUpdateRequest } from "@/lib/types";
function dsAlert(id: string, overrides: Partial<DsAlert> = {}): DsAlert {
return {
id,
alert_type: "disconnected",
device_serial: "DFAS010001",
facility_id: 3,
facility_name: "テスト施設C",
section_name: "1F売り場",
detected_at: "2026-10-19T01:30:00+09:00",
resolution_status: "unresolved",
responded_at: null,
resolved_at: null,
note: null,
...overrides,
};
}
describe("D-Sec アラートの保存の本文に error_list_id が入らない", () => {
it("★下書きに error_list_id が紛れても本文は status / note だけ★", () => {
const draft = { status: "in_progress", note: "確認", error_list_id: 131 } as unknown as ResolutionDraft;
const request = patchRequestFromDraft(dsAlert("DS-1"), draft);
expect(request).toEqual({ status: "in_progress", note: "確認" });
expect(Object.keys(request ?? {}).sort()).toEqual(["note", "status"]);
});
it("★saveDrafts() が send に渡す本文(= JSON.stringify される値)にも入らない★", async () => {
const rows = [dsAlert("DS-1"), dsAlert("DS-2", { note: "既存" })];
const drafts = new Map<string, ResolutionDraft>([
["DS-1", { status: "resolved", error_list_id: 40 } as unknown as ResolutionDraft],
["DS-2", { note: "更新" }],
]);
const sent: PrecheckStatusUpdateRequest[] = [];
await saveDrafts(rows, drafts, async (row, request) => {
sent.push(request);
return row;
});
expect(sent).toHaveLength(2);
for (const request of sent) {
expect(JSON.parse(JSON.stringify(request))).not.toHaveProperty("error_list_id");
}
});
});