{
  "input": {
    "origin": "架空のサンプル9名。実在のお客様のデータではありません。",
    "csv": "id,name,last_visit,menu,cycle_days,line_friend,consent,next_booking,last_contact\nS01,サンプルA,2026-08-01,カット＋カラー,42,yes,yes,,\nS02,サンプルB,2026-08-17,カット,42,yes,yes,,\nS03,サンプルC,2026-06-20,トリートメント,60,yes,yes,,2026-08-01\nS04,サンプルD,2026-08-01,カット,42,yes,no,,\nS05,サンプルE,2026-08-01,カット,42,no,yes,,\nS06,サンプルF,2026-08-01,カット,42,yes,yes,2026-09-30,\nS07,サンプルG,2026-08-01,カラー,42,yes,yes,,2026-09-25\nS08,サンプルH,2026-09-20,カット,42,yes,yes,,\nS09,サンプルI,2026-02-30,カット,42,yes,yes,,",
    "options": {
      "today": "2026-09-28",
      "cooldown": 14,
      "salon": "サンプル美容室"
    }
  },
  "process": {
    "type": "actual-business-logic",
    "engine": "salon-line local rules v1",
    "engineSha256": "eb390eab70f25c611aa7c116b0f4c02845da75f277dfaa2e83bf6df295164edd",
    "steps": [
      "CSVの引用符・列名・行数を解析",
      "日付・状態値・顧客IDの重複を検証",
      "案内への同意・友だち状態・予約・再連絡の間隔を確認",
      "来店周期を満たす方を抽出し、超過日数順に並べる",
      "定型の下書きを作成",
      "テスト操作で1件を確認済みにし、JSON出力を検証"
    ],
    "aiUsed": false,
    "externalRequests": 0,
    "messagesSent": 0
  },
  "output": {
    "total": 9,
    "candidates": [
      {
        "id": "S03",
        "name": "サンプルC",
        "last_visit": "2026-06-20",
        "menu": "トリートメント",
        "cycle_days": "60",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "2026-08-01",
        "row": 4,
        "days": 100,
        "overdue": 40,
        "reasons": [
          "最終来店から100日 / 設定周期60日"
        ],
        "draft": "サンプルC様、こんにちは。サンプル美容室です。\n前回のトリートメントでのご来店、ありがとうございました。\n次のご来店をご希望でしたら、ご都合のよい日をお知らせください。予約の空き状況を確認してご案内します。\nご案内が不要でしたら、その旨をお知らせください。"
      },
      {
        "id": "S01",
        "name": "サンプルA",
        "last_visit": "2026-08-01",
        "menu": "カット＋カラー",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "",
        "row": 2,
        "days": 58,
        "overdue": 16,
        "reasons": [
          "最終来店から58日 / 設定周期42日"
        ],
        "draft": "サンプルA様、こんにちは。サンプル美容室です。\n前回のカット＋カラーでのご来店、ありがとうございました。\n次のご来店をご希望でしたら、ご都合のよい日をお知らせください。予約の空き状況を確認してご案内します。\nご案内が不要でしたら、その旨をお知らせください。"
      },
      {
        "id": "S02",
        "name": "サンプルB",
        "last_visit": "2026-08-17",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "",
        "row": 3,
        "days": 42,
        "overdue": 0,
        "reasons": [
          "最終来店から42日 / 設定周期42日"
        ],
        "draft": "サンプルB様、こんにちは。サンプル美容室です。\n前回のカットでのご来店、ありがとうございました。\n次のご来店をご希望でしたら、ご都合のよい日をお知らせください。予約の空き状況を確認してご案内します。\nご案内が不要でしたら、その旨をお知らせください。"
      }
    ],
    "excluded": [
      {
        "id": "S04",
        "name": "サンプルD",
        "last_visit": "2026-08-01",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "no",
        "next_booking": "",
        "last_contact": "",
        "row": 5,
        "days": 58,
        "overdue": 16,
        "reasons": [
          "案内を希望していない"
        ]
      },
      {
        "id": "S05",
        "name": "サンプルE",
        "last_visit": "2026-08-01",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "no",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "",
        "row": 6,
        "days": 58,
        "overdue": 16,
        "reasons": [
          "LINEの友だちを確認できていない"
        ]
      },
      {
        "id": "S06",
        "name": "サンプルF",
        "last_visit": "2026-08-01",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "2026-09-30",
        "last_contact": "",
        "row": 7,
        "days": 58,
        "overdue": 16,
        "reasons": [
          "次回予約がある"
        ]
      },
      {
        "id": "S07",
        "name": "サンプルG",
        "last_visit": "2026-08-01",
        "menu": "カラー",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "2026-09-25",
        "row": 8,
        "days": 58,
        "overdue": 16,
        "reasons": [
          "前回連絡から14日未満"
        ]
      },
      {
        "id": "S08",
        "name": "サンプルH",
        "last_visit": "2026-09-20",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "",
        "row": 9,
        "days": 8,
        "overdue": -34,
        "reasons": [
          "設定した来店周期にまだ達していない"
        ]
      }
    ],
    "errors": [
      {
        "id": "S09",
        "name": "サンプルI",
        "last_visit": "2026-02-30",
        "menu": "カット",
        "cycle_days": "42",
        "line_friend": "yes",
        "consent": "yes",
        "next_booking": "",
        "last_contact": "",
        "row": 10,
        "days": null,
        "overdue": null,
        "reasons": [
          "最終来店日が不正、または未来日"
        ]
      }
    ],
    "trace": [
      {
        "row": 2,
        "id": "S01",
        "state": "needs_human_review",
        "days": 58,
        "reasons": [
          "最終来店から58日 / 設定周期42日"
        ]
      },
      {
        "row": 3,
        "id": "S02",
        "state": "needs_human_review",
        "days": 42,
        "reasons": [
          "最終来店から42日 / 設定周期42日"
        ]
      },
      {
        "row": 4,
        "id": "S03",
        "state": "needs_human_review",
        "days": 100,
        "reasons": [
          "最終来店から100日 / 設定周期60日"
        ]
      },
      {
        "row": 5,
        "id": "S04",
        "state": "excluded",
        "days": 58,
        "reasons": [
          "案内を希望していない"
        ]
      },
      {
        "row": 6,
        "id": "S05",
        "state": "excluded",
        "days": 58,
        "reasons": [
          "LINEの友だちを確認できていない"
        ]
      },
      {
        "row": 7,
        "id": "S06",
        "state": "excluded",
        "days": 58,
        "reasons": [
          "次回予約がある"
        ]
      },
      {
        "row": 8,
        "id": "S07",
        "state": "excluded",
        "days": 58,
        "reasons": [
          "前回連絡から14日未満"
        ]
      },
      {
        "row": 9,
        "id": "S08",
        "state": "excluded",
        "days": 8,
        "reasons": [
          "設定した来店周期にまだ達していない"
        ]
      },
      {
        "row": 10,
        "id": "S09",
        "state": "needs_correction",
        "days": null,
        "reasons": [
          "最終来店日が不正、または未来日"
        ]
      }
    ]
  },
  "humanReview": {
    "status": "店長による実運用の確認は未実施",
    "method": "検証担当のブラウザ操作で、文面修正→チェック解除→再チェック→1件の保存を検証。店舗の担当者による承認・送信ではありません。",
    "automatedReviewExample": {
      "version": 1,
      "kind": "sample_review_export",
      "status": "reviewed_drafts_not_sent",
      "date": "2026-09-28",
      "sent": 0,
      "notice": "送信前に最新の同意・予約・宛先を店舗で再確認してください。このファイルから送信は行われません。",
      "drafts": [
        {
          "customer_id": "S03",
          "name": "サンプルC",
          "text": "サンプルC様、こんにちは。サンプル美容室です。\n前回のトリートメントでのご来店、ありがとうございました。\n次のご来店をご希望でしたら、ご都合のよい日をお知らせください。予約の空き状況を確認してご案内します。\nご案内が不要でしたら、その旨をお知らせください。",
          "reviewed": true
        }
      ]
    },
    "requiredBeforeSending": [
      "最新の同意と友だち状態",
      "次回予約と直近の連絡",
      "実際の宛先との一致",
      "文面の内容"
    ]
  },
  "provenance": "この公開サンプル用に実装した候補判定プログラムを、架空の入力で実行した記録です。AI生成・LINE接続・顧客の導入実績ではありません。",
  "recordedAt": "2026-09-27T22:49:52.675Z"
}
