You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							246 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							246 lines
						
					
					
						
							5.8 KiB
						
					
					
				
								# Time Safari Architecture — Examples and Testing
							 | 
						|
								
							 | 
						|
								> **Agent role**: Reference this file for architectural examples and
							 | 
						|
								  testing patterns when working with TimeSafari architecture.
							 | 
						|
								
							 | 
						|
								## Error Handling Patterns
							 | 
						|
								
							 | 
						|
								### Global Error Handler
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// main.ts
							 | 
						|
								app.config.errorHandler = (err, instance, info) => {
							 | 
						|
								  const componentName = instance?.$options?.name || 'Unknown';
							 | 
						|
								  logger.error(`[${componentName}] Vue error`, err, info);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								window.addEventListener('unhandledrejection', (event) => {
							 | 
						|
								  logger.error('[Global] Unhandled promise rejection', event.reason);
							 | 
						|
								});
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								### Platform-Specific Error Wrapping
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// services/platforms/CapacitorPlatformService.ts
							 | 
						|
								export class CapacitorPlatformService {
							 | 
						|
								  async getFileContents(path: string): Promise<string> {
							 | 
						|
								    try {
							 | 
						|
								      const result = await Filesystem.readFile({
							 | 
						|
								        path: path,
							 | 
						|
								        encoding: 'utf8'
							 | 
						|
								      });
							 | 
						|
								      return result.data;
							 | 
						|
								    } catch (error) {
							 | 
						|
								      logger.error('[Capacitor API Error] Failed to read file', error, path);
							 | 
						|
								      throw new Error(`Failed to read file: ${path}`);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								## Testing Patterns
							 | 
						|
								
							 | 
						|
								### Platform-Specific Test Skipping
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// tests/QRScanner.test.ts
							 | 
						|
								describe('QRScanner Service', () => {
							 | 
						|
								  test('should start scanning on web', async () => {
							 | 
						|
								    test.skip(process.env.VITE_PLATFORM !== 'web', 'Web-only test');
							 | 
						|
								
							 | 
						|
								    const scanner = new WebInlineQRScanner();
							 | 
						|
								    await scanner.startScanning();
							 | 
						|
								    // Assert scanning started
							 | 
						|
								  });
							 | 
						|
								
							 | 
						|
								  test('should start scanning on mobile', async () => {
							 | 
						|
								    test.skip(process.env.VITE_PLATFORM !== 'capacitor', 'Mobile-only test');
							 | 
						|
								
							 | 
						|
								    const scanner = new CapacitorQRScanner();
							 | 
						|
								    await scanner.startScanning();
							 | 
						|
								    // Assert scanning started
							 | 
						|
								  });
							 | 
						|
								});
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								### Mock Service Testing
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// tests/mocks/QRScannerMock.ts
							 | 
						|
								export class QRScannerMock implements QRScannerService {
							 | 
						|
								  private isScanning = false;
							 | 
						|
								  private listeners: Map<string, Function[]> = new Map();
							 | 
						|
								
							 | 
						|
								  async startScanning(): Promise<void> {
							 | 
						|
								    this.isScanning = true;
							 | 
						|
								    this.emit('scanningStarted');
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  async stopScanning(): Promise<void> {
							 | 
						|
								    this.isScanning = false;
							 | 
						|
								    this.emit('scanningStopped');
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  addListener(event: string, callback: Function): void {
							 | 
						|
								    if (!this.listeners.has(event)) {
							 | 
						|
								      this.listeners.set(event, []);
							 | 
						|
								    }
							 | 
						|
								    this.listeners.get(event)!.push(callback);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  removeListener(event: string, callback: Function): void {
							 | 
						|
								    const callbacks = this.listeners.get(event);
							 | 
						|
								    if (callbacks) {
							 | 
						|
								      const index = callbacks.indexOf(callback);
							 | 
						|
								      if (index > -1) {
							 | 
						|
								        callbacks.splice(index, 1);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  private emit(event: string, ...args: any[]): void {
							 | 
						|
								    const callbacks = this.listeners.get(event);
							 | 
						|
								    if (callbacks) {
							 | 
						|
								      callbacks.forEach(callback => callback(...args));
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  getScanningState(): boolean {
							 | 
						|
								    return this.isScanning;
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								## Integration Examples
							 | 
						|
								
							 | 
						|
								### Service Composition
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// services/QRScannerService.ts
							 | 
						|
								export class QRScannerService {
							 | 
						|
								  constructor(
							 | 
						|
								    private platformService: PlatformService,
							 | 
						|
								    private notificationService: NotificationService
							 | 
						|
								  ) {}
							 | 
						|
								
							 | 
						|
								  async startScanning(): Promise<void> {
							 | 
						|
								    try {
							 | 
						|
								      await this.platformService.startCamera();
							 | 
						|
								      this.notificationService.show('Camera started');
							 | 
						|
								    } catch (error) {
							 | 
						|
								      this.notificationService.showError('Failed to start camera');
							 | 
						|
								      throw error;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								### Component Integration
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// components/QRScannerDialog.vue
							 | 
						|
								export default class QRScannerDialog extends Vue {
							 | 
						|
								  @Inject() private qrScannerService!: QRScannerService;
							 | 
						|
								
							 | 
						|
								  async mounted() {
							 | 
						|
								    try {
							 | 
						|
								      await this.qrScannerService.startScanning();
							 | 
						|
								    } catch (error) {
							 | 
						|
								      this.$notify.error('Failed to start scanner');
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  beforeDestroy() {
							 | 
						|
								    this.qrScannerService.stopScanning();
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								## Best Practices
							 | 
						|
								
							 | 
						|
								### Service Design
							 | 
						|
								
							 | 
						|
								- Keep services focused and single-purpose
							 | 
						|
								
							 | 
						|
								- Use dependency injection for service composition
							 | 
						|
								
							 | 
						|
								- Implement proper error handling and logging
							 | 
						|
								
							 | 
						|
								- Provide clear interfaces and contracts
							 | 
						|
								
							 | 
						|
								### Testing Strategy
							 | 
						|
								
							 | 
						|
								- Test platform-specific behavior separately
							 | 
						|
								
							 | 
						|
								- Use mocks for external dependencies
							 | 
						|
								
							 | 
						|
								- Test error conditions and edge cases
							 | 
						|
								
							 | 
						|
								- Validate service contracts and interfaces
							 | 
						|
								
							 | 
						|
								### Error Handling
							 | 
						|
								
							 | 
						|
								- Log errors with appropriate context
							 | 
						|
								
							 | 
						|
								- Provide user-friendly error messages
							 | 
						|
								
							 | 
						|
								- Implement graceful degradation
							 | 
						|
								
							 | 
						|
								- Handle platform-specific error scenarios
							 | 
						|
								
							 | 
						|
								---
							 | 
						|
								
							 | 
						|
								**See also**:
							 | 
						|
								
							 | 
						|
								- `.cursor/rules/app/architectural_decision_record.mdc` for
							 | 
						|
								
							 | 
						|
								  core architecture principles
							 | 
						|
								
							 | 
						|
								- `.cursor/rules/app/architectural_implementation.mdc` for
							 | 
						|
								
							 | 
						|
								  implementation details
							 | 
						|
								
							 | 
						|
								- `.cursor/rules/app/architectural_patterns.mdc` for core patterns
							 | 
						|
								
							 | 
						|
								**Status**: Active examples and testing guide
							 | 
						|
								**Priority**: Medium
							 | 
						|
								**Estimated Effort**: Ongoing reference
							 | 
						|
								**Dependencies**: architectural_patterns.mdc
							 | 
						|
								**Stakeholders**: Development team, Testing team
							 | 
						|
								
							 | 
						|
								## Model Implementation Checklist
							 | 
						|
								
							 | 
						|
								### Before Architectural Examples
							 | 
						|
								
							 | 
						|
								- [ ] **Pattern Selection**: Choose appropriate architectural pattern for the use
							 | 
						|
								  case
							 | 
						|
								- [ ] **Service Design**: Plan service structure and dependencies
							 | 
						|
								- [ ] **Testing Strategy**: Plan testing approach for the example
							 | 
						|
								- [ ] **Error Handling**: Plan error handling and logging strategy
							 | 
						|
								
							 | 
						|
								### During Architectural Examples
							 | 
						|
								
							 | 
						|
								- [ ] **Service Implementation**: Implement focused, single-purpose services
							 | 
						|
								- [ ] **Dependency Injection**: Use proper dependency injection patterns
							 | 
						|
								- [ ] **Error Handling**: Implement proper error handling and logging
							 | 
						|
								- [ ] **Interface Design**: Provide clear interfaces and contracts
							 | 
						|
								
							 | 
						|
								### After Architectural Examples
							 | 
						|
								
							 | 
						|
								- [ ] **Testing Execution**: Test platform-specific behavior separately
							 | 
						|
								- [ ] **Service Validation**: Validate service contracts and interfaces
							 | 
						|
								- [ ] **Error Testing**: Test error conditions and edge cases
							 | 
						|
								- [ ] **Documentation**: Update architectural examples documentation
							 | 
						|
								
							 |