update CLAUDE.md remember module architecture

This commit is contained in:
padreug 2025-09-14 17:15:08 +02:00
parent 47d81f862c
commit fae7e141ff

117
CLAUDE.md
View file

@ -333,9 +333,122 @@ const onSubmit = form.handleSubmit(async (values) => {
<Button :disabled="!isFormValid">Submit</Button>
```
### **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<void> {
// 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 `<script setup>` syntax
- Follow naming convention: lowercase-with-dashes for directories
- Leverage VueUse functions for enhanced reactivity
@ -343,6 +456,8 @@ const onSubmit = form.handleSubmit(async (values) => {
- Optimize images using WebP format with lazy loading
- **ALWAYS use dependency injection for cross-module service access**
- **ALWAYS use Shadcn Form components for all form implementations**
- **ALWAYS extend BaseService for module services**
- **NEVER create direct dependencies between modules**
**Build Configuration:**
- Vite config includes PWA, image optimization, and bundle analysis