Newer
Older
client_dwatch / lib / format / group-id.ts
/**
 * `customers.group_id`(DB)↔ `group_id`(API)の変換。
 *
 * ```
 * DB : customers.group_id = 0   (NOT NULL。0 = ホールディングスなしのセンチネル。D-011)
 * API: group_id = null
 * ```
 *
 * ★★変換をここ1箇所に閉じ込めること★★(指示書AK §4-4。`lib/format/contract.ts` と同じ作法)—
 *   ルート・`DataSource` 実装・fixtures に `=== 0` を散らすと、
 *   1箇所直し忘れたときに ★「グループ0」という存在しないホールディングスが画面に出る★
 *   (指示書AK 落とし穴3)。★例外もテスト失敗も出ない★。
 *
 * ★センチネル値そのものは `lib/config/index.ts` の `GROUP_ID_NONE` から読む★
 *   (`CLAUDE.md` §7「閾値のハードコード禁止」と同じ考え方)。
 *
 * ★逆方向(API → DB)の関数は用意しない★ — API の `group_id` は
 *   ★1以上しか受け付けない★(0 はセンチネルで有効なIDではない。
 *   `lib/api/master-id.ts` が入口で 422 にする)ので、変換の必要が無い。
 *
 * ★純粋関数にすること★(`CLAUDE.md` §9.4)— DBアクセスやログ出力を混ぜない。
 */
import { GROUP_ID_NONE } from "@/lib/config";

/**
 * DB の `customers.group_id` を API の `group_id`(nullable)に変換する。
 *
 * ★`Number(row.group_id)` で `BigInt` を落としてから渡すこと★
 *   (`prismaSource` の他のメソッドと同じ。`BigInt` のまま `=== 0` は `0n === 0` が
 *   `false` なので静かに外れる)。
 */
export function groupIdFromDb(groupId: number): number | null {
  return groupId === GROUP_ID_NONE ? null : groupId;
}