update CLAUDE.md remember module architecture
This commit is contained in:
parent
47d81f862c
commit
fae7e141ff
1 changed files with 116 additions and 1 deletions
117
CLAUDE.md
117
CLAUDE.md
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue