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>
|
<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:**
|
### **Code Conventions:**
|
||||||
- Use TypeScript interfaces over types for extendability
|
- 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
|
- Use Vue Composition API with `<script setup>` syntax
|
||||||
- Follow naming convention: lowercase-with-dashes for directories
|
- Follow naming convention: lowercase-with-dashes for directories
|
||||||
- Leverage VueUse functions for enhanced reactivity
|
- Leverage VueUse functions for enhanced reactivity
|
||||||
|
|
@ -343,6 +456,8 @@ const onSubmit = form.handleSubmit(async (values) => {
|
||||||
- Optimize images using WebP format with lazy loading
|
- Optimize images using WebP format with lazy loading
|
||||||
- **ALWAYS use dependency injection for cross-module service access**
|
- **ALWAYS use dependency injection for cross-module service access**
|
||||||
- **ALWAYS use Shadcn Form components for all form implementations**
|
- **ALWAYS use Shadcn Form components for all form implementations**
|
||||||
|
- **ALWAYS extend BaseService for module services**
|
||||||
|
- **NEVER create direct dependencies between modules**
|
||||||
|
|
||||||
**Build Configuration:**
|
**Build Configuration:**
|
||||||
- Vite config includes PWA, image optimization, and bundle analysis
|
- Vite config includes PWA, image optimization, and bundle analysis
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue