# Analyse Complète : Page "Pages" et Intégration S3 ## 📋 Vue d'ensemble La page `/pages` est une application de gestion de notes et contacts (carnet) qui utilise un stockage S3-compatible (MinIO) pour persister les données utilisateur. --- ## 🗂️ Structure des Routes ### Route Frontend - **URL** : `/pages` - **Fichier** : `app/pages/page.tsx` - **Type** : Client Component (Next.js App Router) - **Authentification** : Requise (redirection vers `/signin` si non authentifié) ### Routes API #### 1. Routes Principales (`/api/storage/*`) - **`GET /api/storage/status`** : Liste les dossiers disponibles pour l'utilisateur - **`POST /api/storage/init`** : Initialise la structure de dossiers pour un nouvel utilisateur - **`POST /api/storage/init/folder`** : Crée un dossier spécifique - **`GET /api/storage/files?folder={folder}`** : Liste les fichiers d'un dossier - **`GET /api/storage/files/content?path={path}`** : Récupère le contenu d'un fichier - **`POST /api/storage/files`** : Crée un nouveau fichier - **`PUT /api/storage/files`** : Met à jour un fichier existant - **`DELETE /api/storage/files?id={id}`** : Supprime un fichier #### 2. Routes de Compatibilité (`/api/nextcloud/*`) - **Adapter Pattern** : Les routes `/api/nextcloud/*` redirigent vers `/api/storage/*` - **Raison** : Compatibilité avec l'ancien code qui utilisait NextCloud - **Fichiers** : - `app/api/nextcloud/status/route.ts` → Retourne les dossiers standards - `app/api/nextcloud/files/route.ts` → Redirige vers `/api/storage/files` --- ## 🧩 Composants Principaux ### 1. **Page Principale** (`app/pages/page.tsx`) **Responsabilités** : - Gestion de l'état global (notes, contacts, dossiers sélectionnés) - Orchestration des trois panneaux (Navigation, Liste, Éditeur) - Gestion du cache multi-niveaux - Gestion responsive (mobile/tablette/desktop) **États Principaux** : ```typescript - selectedFolder: string (Notes, Diary, Health, Contacts) - selectedNote: Note | null - selectedContact: Contact | null - notes: Note[] - contacts: Contact[] - nextcloudFolders: string[] ``` **Cache** : - **In-memory** : `notesCache`, `noteContentCache`, `foldersCache` - **localStorage** : Cache persistant avec expiration (5-15 minutes) ### 2. **Navigation** (`components/carnet/navigation.tsx`) **Fonctionnalités** : - Affichage des dossiers (Notes, Diary, Health, Contacts) - Recherche de dossiers - Expansion du dossier Contacts pour afficher les fichiers VCF - Icônes contextuelles par type de dossier **Dossiers Standards** : - `Notes` → Bloc-notes - `Diary` → Journal - `Health` → Carnet de santé - `Contacts` → Carnet d'adresses ### 3. **NotesView** (`components/carnet/notes-view.tsx`) **Fonctionnalités** : - Liste des notes avec recherche - Tri par date de modification - Affichage formaté des dates - Actions : Créer, Supprimer, Sélectionner - Formatage spécial pour Diary/Health (extraction de dates) ### 4. **ContactsView** (`components/carnet/contacts-view.tsx`) **Fonctionnalités** : - Liste des contacts avec recherche - Filtrage par nom, email, organisation - Support des fichiers VCF multiples - Création de nouveaux contacts ### 5. **Editor** (`components/carnet/editor.tsx`) **Fonctionnalités** : - Édition de notes en Markdown - Sauvegarde automatique (debounce 1 seconde) - Cache du contenu pour performance - Gestion des erreurs et états de chargement **Sauvegarde** : - Auto-save après 1 seconde d'inactivité - Utilise `PUT /api/storage/files` pour les mises à jour - Invalide le cache après sauvegarde ### 6. **ContactDetails** (`components/carnet/contact-details.tsx`) **Fonctionnalités** : - Affichage détaillé d'un contact - Édition inline des champs - Support VCard (vCard 3.0) - Sauvegarde dans fichiers VCF --- ## 🔌 Configuration S3 ### Fichier de Configuration (`lib/s3.ts`) ```typescript S3_CONFIG = { endpoint: 'https://dome-api.slm-lab.net', region: 'us-east-1', bucket: process.env.S3_BUCKET || 'pages', accessKey: '4aBT4CMb7JIMMyUtp4Pl', secretKey: 'HGn39XhCIlqOjmDVzRK9MED2Fci2rYvDDgbLFElg' } ``` **Type de Stockage** : MinIO (S3-compatible) **Client** : AWS SDK v3 (`@aws-sdk/client-s3`) ### Structure de Stockage ``` bucket: pages/ └── user-{userId}/ ├── notes/ │ ├── note1.md │ └── note2.md ├── diary/ │ └── 2024-01-15-entry.md ├── health/ │ └── health-record.md └── contacts/ ├── Allemanique.vcf └── contacts.vcf ``` **Format des Clés S3** : - Notes : `user-{userId}/{folder}/{title}.md` - Contacts : `user-{userId}/contacts/{filename}.vcf` ### Fonctions S3 Principales #### `putObject(key, content, contentType)` - Upload un fichier vers S3 - Convertit automatiquement les strings en Buffer UTF-8 - Retourne la clé du fichier créé #### `getObjectContent(key)` - Récupère le contenu d'un fichier - Stream le contenu et le convertit en string UTF-8 - Retourne `null` si le fichier n'existe pas #### `deleteObject(key)` - Supprime un fichier de S3 - Utilise `DeleteObjectCommand` #### `listUserObjects(userId, folder)` - Liste les objets d'un dossier utilisateur - Filtre les placeholders et dossiers vides - Retourne métadonnées (nom, taille, date de modification) #### `createUserFolderStructure(userId)` - Crée la structure de dossiers standard - Crée des fichiers `.placeholder` pour chaque dossier - Dossiers créés : `notes`, `diary`, `health`, `contacts` --- ## 🔄 Flux de Données ### 1. Initialisation ``` User Login ↓ POST /api/storage/init ↓ createUserFolderStructure(userId) ↓ Création des dossiers dans S3 ↓ GET /api/storage/status ↓ Affichage des dossiers dans Navigation ``` ### 2. Chargement des Notes ``` User sélectionne un dossier ↓ Check cache (in-memory → localStorage) ↓ Si cache valide → Utiliser cache ↓ Sinon → GET /api/storage/files?folder={folder} ↓ listUserObjects(userId, folder) ↓ Mise à jour du cache + Affichage ``` ### 3. Édition d'une Note ``` User sélectionne une note ↓ Check cache du contenu ↓ Si cache valide → Afficher ↓ Sinon → GET /api/storage/files/content?path={id} ↓ getObjectContent(key) ↓ Affichage dans Editor ``` ### 4. Sauvegarde d'une Note ``` User modifie le contenu ↓ Debounce 1 seconde ↓ PUT /api/storage/files ↓ putObject(key, content, 'text/markdown') ↓ Invalidation du cache ↓ Rafraîchissement de la liste ``` ### 5. Gestion des Contacts ``` User sélectionne "Contacts" ↓ GET /api/storage/files?folder=contacts ↓ Filtrage des fichiers .vcf ↓ Pour chaque VCF → GET /api/storage/files/content ↓ Parsing VCard avec vcard-parser ↓ Affichage dans ContactsView ``` --- ## 🎨 Architecture UI ### Layout Responsive **Desktop (> 1024px)** : - 3 panneaux : Navigation | Liste | Éditeur - Panneaux redimensionnables avec `PanelResizer` **Tablette (768px - 1024px)** : - 2 panneaux : Navigation | Liste/Éditeur - Navigation toujours visible **Mobile (< 768px)** : - 1 panneau à la fois - Bouton toggle pour navigation - Navigation overlay ### Système de Cache **Niveaux de Cache** : 1. **In-memory** : `useRef` pour performance immédiate 2. **localStorage** : Persistance entre sessions 3. **S3** : Source de vérité **Expiration** : - Liste des notes : 5 minutes - Contenu des notes : 15 minutes - Liste des dossiers : 2 minutes **Invalidation** : - Après sauvegarde d'une note - Après création/suppression - Après événement `note-saved` (CustomEvent) --- ## 🔐 Sécurité ### Authentification - **NextAuth** : Vérification de session sur toutes les routes API - **Isolation utilisateur** : Tous les chemins S3 incluent `user-{userId}/` - **Validation** : Vérification que l'utilisateur ne peut accéder qu'à ses propres fichiers ### Exemple de Validation ```typescript // Dans /api/storage/files/content/route.ts if (!key.startsWith(`user-${userId}/`)) { return NextResponse.json({ error: 'Unauthorized' }, { status: 403 }); } ``` --- ## 📝 Formats de Fichiers ### Notes - **Format** : Markdown (`.md`) - **MIME Type** : `text/markdown` - **Structure** : Texte libre avec support Markdown ### Contacts - **Format** : vCard 3.0 (`.vcf`) - **MIME Type** : `text/vcard` - **Bibliothèque** : `vcard-parser` pour parsing/formatting - **Structure** : Multiple vCards dans un fichier **Exemple VCard** : ``` BEGIN:VCARD VERSION:3.0 UID:{id} FN:{fullName} EMAIL;TYPE=INTERNET:{email} TEL;TYPE=CELL:{phone} ORG:{organization} ADR:{address} NOTE:{notes} END:VCARD ``` --- ## 🐛 Points d'Attention ### 1. **Compatibilité NextCloud/S3** - Le code utilise parfois `/api/nextcloud/*` et parfois `/api/storage/*` - Les routes NextCloud sont des adapters qui redirigent vers Storage - **Recommandation** : Migrer progressivement vers `/api/storage/*` uniquement ### 2. **Gestion de la Casse** - Les noms de dossiers sont normalisés en lowercase pour S3 - Mais l'affichage utilise la casse originale (Notes, Diary, etc.) - **Risque** : Incohérences si un dossier est créé avec une casse différente ### 3. **Cache Multi-Niveaux** - Complexité de synchronisation entre caches - **Risque** : Données obsolètes si invalidation incomplète ### 4. **Credentials S3 en Dur** - Les clés d'accès S3 sont hardcodées dans `lib/s3.ts` - **Recommandation** : Utiliser des variables d'environnement ### 5. **Gestion des Erreurs** - Certaines erreurs sont loggées mais pas toujours remontées à l'utilisateur - **Recommandation** : Améliorer le feedback utilisateur --- ## 🚀 Améliorations Suggérées ### 1. **Sécurité** - [ ] Déplacer les credentials S3 vers variables d'environnement - [ ] Implémenter des rate limits sur les API - [ ] Ajouter une validation plus stricte des chemins ### 2. **Performance** - [ ] Implémenter un système de pagination pour les grandes listes - [ ] Optimiser les requêtes S3 avec des préfixes plus spécifiques - [ ] Ajouter un système de compression pour les gros fichiers ### 3. **UX** - [ ] Ajouter des indicateurs de synchronisation - [ ] Implémenter un système de conflits pour les éditions simultanées - [ ] Améliorer les messages d'erreur utilisateur ### 4. **Architecture** - [ ] Unifier les routes API (supprimer les adapters NextCloud) - [ ] Créer un service layer pour abstraire S3 - [ ] Implémenter des tests unitaires pour les fonctions S3 --- ## 📊 Métriques et Monitoring ### Endpoints à Monitorer - Temps de réponse des requêtes S3 - Taux d'erreur des opérations CRUD - Utilisation du cache (hit rate) - Taille des fichiers uploadés ### Logs Importants - Erreurs d'authentification - Échecs de connexion S3 - Échecs de parsing VCard - Incohérences de cache --- ## 🔗 Dépendances Clés ```json { "@aws-sdk/client-s3": "^3.802.0", "@aws-sdk/s3-request-presigner": "^3.802.0", "vcard-parser": "^x.x.x", "next-auth": "^x.x.x" } ``` --- ## 📚 Références - **Fichier S3 Config** : `lib/s3.ts` - **Page Principale** : `app/pages/page.tsx` - **Routes API Storage** : `app/api/storage/**/*.ts` - **Routes API NextCloud** : `app/api/nextcloud/**/*.ts` - **Composants** : `components/carnet/*.tsx` --- *Document généré le : $(date)* *Dernière mise à jour : Analyse complète du système Pages/S3*