Newer
Older
client_dwatch / lib / clean-logs / result-pending.ts
import { RESULT_WAIT_MINUTES } from "@/lib/config";

/**
 * ★結果待ちか★(ユーザー判断 2026-10-07。D-173)— ★判定はこの関数1本★。
 *
 * レポートは清掃の後 30 分より遅れて届くことがあるため、★予定の終了(無ければ開始)から
 * `waitMinutes`(既定 `RESULT_WAIT_MINUTES`)分のあいだは、レポートが無くても出発失敗に数えない★。
 *
 * - レポートあり → `false`
 * - `startAt > now`(未来の予定)→ `false`(★この関数の対象外★。未来の予定は今までどおり行が出ない・数えない)
 * - `now < (endAt ?? startAt) + waitMinutes` → `true`(★清掃中も含む★。境界ちょうどは `false`=確定)
 * - それ以外 → `false`(今までどおり出発失敗)
 *
 * ★`true` でも行の `departed` / `task_status` / `completion_rate` / `grade` は変えない★ —
 * 結果待ちは `CleanLogItem.result_pending` という別の旗で表す(旗を見ない処理は安全側に出発失敗のまま)。
 * ★D-091 項1(当方で「予定+猶予」を計算しない)は、この件に限りユーザー判断で上書き★。
 * `LAUNCH_GRACE_MINUTES` は使わない。
 *
 * ★`Date` は「真の瞬間」で渡すこと★(DB の壁時計値は `fromDbJst()` で直してから)。期待値表は
 * `lib/clean-logs/__tests__/result-pending.test.ts`(表1)。
 */
export function isResultPending(params: {
  startAt: Date;
  endAt: Date | null;
  now: Date;
  hasReport: boolean;
  waitMinutes?: number;
}): boolean {
  const { startAt, endAt, now, hasReport, waitMinutes = RESULT_WAIT_MINUTES } = params;
  if (hasReport) return false;
  if (startAt.getTime() > now.getTime()) return false;
  const base = (endAt ?? startAt).getTime();
  return now.getTime() < base + waitMinutes * 60_000;
}