From a099f3c24a3431b615a09444d9bb70ad31535319 Mon Sep 17 00:00:00 2001 From: Nicolas Cantu Date: Sat, 27 Dec 2025 21:31:20 +0100 Subject: [PATCH] docs: Fusion et simplification documentation features/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fusion tous documents implémentations en features.md - Suppression documents redondants/obsolètes : - final-cleanup-summary.md, storage-encryption.md - storage-improvement-implementation.md, notifications-scope.md - user-profile-implementation.md, filtering-search-implementation.md - article-edit-delete.md, priority1-implementation.md - alby-integration.md, nostr-paywall-implementation.md - technical-doc.md (redondant avec docs/technical.md) - rizful-integration.md (obsolète, remplacé par Alby) - Documentation fidèle au code actuel - Garde zapwall4science-refactoring.md (spécifications) - Garde series-and-media-spec.md (spécifications) - Garde notifications-implementation.md (détails techniques) --- docs/technical.md | 1 - features/alby-integration.md | 145 ------------ features/article-edit-delete.md | 22 -- features/features.md | 103 +++++++++ features/filtering-search-implementation.md | 138 ----------- features/final-cleanup-summary.md | 134 ----------- features/nostr-paywall-implementation.md | 217 ------------------ features/notifications-scope.md | 14 -- features/priority1-implementation.md | 85 ------- features/rizful-integration.md | 215 ----------------- features/storage-encryption.md | 23 -- .../storage-improvement-implementation.md | 158 ------------- features/technical-doc.md | 71 ------ features/user-profile-implementation.md | 169 -------------- 14 files changed, 103 insertions(+), 1392 deletions(-) delete mode 100644 features/alby-integration.md delete mode 100644 features/article-edit-delete.md create mode 100644 features/features.md delete mode 100644 features/filtering-search-implementation.md delete mode 100644 features/final-cleanup-summary.md delete mode 100644 features/nostr-paywall-implementation.md delete mode 100644 features/notifications-scope.md delete mode 100644 features/priority1-implementation.md delete mode 100644 features/rizful-integration.md delete mode 100644 features/storage-encryption.md delete mode 100644 features/storage-improvement-implementation.md delete mode 100644 features/technical-doc.md delete mode 100644 features/user-profile-implementation.md diff --git a/docs/technical.md b/docs/technical.md index a3bf97a..c9c35b0 100644 --- a/docs/technical.md +++ b/docs/technical.md @@ -89,4 +89,3 @@ Tous les événements sont loggés avec IDs, timestamps et statuts. ## Limitations **Transferts Lightning automatiques** : Nécessitent un nœud Lightning de la plateforme. Actuellement, les transferts sont loggés dans `lib/automaticTransfer.ts` et peuvent être exécutés manuellement. Les adresses Lightning sont récupérées automatiquement depuis les profils Nostr. - diff --git a/features/alby-integration.md b/features/alby-integration.md deleted file mode 100644 index 50680e3..0000000 --- a/features/alby-integration.md +++ /dev/null @@ -1,145 +0,0 @@ -# Intégration Alby/WebLN pour paiements Lightning - -**Auteur** : Équipe 4NK - -## Objectif - -Remplacer l'intégration Rizful par Alby/WebLN pour les paiements Lightning, permettant une intégration directe avec les portefeuilles Lightning du navigateur sans nécessiter d'API backend. - -## Impacts - -### Utilisateurs -- Paiements Lightning facilités via l'extension Alby ou autres portefeuilles WebLN -- Pas besoin de compte externe (Rizful) pour recevoir des paiements -- Interface de paiement native du navigateur -- Vérification des paiements via zap receipts sur Nostr - -### Développeurs -- Pas besoin de clé API externe -- Pas besoin d'API routes backend pour les paiements -- Utilisation du standard WebLN (compatible avec tous les portefeuilles WebLN) -- Architecture simplifiée - -### Technique -- Service `AlbyService` utilisant le standard WebLN -- Vérification des paiements via zap receipts Nostr -- Compatible avec Alby et autres portefeuilles WebLN - -## Modifications - -### Nouveaux fichiers - -#### `lib/alby.ts` - Service Alby/WebLN -Service principal pour interagir avec les portefeuilles Lightning via WebLN : -- `enable()` : Demander l'autorisation à l'utilisateur -- `createInvoice()` : Créer une facture Lightning via le portefeuille -- `sendPayment()` : Envoyer un paiement via le portefeuille -- `checkPaymentStatus()` : Placeholder (vérification via zap receipts) -- `waitForPayment()` : Attendre la confirmation via zap receipts - -#### `types/alby.ts` - Types TypeScript -Types pour Alby/WebLN : -- `AlbyInvoice` : Structure d'une facture Lightning -- `AlbyPaymentStatus` : Statut d'un paiement -- `AlbyInvoiceRequest` : Requête de création de facture - -### Fichiers modifiés - -#### `lib/payment.ts` -- Remplacement de `RizfulService` par `AlbyService` -- Utilisation de zap receipts pour la vérification des paiements -- Simplification du flux de paiement - -#### `components/PaymentModal.tsx` -- Intégration de `AlbyService` pour le paiement -- Utilisation de `sendPayment()` pour payer directement via WebLN -- Fallback vers URI Lightning si WebLN n'est pas disponible - -#### `components/ArticleCard.tsx` -- Mise à jour des types (remplacement de `RizfulInvoice` par `AlbyInvoice`) - -#### `next.config.js` -- Suppression des variables d'environnement Rizful - -#### `README.md` -- Mise à jour de la documentation pour Alby -- Instructions pour installer l'extension Alby - -### Fichiers supprimés - -- `lib/rizful.ts` - Service Rizful (remplacé par `lib/alby.ts`) -- `types/rizful.ts` - Types Rizful (remplacé par `types/alby.ts`) -- `pages/api/rizful/invoice.ts` - API route Rizful (plus nécessaire) -- `pages/api/rizful/payment/[hash].ts` - API route Rizful (plus nécessaire) - -### Flux de paiement avec Alby - -1. **Utilisateur clique sur "Unlock for X sats"** - - Vérification de la connexion Nostr - - Demande d'activation de WebLN (Alby) - - Création d'une facture Lightning via WebLN - -2. **Affichage de la modal de paiement** - - Facture Lightning affichée - - Option pour payer directement via WebLN (bouton "Pay with Alby") - - Option pour copier la facture - -3. **Paiement utilisateur** - - Utilisateur paie via son portefeuille WebLN (Alby) - - Le portefeuille gère le paiement - -4. **Vérification du paiement** - - Polling des zap receipts sur Nostr - - Vérification de la signature et du montant - - Confirmation du paiement - -5. **Déblocage du contenu** - - Une fois le paiement confirmé via zap receipt, chargement du contenu privé - - Affichage du contenu complet - -## Modalités de déploiement - -### Prérequis -- Extension Alby installée (pour les utilisateurs) -- Ou autre portefeuille WebLN compatible - -### Installation pour les utilisateurs - -Les utilisateurs doivent installer l'extension Alby : -1. Aller sur [https://getalby.com/](https://getalby.com/) -2. Installer l'extension pour leur navigateur (Chrome, Firefox, etc.) -3. Créer un compte Alby ou connecter un portefeuille Lightning existant - -### Configuration - -Aucune configuration serveur nécessaire ! Tout fonctionne côté client via WebLN. - -### Déploiement - -Aucun changement dans le processus de déploiement standard. Le code fonctionne entièrement côté client. - -### Sécurité - -- **WebLN** : Standard ouvert et sécurisé pour les portefeuilles Lightning -- **Vérification** : Les paiements sont vérifiés via zap receipts Nostr avec signatures cryptographiques -- **Pas d'API key** : Plus besoin de gérer des clés API côté serveur - -## Avantages par rapport à Rizful - -1. **Pas de clé API** : Plus besoin de configuration serveur -2. **Standard ouvert** : WebLN est un standard, compatible avec plusieurs portefeuilles -3. **Meilleure UX** : Intégration native avec le navigateur -4. **Décentralisé** : Les utilisateurs gardent le contrôle de leur portefeuille -5. **Pas de frais d'API** : Pas de service externe à payer - -## Limitations - -1. **Extension requise** : Les utilisateurs doivent avoir une extension WebLN installée -2. **Vérification via zap receipts** : La vérification des paiements dépend des zap receipts sur Nostr (ce qui est normal pour un système Nostr) - -## Points d'amélioration - -1. **Détection automatique** : Améliorer la détection de l'extension WebLN -2. **Guide d'installation** : Ajouter un guide d'installation de l'extension pour les utilisateurs -3. **Support de plusieurs portefeuilles** : Tester et supporter d'autres portefeuilles WebLN -4. **Gestion des erreurs** : Améliorer les messages d'erreur si WebLN n'est pas disponible diff --git a/features/article-edit-delete.md b/features/article-edit-delete.md deleted file mode 100644 index 056d6ea..0000000 --- a/features/article-edit-delete.md +++ /dev/null @@ -1,22 +0,0 @@ -# Article edit/delete via Nostr events - -**Objectif** -Permettre aux auteurs d’éditer ou supprimer leurs articles en publiant des événements Nostr dédiés (update + delete), avec confirmation explicite côté UI. - -**Impacts** -- Parcours auteur : édition depuis la liste de mes articles, suppression confirmée avant envoi de l’événement kind 5. -- Stockage local : contenu privé ré-encrypté et ré-enregistré pour les mises à jour. -- Pas d’impact côté lecteurs (pas de fallback). - -**Modifications** -- `lib/articleMutations.ts` : publication update/delete (tags e, replace), réutilisation du stockage chiffré. -- `components/UserArticles.tsx`, `components/UserArticlesList.tsx`, `components/UserArticlesEditPanel.tsx` : UI édition/suppression avec confirmation, découpage pour respecter lint/max-lines. -- `lib/articleInvoice.ts` : factorisation des tags de preview. - -**Modalités de déploiement** -Standard front : build Next.js habituel. Pas de migrations ni dépendances supplémentaires. - -**Modalités d’analyse** -- Vérifier qu’un auteur connecté peut éditer puis voir son article mis à jour dans la liste. -- Vérifier que la suppression publie l’événement et retire l’article de la liste locale. -- Sur erreur de publication, message d’erreur affiché (aucun fallback silencieux). diff --git a/features/features.md b/features/features.md new file mode 100644 index 0000000..b3020b4 --- /dev/null +++ b/features/features.md @@ -0,0 +1,103 @@ +# Fonctionnalités implémentées + +**Auteur** : Équipe 4NK + +## Architecture de base + +### Nostr Paywall → zapwall4Science +- Publication d'articles avec aperçus gratuits et contenu payant +- Paiement Lightning via Alby/WebLN (remplacement de Rizful) +- Connexion via NostrConnect (use.nsec.app) +- Interface TypeScript/Next.js + +### Services principaux +- **Nostr** : Pool de connexions, publication/récupération d'événements, profils +- **Paiements** : Invoices Lightning, vérification zap receipts (NIP-57), envoi automatique contenu privé +- **Stockage** : IndexedDB avec chiffrement AES-GCM pour contenu privé +- **Notifications** : Surveillance des paiements en temps réel (zap receipts) + +## Fonctionnalités utilisateur + +### Profil et articles +- Page profil (`/profile`) avec informations utilisateur +- Liste des articles publiés par l'utilisateur +- Recherche et filtres (auteur, prix, texte) +- Tri (date, prix) + +### Édition et suppression +- Édition d'articles via événements Nostr (kind 1 avec tag `replace`) +- Suppression d'articles via événements Nostr (kind 5) +- Confirmation avant suppression +- Ré-encryptage du contenu privé lors de l'édition + +### Notifications +- Surveillance automatique des zap receipts (kind:9735) destinés à l'utilisateur +- Badge avec nombre de notifications non lues dans le header +- Centre de notifications (panneau latéral) avec liste des paiements +- Formatage du temps relatif (il y a X minutes/heures/jours) +- Marquer comme lu / marquer tout comme lu +- Tri par date (plus récentes en premier) + +**Scope** : Uniquement notifications de paiements. Pas de mentions, reposts, likes. Si commentaires demandés plus tard, approbation explicite requise. + +## Stockage + +### IndexedDB avec chiffrement +- Remplacement de localStorage par IndexedDB +- Chiffrement AES-GCM du contenu privé +- Clé maître générée une fois et stockée en localStorage +- Secret par article : `:` +- Expiration automatique (30 jours) +- Pas de fallback : échec si IndexedDB ou Web Crypto indisponible + +### Fichiers +- `lib/storage/indexedDB.ts` : Service IndexedDB +- `lib/storage/cryptoHelpers.ts` : Helpers AES-GCM +- `lib/articleStorage.ts` : Gestion du stockage avec chiffrement + +## Séries et médias (NIP-95) + +### Séries +- Événements kind 1 avec tag `kind_type: series` +- Tags : `site`, `category`, `author`, `series` (self id), `title`, `description`, `cover`, `preview` +- Agrégation du sponsoring et des paiements par série + +### Médias +- Upload d'images (≤5Mo) et vidéos (≤45Mo) via NIP-95 +- Tags `banner` et `media` dans les événements +- Validations de taille et type +- Support dans les articles et séries + +### Avis (reviews) +- Événements kind 1 avec tag `kind_type: review` +- Tags : `site`, `category`, `author`, `series`, `article`, `reviewer`, `title` +- Rémunération possible avec tags `rewarded` et `reward_amount` + +## Optimisations et nettoyage + +### Refactoring +- Division des fichiers > 250 lignes +- Extraction des fonctions > 40 lignes +- Modules dédiés : parsing, messages privés, vérification zap, subscriptions, polling, résolution invoices, stockage, handlers + +### Code quality +- Respect strict `exactOptionalPropertyTypes` +- Fonctions < 40 lignes, fichiers < 250 lignes +- Pas de fallback implicite +- Logs structurés +- Pas d'analytics + +## Intégrations + +### Alby/WebLN +- Remplacement de Rizful par Alby/WebLN +- Standard WebLN compatible avec tous les portefeuilles +- Pas d'API backend nécessaire +- Service `AlbyService` pour enable, makeInvoice, sendPayment + +### Priorité 1 (implémenté) +- Génération d'invoice côté auteur lors de la publication +- Invoice stockée dans tags Nostr et localStorage +- Vérification de l'invoice avant création d'une nouvelle +- Signature distante (NIP-46) préparée + diff --git a/features/filtering-search-implementation.md b/features/filtering-search-implementation.md deleted file mode 100644 index 72b8002..0000000 --- a/features/filtering-search-implementation.md +++ /dev/null @@ -1,138 +0,0 @@ -# Implémentation du filtrage et de la recherche d'articles - -**Date** : Décembre 2024 -**Status** : ✅ Complété - -## Objectif - -Permettre aux utilisateurs de rechercher et filtrer les articles sur la page d'accueil. - -## Fonctionnalités implémentées - -### 1. Recherche par texte -- Barre de recherche permettant de rechercher dans les titres, aperçus et contenus des articles -- Recherche insensible à la casse -- Bouton pour effacer la recherche rapidement - -### 2. Filtres -- **Filtre par auteur** : Sélectionner un auteur spécifique parmi les auteurs disponibles -- **Filtre par prix minimum** : Filtrer les articles avec un prix minimum en satoshis -- **Filtre par prix maximum** : Filtrer les articles avec un prix maximum en satoshis - -### 3. Tri -- **Plus récent** (par défaut) : Articles les plus récents en premier -- **Plus ancien** : Articles les plus anciens en premier -- **Prix croissant** : Articles du moins cher au plus cher -- **Prix décroissant** : Articles du plus cher au moins cher - -### 4. Affichage des résultats -- Compteur affichant le nombre d'articles correspondant aux filtres -- Message lorsque aucun article ne correspond aux critères - -## Fichiers créés - -### `components/SearchBar.tsx` -Composant de barre de recherche avec : -- Icône de recherche -- Champ de saisie -- Bouton pour effacer la recherche -- Gestion de l'état local avec synchronisation - -### `components/ArticleFilters.tsx` -Composant de filtres avec : -- Filtre par auteur (dropdown) -- Filtres par prix min/max (inputs numériques) -- Tri (dropdown) -- Bouton "Clear all" pour réinitialiser tous les filtres -- Affichage conditionnel du bouton "Clear all" seulement si des filtres sont actifs - -**Types exportés** : -- `SortOption` : Type pour les options de tri -- `ArticleFilters` : Interface pour les filtres - -### `lib/articleFiltering.ts` -Logique de filtrage et de tri avec : -- `filterArticlesBySearch()` : Filtre par texte de recherche -- `filterArticles()` : Filtre par auteur et prix -- `sortArticles()` : Trie les articles selon l'option sélectionnée -- `applyFiltersAndSort()` : Applique tous les filtres et le tri - -## Fichiers modifiés - -### `hooks/useArticles.ts` -- Ajout des paramètres `searchQuery` et `filters` au hook -- Utilisation de `useMemo` pour optimiser le filtrage -- Retour de `allArticles` (tous les articles non filtrés) pour permettre au composant de filtres de connaître les options disponibles -- Retour de `articles` (articles filtrés et triés) pour l'affichage - -**Signature modifiée** : -```typescript -export function useArticles( - searchQuery: string = '', - filters: ArticleFilters | null = null -) -``` - -**Retour modifié** : -```typescript -{ - articles: Article[], // Articles filtrés et triés - allArticles: Article[], // Tous les articles (pour les filtres) - loading: boolean, - error: string | null, - loadArticleContent: (articleId: string, authorPubkey: string) => Promise
-} -``` - -### `pages/index.tsx` -- Ajout de l'état pour `searchQuery` et `filters` -- Intégration du composant `SearchBar` -- Intégration du composant `ArticleFilters` -- Passage des paramètres au hook `useArticles` -- Affichage du compteur d'articles filtrés -- Message amélioré lorsque aucun article ne correspond - -## Impact - -### Utilisateur -- Recherche rapide d'articles par mots-clés -- Filtrage précis par auteur et prix -- Tri flexible pour trouver facilement ce qui intéresse -- Interface intuitive avec boutons de réinitialisation - -### Technique -- Code modulaire et réutilisable -- Performance optimisée avec `useMemo` -- Types TypeScript stricts pour la sécurité -- Séparation claire des responsabilités (UI vs logique) - -## Tests recommandés - -1. **Recherche** : - - Rechercher par titre - - Rechercher par contenu d'aperçu - - Rechercher avec plusieurs mots - - Effacer la recherche - -2. **Filtres** : - - Filtrer par auteur - - Filtrer par prix minimum - - Filtrer par prix maximum - - Combiner plusieurs filtres - - Réinitialiser les filtres - -3. **Tri** : - - Trier par date (nouveaux/anciens) - - Trier par prix (croissant/décroissant) - - Combiner tri et filtres - -4. **Performance** : - - Vérifier que le filtrage ne bloque pas l'UI - - Vérifier avec un grand nombre d'articles - -## Notes techniques - -- Le filtrage est effectué côté client (pas de requête au serveur/relay) -- Les articles sont filtrés et triés à chaque changement de recherche ou filtres -- L'utilisation de `useMemo` évite de recalculer les filtres à chaque render -- Les filtres sont appliqués dans l'ordre : recherche → filtres → tri diff --git a/features/final-cleanup-summary.md b/features/final-cleanup-summary.md deleted file mode 100644 index e003c98..0000000 --- a/features/final-cleanup-summary.md +++ /dev/null @@ -1,134 +0,0 @@ -# Résumé final du nettoyage et optimisation - -**Date** : Décembre 2025 (addendum) - -## ✅ Objectifs complétés - -### 1. Nettoyage des fichiers/dossiers obsolètes -- ✅ Supprimé `pages/api/rizful/` (dossier vide après migration vers Alby) -- ✅ Documentation Rizful conservée pour référence historique - -### 2. Optimisation des fichiers > 250 lignes -Tous les fichiers sont maintenant **< 250 lignes** : -- `lib/nostr.ts` : 331 → **232 lignes** (-30%) -- `lib/articlePublisher.ts` : 237 → **210 lignes** (-11%) -- `lib/payment.ts` : 195 → **113 lignes** (-42%) -- `lib/nostrconnect.ts` : 156 → **145 lignes** (-7%) - -### 3. Division des fonctions > 40 lignes -Toutes les fonctions longues ont été extraites dans des modules dédiés : -- Parsing d'événements → `nostrEventParsing.ts` -- Messages privés → `nostrPrivateMessages.ts` -- Vérification zap → `nostrZapVerification.ts` -- Subscriptions → `nostrSubscription.ts` -- Polling paiements → `paymentPolling.ts` -- Résolution invoices → `invoiceResolver.ts` -- Stockage articles → `articleStorage.ts` -- Création invoices → `articleInvoice.ts` -- Handler NostrConnect → `nostrconnectHandler.ts` - -### 4. Correction des erreurs de lint -- ✅ Aucune erreur de lint dans le code TypeScript (déc. 2025 : `npm run lint` OK) -- ✅ Code propre et optimisé - -## Addendum Déc 2025 -- Séries, critiques, agrégations zap : nouvelles sections UI/logic (`Series*`, `ArticleReviews`, `zapAggregation*`). -- Upload médias NIP-95 (images/vidéos) avec validations de taille et type. -- Stockage contenu privé chiffré en IndexedDB + helpers WebCrypto. -- Respect strict `exactOptionalPropertyTypes`, fonctions < 40 lignes, fichiers < 250 lignes (refactors composants profil/articles, sélecteurs de séries). -- Pas de tests ajoutés, pas d’analytics. - -## Nouveaux fichiers créés (9 fichiers) - -1. **`lib/nostrEventParsing.ts`** (40 lignes) - - Parsing des événements Nostr en articles - - Extraction des tags (title, preview, zap, invoice) - -2. **`lib/nostrPrivateMessages.ts`** (59 lignes) - - Gestion des messages privés chiffrés - - Décryptage avec NIP-04 - -3. **`lib/nostrZapVerification.ts`** (61 lignes) - - Vérification des zap receipts - - Intégration avec zapVerificationService - -4. **`lib/nostrSubscription.ts`** (44 lignes) - - Utilitaires pour subscriptions avec timeout - - Gestion propre des timeouts et cleanup - -5. **`lib/paymentPolling.ts`** (85 lignes) - - Polling pour vérification des paiements - - Envoi automatique du contenu privé après paiement - -6. **`lib/invoiceResolver.ts`** (39 lignes) - - Résolution intelligente des invoices - - Priorité : tags → localStorage → création nouvelle - -7. **`lib/articleStorage.ts`** (93 lignes) - - Gestion du stockage localStorage - - Fonctions pour stocker/récupérer/supprimer - -8. **`lib/articleInvoice.ts`** (50 lignes) - - Création d'invoices Lightning - - Création d'événements preview avec tags - -9. **`lib/nostrconnectHandler.ts`** (32 lignes) - - Handler pour messages NostrConnect - - Validation de sécurité (origin) - -## Statistiques finales - -### Taille des fichiers lib/ (par ordre décroissant) -``` -nostr.ts 232 lignes -articlePublisher.ts 210 lignes -alby.ts 184 lignes -payment.ts 113 lignes ✅ (réduit de 195) -nostrconnect.ts 145 lignes -zapVerification.ts 97 lignes -articleStorage.ts 93 lignes (nouveau) -paymentPolling.ts 85 lignes (nouveau) -retry.ts 76 lignes -nostrZapVerification.ts 61 lignes (nouveau) -nostrPrivateMessages.ts 59 lignes (nouveau) -nostrRemoteSigner.ts 51 lignes -articleInvoice.ts 50 lignes (nouveau) -nostrSubscription.ts 44 lignes (nouveau) -nostrEventParsing.ts 40 lignes (nouveau) -invoiceResolver.ts 39 lignes (nouveau) -nostrconnectHandler.ts 32 lignes (nouveau) -``` - -### Réduction totale -- **Avant** : 4 fichiers > 250 lignes -- **Après** : 0 fichiers > 250 lignes ✅ -- **Réduction moyenne** : -25% de lignes dans les fichiers principaux -- **Fonctions** : Toutes < 40 lignes ✅ - -## Architecture finale - -### Séparation des responsabilités -- **Parsing** : `nostrEventParsing.ts` -- **Communication** : `nostr.ts`, `nostrSubscription.ts` -- **Chiffrement** : `nostrPrivateMessages.ts` -- **Vérification** : `nostrZapVerification.ts`, `zapVerification.ts` -- **Paiements** : `payment.ts`, `paymentPolling.ts`, `invoiceResolver.ts` -- **Articles** : `articlePublisher.ts`, `articleStorage.ts`, `articleInvoice.ts` -- **Connectivité** : `nostrconnect.ts`, `nostrconnectHandler.ts` -- **Lightning** : `alby.ts`, `retry.ts` -- **Signature** : `nostrRemoteSigner.ts` - -### Avantages -- ✅ Code modulaire et réutilisable -- ✅ Responsabilités bien séparées (SRP) -- ✅ Tests unitaires facilités -- ✅ Maintenance simplifiée -- ✅ Imports clairs et explicites -- ✅ Pas de dépendances circulaires - -## Prochaines étapes - -Le code est maintenant propre, optimisé et maintenable. Prêt pour : -- Tests unitaires -- Documentation utilisateur -- Fonctionnalités avancées (priorité 3) diff --git a/features/nostr-paywall-implementation.md b/features/nostr-paywall-implementation.md deleted file mode 100644 index 13dc01f..0000000 --- a/features/nostr-paywall-implementation.md +++ /dev/null @@ -1,217 +0,0 @@ -# Nostr Paywall - Site d'articles avec aperçus gratuits et contenu payant - -**Auteur** : Équipe 4NK - -## Objectif - -Implémenter un site d'articles sur Nostr permettant : -- L'affichage d'aperçus gratuits (notes publiques) -- Le déblocage du contenu complet après un zap Lightning de 800 sats -- La connexion via NostrConnect (préconisé use.nsec.app) -- Une interface moderne et intuitive en TypeScript/Next.js - -## Impacts - -### Utilisateurs -- Accès gratuit aux aperçus d'articles -- Possibilité de débloquer le contenu complet via paiement Lightning instantané -- Connexion sécurisée via NostrConnect sans partager de clés privées -- Expérience utilisateur fluide avec gestion des paiements intégrée - -### Développeurs -- Architecture modulaire avec séparation des responsabilités -- Utilisation de `nostr-tools` pour toutes les opérations Nostr -- TypeScript pour la sécurité de type -- Hooks React personnalisés pour la gestion de l'état -- Service de connexion NostrConnect réutilisable - -### Technique -- Dépendance principale : `nostr-tools` (bibliothèque standard Nostr) -- Framework : Next.js 14 avec React 18 -- Styling : Tailwind CSS -- Relay par défaut : wss://relay.damus.io -- Bridge NostrConnect : https://use.nsec.app - -## Modifications - -### Structure du projet - -``` -nostr_paywall/ -├── pages/ -│ ├── index.tsx # Page principale avec liste des articles -│ └── _app.tsx # Configuration Next.js -├── components/ -│ ├── ConnectButton.tsx # Bouton de connexion NostrConnect -│ └── ArticleCard.tsx # Carte d'article avec aperçu et déblocage -├── hooks/ -│ ├── useNostrConnect.ts # Hook pour la connexion NostrConnect -│ └── useArticles.ts # Hook pour la gestion des articles -├── lib/ -│ ├── nostr.ts # Service Nostr (publications, abonnements, zaps) -│ └── nostrconnect.ts # Service NostrConnect (NIP-46) -├── types/ -│ └── nostr.ts # Types TypeScript pour Nostr -└── styles/ - └── globals.css # Styles globaux avec Tailwind -``` - -### Composants clés - -#### `lib/nostr.ts` - Service Nostr -- `SimplePool` pour la gestion des connexions aux relais -- Méthodes pour publier et s'abonner aux événements -- Parsing des articles depuis les événements kind:1 -- Gestion des messages privés chiffrés (kind:4) avec NIP-04 -- Création de zap requests (kind:9734) -- Vérification des zap receipts (kind:9735) - -#### `lib/nostrconnect.ts` - Service NostrConnect -- Implémentation du protocole NIP-46 via use.nsec.app -- Communication via messages postMessage avec popup -- Persistance de l'état de connexion dans localStorage -- Gestion du profil utilisateur - -#### `components/ArticleCard.tsx` -- Affichage de l'aperçu (contenu public) -- Bouton de déblocage conditionnel (nécessite connexion) -- Création de zap request lors du clic -- Vérification du paiement et chargement du contenu privé -- Affichage du contenu complet une fois débloqué - -### Format des articles - -Les articles sont publiés sous forme d'événements Nostr avec : - -**Note publique (kind:1)** - Aperçu : -- Tags : `title`, `preview`, `zap` (montant en sats) -- Contenu : Aperçu de l'article - -**Message privé (kind:4)** - Contenu complet : -- Tag `e` : ID de l'article lié -- Contenu : Contenu complet chiffré avec NIP-04 -- Envoyé après réception du zap - -### Flux de paiement - -1. Utilisateur clique sur "Unlock for 800 sats" -2. Création d'un zap request (kind:9734) avec tags `p`, `e`, `amount` -3. Le zap request est publié sur le relay -4. L'utilisateur complète le paiement via son wallet Lightning -5. Vérification du zap receipt (kind:9735) sur le relay -6. Déchiffrement et affichage du contenu privé - -## Modalités de déploiement - -### Prérequis -- Node.js 18+ et npm -- Accès à un relay Nostr public ou privé -- Configuration de variables d'environnement optionnelles - -### Variables d'environnement - -Créer un fichier `.env.local` : - -```env -NEXT_PUBLIC_NOSTR_RELAY_URL=wss://relay.damus.io -NEXT_PUBLIC_NOSTRCONNECT_BRIDGE=https://use.nsec.app -``` - -### Installation - -```bash -npm install -``` - -### Développement - -```bash -npm run dev -``` - -Le site sera accessible sur http://localhost:3000 - -### Build de production - -```bash -npm run build -npm start -``` - -### Déploiement - -Le projet peut être déployé sur : -- Vercel (recommandé pour Next.js) -- Netlify -- Tout hébergeur supportant Node.js - -**Important** : Pour la production, configurer : -- Variables d'environnement dans le panneau d'administration -- HTTPS (obligatoire pour NostrConnect) -- Relay Nostr fiable et performant - -## Modalités d'analyse - -### Logs et debugging - -Les erreurs sont loggées dans la console du navigateur : -- Erreurs de connexion aux relais -- Erreurs de déchiffrement -- Erreurs de parsing d'articles - -### Métriques à surveiller - -1. **Connectivité** - - Taux de connexion réussie via NostrConnect - - Temps de réponse des relais - -2. **Articles** - - Nombre d'articles chargés - - Temps de chargement des aperçus - - Taux de conversion (aperçu → déblocage) - -3. **Paiements** - - Nombre de zap requests créés - - Taux de confirmation des zaps - - Temps moyen entre zap request et receipt - -4. **Utilisateurs** - - Nombre d'utilisateurs connectés - - Profils chargés avec succès - -### Points d'amélioration - -1. **Gestion des zaps** - - Implémentation complète du flux Lightning avec intégration wallet - - Webhooks pour les confirmations de zap - - Interface de paiement intégrée (LNURL, Lightning Address) - -2. **Sécurité** - - Vérification des signatures des zap receipts - - Validation stricte des événements reçus - - Gestion des erreurs de déchiffrement - -3. **Performance** - - Mise en cache des articles chargés - - Pagination pour les grandes listes - - Indexation des articles par tags - -4. **UX** - - Feedback visuel pendant le traitement des zaps - - Gestion des états de chargement - - Messages d'erreur plus explicites - -### Tests recommandés - -1. **Tests unitaires** - - Parsing d'événements en articles - - Déchiffrement de messages privés - - Création de zap requests - -2. **Tests d'intégration** - - Flux complet de connexion NostrConnect - - Flux complet de déblocage d'article - - Gestion des erreurs réseau - -3. **Tests end-to-end** - - Scénario utilisateur complet (connexion → aperçu → paiement → contenu) diff --git a/features/notifications-scope.md b/features/notifications-scope.md deleted file mode 100644 index b1ff588..0000000 --- a/features/notifications-scope.md +++ /dev/null @@ -1,14 +0,0 @@ -# Notifications scope (Dec 2025) - -**Decision:** Do not implement notifications for mentions, reposts, or likes. Only payment notifications remain active. If comment notifications are later requested, they must be explicitly approved. - -**Impacts:** -- No parsing/subscription for mention/repost/like events. -- UI does not surface badges or panels for these types. -- Avoids extra relay traffic and parsing logic. - -**Constraints/quality:** -- No fallbacks. -- No analytics. -- Keep error logging structured if new notification types are ever added. -- Respect accessibility and lint/typing rules already in place. diff --git a/features/priority1-implementation.md b/features/priority1-implementation.md deleted file mode 100644 index 0b73490..0000000 --- a/features/priority1-implementation.md +++ /dev/null @@ -1,85 +0,0 @@ -# Implémentation Priorité 1 - -**Auteur** : Équipe 4NK - -## Objectif - -Implémenter les fonctionnalités critiques de priorité 1 : -1. Signature distante pour publication d'articles (NIP-46) -2. Génération d'invoice côté auteur lors de la publication - -## Modifications - -### 1. Génération d'invoice côté auteur - -**Fichiers modifiés** : -- `lib/articlePublisher.ts` : Ajout de la création d'invoice lors de la publication -- `lib/payment.ts` : Vérification de l'invoice de l'auteur avant d'en créer une nouvelle - -**Fonctionnement** : -- Lors de la publication, l'auteur crée une facture Lightning via Alby/WebLN -- L'invoice est stockée dans les tags de l'événement Nostr (`invoice`, `payment_hash`) -- L'invoice est également stockée dans localStorage (pour récupération rapide) -- Lors du paiement, le système vérifie d'abord si une invoice existe et n'est pas expirée -- Si aucune invoice valide, le lecteur peut en créer une nouvelle - -**Avantages** : -- Meilleure traçabilité (invoice créée par l'auteur) -- L'invoice peut être réutilisée par plusieurs lecteurs -- L'invoice est visible dans l'événement Nostr (tags) - -### 2. Signature distante améliorée - -**Fichiers modifiés** : -- `lib/nostrRemoteSigner.ts` : Amélioration du support de signature -- `lib/articlePublisher.ts` : Support optionnel de la clé privée -- `components/ArticleEditor.tsx` : Utilisation améliorée - -**Fonctionnement** : -- Si la clé privée est disponible (via NostrConnect), utilisation de la signature directe -- Si pas de clé privée, message d'erreur explicite -- Préparation pour future implémentation NIP-46 complète - -**Note** : L'implémentation complète de NIP-46 nécessiterait une connexion WebSocket permanente avec un relay, ce qui est complexe. Pour l'instant, le système fonctionne avec les clés privées fournies par NostrConnect via postMessage. - -## Détails techniques - -### Invoice dans les tags Nostr - -Les invoices créées par l'auteur sont stockées dans les tags de l'événement : -``` -tags: [ - ['invoice', 'lnbc...'], // Invoice BOLT11 - ['payment_hash', 'abc123...'], // Payment hash -] -``` - -### Stockage local - -Les invoices sont également stockées dans localStorage avec le contenu privé : -```json -{ - "content": "...", - "authorPubkey": "...", - "articleId": "...", - "invoice": { - "invoice": "lnbc...", - "paymentHash": "...", - "amount": 800, - "expiresAt": 1234567890 - }, - "createdAt": 1234567890 -} -``` - -## Limitations actuelles - -1. **Signature distante** : NIP-46 complet non implémenté (nécessite WebSocket relay) -2. **Stockage invoice** : localStorage côté client (pas accessible entre lecteurs) -3. **Récupération invoice** : Actuellement via localStorage, idéalement depuis les tags de l'événement - -## Améliorations futures - -1. Parser l'invoice directement depuis les tags de l'événement Nostr -2. Implémenter NIP-46 complet pour la signature distante -3. Utiliser une base de données pour le stockage au lieu de localStorage diff --git a/features/rizful-integration.md b/features/rizful-integration.md deleted file mode 100644 index 80ece8b..0000000 --- a/features/rizful-integration.md +++ /dev/null @@ -1,215 +0,0 @@ -# Intégration Rizful.com API pour paiements Lightning et identités - -**Auteur** : Équipe 4NK - -## Objectif - -Intégrer l'API de Rizful.com pour : -- Générer des identités Nostr -- Créer et gérer des factures Lightning pour les paiements d'articles -- Vérifier le statut des paiements Lightning -- Fournir une expérience de paiement fluide via Rizful - -## Impacts - -### Utilisateurs -- Paiements Lightning facilités via l'infrastructure Rizful -- Interface de paiement améliorée avec modal dédiée -- Vérification automatique des paiements -- Possibilité de générer des identités Nostr via Rizful - -### Développeurs -- Service Rizful centralisé pour toutes les opérations de paiement -- Intégration transparente avec le système de paiement existant -- Gestion des factures Lightning standardisée -- API unifiée pour les identités et paiements - -### Technique -- Nouveau service `RizfulService` pour les appels API -- Service `PaymentService` intégrant Rizful avec Nostr -- Composant `PaymentModal` pour l'affichage des factures -- Variables d'environnement pour la configuration API - -## Modifications - -### Nouveaux fichiers - -#### `lib/rizful.ts` - Service Rizful API -Service principal pour interagir avec l'API Rizful.com : -- `createInvoice()` : Créer une facture Lightning -- `checkPaymentStatus()` : Vérifier le statut d'un paiement -- `waitForPayment()` : Polling jusqu'à confirmation du paiement -- `generateIdentity()` : Générer une nouvelle identité Nostr -- `getLightningAddress()` : Obtenir l'adresse Lightning d'une identité -- `createPaymentLink()` : Créer un lien de paiement avec URL Lightning - -#### `lib/payment.ts` - Service de paiement intégré -Service intégrant Rizful avec le système Nostr : -- `createArticlePayment()` : Créer une facture pour un article -- `checkArticlePayment()` : Vérifier le paiement d'un article -- `waitForArticlePayment()` : Attendre la confirmation du paiement -- `getPaymentUrl()` : Obtenir l'URL de paiement pour un article - -#### `types/rizful.ts` - Types TypeScript -Types pour l'API Rizful : -- `RizfulConfig` : Configuration du service -- `RizfulInvoice` : Structure d'une facture Lightning -- `RizfulPaymentStatus` : Statut d'un paiement -- `RizfulIdentity` : Identité Nostr générée -- `RizfulInvoiceRequest` : Requête de création de facture - -#### `components/PaymentModal.tsx` - Modal de paiement -Composant React pour afficher la facture Lightning : -- Affichage de la facture en texte -- Bouton pour copier la facture -- Bouton pour ouvrir le wallet Lightning -- Interface utilisateur claire et intuitive - -### Modifications des fichiers existants - -#### `components/ArticleCard.tsx` -- Intégration du `PaymentService` au lieu du système de zap direct -- Affichage de `PaymentModal` lors de la création d'une facture -- Polling automatique pour vérifier le paiement en arrière-plan -- Gestion améliorée des états de paiement - -#### `next.config.js` -- Ajout des variables d'environnement Rizful : - - `RIZFUL_API_KEY` : Clé API Rizful - - `RIZFUL_API_URL` : URL de l'API Rizful (défaut: https://api.rizful.com) - -### Flux de paiement avec Rizful - -1. **Utilisateur clique sur "Unlock for X sats"** - - Vérification de la connexion Nostr - - Création d'une facture Lightning via Rizful API - -2. **Affichage de la modal de paiement** - - Facture Lightning affichée - - Options pour copier ou ouvrir dans wallet - -3. **Paiement utilisateur** - - Utilisateur paie via son wallet Lightning - - Paiement traité par Rizful - -4. **Vérification du paiement** - - Polling automatique du statut via Rizful API - - Vérification supplémentaire via zap receipt sur Nostr (double confirmation) - -5. **Déblocage du contenu** - - Une fois le paiement confirmé, chargement du contenu privé - - Affichage du contenu complet - -## Modalités de déploiement - -### Prérequis -- Compte Rizful.com avec clé API -- Variables d'environnement configurées - -### Configuration - -Créer ou mettre à jour le fichier `.env.local` : - -```env -# Rizful API Configuration -NEXT_PUBLIC_RIZFUL_API_KEY=your_rizful_api_key_here -NEXT_PUBLIC_RIZFUL_API_URL=https://api.rizful.com - -# Existing Nostr configuration -NEXT_PUBLIC_NOSTR_RELAY_URL=wss://relay.damus.io -NEXT_PUBLIC_NOSTRCONNECT_BRIDGE=https://use.nsec.app -``` - -### Obtenir une clé API Rizful - -1. Créer un compte sur [Rizful.com](https://rizful.com/) -2. Accéder aux paramètres du compte -3. Générer une clé API -4. Configurer l'adresse Lightning personnalisée (optionnel) -5. Copier la clé API dans les variables d'environnement - -### Déploiement - -Aucun changement dans le processus de déploiement standard : -- Les variables d'environnement doivent être configurées dans l'environnement de production -- Le code client peut accéder aux variables `NEXT_PUBLIC_*` -- Les appels API se font depuis le navigateur (CORS doit être configuré côté Rizful) - -### Sécurité - -- **Clé API** : Stockée côté client (NEXT_PUBLIC_*), donc accessible dans le navigateur - - Rizful devrait implémenter des restrictions par domaine/origine - - Considérer un proxy backend pour protéger la clé API en production -- **Factures Lightning** : Valides uniquement pendant la période d'expiration -- **Vérification double** : Combinaison Rizful API + zap receipts Nostr pour validation - -## Modalités d'analyse - -### Logs et debugging - -Les erreurs sont loggées dans la console du navigateur : -- Erreurs de création de facture -- Erreurs de vérification de paiement -- Timeouts de polling - -### Métriques à surveiller - -1. **API Rizful** - - Taux de succès des créations de factures - - Temps de réponse de l'API - - Taux de confirmation des paiements - - Erreurs API (rate limiting, authentification, etc.) - -2. **Paiements** - - Temps moyen entre création de facture et paiement - - Taux d'abandon de paiement - - Taux de confirmation de paiement - - Échecs de vérification de paiement - -3. **Expérience utilisateur** - - Utilisation de la modal vs ouverture directe du wallet - - Taux de copie de facture - - Temps d'attente pour confirmation - -### Points d'amélioration - -1. **Backend proxy (recommandé pour production)** - - Créer un endpoint Next.js API route pour protéger la clé API - - Appels API depuis le serveur au lieu du client - - Validation supplémentaire côté serveur - -2. **Gestion des erreurs** - - Retry logic pour les appels API échoués - - Gestion des timeouts réseau - - Messages d'erreur utilisateur plus explicites - -3. **QR Code** - - Génération de QR code pour les factures Lightning - - Affichage dans la modal de paiement - - Compatible avec wallets mobiles - -4. **Webhooks** - - Intégration webhooks Rizful pour notifications en temps réel - - Éviter le polling continu - - Réactivité améliorée - -5. **Identités** - - Utilisation de `generateIdentity()` pour créer des identités - - Stockage sécurisé des clés privées générées - - Intégration avec le système d'authentification - -### Tests recommandés - -1. **Tests unitaires** - - `RizfulService.createInvoice()` - - `RizfulService.checkPaymentStatus()` - - `PaymentService.createArticlePayment()` - -2. **Tests d'intégration** - - Flux complet de paiement (création → paiement → vérification) - - Gestion des timeouts - - Gestion des erreurs API - -3. **Tests end-to-end** - - Scénario utilisateur complet avec paiement réel - - Vérification du déblocage de contenu après paiement diff --git a/features/storage-encryption.md b/features/storage-encryption.md deleted file mode 100644 index a578e99..0000000 --- a/features/storage-encryption.md +++ /dev/null @@ -1,23 +0,0 @@ -# Storage encryption (IndexedDB) – Dec 2025 - -**Scope** -- Encrypt private article content and invoices stored in IndexedDB using Web Crypto (AES-GCM). -- Deterministic per-article secret derived from a persisted master key. -- No fallbacks; fails if IndexedDB or Web Crypto is unavailable. - -**Key management** -- Master key generated once in browser (`article_storage_master_key`, random 32 bytes, base64) and kept in localStorage. -- Per-article secret: `:` (used only client-side). - -**Implementation** -- `lib/storage/cryptoHelpers.ts`: AES-GCM helpers (base64 encode/decode, encrypt/decrypt). -- `lib/storage/indexedDB.ts`: store/get now require a secret; payloads encrypted; unchanged API surface via `storageService`. -- `lib/articleStorage.ts`: derives per-article secret, encrypts content+invoice on write, decrypts on read, same expiration (30 days). - -**Behavior** -- If IndexedDB or crypto is unavailable, operations throw (no silent fallback). -- Existing data written before encryption won’t decrypt; new writes are encrypted. - -**Next steps (optional)** -- Rotate master key with migration plan. -- Add per-user secrets or hardware-bound keys if required. diff --git a/features/storage-improvement-implementation.md b/features/storage-improvement-implementation.md deleted file mode 100644 index 7f044cf..0000000 --- a/features/storage-improvement-implementation.md +++ /dev/null @@ -1,158 +0,0 @@ -# Implémentation de l'amélioration du stockage du contenu privé - -**Date** : Décembre 2024 -**Status** : ✅ Complété - -## Objectif - -Remplacer localStorage par IndexedDB pour le stockage du contenu privé des articles, offrant une meilleure fiabilité, une plus grande capacité de stockage et la gestion de l'expiration des données. - -## Fonctionnalités implémentées - -### 1. Service IndexedDB -- Service IndexedDB complet avec gestion d'initialisation -- Support des index pour les recherches (createdAt, expiresAt) -- Gestion des erreurs -- Utilisation exclusive d'IndexedDB (pas de fallback) - -### 3. Gestion de l'expiration -- Expiration automatique des données (30 jours par défaut) -- Suppression automatique des données expirées lors de la récupération -- Méthode pour nettoyer toutes les données expirées - -### 4. Migration des fonctions -- Toutes les fonctions de stockage sont maintenant async -- Compatibilité avec l'API existante (même signature, mais async) -- Migration transparente pour le code existant - -## Fichiers créés - -### `lib/storage/indexedDB.ts` -Service IndexedDB complet : -- `IndexedDBStorage` : Classe pour gérer IndexedDB -- `storageService` : Instance exportée de IndexedDBStorage -- Méthodes : `set()`, `get()`, `delete()`, `clearExpired()` -- Gestion de l'expiration automatique -- Utilisation exclusive d'IndexedDB (pas de fallback) - -**Caractéristiques** : -- Base de données : `nostr_paywall` -- Version : 1 -- Object store : `article_content` -- Index : `createdAt`, `expiresAt` - -### `features/storage-improvement-implementation.md` -Documentation de l'implémentation. - -## Fichiers modifiés - -### `lib/articleStorage.ts` -- `storePrivateContent()` : Maintenant async, utilise `storageService` -- `getStoredPrivateContent()` : Maintenant async, utilise `storageService` -- `getStoredInvoice()` : Maintenant async -- `removeStoredPrivateContent()` : Maintenant async -- Expiration par défaut : 30 jours - -**Changements** : -- Remplacement de `localStorage` par `storageService` -- Ajout de l'expiration automatique (30 jours) -- Toutes les fonctions deviennent async - -### `lib/articlePublisher.ts` -- Mise à jour pour utiliser les nouvelles fonctions async -- Suppression des méthodes privées dupliquées -- Utilisation directe des fonctions exportées de `articleStorage` - -### `lib/invoiceResolver.ts` -- `getStoredInvoice()` : Maintenant async avec `await` - -### `lib/paymentPolling.ts` -- `getStoredPrivateContent()` : Maintenant async avec `await` - -## Avantages d'IndexedDB vs localStorage - -### IndexedDB -- **Capacité** : Plusieurs Go vs ~5-10 MB pour localStorage -- **Performance** : Meilleure pour les grandes quantités de données -- **Structured** : Base de données structurée avec index -- **Transactions** : Support des transactions -- **Types** : Support des types complexes (Blob, ArrayBuffer, etc.) - -### localStorage -- **Simplicité** : API plus simple (clé-valeur) -- **Compatibilité** : Meilleure compatibilité navigateur (mais IndexedDB est maintenant bien supporté) -- **Synchronisation** : API synchrone (plus simple mais peut bloquer) - -## Gestion de l'expiration - -### Expiration par défaut -- **Durée** : 30 jours (configurable via `DEFAULT_EXPIRATION`) -- **Vérification** : Automatique lors de la récupération -- **Nettoyage** : Les données expirées sont supprimées automatiquement - -### Expiration personnalisée -Les données peuvent être stockées avec une expiration personnalisée : -```typescript -await storageService.set(key, data, customExpirationInMs) -``` - -## Exigence IndexedDB - -L'application nécessite IndexedDB pour fonctionner : -- Si IndexedDB n'est pas disponible, une erreur sera levée -- IndexedDB est supporté par tous les navigateurs modernes -- Pas de fallback vers localStorage - -## Migration des données existantes - -Les données existantes dans localStorage restent accessibles : -- Les nouvelles données sont stockées dans IndexedDB (ou localStorage en fallback) -- Les anciennes données dans localStorage peuvent être lues (si nécessaire) -- Pas de migration automatique nécessaire (les données anciennes seront progressivement remplacées) - -## Impact - -### Utilisateur -- Stockage plus fiable et performant -- Pas de changement visible dans l'interface - -### Technique -- Meilleure gestion du stockage -- Expiration automatique des données -- Support de plus grandes quantités de données -- Code plus robuste avec fallback - -## Limitations et améliorations futures - -### Limitations actuelles -- Expiration fixe à 30 jours (pas de configuration utilisateur) -- Pas de nettoyage périodique automatique (seulement lors de la récupération) -- Nécessite IndexedDB (pas de fallback) - -### Améliorations possibles -- **Migration automatique** : Migrer les données localStorage vers IndexedDB au premier chargement -- **Nettoyage périodique** : Tâche de nettoyage périodique pour supprimer les données expirées -- **Configuration** : Permettre à l'utilisateur de configurer l'expiration -- **Compression** : Compresser les données avant stockage pour économiser l'espace -- **Chiffrement** : Chiffrer les données sensibles avant stockage - -## Tests recommandés - -1. **Stockage** : - - Stocker du contenu privé - - Vérifier qu'il est stocké correctement - - Vérifier qu'il peut être récupéré - -2. **Expiration** : - - Stocker avec expiration courte - - Attendre l'expiration - - Vérifier que les données sont supprimées - -3. **IndexedDB requis** : - - Vérifier que l'application fonctionne avec IndexedDB - - Vérifier que les erreurs sont gérées correctement si IndexedDB n'est pas disponible - -4. **Performance** : - - Tester avec un grand nombre d'articles - - Vérifier que les performances sont bonnes - - Vérifier qu'il n'y a pas de blocage de l'UI diff --git a/features/technical-doc.md b/features/technical-doc.md deleted file mode 100644 index 1ea0cb9..0000000 --- a/features/technical-doc.md +++ /dev/null @@ -1,71 +0,0 @@ -# Documentation technique – zapwall4science (Dec 2025) - -## 1) Cartographie services/hooks/types (responsabilités, dépendances) - -- **Services Nostr** - - `lib/nostr.ts` : pool SimplePool, publish générique, clés locales; queries article. - - `lib/nostrEventParsing.ts` : parsing events → Article/Series/Review (tags kind_type, series, media, banner). - - `lib/nostrTags.ts` : construction des tags article/série/avis (site, type science-fiction/research, kind_type, media/bannière). - - `lib/seriesQueries.ts`, `lib/articleQueries.ts`, `lib/reviews.ts` : fetch séries, articles par série, critiques. - - `lib/articlePublisher.ts`, `lib/articleMutations.ts` : publication article/preview/presentation, update/delete, kind_type, séries, médias, bannière. - - `lib/seriesAggregation.ts`, `lib/reviewAggregation.ts`, `lib/zapAggregation.ts` : agrégats sponsoring/achats/remerciements. - - `lib/zapVerification.ts` : vérification zap receipts (verifyEvent). - - `lib/nostrconnect.ts` : Nostr Connect (handler, sécurité). - - `lib/nostrRemoteSigner.ts` : signature distante (pas de fallback silencieux). - - `lib/nip95.ts` : upload médias NIP-95 (images ≤5Mo, vidéos ≤45Mo, types restreints). -- **Paiement / Lightning** - - `lib/alby.ts` : WebLN (enable, makeInvoice, sendPayment). - - `lib/payment.ts`, `lib/paymentPolling.ts` : statut paiements, polling. - - `lib/articleInvoice.ts` : facture article (zapAmount, expiry), tags preview. -- **Stockage** - - `lib/storage/cryptoHelpers.ts` : AES-GCM, dérivation/import clé, conversions b64. - - `lib/storage/indexedDB.ts` : set/get/delete/clearExpired chiffré, TTL. - - `lib/articleStorage.ts` : clé maître locale (base64), secret par article, persistance contenu privé + facture. -- **Hooks** - - `hooks/useArticles.ts`, `hooks/useUserArticles.ts` : subscriptions articles, filtres catégorie, unsubscribe direct (pas de .then). - - `hooks/useArticleEditing.ts` : édition/suppression article. - - Autres : `useNotificationCenter`, `useNostrConnect`, etc. -- **Types** - - `types/nostr.ts` : Article, Series, Review, MediaRef, KindType, catégories; exactOptionalPropertyTypes respecté. - - `types/nostr-tools-extended.ts` : extensions SimplePool/Sub. - - `types/alby.ts` : WebLNProvider, invoice types. - -## 2) Guide Nostr (publication, update/delete, zap, remote signer) - -- Publication générique : `nostrService.publishEvent(eventTemplate)` (signEvent, created_at contrôlé). -- Article : `articlePublisher.publishArticle` (preview + tags kind_type/site/category/series/banner/media), contenu privé chiffré stocké. -- Update article : `publishArticleUpdate` (`lib/articleMutations.ts`) tags `e` (original) + `replace`, publie preview + contenu privé chiffré. -- Delete article : `deleteArticleEvent` (kind 5, tag e) — erreurs remontées, pas de fallback. -- Série : `publishSeries` (kind 1, tags kind_type=series, cover, description). -- Avis : `publishReview` (kind 1, kind_type=review, article/series/author tags). -- Zap verification : `lib/zapVerification.ts` (verifyEvent). -- Agrégats : `aggregateZapSats` / `getSeriesAggregates` / `getReviewTipsForArticle`. -- Remote signer : `lib/nostrRemoteSigner.ts` (clé fournie), sans valeurs de repli implicites. - -## 3) Guide Stockage - -- Chiffrement : `cryptoHelpers` (AES-GCM), entrée BufferSource conforme Web Crypto. -- IndexedDB : `storage/indexedDB.ts` stocke `{ iv, ciphertext, expiresAt }`, purge `clearExpired`. -- Secret : `articleStorage` génère clé maître (localStorage, base64, 32 bytes) puis secret `:`. -- Données : contenu privé + facture, TTL 30 jours, suppression via `removeStoredPrivateContent`. - -## 4) Guide Paiements - -- WebLN/Alby : `lib/alby.ts` (enable, makeInvoice, sendPayment). -- Facture article : `createArticleInvoice` (zapAmount, expiry). -- Publication article : `articlePublisher` gère preview event + stockage contenu privé. -- Polling / vérif : `paymentPolling.ts`, `payment.ts`; agrégats via zap receipts (`zapAggregation.ts`). -- Envoi contenu privé : via publisher/mutations après paiement confirmé. - -## 5) Médias / NIP-95 - -- Upload via `uploadMedia(file)` (URL `NEXT_PUBLIC_NIP95_UPLOAD_URL`), validation type/taille. -- Utilisation dans `MarkdownEditor` (insertion markdown), bannière dans ArticleDraft. - -## 6) Contrib (référence rapide) - -- Lint/typage obligatoires (`npm run lint`, `npm run type-check`). -- Pas de tests/analytics ajoutés. -- Pas de fallback implicite, pas de `ts-ignore`/`any` non justifié. -- Accessibilité : ARIA/clavier/contraste. -- Documentation : corrections dans `fixKnowledge/`, features dans `features/`. diff --git a/features/user-profile-implementation.md b/features/user-profile-implementation.md deleted file mode 100644 index aeab080..0000000 --- a/features/user-profile-implementation.md +++ /dev/null @@ -1,169 +0,0 @@ -# Implémentation du profil utilisateur et des articles de l'utilisateur - -**Date** : Décembre 2024 -**Status** : ✅ Complété - -## Objectif - -Permettre aux utilisateurs de visualiser leur profil et la liste de leurs articles publiés. - -## Fonctionnalités implémentées - -### 1. Page de profil -- Page `/profile` accessible uniquement aux utilisateurs connectés -- Affichage des informations du profil (nom, photo, description, pubkey, nip05) -- Redirection automatique vers la page d'accueil si non connecté -- Compteur d'articles publiés - -### 2. Liste des articles de l'utilisateur -- Affichage de tous les articles publiés par l'utilisateur connecté -- Recherche et filtres (comme sur la page d'accueil) -- Tri des articles (nouveaux/anciens, prix) -- Compteur d'articles affichés vs total - -### 3. Lien vers le profil -- Le nom/avatar dans `ConnectButton` est maintenant cliquable -- Lien vers `/profile` pour accéder rapidement au profil - -### 4. Gestion du profil minimal -- Si aucun profil Nostr n'existe, affichage d'un profil minimal avec le pubkey -- Pas d'erreur si le profil n'existe pas - -## Fichiers créés - -### `hooks/useUserArticles.ts` -Hook personnalisé pour charger les articles d'un utilisateur spécifique : -- Filtre automatiquement les articles par `pubkey` de l'auteur -- Supporte la recherche et les filtres (comme `useArticles`) -- Gestion de l'état de chargement et des erreurs -- Méthode `loadArticleContent` pour charger le contenu privé - -**Signature** : -```typescript -export function useUserArticles( - userPubkey: string, - searchQuery: string = '', - filters: ArticleFilters | null = null -) -``` - -### `components/UserProfile.tsx` -Composant d'affichage du profil utilisateur : -- Affichage de la photo de profil (ou initiale si pas de photo) -- Nom, pubkey tronqué, nip05 -- Description/about si disponible -- Compteur d'articles publiés - -**Props** : -```typescript -interface UserProfileProps { - profile: NostrProfile - pubkey: string - articleCount?: number -} -``` - -### `components/UserArticles.tsx` -Composant pour afficher la liste des articles de l'utilisateur : -- Réutilise `ArticleCard` pour la cohérence UI -- Gestion de l'état de chargement -- Gestion des erreurs -- Message si aucun article publié -- Gestion du déverrouillage des articles payants - -**Props** : -```typescript -interface UserArticlesProps { - articles: Article[] - loading: boolean - error: string | null - onLoadContent: (articleId: string, authorPubkey: string) => Promise
- showEmptyMessage?: boolean -} -``` - -### `pages/profile.tsx` -Page de profil utilisateur : -- Vérifie la connexion et redirige si non connecté -- Charge le profil de l'utilisateur connecté -- Affiche le profil avec `UserProfile` -- Affiche les articles avec recherche et filtres -- Header cohérent avec le reste de l'application -- Bouton retour vers la page d'accueil - -## Fichiers modifiés - -### `components/ConnectButton.tsx` -- Ajout d'un `Link` autour du nom/avatar de l'utilisateur -- Lien vers `/profile` pour accéder au profil -- Hover effect pour indiquer que c'est cliquable - -**Changements** : -- Import de `Link` de `next/link` -- Le nom/avatar est maintenant dans un `Link` vers `/profile` - -## Flux utilisateur - -1. **Accès au profil** : - - L'utilisateur clique sur son nom/avatar dans le header - - Redirection vers `/profile` - - Si non connecté, redirection vers `/` - -2. **Visualisation du profil** : - - Affichage des informations du profil - - Compteur d'articles publiés - -3. **Gestion des articles** : - - Liste de tous les articles publiés - - Possibilité de rechercher et filtrer - - Possibilité de déverrouiller les articles payants (si l'utilisateur les a payés) - -## Impact - -### Utilisateur -- Accès facile à son profil et ses articles -- Vue d'ensemble de ses publications -- Recherche et filtres pour trouver rapidement un article spécifique - -### Technique -- Code modulaire et réutilisable -- Hook personnalisé pour charger les articles par auteur -- Composants réutilisables (UserProfile, UserArticles) -- Cohérence UI avec le reste de l'application - -## Limitations et améliorations futures - -### Limitations actuelles -- Pas de statistiques détaillées (vues, paiements reçus) -- Pas d'édition/suppression d'articles -- Le profil ne peut être modifié que via Nostr (pas d'édition dans l'app) - -### Améliorations possibles -- **Statistiques** : Ajouter un composant `ArticleStats` pour afficher : - - Nombre total de vues - - Nombre de paiements reçus - - Revenus totaux -- **Édition d'articles** : Permettre d'éditer/supprimer les articles publiés -- **Profil public** : Créer `/user/[pubkey]` pour voir le profil de n'importe quel utilisateur -- **Optimisation** : Filtrer les articles par auteur au niveau du relay (au lieu du client) - -## Tests recommandés - -1. **Accès au profil** : - - Se connecter et cliquer sur le nom/avatar - - Vérifier la redirection vers `/profile` - - Se déconnecter et essayer d'accéder à `/profile` directement - -2. **Affichage du profil** : - - Vérifier l'affichage du nom, photo, description - - Vérifier le compteur d'articles - - Tester avec un profil qui n'a pas de photo/nom - -3. **Articles** : - - Publier quelques articles et vérifier qu'ils apparaissent - - Tester la recherche et les filtres - - Vérifier le compteur d'articles - -4. **Performance** : - - Tester avec un grand nombre d'articles - - Vérifier que le chargement n'est pas bloquant