web-app/docs/Product-Model-Analysis.md
2025-10-20 06:48:21 +02:00

393 lines
No EOL
11 KiB
Markdown

# Product Model Analysis: Nostr Market vs LNbits Integration
**Date:** 2025-01-27
**Project:** Ario Web App - Market Module
**Analysis:** Comparison between nostr-market-app reference implementation and current LNbits integration
---
## Executive Summary
This analysis compares the Product data models across three implementations:
1. **nostr-market-app** (JavaScript reference implementation)
2. **LNbits Nostrmarket API** (Python/FastAPI backend)
3. **Ario Web App** (Vue 3/TypeScript frontend)
**Key Finding:** Critical Nostr-specific fields are missing from our current implementation, which may impact full Nostr marketplace compatibility.
---
## Current Product Model Implementations
### 1. nostr-market-app (Reference Implementation)
**Location:** `../nostr-market-app/src/composables/useEvents.js:140-150`
```javascript
{
// Core product data
id: string,
stall_id: string,
name: string,
price: number,
currency: string, // TOP-LEVEL
quantity: number,
images: string[],
categories: string[],
description?: string, // TOP-LEVEL
// Nostr-specific fields
pubkey: string, // CRITICAL: Merchant public key
eventId: string, // CRITICAL: Nostr event ID
relayUrls: string[], // CRITICAL: Source relay URLs
// Processing metadata
stallName: string, // Added during processing
createdAt: number, // Added during processing
formattedPrice?: string // Conditional formatting
}
```
### 2. LNbits Nostrmarket API
**Location:** `src/modules/market/services/nostrmarketAPI.ts:71-84`
```typescript
{
id?: string,
stall_id: string,
name: string,
categories: string[],
images: string[],
price: number,
quantity: number,
active: boolean,
pending: boolean,
// NESTED CONFIG STRUCTURE
config: {
description?: string, // NESTED (different from reference)
currency?: string, // NESTED (different from reference)
use_autoreply?: boolean,
autoreply_message?: string,
shipping: ProductShippingCost[]
},
event_id?: string,
event_created_at?: number
}
```
### 3. Ario Web App (Current Implementation)
**Location:** `src/modules/market/types/market.ts:29-43`
```typescript
{
id: string,
stall_id: string,
stallName: string,
name: string,
description?: string, // TOP-LEVEL (matches reference)
price: number,
currency: string, // TOP-LEVEL (matches reference)
quantity: number,
images?: string[],
categories?: string[],
createdAt: number,
updatedAt: number,
nostrEventId?: string
}
```
---
## Critical Discrepancies Analysis
### **CRITICAL MISSING FIELDS**
| Field | nostr-market-app | LNbits API | Ario Web App | Impact Level |
|-------|------------------|------------|--------------|--------------|
| `pubkey` | **Required** | Missing | **MISSING** | **CRITICAL** |
| `eventId` | **Required** | `event_id` | `nostrEventId` | **HIGH** |
| `relayUrls` | **Required** | Missing | **MISSING** | **HIGH** |
**Impact Analysis:**
- **`pubkey`**: Essential for Nostr protocol compliance and merchant identification
- **`eventId`**: Required for proper event tracking and updates
- **`relayUrls`**: Needed for distributed Nostr functionality and relay management
### **STRUCTURAL DIFFERENCES**
| Field | nostr-market-app | LNbits API | Ario Web App | Status |
|-------|------------------|------------|--------------|--------|
| `description` | Top-level | `config.description` | Top-level | **INCONSISTENT** |
| `currency` | Top-level | `config.currency` | Top-level | **INCONSISTENT** |
| `active` | Missing | Present | Missing | **MEDIUM** |
| `pending` | Missing | Present | Missing | **MEDIUM** |
### **TIMESTAMP HANDLING**
| Implementation | Created At | Event Created |
|----------------|------------|---------------|
| nostr-market-app | `createdAt` (processed) | |
| LNbits API | | `event_created_at` |
| Ario Web App | `createdAt`, `updatedAt` | |
---
## Processing Flow Comparison
### nostr-market-app Processing
```mermaid
graph TD
A[Nostr Event] --> B[Parse Content]
B --> C[Extract Categories from Tags]
C --> D[Add Stall Info]
D --> E[Add Processing Metadata]
E --> F[Final Product Object]
```
**Key Steps:**
1. Parse Nostr event content (JSON)
2. Extract categories from `t` tags
3. Enrich with stall name and merchant info
4. Add processing timestamps
5. Store in market store
### Current Ario Implementation
```mermaid
graph TD
A[LNbits API] --> B[Enrich with Required Fields]
B --> C[Type Conversion]
C --> D[Market Store]
```
**Key Steps:**
1. Fetch from LNbits API
2. Add missing required fields (`stallName`, `currency`, etc.)
3. Convert to Market Product type
4. Store in Pinia store
---
## Compatibility Issues
### 1. **Nostr Protocol Compliance**
```typescript
// CURRENT - Missing critical Nostr fields
const product = await nostrmarketAPI.getProduct(id)
// Missing: pubkey, eventId, relayUrls
// SHOULD BE - Full Nostr compatibility
const product = {
...apiProduct,
pubkey: merchantPubkey, // From merchant context
eventId: apiProduct.event_id, // Map API field
relayUrls: [...relayUrls] // From relay context
}
```
### 2. **Configuration Mismatch**
```typescript
// CURRENT - Flat structure conflicts with API
interface Product {
currency: string, // Top-level
description?: string // Top-level
}
// vs API expectation:
config: {
currency?: string, // Nested
description?: string // Nested
}
```
### 3. **Event ID Handling**
```typescript
// Multiple formats across implementations:
event_id // LNbits API format
eventId // nostr-market-app format
nostrEventId // Our current format
```
---
## Recommended Solutions
### Option 1: **Unified Product Model** (Recommended)
Create a comprehensive model that supports all three implementations:
```typescript
export interface Product {
// Core LNbits fields
id: string
stall_id: string
name: string
price: number
quantity: number
categories?: string[]
images?: string[]
active: boolean
pending: boolean
// Nostr-specific fields (CRITICAL ADDITIONS)
pubkey: string // ADD: Merchant public key
eventId: string // ADD: Nostr event ID
relayUrls: string[] // ADD: Relay URLs
// Processed fields
stallName: string
description?: string // Top-level (matches nostr-market-app)
currency: string // Top-level (matches nostr-market-app)
createdAt: number
updatedAt: number
// LNbits compatibility (optional)
config?: ProductConfig // For API requests
event_id?: string // LNbits format mapping
event_created_at?: number // LNbits format mapping
nostrEventId?: string // Legacy compatibility
}
```
### Option 2: **Type Adapters**
Create adapter functions to handle different formats:
```typescript
// Type adapters for different sources
export const adaptLNbitsToMarket = (
product: LNbitsProduct,
context: { pubkey: string; relayUrls: string[] }
): Product => ({
...product,
pubkey: context.pubkey,
eventId: product.event_id || '',
relayUrls: context.relayUrls,
currency: product.config?.currency || 'sats',
description: product.config?.description,
createdAt: product.event_created_at || Date.now(),
updatedAt: Date.now()
})
export const adaptNostrToMarket = (
product: NostrProduct
): Product => ({
// Direct mapping for nostr-market-app format
...product,
// Additional processing as needed
})
```
### Option 3: **Progressive Enhancement**
Gradually add missing fields without breaking existing functionality:
```typescript
// Phase 1: Add critical Nostr fields
export interface Product extends CurrentProduct {
pubkey?: string // Optional for backward compatibility
eventId?: string // Optional for backward compatibility
relayUrls?: string[] // Optional for backward compatibility
}
// Phase 2: Implement field population
// Phase 3: Make fields required
```
---
## Implementation Priority
### **Phase 1: Critical Fixes** (High Priority)
1. Add `pubkey` field to Product model
2. Map `event_id` to `eventId` consistently
3. Add `relayUrls` array
4. Update type definitions
### **Phase 2: Structure Alignment** (Medium Priority)
1. Implement configuration adapters
2. Standardize currency/description placement
3. Add active/pending state handling
### **Phase 3: Full Compatibility** (Future)
1. Implement complete nostr-market-app compatibility
2. Add relay management features
3. Implement proper Nostr event handling
---
## Testing Requirements
### Unit Tests Needed
```typescript
describe('Product Model Compatibility', () => {
test('should adapt LNbits API format to unified format', () => {
const lnbitsProduct = { /* LNbits format */ }
const context = { pubkey: 'abc123', relayUrls: ['wss://relay.com'] }
const result = adaptLNbitsToMarket(lnbitsProduct, context)
expect(result.pubkey).toBe('abc123')
expect(result.relayUrls).toContain('wss://relay.com')
expect(result.currency).toBeDefined()
})
test('should maintain backward compatibility', () => {
const currentProduct = { /* Current format */ }
// Should not break existing functionality
expect(() => processProduct(currentProduct)).not.toThrow()
})
})
```
### Integration Tests
1. API compatibility with LNbits
2. Nostr event processing compatibility
3. Market store operations
4. UI component rendering
---
## Migration Plan
### **Immediate Actions**
1. Document current state (this analysis)
2. Update Product interface with optional Nostr fields
3. Implement adapter functions
4. Add field population in MerchantStore.vue
### **Short Term** (1-2 weeks)
1. Make Nostr fields required
2. Update all product processing logic
3. Add comprehensive tests
4. Update documentation
### **Long Term** (1-2 months)
1. Full nostr-market-app compatibility
2. Advanced Nostr features
3. Performance optimization
4. Enhanced relay management
---
## Conclusion
The analysis reveals **critical gaps** in our current Product model that limit full Nostr marketplace compatibility. The missing `pubkey`, `eventId`, and `relayUrls` fields are essential for proper Nostr protocol integration.
**Recommended Immediate Action:** Implement Option 1 (Unified Product Model) with progressive enhancement to maintain backward compatibility while adding essential Nostr functionality.
**Success Criteria:**
- Full compatibility with nostr-market-app reference implementation
- Maintained LNbits API integration
- No breaking changes to existing functionality
- Enhanced Nostr marketplace capabilities
---
**Document Version:** 1.0
**Last Updated:** 2025-01-27
**Next Review:** Before implementing Product model changes