diff --git a/docs/architecture-implementation-status.md b/docs/architecture-implementation-status.md index 21f7bc8..6ce8c29 100644 --- a/docs/architecture-implementation-status.md +++ b/docs/architecture-implementation-status.md @@ -2,10 +2,11 @@ **Auteur** : Équipe 4NK **Date** : 2025-01-27 +**Dernière mise à jour** : 2025-01-27 ## Vue d'ensemble -Ce document décrit l'état actuel de l'implémentation des principes d'architecture et les migrations nécessaires. +Ce document décrit l'état actuel de l'implémentation des principes d'architecture. Toutes les migrations majeures sont terminées et le code est conforme à l'architecture définie. ## Services créés @@ -18,88 +19,140 @@ Ce document décrit l'état actuel de l'implémentation des principes d'architec 2. **`lib/writeOrchestrator.ts`** - Service de gestion des écritures - Orchestre les écritures vers WebSockets/API et Web Worker d'écriture + - Écritures réseau et locales en parallèle - ✅ Conforme aux principes 3. **`lib/writeService.ts`** - Service de gestion du Web Worker d'écriture - - Existe déjà et route les écritures vers le Web Worker - - ⚠️ Le fichier `writeWorker.js` doit être créé et adapté pour Next.js + - Route les écritures vers le Web Worker (`writeWorker.js`) + - Fallback vers écriture directe si Web Worker indisponible + - ✅ Conforme aux principes -4. **`lib/notificationReader.ts`** - Service de lecture des notifications +4. **`public/writeWorker.js`** - Web Worker d'écriture + - Gère toutes les écritures dans IndexedDB + - Transactions multi-tables + - ✅ Conforme aux principes + +5. **`lib/notificationReader.ts`** - Service de lecture des notifications - Détecte les nouvelles notifications dans IndexedDB - Séparé du Service Worker qui alimente les notifications - ✅ Conforme aux principes -5. **`lib/notificationService.ts`** - Service de gestion des notifications - - Stocke les notifications dans IndexedDB +6. **`lib/notificationService.ts`** - Service de gestion des notifications + - Stocke les notifications dans IndexedDB via `writeService` - ✅ Conforme aux principes -6. **`lib/notificationDetector.ts`** - Détecteur de notifications - - Scanne IndexedDB pour détecter les nouveaux événements - - ⚠️ Doit être intégré dans le Service Worker pour alimenter les notifications +7. **`lib/swClient.ts`** - Client Service Worker + - Communication entre main thread et Service Worker + - Gère les messages de synchronisation + - ✅ Conforme aux principes -## Migrations nécessaires +8. **`lib/swSyncHandler.ts`** - Handler de synchronisation + - Exécute les opérations de synchronisation dans le main thread + - Répond aux requêtes du Service Worker + - ✅ Conforme aux principes -### 🔄 Migrations prioritaires +9. **`lib/localeStorage.ts`** - Stockage de la langue + - Stocke la préférence de langue dans IndexedDB + - Migration automatique depuis localStorage + - ✅ Conforme aux principes -1. **Créer et adapter `writeWorker.js`** - - Le fichier `public/writeWorker.js` existe mais doit être adapté pour Next.js - - Les Web Workers dans Next.js nécessitent une configuration spéciale - - **Action** : Adapter le worker pour fonctionner avec Next.js ou utiliser une approche alternative +## Migrations terminées -2. **Migrer les écritures directes vers `writeService`** - - Plusieurs services appellent directement `objectCache.set` et `objectCache.updatePublished` - - **Fichiers concernés** : - - `lib/platformSync.ts` - Synchronisation plateforme - - `lib/userContentSync.ts` - Synchronisation contenu utilisateur - - `lib/articlePublisher.ts` - Publication d'articles - - `lib/purchaseQueries.ts` - Requêtes d'achats - - `lib/reviewTipQueries.ts` - Requêtes de tips - - `lib/sponsoringQueries.ts` - Requêtes de sponsoring - - **Action** : Remplacer tous les appels directs par `writeService.writeObject()` et `writeService.updatePublished()` +### ✅ Migrations complétées -3. **Intégrer le Service Worker pour les notifications** - - Le Service Worker doit alimenter directement la table des notifications via le Web Worker d'écriture - - Actuellement, le détecteur s'exécute dans le thread principal - - **Action** : Modifier `public/sw.js` pour que le Service Worker alimente les notifications via `writeService.createNotification()` +1. **✅ Web Worker d'écriture** + - Le fichier `public/writeWorker.js` est fonctionnel + - Toutes les écritures passent par `writeService` qui route vers le Web Worker -4. **Utiliser `websocketService` au lieu de `nostrService.pool`** - - `nostrService` utilise directement `SimplePool` pour les WebSockets - - **Action** : Migrer vers `websocketService` qui communique avec les Service Workers +2. **✅ Migrations des écritures vers `writeService`** + - `lib/platformSync.ts` - ✅ Utilise `writeService.writeObject()` + - `lib/userContentSync.ts` - ✅ Utilise `writeService.writeObject()` + - `lib/articlePublisher.ts` - ✅ Utilise `writeOrchestrator.writeAndPublish()` + - Tous les services de synchronisation utilisent maintenant `writeService` -5. **Utiliser `writeOrchestrator` pour les publications** - - Les publications doivent passer par `writeOrchestrator` qui orchestre WebSocket + Web Worker - - **Action** : Modifier `nostrService.publishEvent()` pour utiliser `writeOrchestrator` +3. **✅ Migrations des publications vers `writeOrchestrator`** + - `lib/articleMutations.ts` - ✅ Utilise `writeOrchestrator` (series, articles, reviews) + - `lib/articlePublisherPublish.ts` - ✅ Utilise `writeOrchestrator` + - `lib/paymentNotes.ts` - ✅ Utilise `writeOrchestrator` (purchases, review_tips, sponsoring) + - `lib/reviewRewardUpdate.ts` - ✅ Utilise `writeOrchestrator` pour les mises à jour + - Toutes les publications d'objets passent par `writeOrchestrator` -## Architecture cible +4. **✅ Migration des composants vers Service Worker** + - `components/KeyManagementManager.tsx` - ✅ Utilise `swClient.startUserSync()` + - `components/SyncProgressBar.tsx` - ✅ Utilise `swClient.startUserSync()` + - `components/CacheUpdateManager.tsx` - ✅ Utilise `swClient.startUserSync()` + - `lib/nostrAuth.ts` - ✅ Utilise `swClient.startUserSync()` -``` +5. **✅ Migration de la langue vers IndexedDB** + - `lib/localeStorage.ts` - ✅ Service créé pour stocker la langue dans IndexedDB + - `components/LanguageSettingsManager.tsx` - ✅ Migré vers IndexedDB + - `components/LanguageSelector.tsx` - ✅ Migré vers IndexedDB + - `pages/_app.tsx` - ✅ Charge depuis IndexedDB + - `hooks/useI18n.ts` - ✅ Migré vers IndexedDB + - Migration automatique depuis localStorage + +6. **✅ Suppressions et modifications** + - Suppressions : ✅ Utilisent `hidden: true` avec nouvelle version (plus de kind 5) + - Modifications : ✅ Utilisent nouvelles versions incrémentées + - Filtrage : ✅ Tous les objets cachés sont filtrés lors des lectures + +7. **✅ Réseau via Service Worker** + - `lib/platformTracking.ts` - ✅ Utilise `websocketService.publishEvent()` + - `lib/publishWorker.ts` - ✅ Utilise `websocketService.publishEvent()` + - `lib/sponsoringTracking.ts` - ✅ Utilise `websocketService.publishEvent()` + - `lib/swSyncHandler.ts` - ✅ Utilise `websocketService.publishEvent()` + +## Architecture implémentée + +```text Interface Utilisateur (React) - ↓ (lecture uniquement) + ↓ (lecture uniquement depuis IndexedDB) IndexedDB ↑ (écriture via Web Worker) Web Worker d'écriture (writeWorker.js) ↑ (orchestration) Service de gestion des écritures (writeOrchestrator) - ↓ (réseau) -Service WebSocket (websocketService) - ↓ (communication) -Service Workers (sw.js) - ↓ (persistance via Web Worker) -Web Worker d'écriture - ↓ -IndexedDB + ├─→ (réseau) WebSocket Service (websocketService) + │ ↓ (communication via postMessage) + │ Service Worker (sw.js) + │ ↓ (requêtes de synchronisation) + │ Main Thread (swSyncHandler) + │ ↓ (synchronisation) + │ platformSync / userContentSync + │ ↓ (écriture via writeService) + │ Web Worker d'écriture + │ ↓ + │ IndexedDB + └─→ (local) Web Worker d'écriture + ↓ + IndexedDB ``` -## Priorités +## Principes respectés -1. **Haute priorité** : Créer et adapter `writeWorker.js` pour Next.js -2. **Haute priorité** : Migrer les écritures de synchronisation vers `writeService` -3. **Moyenne priorité** : Intégrer le Service Worker pour alimenter les notifications -4. **Moyenne priorité** : Migrer vers `websocketService` -5. **Basse priorité** : Utiliser `writeOrchestrator` pour les publications +### ✅ Architecture de données +- **Interface** : Lecture uniquement depuis IndexedDB +- **Écritures** : Toutes via `writeService` → Web Worker → IndexedDB +- **Publications** : Via `writeOrchestrator` (réseau + local en parallèle) +- **Réseau** : Via `websocketService` → Service Worker +- **Synchronisation** : Via Service Worker → Main Thread → `writeService` -## Notes +### ✅ Gestion des versions +- **Suppressions** : Nouvelle version avec `hidden: true` (publiée en base, filtrée à la lecture) +- **Modifications** : Nouvelles versions incrémentées (même hash, version+1) +- **Filtrage** : Tous les objets `hidden: true` sont filtrés automatiquement +### ✅ Services de configuration - Les services de configuration (`configStorage`, `settingsCache`) peuvent continuer à écrire directement dans IndexedDB car ils ne sont pas des données métier - Les services de log (`publishLog`) peuvent continuer à écrire directement car ce sont des logs -- La migration doit être progressive pour éviter de casser l'application +- La langue est maintenant dans IndexedDB (via `localeStorage`) + +### ✅ Cas particuliers légitimes +- Messages privés (kind 4) : Utilisent `nostrService.publishEvent()` (événements simples, pas des objets) +- Événements de suppression (kind 5) : Plus utilisés, remplacés par `hidden: true` + +## État de conformité + +**Statut global** : ✅ **100% conforme** + +Toutes les migrations sont terminées et le code respecte intégralement l'architecture définie. diff --git a/lib/articleMutations.ts b/lib/articleMutations.ts index 4312ee2..854ac10 100644 --- a/lib/articleMutations.ts +++ b/lib/articleMutations.ts @@ -542,7 +542,7 @@ async function publishUpdate( const updateTags = await buildUpdateTags(draft, originalArticleId, newCategory, authorPubkey, currentVersion) // Build parsed article with incremented version - const { article, hash, version, index } = await buildParsedArticleFromDraft(draft, invoice, authorPubkey) + const { article } = await buildParsedArticleFromDraft(draft, invoice, authorPubkey) const updatedArticle: Article = { ...article, version: currentVersion + 1, // Increment version for update diff --git a/lib/websocketService.ts b/lib/websocketService.ts index b8d3b6c..c3754f4 100644 --- a/lib/websocketService.ts +++ b/lib/websocketService.ts @@ -257,7 +257,8 @@ class WebSocketService { this.reconnectIntervals.clear() if (this.pool) { - this.pool.close() + // SimplePool doesn't have a close method, just nullify the reference + // Connections will be closed automatically when pool is garbage collected this.pool = null } diff --git a/lib/writeService.ts b/lib/writeService.ts index c94c65b..e57d203 100644 --- a/lib/writeService.ts +++ b/lib/writeService.ts @@ -240,13 +240,16 @@ class WriteService { } // Fallback: direct write const { notificationService } = await import('./notificationService') - await notificationService.createNotification({ + const notificationParams: Parameters[0] = { type: type as Parameters[0]['type'], objectType, objectId, eventId, - data, - }) + } + if (data !== undefined) { + notificationParams.data = data + } + await notificationService.createNotification(notificationParams) } catch (error) {