# Plan: Implement Check-in Logic ## TL;DR > **Quick Summary**: Connect the scanner to the backend check-in API. When a 6-digit code is scanned, submit it to `/event/checkin/submit`. Show success/error toasts. > > **Deliverables**: > - Updated `CheckinScannerNavContainer` with mutation logic. > - Integration with `sonner` for user feedback. > - Proper parameter mapping (`checkin_code`). > > **Estimated Effort**: Short > **Parallel Execution**: NO - sequential implementation. > **Critical Path**: Implement Mutation → Update View Integration --- ## Context ### Original Request "扫码器扫到的如果是6位数字,使用/event/checkin/submit接口进行签到,成功/失败都弹出toaster提示。" ### Interview Summary **Key Discussions**: - **API**: `postEventCheckinSubmit` is the correct client function. - **Parameters**: API expects `checkin_code` in the body. - **Input**: "6位数字" implies regex validation `^\d{6}$`. - **Feedback**: Use `sonner` (`toast.success`, `toast.error`). **Metis Review Findings**: - **Critical Fix**: Ensure parameter name is `checkin_code`, not `code`. - **UX**: Disable scanning while `isPending` to prevent double submissions. - **Error Handling**: Use generic "签到失败" for errors unless specific message available. --- ## Work Objectives ### Core Objective Make the check-in scanner functional by connecting it to the backend. ### Concrete Deliverables - `src/components/checkin/checkin-scanner-nav.container.tsx`: Updated with `useMutation`. - `src/components/checkin/checkin-scanner-nav.view.tsx`: Updated to receive `isPending` prop and handle scan events. ### Definition of Done - [ ] Scanning "123456" calls API with `{"checkin_code": "123456"}`. - [ ] Success response shows "签到成功" toast. - [ ] Error response shows "签到失败" toast. - [ ] Scanner ignores non-6-digit inputs. - [ ] Scanner pauses/ignores input while API is pending. ### Must Have - Regex validation: `^\d{6}$`. - `checkin_code` parameter mapping. - Toaster feedback. ### Must NOT Have (Guardrails) - Do NOT change the existing permission logic in the container. - Do NOT remove the Dialog wrapping. --- ## Verification Strategy (MANDATORY) > **UNIVERSAL RULE: ZERO HUMAN INTERVENTION** > ALL tasks in this plan MUST be verifiable WITHOUT any human action. ### Test Decision - **Infrastructure exists**: YES (Playwright). - **Automated tests**: YES (Playwright API mocking). ### Agent-Executed QA Scenarios (MANDATORY) **Scenario 1: Successful Check-in** - **Tool**: Playwright - **Steps**: 1. Mock `/event/checkin/submit` to return 200 OK. 2. Simulate scan event with "123456". 3. Assert API called with correct body. 4. Assert "签到成功" toast visible. **Scenario 2: Failed Check-in** - **Tool**: Playwright - **Steps**: 1. Mock `/event/checkin/submit` to return 400 Bad Request. 2. Simulate scan event with "123456". 3. Assert "签到失败" toast visible. **Scenario 3: Invalid Input** - **Tool**: Playwright (if view exposes logic) or Unit Test - **Steps**: 1. Simulate scan event with "ABC". 2. Assert API NOT called. --- ## Execution Strategy ### Parallel Execution Waves ``` Wave 1: ├── Task 1: Create Data Hook └── Task 2: Implement Container & View Logic ``` --- ## TODOs - [x] 1. Create Data Hook **What to do**: - Create `src/hooks/data/useCheckinSubmit.ts`. - Import `useMutation` from `@tanstack/react-query`. - Import `postEventCheckinSubmitMutation` from `@/client/@tanstack/react-query.gen`. - Import `toast` from `sonner`. - Export `useCheckinSubmit` hook that returns the mutation. - Use `...postEventCheckinSubmitMutation()` pattern. - On success: `toast.success('签到成功')`. - On error: `toast.error('签到失败')`. **Recommended Agent Profile**: - **Category**: `quick` - **Skills**: [`frontend-ui-ux`] **Parallelization**: - **Can Run In Parallel**: YES - **Parallel Group**: Wave 1 **References**: - `src/hooks/data/useJoinEvent.ts` (Pattern reference) - `src/client/@tanstack/react-query.gen.ts` **Acceptance Criteria**: - [ ] Hook uses `@hey-api` pattern. - [ ] Toasts are configured. - [x] 2. Implement Container & View Logic **What to do**: - Update `src/components/checkin/checkin-scanner-nav.container.tsx`: - Import `useCheckinSubmit` from `@/hooks/data/useCheckinSubmit`. - Use the hook to get `mutate` and `isPending`. - Pass `handleScan` (wrapper calling mutate with `{ body: { checkin_code: code } }`) and `isPending` to View. - Update `src/components/checkin/checkin-scanner-nav.view.tsx`: - Accept `onScan` and `isPending` props. - Inside internal `handleScan`, check regex `^\d{6}$`. - If valid and !isPending, call prop `onScan`. **Recommended Agent Profile**: - **Category**: `visual-engineering` - **Skills**: [`frontend-ui-ux`] **Parallelization**: - **Can Run In Parallel**: YES - **Parallel Group**: Wave 1 - **References**: - `src/hooks/data/useCheckinSubmit.ts` (Dependency) **Acceptance Criteria**: - [ ] Container uses the new hook. - [ ] View logic validates regex. - [ ] 2. Update Playwright Verification **What to do**: - Update `tests/checkin-scanner.spec.ts`. - Add test case for successful check-in (mock API success). - Add test case for failed check-in (mock API failure). - Verify toaster appearance. **Recommended Agent Profile**: - **Category**: `quick` - **Skills**: [`playwright`] **Parallelization**: - **Can Run In Parallel**: NO - **Parallel Group**: Wave 1 - **Blocked By**: Task 1 **References**: - `tests/checkin-scanner.spec.ts` **Acceptance Criteria**: - [ ] Tests pass. **Agent-Executed QA Scenarios**: ``` Scenario: Run Updated Tests Tool: Bash Steps: 1. npx playwright test tests/checkin-scanner.spec.ts ``` --- ## Success Criteria ### Final Checklist - [ ] API integration complete. - [ ] Regex validation matches `^\d{6}$`. - [ ] User feedback (toasts) functional.