{
    "about": "Golden cases for the check-in decision (CHECKIN_PROTOCOL §3 steps 1–10). Run by both tests/Feature/Checkin/GoldenCasesTest.php (ScanService) and apps/scanner/tests/golden.spec.ts (the scanner's local decision). Add a case whenever either changes. The world is Tests\\Support\\ScanScenario; the Pest suite fails if it drifts from what is written here. Result codes must match; wording may differ.",
    "world": {
        "timezone": "America/Chicago",
        "days": [
            { "code": "DAY1", "name": "Day 1 (Saturday)", "starts_at": "2026-11-07T14:00:00Z" },
            { "code": "DAY2", "name": "Day 2 (Sunday)", "starts_at": "2026-11-08T14:00:00Z" }
        ],
        "check_in_points": [
            {
                "code": "PRE", "name": "Group Pre-Check-in", "kind": "satellite",
                "window": { "DAY1": { "opens": "03:30", "closes": "12:00" }, "DAY2": { "opens": "03:30", "closes": "12:00" } },
                "policy": { "accept_types": ["VOL", "CHP", "YTH"], "days": [], "requires_prior": [], "override_roles": ["admin"], "scan_everyone_prompt": true, "search_enabled": true, "manual_entry_enabled": false, "day_lock": false, "once_per_day": false, "result_on_accept": "pre_checked" }
            },
            {
                "code": "GATE1", "name": "Venue Gate — DAY1", "kind": "gate", "window": null,
                "policy": { "accept_types": ["VOL", "CHP", "YTH"], "days": ["DAY1"], "requires_prior": [], "override_roles": ["admin", "group_lead"], "scan_everyone_prompt": true, "search_enabled": false, "manual_entry_enabled": false, "day_lock": true, "once_per_day": false, "result_on_accept": "accepted" }
            },
            {
                "code": "GATE2", "name": "Venue Gate — DAY2", "kind": "gate", "window": null,
                "policy": { "accept_types": ["VOL", "CHP", "YTH"], "days": ["DAY2"], "requires_prior": [], "override_roles": ["admin", "group_lead"], "scan_everyone_prompt": true, "search_enabled": false, "manual_entry_enabled": false, "day_lock": true, "once_per_day": false, "result_on_accept": "accepted" }
            },
            {
                "code": "Z-SPLASH", "name": "Splash Zone", "kind": "zone", "window": null,
                "policy": { "accept_types": [], "days": [], "requires_prior": ["gate"], "override_roles": [], "scan_everyone_prompt": true, "search_enabled": false, "manual_entry_enabled": false, "day_lock": false, "once_per_day": false, "result_on_accept": "zone_entered" }
            }
        ]
    },
    "setup_help": {
        "ticket": "a person of `type` holding one whole-event ticket; `registered` lists the days they signed up for; `then` is void or reissue (a reissue's replacement is the key plus 2)",
        "shared": "a chaperone holding a shared ticket that covers the named youths, each of whom also holds their own ticket"
    },
    "scan_help": {
        "form": "qr (default: the signed payload) · bare (the code alone, as a barcode carries it) · forged (the code with a wrong signature) · raw (the `raw` text as typed)",
        "people": "for a shared ticket: the covered people ticked as here"
    },
    "cases": [
        {
            "name": "a gate admits a volunteer to its only day",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [{ "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted", "people": { "amina": "accepted" } } }]
        },
        {
            "name": "the same ticket at a gate again is a duplicate",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [
                { "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted" } },
                { "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:05:00Z", "expect": { "result": "duplicate" } }
            ]
        },
        {
            "name": "a person admitted to Day 1 is locked out of Day 2 (acceptance 3)",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [
                { "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted" } },
                { "point": "GATE2", "ticket": "amina", "at": "2026-11-08T15:00:00Z", "expect": { "result": "day_locked" } }
            ]
        },
        {
            "name": "a type the gate does not take is rejected",
            "setup": [{ "ticket": "farid", "type": "REG" }],
            "scans": [{ "point": "GATE1", "ticket": "farid", "at": "2026-11-07T15:00:00Z", "expect": { "result": "rejected" } }]
        },
        {
            "name": "the pre-check opens at 03:30 local, closes after 12:00, and the gate then admits (acceptance 5)",
            "setup": [{ "ticket": "amina", "type": "VOL" }, { "ticket": "leila", "type": "VOL" }],
            "scans": [
                { "point": "PRE", "ticket": "amina", "day": "DAY1", "at": "2026-11-07T09:29:00Z", "expect": { "result": "not_yet_open" } },
                { "point": "PRE", "ticket": "amina", "day": "DAY1", "at": "2026-11-07T09:30:00Z", "expect": { "result": "pre_checked" } },
                { "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted" } },
                { "point": "PRE", "ticket": "leila", "day": "DAY1", "at": "2026-11-07T18:01:00Z", "expect": { "result": "closed" } }
            ]
        },
        {
            "name": "a zone wants the gate first, then admits every time (acceptance 6)",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [
                { "point": "Z-SPLASH", "ticket": "amina", "day": "DAY1", "at": "2026-11-07T15:00:00Z", "expect": { "result": "rejected" } },
                { "point": "GATE1", "ticket": "amina", "at": "2026-11-07T15:01:00Z", "expect": { "result": "accepted" } },
                { "point": "Z-SPLASH", "ticket": "amina", "day": "DAY1", "at": "2026-11-07T15:30:00Z", "expect": { "result": "zone_entered" } },
                { "point": "Z-SPLASH", "ticket": "amina", "day": "DAY1", "at": "2026-11-07T16:00:00Z", "expect": { "result": "zone_entered" } }
            ]
        },
        {
            "name": "a shared ticket asks who is here",
            "setup": [{ "shared": "karim", "youth": ["sara", "omar"] }],
            "scans": [{ "point": "GATE1", "ticket": "karim", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted", "needs_selection": true } }]
        },
        {
            "name": "a shared ticket admits its holder and the people ticked, and the others scan on their own (acceptance 4)",
            "setup": [{ "shared": "karim", "youth": ["sara", "omar"] }],
            "scans": [
                { "point": "GATE1", "ticket": "karim", "people": ["sara"], "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted", "people": { "karim": "accepted", "sara": "accepted" } } },
                { "point": "GATE1", "ticket": "omar", "at": "2026-11-07T15:02:00Z", "expect": { "result": "accepted" } },
                { "point": "GATE1", "ticket": "sara", "at": "2026-11-07T15:03:00Z", "expect": { "result": "duplicate" } }
            ]
        },
        {
            "name": "a void ticket and a replaced ticket are refused, the replaced one naming its replacement",
            "setup": [{ "ticket": "nadia", "type": "VOL", "then": "void" }, { "ticket": "noor", "type": "VOL", "then": "reissue" }],
            "scans": [
                { "point": "GATE1", "ticket": "nadia", "at": "2026-11-07T15:00:00Z", "expect": { "result": "voided" } },
                { "point": "GATE1", "ticket": "noor", "at": "2026-11-07T15:01:00Z", "expect": { "result": "voided", "replacement": true } },
                { "point": "GATE1", "ticket": "noor2", "at": "2026-11-07T15:02:00Z", "expect": { "result": "accepted" } }
            ]
        },
        {
            "name": "a forged signature or a code with no ticket behind it is unknown (acceptance 10)",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [
                { "point": "GATE1", "ticket": "amina", "form": "forged", "at": "2026-11-07T15:00:00Z", "expect": { "result": "unknown" } },
                { "point": "GATE1", "form": "raw", "raw": "NOPE-0001", "at": "2026-11-07T15:01:00Z", "expect": { "result": "unknown" } },
                { "point": "GATE1", "form": "raw", "raw": "EW1:broken", "at": "2026-11-07T15:02:00Z", "expect": { "result": "unknown" } }
            ]
        },
        {
            "name": "a bare code from a barcode is taken as it is",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [{ "point": "GATE1", "ticket": "amina", "form": "bare", "at": "2026-11-07T15:00:00Z", "expect": { "result": "accepted" } }]
        },
        {
            "name": "a zone that scans every day, with none chosen, asks for the day",
            "setup": [{ "ticket": "amina", "type": "VOL" }],
            "scans": [{ "point": "Z-SPLASH", "ticket": "amina", "at": "2026-11-07T15:00:00Z", "expect": { "result": "rejected" } }]
        },
        {
            "name": "someone registered only for Day 2 is the wrong day at the Day 1 gate",
            "setup": [{ "ticket": "leila", "type": "VOL", "registered": ["DAY2"] }],
            "scans": [{ "point": "GATE1", "ticket": "leila", "at": "2026-11-07T15:00:00Z", "expect": { "result": "wrong_day" } }]
        }
    ]
}
