Design Spec: Resilient Player Sessions & ScanView Refactor
1. Problem Statement
Players currently lose their scavenger hunt progress if their mobile browser clears localStorage or if they accidentally close an "In-App" browser (common in QR scanners). This creates friction and frustration in a museum/venue setting. Additionally, the ScanView.vue component has become too large and complex to maintain easily.
2. Goals
- Recovery: Allow players to recover sessions using their Nickname and PIN.
- Resilience: Decouple "Collection" views from transient local storage.
- Maintainability: Decompose
ScanView.vueinto smaller, reusable components.
3. Proposed Changes
3.1 Player Recovery UI (PlayerView.vue)
- Empty State Update: If no
participantIdis found inlocalStorage, display a "Resume Adventure" card instead of "No Active Hunt". - Recovery Form: A simple form (Nickname + PIN) that calls
/api/scan/progress. - Session Restoration: Upon successful API response, restore the
participantIdtolocalStorageand refresh the view.
3.2 Unified Join/Resume (ScanView.vue)
- UI Update: Change form title to "Join or Resume".
- Subtext: Add: "Already playing? Enter your details to continue where you left off."
- Logic: The existing
/api/scan/joinendpoint is already deterministic (Name+PIN+Date). If a user "Joins" with existing credentials, it will return their current progress seamlessly.
3.3 Component Decomposition (ScanView.vue)
Split ScanView.vue into:
ScanInfoCard.vue: Displays hunt name, organization logo, and stop details.ScanStatus.vue: Handles loading, error, and success states (Found It / Victory).ScanJoinForm.vue: The Name/PIN/Email form logic.
3.4 Backend Consistency
- Ensure the
Participantrecord in Firestore tracksdevice_uuidsas an array (Already implemented). - Verify that the
participant_idgeneration logic inscans.pyremains stable for the duration of a visit (Same-day expiry).
4. Testing & Validation
- Manual Test:
- Scan Stop A, join as "Hunter1" / "0000".
- Verify Stop A appears in "My Collection".
- Manually clear browser data.
- Return to "My Collection", use the "Resume" form with "Hunter1" / "0000".
- Verify Stop A is recovered.
- Edge Case: Entering the wrong PIN should show a "Name/PIN combination not found" or "Incorrect PIN" error.