439 lines
11 KiB
Markdown
439 lines
11 KiB
Markdown
# 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*
|