From fae7e141ff68411679b366a6874b57a9be0be9ed Mon Sep 17 00:00:00 2001 From: padreug Date: Sun, 14 Sep 2025 17:15:08 +0200 Subject: [PATCH] update CLAUDE.md remember module architecture --- CLAUDE.md | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 16ce671..9d106b1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -333,9 +333,122 @@ const onSubmit = form.handleSubmit(async (values) => { ``` +### **Module Development Best Practices** + +**Module Structure Requirements:** +1. **Independence**: Modules must be independent of each other - no direct imports between modules +2. **Base Dependency**: All modules should depend on 'base' module for core infrastructure +3. **Service Pattern**: All services should extend `BaseService` for standardized initialization +4. **API Isolation**: Module-specific API calls must be in the module's services folder +5. **Dependency Injection**: Cross-module communication only through DI container + +**Required Module Structure:** +``` +src/modules/[module-name]/ +├── index.ts # Module plugin definition (REQUIRED) +├── components/ # Module-specific components +├── composables/ # Module composables (use DI for services) +├── services/ # Module services (extend BaseService) +│ ├── [module]Service.ts # Core module service +│ └── [module]API.ts # LNbits API integration +├── stores/ # Module-specific Pinia stores +├── types/ # Module type definitions +└── views/ # Module pages/views +``` + +**Service Implementation Pattern:** +```typescript +// Always extend BaseService for services +export class MyModuleService extends BaseService { + protected readonly metadata = { + name: 'MyModuleService', + version: '1.0.0', + dependencies: [] // List service dependencies + } + + protected async onInitialize(): Promise { + // Service-specific initialization + } +} + +// API services for LNbits integration +export class MyModuleAPI extends BaseService { + private baseUrl: string + + constructor() { + super() + const config = appConfig.modules.myModule.config + this.baseUrl = config.apiConfig.baseUrl + } + + // API methods here +} +``` + +**Module Plugin Pattern:** +```typescript +export const myModule: ModulePlugin = { + name: 'my-module', + version: '1.0.0', + dependencies: ['base'], // Always depend on base + + async install(app: App, options?: { config?: MyModuleConfig }) { + // 1. Create service instances + const myService = new MyModuleService() + const myAPI = new MyModuleAPI() + + // 2. Register in DI container + container.provide(SERVICE_TOKENS.MY_SERVICE, myService) + container.provide(SERVICE_TOKENS.MY_API, myAPI) + + // 3. Initialize services + await myService.initialize({ + waitForDependencies: true, + maxRetries: 3 + }) + + // 4. Register components if needed + app.component('MyComponent', MyComponent) + } +} +``` + +**Nostr Integration Rules:** +1. **NEVER create separate relay connections** - always use the central RelayHub +2. **Access RelayHub through DI**: `const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)` +3. **Use RelayHub methods** for all Nostr operations (subscribe, publish, etc.) +4. **Event kinds** should be module-specific and follow NIP specifications + +**LNbits API Integration:** +1. **Create module-specific API service** in `services/[module]API.ts` +2. **Extend BaseService** for automatic dependency management +3. **Use authentication headers**: `X-Api-Key: walletKey` +4. **Base URL from config**: Use `appConfig.modules.[module].config.apiConfig.baseUrl` +5. **Error handling**: Implement proper error handling with user feedback + +**Composables Best Practices:** +```typescript +export function useMyModule() { + // Always use DI for services + const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB) + const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE) + const myAPI = injectService(SERVICE_TOKENS.MY_API) + + // Never import services directly + // ❌ import { relayHub } from '@/modules/base/nostr/relay-hub' + // ✅ const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB) +} +``` + +**WebSocket & Visibility Management:** +- Services with WebSocket connections MUST integrate with VisibilityService +- Register visibility callbacks: `this.visibilityService.registerService(name, onResume, onPause)` +- Handle connection recovery in `onResume()` callback +- Implement battery-conscious pausing in `onPause()` callback + ### **Code Conventions:** - Use TypeScript interfaces over types for extendability -- Prefer functional and declarative patterns over classes +- Prefer functional and declarative patterns over classes (except for services) - Use Vue Composition API with `