forked from jsnbuchanan/crowd-funder-for-time-pwa
- Deleted src/registerServiceWorker.ts and all related imports - Cleaned up WebPlatformService and main.web.ts to remove manual SW logic - Updated VitePWA config for correct dev/prod SW handling - Fixed missing FontAwesome download icon in PWA prompt - Updated docs to reflect new PWA registration approach PWA now works reliably in all web environments with zero manual SW code.
288 lines
7.5 KiB
Plaintext
288 lines
7.5 KiB
Plaintext
---
|
|
description:
|
|
globs:
|
|
alwaysApply: true
|
|
---
|
|
# TimeSafari Cross-Platform Architecture Guide
|
|
|
|
## 1. Platform Support Matrix
|
|
|
|
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) |
|
|
|---------|-----------|-------------------|-------------------|
|
|
| QR Code Scanning | WebInlineQRScanner | @capacitor-mlkit/barcode-scanning | Not Implemented |
|
|
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented |
|
|
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs |
|
|
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented |
|
|
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks |
|
|
|
|
## 2. Project Structure
|
|
|
|
### 2.1 Core Directories
|
|
```
|
|
src/
|
|
├── components/ # Vue components
|
|
├── services/ # Platform services and business logic
|
|
├── views/ # Page components
|
|
├── router/ # Vue router configuration
|
|
├── types/ # TypeScript type definitions
|
|
├── utils/ # Utility functions
|
|
├── lib/ # Core libraries
|
|
├── platforms/ # Platform-specific implementations
|
|
├── electron/ # Electron-specific code
|
|
├── constants/ # Application constants
|
|
├── db/ # Database related code
|
|
├── interfaces/ # TypeScript interfaces and type definitions
|
|
└── assets/ # Static assets
|
|
```
|
|
|
|
### 2.2 Entry Points
|
|
```
|
|
src/
|
|
├── main.ts # Base entry
|
|
├── main.common.ts # Shared initialization
|
|
├── main.capacitor.ts # Mobile entry
|
|
├── main.electron.ts # Electron entry
|
|
└── main.web.ts # Web/PWA entry
|
|
```
|
|
|
|
### 2.3 Build Configurations
|
|
```
|
|
root/
|
|
├── vite.config.common.mts # Shared config
|
|
├── vite.config.capacitor.mts # Mobile build
|
|
├── vite.config.electron.mts # Electron build
|
|
└── vite.config.web.mts # Web/PWA build
|
|
```
|
|
|
|
## 3. Service Architecture
|
|
|
|
### 3.1 Service Organization
|
|
```
|
|
services/
|
|
├── QRScanner/ # QR code scanning service
|
|
│ ├── WebInlineQRScanner.ts
|
|
│ └── interfaces.ts
|
|
├── platforms/ # Platform-specific services
|
|
│ ├── WebPlatformService.ts
|
|
│ ├── CapacitorPlatformService.ts
|
|
│ └── ElectronPlatformService.ts
|
|
└── factory/ # Service factories
|
|
└── PlatformServiceFactory.ts
|
|
```
|
|
|
|
### 3.2 Service Factory Pattern
|
|
```typescript
|
|
// PlatformServiceFactory.ts
|
|
export class PlatformServiceFactory {
|
|
private static instance: PlatformService | null = null;
|
|
|
|
public static getInstance(): PlatformService {
|
|
if (!PlatformServiceFactory.instance) {
|
|
const platform = process.env.VITE_PLATFORM || "web";
|
|
PlatformServiceFactory.instance = createPlatformService(platform);
|
|
}
|
|
return PlatformServiceFactory.instance;
|
|
}
|
|
}
|
|
```
|
|
|
|
## 4. Feature Implementation Guidelines
|
|
|
|
### 4.1 QR Code Scanning
|
|
|
|
1. **Service Interface**
|
|
```typescript
|
|
interface QRScannerService {
|
|
checkPermissions(): Promise<boolean>;
|
|
requestPermissions(): Promise<boolean>;
|
|
isSupported(): Promise<boolean>;
|
|
startScan(): Promise<void>;
|
|
stopScan(): Promise<void>;
|
|
addListener(listener: ScanListener): void;
|
|
onStream(callback: (stream: MediaStream | null) => void): void;
|
|
cleanup(): Promise<void>;
|
|
}
|
|
```
|
|
|
|
2. **Platform-Specific Implementation**
|
|
```typescript
|
|
// WebInlineQRScanner.ts
|
|
export class WebInlineQRScanner implements QRScannerService {
|
|
private scanListener: ScanListener | null = null;
|
|
private isScanning = false;
|
|
private stream: MediaStream | null = null;
|
|
private events = new EventEmitter();
|
|
|
|
// Implementation of interface methods
|
|
}
|
|
```
|
|
|
|
### 4.2 Deep Linking
|
|
|
|
1. **URL Structure**
|
|
```typescript
|
|
// Format: timesafari://<route>[/<param>][?queryParam1=value1]
|
|
interface DeepLinkParams {
|
|
route: string;
|
|
params?: Record<string, string>;
|
|
query?: Record<string, string>;
|
|
}
|
|
```
|
|
|
|
2. **Platform Handlers**
|
|
```typescript
|
|
// Capacitor
|
|
App.addListener("appUrlOpen", handleDeepLink);
|
|
|
|
// Web
|
|
router.beforeEach((to, from, next) => {
|
|
handleWebDeepLink(to.query);
|
|
});
|
|
```
|
|
|
|
## 5. Build Process
|
|
|
|
### 5.1 Environment Configuration
|
|
```typescript
|
|
// vite.config.common.mts
|
|
export function createBuildConfig(mode: string) {
|
|
return {
|
|
define: {
|
|
'process.env.VITE_PLATFORM': JSON.stringify(mode),
|
|
// PWA is automatically enabled for web platforms via build configuration
|
|
__IS_MOBILE__: JSON.stringify(isCapacitor),
|
|
__USE_QR_READER__: JSON.stringify(!isCapacitor)
|
|
}
|
|
};
|
|
}
|
|
```
|
|
|
|
### 5.2 Platform-Specific Builds
|
|
|
|
```bash
|
|
# Build commands from package.json
|
|
"build:web": "vite build --config vite.config.web.mts",
|
|
"build:capacitor": "vite build --config vite.config.capacitor.mts",
|
|
"build:electron": "vite build --config vite.config.electron.mts"
|
|
```
|
|
|
|
## 6. Testing Strategy
|
|
|
|
### 6.1 Test Configuration
|
|
```typescript
|
|
// playwright.config-local.ts
|
|
const config: PlaywrightTestConfig = {
|
|
projects: [
|
|
{
|
|
name: 'web',
|
|
use: { browserName: 'chromium' }
|
|
},
|
|
{
|
|
name: 'mobile',
|
|
use: { ...devices['Pixel 5'] }
|
|
}
|
|
]
|
|
};
|
|
```
|
|
|
|
### 6.2 Platform-Specific Tests
|
|
```typescript
|
|
test('QR scanning works on mobile', async ({ page }) => {
|
|
test.skip(!process.env.MOBILE_TEST, 'Mobile-only test');
|
|
// Test implementation
|
|
});
|
|
```
|
|
|
|
## 7. Error Handling
|
|
|
|
### 7.1 Global Error Handler
|
|
```typescript
|
|
function setupGlobalErrorHandler(app: VueApp) {
|
|
app.config.errorHandler = (err, instance, info) => {
|
|
logger.error("[App Error]", {
|
|
error: err,
|
|
info,
|
|
component: instance?.$options.name
|
|
});
|
|
};
|
|
}
|
|
```
|
|
|
|
### 7.2 Platform-Specific Error Handling
|
|
```typescript
|
|
// API error handling for Capacitor
|
|
if (process.env.VITE_PLATFORM === 'capacitor') {
|
|
logger.error(`[Capacitor API Error] ${endpoint}:`, {
|
|
message: error.message,
|
|
status: error.response?.status
|
|
});
|
|
}
|
|
```
|
|
|
|
## 8. Best Practices
|
|
|
|
### 8.1 Code Organization
|
|
- Use platform-specific directories for unique implementations
|
|
- Share common code through service interfaces
|
|
- Implement feature detection before using platform capabilities
|
|
- Keep platform-specific code isolated in dedicated directories
|
|
- Use TypeScript interfaces for cross-platform compatibility
|
|
|
|
### 8.2 Platform Detection
|
|
```typescript
|
|
const platformService = PlatformServiceFactory.getInstance();
|
|
const capabilities = platformService.getCapabilities();
|
|
|
|
if (capabilities.hasCamera) {
|
|
// Implement camera features
|
|
}
|
|
```
|
|
|
|
### 8.3 Feature Implementation
|
|
1. Define platform-agnostic interface
|
|
2. Create platform-specific implementations
|
|
3. Use factory pattern for instantiation
|
|
4. Implement graceful fallbacks
|
|
5. Add comprehensive error handling
|
|
6. Use dependency injection for better testability
|
|
|
|
## 9. Dependency Management
|
|
|
|
### 9.1 Platform-Specific Dependencies
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"@capacitor/core": "^6.2.0",
|
|
"electron": "^33.2.1",
|
|
"vue": "^3.4.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 9.2 Conditional Loading
|
|
```typescript
|
|
if (process.env.VITE_PLATFORM === 'capacitor') {
|
|
await import('@capacitor/core');
|
|
}
|
|
```
|
|
|
|
## 10. Security Considerations
|
|
|
|
### 10.1 Permission Handling
|
|
```typescript
|
|
async checkPermissions(): Promise<boolean> {
|
|
if (platformService.isCapacitor()) {
|
|
return await checkNativePermissions();
|
|
}
|
|
return await checkWebPermissions();
|
|
}
|
|
```
|
|
|
|
### 10.2 Data Storage
|
|
- Use secure storage mechanisms for sensitive data
|
|
- Implement proper encryption for stored data
|
|
- Follow platform-specific security guidelines
|
|
- Regular security audits and updates
|
|
|
|
This document should be updated as new features are added or platform-specific implementations change. Regular reviews ensure it remains current with the codebase.
|