Newer
Older
client_dwatch / lib / db / fixture-clean-logs.ts
/**
 * fixtures 版 `cleanLogs()` の絞り込み(指示書AC 段階2 ★D-5★)。
 *
 * ★★`USE_FIXTURES` の true/false で件数が変わってはいけない★★(指示書AC 禁止事項6)。
 *   Prisma 版が SQL に降ろした条件(日付範囲・施設ID)と ★同じ意味★ をここで再現します。
 *
 * ★★`null` と `[]` を同じ意味で扱わないこと★★(★罠9★ / 罠1):
 *   - `facility_ids === null` … 施設で絞らない(全件)
 *   - `facility_ids === []`   … ★0件を返す★(「施設名で照合したが1件も当たらなかった」)
 *   ★`[]` を「条件なし」と読んで全件返す実装にすると、`USE_FIXTURES` の true/false で
 *   件数が変わります★(Prisma 側は `in: []` = `WHERE 1=0` = 0件)。
 *
 * ★DBアクセスを混ぜない純粋関数★(テストから直接呼べるようにするため)。
 *
 * ★★`id`(単一ID の取得。指示書AC 段階3)も同じ意味で扱うこと★★ —
 *   `null` = 指定なし(全件)/ 値あり = ★その1件だけ★。
 */
import type { CleanLogDbQuery, CleanLogItem } from "@/lib/types";

/**
 * ★日付の比較は文字列のまま行う★ — `scheduled_at` は ISO8601(+09:00)なので
 * ★先頭10文字が JST の日付そのもの★ になり、実行環境のタイムゾーンに依存しません
 * (`app/api/dashboard/route.ts` が当日の絞り込みで使っているのと同じ作法)。
 * ★`new Date()` を挟むと、Prisma 版が壁時計値で絞っているのと基準がずれます★。
 */
export function filterFixtureCleanLogs(
  rows: readonly CleanLogItem[],
  query: CleanLogDbQuery
): CleanLogItem[] {
  return rows.filter((row) => {
    // ★単一ID の取得経路(指示書AC 段階3)★ — ★★`!== null` で分岐すること★★
    //   (`id: 0` は `clean_timetables.id` としてありえない値だが、`?` や `||` で
    //   書くと「0 を指定した」が「指定なし=全件」に化ける書き方の練習になってしまう)。
    if (query.id !== null && row.id !== query.id) return false;
    const date = row.scheduled_at.slice(0, 10);
    if (query.date_from !== null && date < query.date_from) return false;
    // ★`date_to` はその日を**含む**(`dbDateRange()` の `lt` = 翌日 00:00 と同じ意味)★
    if (query.date_to !== null && date > query.date_to) return false;
    // ★★必ず `!== null` で分岐すること★★(罠1。`?.length` や三項で書くと
    //   ★`[]` が「条件なし」に化けて 0件が全件になります★)
    if (query.facility_ids !== null && !query.facility_ids.includes(row.facility_id)) {
      return false;
    }
    return true;
  });
}