- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
368 lines
10 KiB
Markdown
368 lines
10 KiB
Markdown
# Scanner PWA - Offline-First Ticket Scanning
|
|
|
|
## Overview
|
|
|
|
The BCT Scanner is an offline-first Progressive Web App (PWA) designed for gate staff to scan tickets even without an internet connection. It features automatic background sync, conflict resolution, and a mobile-optimized interface.
|
|
|
|
## Features
|
|
|
|
### Core Functionality
|
|
- **QR Code Scanning**: Uses native BarcodeDetector API with ZXing fallback
|
|
- **Offline Operation**: Full functionality without internet connection
|
|
- **Background Sync**: Automatic synchronization when connection is restored
|
|
- **Conflict Resolution**: Handles duplicate scans and offline/online discrepancies
|
|
- **Multi-Device Support**: Unique device identification for analytics
|
|
- **Zone/Gate Tracking**: Configurable location identification
|
|
|
|
### User Experience
|
|
- **Optimistic UI**: Instant feedback even when offline
|
|
- **Haptic Feedback**: Vibration patterns for scan results
|
|
- **Audio Feedback**: Sound confirmation for successful scans
|
|
- **Torch Control**: Automatic and manual flashlight control
|
|
- **Responsive Design**: Optimized for mobile devices
|
|
- **PWA Features**: Installable, works offline, background sync
|
|
|
|
## Installation & Setup
|
|
|
|
### 1. PWA Installation
|
|
|
|
**Mobile (iOS/Android):**
|
|
1. Open `/scan?eventId=your-event-id` in browser
|
|
2. Look for "Add to Home Screen" prompt
|
|
3. Follow device-specific installation steps
|
|
|
|
**Desktop:**
|
|
1. Navigate to scanner page
|
|
2. Look for install prompt in address bar
|
|
3. Click "Install" to add to desktop
|
|
|
|
### 2. Camera Permissions
|
|
|
|
The scanner requires camera access:
|
|
- **First Visit**: Browser will prompt for camera permission
|
|
- **Grant Access**: Select "Allow" to enable scanning
|
|
- **Denied Access**: Use settings to re-enable camera permission
|
|
|
|
### 3. Device Configuration
|
|
|
|
Set your gate/zone identifier in scanner settings:
|
|
1. Click settings icon (gear) in header
|
|
2. Enter zone name (e.g., "Gate A", "Main Entrance")
|
|
3. Zone is saved locally and included in scan logs
|
|
|
|
## Usage Guide
|
|
|
|
### Basic Scanning
|
|
|
|
1. **Access Scanner**: Navigate to `/scan?eventId={eventId}`
|
|
2. **Position QR Code**: Center QR code within scanning frame
|
|
3. **Wait for Scan**: Scanner automatically detects and processes codes
|
|
4. **View Result**: Status banner shows scan result with color coding
|
|
|
|
### Scan Results
|
|
|
|
**Success (Green)**
|
|
- Valid ticket, entry allowed
|
|
- Shows ticket information (event, type, customer)
|
|
|
|
**Already Scanned (Yellow)**
|
|
- Ticket previously used
|
|
- Shows original scan timestamp
|
|
|
|
**Invalid (Red)**
|
|
- Invalid or expired ticket
|
|
- Shows error reason
|
|
|
|
**Offline Accepted (Blue)**
|
|
- Accepted in offline mode (if optimistic mode enabled)
|
|
- Will be verified when connection restored
|
|
|
|
### Settings Configuration
|
|
|
|
**Optimistic Accept (Default: ON)**
|
|
- When enabled: Show success for scans when offline
|
|
- When disabled: Queue scans for later verification
|
|
|
|
**Zone/Gate Setting**
|
|
- Identifies scanning location
|
|
- Included in all scan logs for analytics
|
|
- Persisted locally across sessions
|
|
|
|
**Audio/Haptic Feedback**
|
|
- Success: Short beep + brief vibration
|
|
- Already Scanned: Double vibration
|
|
- Invalid: Long vibration
|
|
|
|
## Offline Behavior
|
|
|
|
### How It Works
|
|
|
|
1. **Scan Detection**: QR codes are processed immediately
|
|
2. **Local Storage**: Scans stored in IndexedDB queue
|
|
3. **Optimistic UI**: Instant feedback based on settings
|
|
4. **Background Sync**: Automatic verification when online
|
|
5. **Conflict Detection**: Handles offline/online discrepancies
|
|
|
|
### Queue Management
|
|
|
|
**Pending Scans**
|
|
- Stored locally until internet connection restored
|
|
- Automatically synced with exponential backoff
|
|
- Retry logic handles temporary failures
|
|
|
|
**Sync Status**
|
|
- Total scans: All scans from this device
|
|
- Pending sync: Queued scans awaiting verification
|
|
- Last sync: Timestamp of most recent successful sync
|
|
|
|
### Conflict Resolution
|
|
|
|
**Conflict Scenarios**
|
|
- Offline scan shows "success" but server says "already scanned"
|
|
- Multiple devices scan same ticket while offline
|
|
|
|
**Resolution Process**
|
|
1. Conflicts automatically logged when detected
|
|
2. Admin can review conflict log in settings
|
|
3. Manual resolution may be required for edge cases
|
|
|
|
## Technical Architecture
|
|
|
|
### Frontend Components
|
|
|
|
```
|
|
src/features/scanner/
|
|
├── ScannerPage.tsx # Main scanner interface
|
|
├── useScanner.ts # Camera/scanning hook
|
|
├── useScanQueue.ts # Offline queue management
|
|
└── types.ts # TypeScript definitions
|
|
```
|
|
|
|
### Offline Storage
|
|
|
|
**IndexedDB Database: `sentinel_scans`**
|
|
- `scans`: Individual scan records with sync status
|
|
- `conflicts`: Offline/online result discrepancies
|
|
- `settings`: User preferences and device configuration
|
|
|
|
### Background Sync
|
|
|
|
**Service Worker** (`/public/sw.js`)
|
|
- Handles background synchronization
|
|
- Caches essential assets for offline use
|
|
- Manages retry logic with exponential backoff
|
|
|
|
### API Endpoints
|
|
|
|
**Verification**: `/api/tickets/verify`
|
|
- Validates QR codes against ticket database
|
|
- Returns ticket information and scan history
|
|
|
|
**Logging**: `/api/scans/log`
|
|
- Records scan events for analytics
|
|
- Includes device, zone, and timing information
|
|
|
|
## Security & Access Control
|
|
|
|
### Authentication
|
|
- **Required**: User must be authenticated to access scanner
|
|
- **Permissions**: Requires `scan:tickets` permission
|
|
- **Roles**: Available to staff, organizers, and admins
|
|
|
|
### Data Protection
|
|
- **Local Storage**: Encrypted scan queue in IndexedDB
|
|
- **Device ID**: Unique identifier for tracking (not personally identifiable)
|
|
- **No Secrets**: All verification happens server-side
|
|
|
|
## Testing
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# All scanner tests
|
|
npm run test tests/scan-offline.spec.ts
|
|
|
|
# With UI (helpful for debugging)
|
|
npm run test:ui tests/scan-offline.spec.ts
|
|
|
|
# Headed mode (see actual browser)
|
|
npm run test:headed tests/scan-offline.spec.ts
|
|
```
|
|
|
|
### Test Coverage
|
|
|
|
**Online Scenarios**
|
|
1. Valid ticket scan → success + server verification
|
|
2. Invalid ticket scan → error from server
|
|
3. Duplicate scan → already_scanned response
|
|
|
|
**Offline Scenarios**
|
|
1. Offline scan with optimistic ON → immediate success
|
|
2. Offline scan with optimistic OFF → queued status
|
|
3. Connection restored → background sync processes queue
|
|
|
|
**Conflict Scenarios**
|
|
1. Offline success + server already_scanned → conflict logged
|
|
2. Multiple device conflicts → resolution workflow
|
|
|
|
**Access Control**
|
|
1. Unauthenticated user → redirect to login
|
|
2. User without scan permission → unauthorized error
|
|
3. Staff/admin user → scanner access granted
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Camera Not Working**
|
|
- Check browser permissions in settings
|
|
- Try different browser (Chrome/Firefox recommended)
|
|
- Ensure HTTPS connection (required for camera access)
|
|
|
|
**Scans Not Syncing**
|
|
- Check internet connection
|
|
- Open settings to view pending sync count
|
|
- Use "Force Sync" button if available
|
|
|
|
**App Not Installing**
|
|
- Ensure HTTPS connection
|
|
- Clear browser cache and retry
|
|
- Check if PWA is already installed
|
|
|
|
**Performance Issues**
|
|
- Close other camera-using apps
|
|
- Restart browser
|
|
- Clear scanner app data and reinstall
|
|
|
|
### Browser Support
|
|
|
|
**Recommended Browsers**
|
|
- Chrome 88+ (best performance)
|
|
- Safari 14+ (iOS support)
|
|
- Firefox 85+ (good fallback)
|
|
- Edge 88+ (Windows support)
|
|
|
|
**Required Features**
|
|
- Camera API (getUserMedia)
|
|
- IndexedDB (offline storage)
|
|
- Service Workers (background sync)
|
|
- Web App Manifest (PWA installation)
|
|
|
|
### Debugging Tools
|
|
|
|
**Browser DevTools**
|
|
- Application tab → Service Workers (check registration)
|
|
- Application tab → IndexedDB (view scan queue)
|
|
- Console tab → Look for scanner logs
|
|
- Network tab → Monitor API calls
|
|
|
|
**Scanner Settings**
|
|
- View pending sync count
|
|
- Check last sync timestamp
|
|
- Review conflict log
|
|
- Force manual sync
|
|
|
|
## Analytics & Monitoring
|
|
|
|
### Scan Metrics
|
|
|
|
**Per Device**
|
|
- Total scans processed
|
|
- Success/failure rates
|
|
- Average scan time
|
|
- Offline vs online scans
|
|
|
|
**Per Event**
|
|
- Device coverage (zones/gates)
|
|
- Peak scanning times
|
|
- Conflict rates
|
|
- Sync latency
|
|
|
|
### Data Export
|
|
|
|
Scan data can be exported for analysis:
|
|
- Individual scan records with timestamps
|
|
- Device and zone information
|
|
- Sync status and conflicts
|
|
- Customer and ticket details
|
|
|
|
## API Reference
|
|
|
|
### Scanner API Service
|
|
|
|
```typescript
|
|
// Verify a QR code
|
|
const result = await api.scanner.verifyTicket(qrCode);
|
|
|
|
// Log scan event (fire-and-forget)
|
|
await api.scanner.logScan({
|
|
eventId: 'evt-123',
|
|
qr: 'TICKET_456',
|
|
deviceId: 'device_789',
|
|
zone: 'Gate A',
|
|
result: 'valid',
|
|
latency: 250
|
|
});
|
|
|
|
// Get scan history
|
|
const history = await api.scanner.getScanHistory(eventId, page, pageSize);
|
|
```
|
|
|
|
### Response Formats
|
|
|
|
**Verify Response**
|
|
```json
|
|
{
|
|
"valid": true,
|
|
"reason": "already_scanned", // if invalid
|
|
"scannedAt": "2024-01-01T12:00:00Z", // if duplicate
|
|
"ticketInfo": {
|
|
"eventTitle": "Sample Event",
|
|
"ticketTypeName": "General Admission",
|
|
"customerEmail": "customer@example.com",
|
|
"seatNumber": "A-15" // if assigned seating
|
|
}
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### For Gate Staff
|
|
|
|
1. **Keep Device Charged**: Scanner is power-intensive
|
|
2. **Good Lighting**: Use torch in dark environments
|
|
3. **Steady Hands**: Hold device stable for better scanning
|
|
4. **Check Sync**: Periodically verify pending sync count
|
|
5. **Report Issues**: Note any conflicts or unusual behavior
|
|
|
|
### For Event Managers
|
|
|
|
1. **Test Before Event**: Verify scanner works with sample tickets
|
|
2. **Multiple Devices**: Deploy scanners at all entry points
|
|
3. **Backup Plan**: Have manual ticket list as fallback
|
|
4. **Monitor Conflicts**: Review conflict logs after event
|
|
5. **Network Planning**: Ensure WiFi coverage at gates
|
|
|
|
### For Developers
|
|
|
|
1. **Error Handling**: Graceful degradation when camera fails
|
|
2. **Performance**: Optimize for mobile device constraints
|
|
3. **Security**: Never store sensitive data locally
|
|
4. **Testing**: Include both online and offline scenarios
|
|
5. **Monitoring**: Track sync success rates and latency
|
|
|
|
## Future Enhancements
|
|
|
|
### Planned Features
|
|
- **Bulk Scan Mode**: Rapid scanning for high-volume events
|
|
- **Advanced Analytics**: Real-time dashboard for scan monitoring
|
|
- **Multi-Event Support**: Switch between events without app restart
|
|
- **Biometric Integration**: Facial recognition for VIP verification
|
|
- **Inventory Alerts**: Real-time capacity warnings
|
|
|
|
### Technical Improvements
|
|
- **WebAssembly Scanner**: Faster QR code detection
|
|
- **Machine Learning**: Improved camera auto-focus
|
|
- **Push Notifications**: Sync status and conflict alerts
|
|
- **Cloud Sync**: Cross-device scan sharing
|
|
- **Advanced PWA**: Enhanced installation and app store distribution |