/**
* 清掃レポート・エラーの `clean_timetable_id` から「予定のタスクか、予定外のタスクか」を決める1本
* (TeamWorks 回答 2026-10-27。ユーザー指示「clean_timetable_id が入っているのでそれで予定タスクか予定外タスクかの判断をしてください」)。
*
* - ★`0`(`CLEAN_TIMETABLE_ID_UNSCHEDULED`)と NULL は予定外★ → `null`
* - それ以外は予定の id(`clean_timetables` / `clean_timetable_histories` の id)→ そのまま返す
* (★予定の表に行があるかは見ない★ — 無ければ呼び出し側が今までどおり「参照先なし」として扱う)
*
* ★`clean_timetable_id === null` や Prisma の `{ not: null }` を直書きしないこと★ — 0 が「予定の id」として
* すり抜け、エラー一覧の「紐づく予定」が「不明」になる・清掃エリアで予定を引けない行としてログに出る。
*/
import { CLEAN_TIMETABLE_ID_UNSCHEDULED } from "@/lib/config";
import type { Prisma } from "@/lib/generated/prisma/client";
/**
* `clean_timetable_id` の生値 → 予定の id。予定外(0・NULL)なら `null`。
*
* @param raw DB(`bigint`)または fixtures(`number`)の `clean_timetable_id`
*/
export function scheduledTimetableId<T extends bigint | number>(raw: T | null | undefined): T | null {
if (raw === null || raw === undefined) return null;
if (Number(raw) === CLEAN_TIMETABLE_ID_UNSCHEDULED) return null;
return raw;
}
/**
* Prisma の `where` で「予定のタスクの行だけ」に絞る条件(`clean_timetable_id: SCHEDULED_TIMETABLE_ID_WHERE`)。
*
* ★`gt` は NULL を含まない★(SQL の比較で NULL は偽)。列は unsigned なので `> 0` =「0 でも NULL でもない」。
*/
export const SCHEDULED_TIMETABLE_ID_WHERE = { gt: BigInt(CLEAN_TIMETABLE_ID_UNSCHEDULED) } as const;
/**
* Prisma の `where` で「予定外のタスクの行だけ」に絞る条件(`SCHEDULED_TIMETABLE_ID_WHERE` の裏返し。指示書BG)。
* `clean_task_reports` / `robot_error_reports` の `where` に ★展開して★ 混ぜる(`...UNSCHEDULED_TIMETABLE_ID_WHERE`)。
*
* ★SQL 側の写し★ — 判定の正は `scheduledTimetableId()`(取り寄せた行は必ずそちらでも絞り直す)。
* ★`{ not: ... }` / `NOT` で書かないこと★ — `NOT (clean_timetable_id > 0)` は NULL の行を落とす(SQL の比較で NULL は偽)。
* ★トップレベルの `OR` を持つ★ので、同じ階層に別の `OR` を置くときは `AND: [...]` で包む。
*/
export const UNSCHEDULED_TIMETABLE_ID_WHERE = {
OR: [
{ clean_timetable_id: null },
{ clean_timetable_id: BigInt(CLEAN_TIMETABLE_ID_UNSCHEDULED) },
],
} as const satisfies Prisma.CleanTaskReportWhereInput & Prisma.RobotErrorReportWhereInput;