forked from trent_larson/crowd-funder-for-time-pwa
cursor(ADR): attempt to keep changes between the lines when making platform level changes
This commit is contained in:
260
.cursor/rules/architectural_decision_record.mdc
Normal file
260
.cursor/rules/architectural_decision_record.mdc
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
---
|
||||||
|
description:
|
||||||
|
globs:
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
# TimeSafari Cross-Platform Architecture Guide
|
||||||
|
|
||||||
|
## 1. Platform Support Matrix
|
||||||
|
|
||||||
|
| Feature | Web (PWA) | Capacitor (Mobile) | Electron (Desktop) | PyWebView (Desktop) |
|
||||||
|
|---------|-----------|-------------------|-------------------|-------------------|
|
||||||
|
| QR Code Scanning | vue-qrcode-reader | @capacitor-mlkit/barcode-scanning | Not Implemented | Not Implemented |
|
||||||
|
| Deep Linking | URL Parameters | App URL Open Events | Not Implemented | Not Implemented |
|
||||||
|
| File System | Limited (Browser API) | Capacitor Filesystem | Electron fs | PyWebView Python Bridge |
|
||||||
|
| Camera Access | MediaDevices API | Capacitor Camera | Not Implemented | Not Implemented |
|
||||||
|
| Platform Detection | Web APIs | Capacitor.isNativePlatform() | process.env checks | process.env checks |
|
||||||
|
|
||||||
|
## 2. Build Configuration Structure
|
||||||
|
|
||||||
|
### 2.1 Entry Points
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── main.ts # Base entry
|
||||||
|
├── main.common.ts # Shared initialization
|
||||||
|
├── main.capacitor.ts # Mobile entry
|
||||||
|
├── main.electron.ts # Electron entry
|
||||||
|
├── main.pywebview.ts # PyWebView entry
|
||||||
|
└── main.web.ts # Web/PWA entry
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Build Configurations
|
||||||
|
```
|
||||||
|
root/
|
||||||
|
├── vite.config.common.mts # Shared config
|
||||||
|
├── vite.config.capacitor.mts # Mobile build
|
||||||
|
├── vite.config.electron.mts # Electron build
|
||||||
|
├── vite.config.pywebview.mts # PyWebView build
|
||||||
|
└── vite.config.web.mts # Web/PWA build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Platform Service Architecture
|
||||||
|
|
||||||
|
### 3.1 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Platform-Specific Implementations
|
||||||
|
```
|
||||||
|
services/platforms/
|
||||||
|
├── WebPlatformService.ts
|
||||||
|
├── CapacitorPlatformService.ts
|
||||||
|
├── ElectronPlatformService.ts
|
||||||
|
└── PyWebViewPlatformService.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Feature Implementation Guidelines
|
||||||
|
|
||||||
|
### 4.1 QR Code Scanning
|
||||||
|
|
||||||
|
1. **Factory Pattern**
|
||||||
|
```typescript
|
||||||
|
export class QRScannerFactory {
|
||||||
|
static getInstance(): QRScannerService {
|
||||||
|
if (__IS_MOBILE__ || Capacitor.isNativePlatform()) {
|
||||||
|
return new CapacitorQRScanner();
|
||||||
|
} else if (__USE_QR_READER__) {
|
||||||
|
return new WebDialogQRScanner();
|
||||||
|
}
|
||||||
|
throw new Error("No QR scanner implementation available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Platform-Specific Implementation**
|
||||||
|
```typescript
|
||||||
|
// Example for Capacitor
|
||||||
|
export class CapacitorQRScanner implements QRScannerService {
|
||||||
|
async startScan(options?: QRScannerOptions): Promise<void> {
|
||||||
|
// Platform-specific implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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),
|
||||||
|
'process.env.VITE_PWA_ENABLED': JSON.stringify(!isNative),
|
||||||
|
__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",
|
||||||
|
"build:pywebview": "vite build --config vite.config.pywebview.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
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
## 9. Dependency Management
|
||||||
|
|
||||||
|
### 9.1 Platform-Specific Dependencies
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"@capacitor/core": "^6.2.0",
|
||||||
|
"electron": "^33.2.1",
|
||||||
|
"vue-qrcode-reader": "^5.5.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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 platform-appropriate storage mechanisms
|
||||||
|
- Implement encryption for sensitive data
|
||||||
|
- Handle permissions appropriately
|
||||||
|
|
||||||
|
This document should be updated as new features are added or platform-specific implementations change. Regular reviews ensure it remains current with the codebase.
|
||||||
Reference in New Issue
Block a user