Files
blackcanyontickets/reactrebuild0825/scripts/qr-system-demo.ts
dzinesco aa81eb5adb feat: add advanced analytics and territory management system
- 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>
2025-08-26 09:25:10 -06:00

175 lines
5.8 KiB
TypeScript

/**
* QR System Demonstration Script
* Shows QR validation, backup code generation, and manual entry flow
*/
import { QRValidator, createQRValidator, getQRErrorMessage, formatBackupCode } from '../src/lib/qr-validator';
import { QRGenerator, createQRGenerator, generateTicketQR, generateQRForFormat, validateQRData } from '../src/lib/qr-generator';
console.log('🎫 Black Canyon Tickets - QR System Demonstration\n');
// Sample ticket data
const sampleTicketData = {
ticketId: '550e8400-e29b-41d4-a716-446655440000',
eventId: 'evt_789012345',
zone: 'GA',
seat: 'A12',
expiresInDays: 30
};
console.log('1. Ticket Data Validation');
console.log('=========================');
const validation = validateQRData(sampleTicketData);
console.log(`✅ Valid: ${validation.valid}`);
if (!validation.valid) {
console.log(`❌ Errors: ${validation.errors.join(', ')}`);
}
console.log();
console.log('2. QR Code Generation');
console.log('====================');
const generator = createQRGenerator();
// Generate QR for different formats
const formats = ['email', 'print', 'thermal', 'wallet'] as const;
for (const format of formats) {
const { qr, svg } = generateQRForFormat(sampleTicketData, format);
console.log(`📱 ${format.toUpperCase()} Format:`);
console.log(` QR Data: ${qr.qrData.substring(0, 50)}...`);
console.log(` Backup Code: ${qr.backupCode}`);
console.log(` Format: ${qr.metadata.format}`);
console.log(` Generated: ${new Date(qr.metadata.generatedAt).toLocaleString()}`);
if (qr.metadata.expiresAt) {
console.log(` Expires: ${new Date(qr.metadata.expiresAt).toLocaleString()}`);
}
console.log();
}
console.log('3. QR Code Validation');
console.log('====================');
const validator = createQRValidator();
// Test different QR formats
const testQRs = [
// Simple format
`TICKET_${sampleTicketData.ticketId}`,
// Signed token format (generated)
generateTicketQR(sampleTicketData).qrData,
// Invalid formats
'INVALID_QR_CODE',
'BCT.v2.invalid.signature',
'TICKET_not-a-uuid'
];
testQRs.forEach((qr, index) => {
console.log(`Test ${index + 1}: ${qr.substring(0, 40)}${qr.length > 40 ? '...' : ''}`);
const result = validator.validateQR(qr);
console.log(` ✅ Valid: ${result.valid}`);
console.log(` 📱 Format: ${result.format}`);
if (result.ticketId) {
console.log(` 🎫 Ticket ID: ${result.ticketId}`);
}
if (result.eventId) {
console.log(` 🎪 Event ID: ${result.eventId}`);
}
if (!result.valid) {
console.log(` ❌ Error: ${getQRErrorMessage(result)}`);
}
if (result.metadata) {
if (result.metadata.expiresAt) {
const expires = new Date(result.metadata.expiresAt * 1000);
console.log(` ⏰ Expires: ${expires.toLocaleString()}`);
}
if (result.metadata.zone) {
console.log(` 🏟️ Zone: ${result.metadata.zone}`);
}
if (result.metadata.seat) {
console.log(` 💺 Seat: ${result.metadata.seat}`);
}
}
console.log();
});
console.log('4. Backup Code Validation');
console.log('=========================');
const testBackupCodes = [
'55440000', // Valid (last 8 chars of ticket ID)
'1234ABCD', // Valid hex format
'12345', // Too short
'123456789', // Too long
'1234GHIJ', // Invalid characters
'' // Empty
];
testBackupCodes.forEach((code, index) => {
console.log(`Test ${index + 1}: "${code}"`);
const result = validator.validateBackupCode(code);
console.log(` ✅ Valid: ${result.valid}`);
if (result.valid && result.normalizedCode) {
console.log(` 🔢 Normalized: ${formatBackupCode(result.normalizedCode)}`);
}
console.log();
});
console.log('5. Backup Code Generation');
console.log('========================');
const testTicketIds = [
sampleTicketData.ticketId,
'123e4567-e89b-12d3-a456-426614174000',
'invalid-uuid'
];
testTicketIds.forEach((ticketId, index) => {
console.log(`Test ${index + 1}: ${ticketId}`);
try {
const backupCode = generator.generateBackupCode(ticketId);
console.log(` 🔢 Backup Code: ${formatBackupCode(backupCode)}`);
} catch (error) {
console.log(` ❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
console.log();
});
console.log('6. QR Format Detection');
console.log('======================');
const mixedQRs = [
'TICKET_550e8400-e29b-41d4-a716-446655440000',
'BCT.v2.eyJ0aWQiOiIxMjMiLCJlaWQiOiI0NTYifQ.signature',
'550e8400-e29b-41d4-a716-446655440000', // Legacy UUID only
'MANUAL_55440000'
];
mixedQRs.forEach((qr, index) => {
console.log(`QR ${index + 1}: ${qr}`);
const ticketId = validator.extractTicketId(qr);
if (ticketId) {
console.log(` 🎫 Extracted Ticket ID: ${ticketId}`);
const backupCode = generator.generateBackupCode(ticketId);
console.log(` 🔢 Backup Code: ${formatBackupCode(backupCode)}`);
} else {
console.log(` ❌ Could not extract ticket ID`);
}
console.log();
});
console.log('7. Production Recommendations');
console.log('=============================');
console.log('✅ Use signed tokens (BCT.v2.{payload}.{signature}) for security');
console.log('✅ Implement proper HMAC-SHA256 signatures in production');
console.log('✅ Rotate signing keys quarterly');
console.log('✅ Use Error Correction Level M (15%) for most use cases');
console.log('✅ Use Error Correction Level H (30%) for thermal printers');
console.log('✅ Include backup codes on all printed tickets');
console.log('✅ Train gate staff on manual entry procedures');
console.log('✅ Test QR codes across different devices and lighting conditions');
console.log('✅ Monitor QR scan success rates and manual entry frequency');
console.log();
console.log('🚀 QR System Demo Complete!');
console.log('Visit /scanner?eventId=test-event-123 to test the scanner interface');
console.log(`Server running at: http://localhost:5174`);
console.log();
export {};