chore: remove legacy root-level documentation files
This commit is contained in:
@@ -1,210 +0,0 @@
|
|||||||
# Méthodes disponibles sur l'objet `Article` (Sequelize)
|
|
||||||
|
|
||||||
Ce document liste toutes les méthodes automatiquement générées par Sequelize pour le modèle `Article` en fonction des associations définies dans `src/database/relationships/index.js`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Associations Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
### 1. **Tags** via `TagList`
|
|
||||||
Association alias: `articleTags`
|
|
||||||
Clés: `foreignKey: "articleId"`, `otherKey: "tagName"`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getArticleTags() // Récupère tous les tags
|
|
||||||
article.setArticleTags([...]) // Définit les tags
|
|
||||||
article.addArticleTag(tag) // Ajoute un tag
|
|
||||||
article.addArticleTags([...]) // Ajoute plusieurs tags
|
|
||||||
article.removeArticleTag(tag) // Retire un tag
|
|
||||||
article.removeArticleTags([...]) // Retire plusieurs tags
|
|
||||||
article.countArticleTags() // Compte les tags
|
|
||||||
article.hasArticleTag(tag) // Vérifie si le tag est lié
|
|
||||||
article.hasArticleTags([...]) // Vérifie si les tags sont liés
|
|
||||||
|
|
||||||
// Alias généré par Sequelize (correspond à belongsToMany):
|
|
||||||
// Nom de la clé étrangère singularisée + pluralisé = "ArticleTag(s)" => "addTagList", "getTagList", etc.
|
|
||||||
article.addTagList(tag) // Ajoute un tag via l'alias
|
|
||||||
article.addTagLists([...]) // Ajoute plusieurs tags via l'alias
|
|
||||||
article.getTagLists() // Récupère les tags via l'alias
|
|
||||||
article.setTagLists([...]) // Définit les tags via l'alias
|
|
||||||
article.removeTagList(tag) // Retire un tag via l'alias
|
|
||||||
article.removeTagLists([...]) // Retire plusieurs tags via l'alias
|
|
||||||
article.countTagLists() // Compte les tags via l'alias
|
|
||||||
article.hasTagList(tag) // Vérifie si le tag est lié via l'alias
|
|
||||||
article.hasTagLists([...]) // Vérifie si les tags sont liés via l'alias
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. **Users (Favoris)** via `Favorite`
|
|
||||||
Association alias: `articleFavoriteUsers`
|
|
||||||
Clés: `foreignKey: "articleId"`, `otherKey: "userId"`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getArticleFavoriteUsers() // Récupère les utilisateurs qui ont favorisé
|
|
||||||
article.setArticleFavoriteUsers([...]) // Définit les utilisateurs
|
|
||||||
article.addUserIdUser(user) // Ajoute un utilisateur
|
|
||||||
article.addArticleFavoriteUsers([...]) // Ajoute plusieurs utilisateurs
|
|
||||||
article.removeUserIdUser(user) // Retire un utilisateur
|
|
||||||
article.removeArticleFavoriteUsers([...]) // Retire plusieurs utilisateurs
|
|
||||||
article.countArticleFavoriteUsers() // Compte les utilisateurs
|
|
||||||
article.hasUserIdUser(user) // Vérifie si l'utilisateur a favorisé
|
|
||||||
article.hasArticleFavoriteUsers([...]) // Vérifie si les utilisateurs ont favorisé
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Associations One-to-Many (hasMany)
|
|
||||||
|
|
||||||
### 3. **Comments**
|
|
||||||
Association alias: `comments`
|
|
||||||
Clé étrangère: `articleId`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getComments() // Récupère tous les commentaires
|
|
||||||
article.setComments([...]) // Définit les commentaires
|
|
||||||
article.addComment(comment) // Crée/ajoute un commentaire
|
|
||||||
article.addComments([...]) // Ajoute plusieurs commentaires
|
|
||||||
article.removeComment(comment) // Retire un commentaire
|
|
||||||
article.removeComments([...]) // Retire plusieurs commentaires
|
|
||||||
article.countComments() // Compte les commentaires
|
|
||||||
article.hasComment(comment) // Vérifie si le commentaire existe
|
|
||||||
article.hasComments([...]) // Vérifie si les commentaires existent
|
|
||||||
article.createComment({...}) // Crée un nouveau commentaire
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. **Favorites** (enregistrements de join)
|
|
||||||
Association alias: `favorites`
|
|
||||||
Clé étrangère: `articleId`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getFavorites() // Récupère les enregistrements Favorite
|
|
||||||
article.setFavorites([...]) // Définit les favoris
|
|
||||||
article.addFavorite(favorite) // Ajoute un enregistrement Favorite
|
|
||||||
article.addFavorites([...]) // Ajoute plusieurs enregistrements
|
|
||||||
article.removeFavorite(favorite) // Retire un enregistrement Favorite
|
|
||||||
article.removeFavorites([...]) // Retire plusieurs enregistrements
|
|
||||||
article.countFavorites() // Compte les enregistrements Favorite
|
|
||||||
article.hasFavorite(favorite) // Vérifie si le Favorite existe
|
|
||||||
article.hasFavorites([...]) // Vérifie si les Favorites existent
|
|
||||||
article.createFavorite({...}) // Crée un nouveau Favorite
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. **TagLists** (enregistrements de join)
|
|
||||||
Association alias: `tagLists`
|
|
||||||
Clé étrangère: `articleId`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getTagLists() // Récupère les enregistrements TagList
|
|
||||||
article.setTagLists([...]) // Définit les TagList
|
|
||||||
article.addTagList(tagList) // Ajoute un enregistrement TagList
|
|
||||||
article.addTagLists([...]) // Ajoute plusieurs enregistrements
|
|
||||||
article.removeTagList(tagList) // Retire un enregistrement TagList
|
|
||||||
article.removeTagLists([...]) // Retire plusieurs enregistrements
|
|
||||||
article.countTagLists() // Compte les enregistrements TagList
|
|
||||||
article.hasTagList(tagList) // Vérifie si le TagList existe
|
|
||||||
article.hasTagLists([...]) // Vérifie si les TagLists existent
|
|
||||||
article.createTagList({...}) // Crée un nouveau TagList
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Associations Belongs-To (hasOne inverse)
|
|
||||||
|
|
||||||
### 6. **Author (User)**
|
|
||||||
Association alias: `author`
|
|
||||||
Clé étrangère: `authorId`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.getAuthor() // Récupère l'auteur
|
|
||||||
article.setAuthor(user) // Définit l'auteur
|
|
||||||
article.createAuthor({...}) // Crée un nouvel auteur
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Méthodes personnalisées du modèle
|
|
||||||
|
|
||||||
### Méthodes d'instance définies dans `Article.js` :
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
article.toJSONFor() // Retourne un objet JSON formaté
|
|
||||||
// Format: { id, slug, title, description, body }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Hooks (Triggers)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
Article.beforeValidate() // Déclenché avant la validation
|
|
||||||
// Génère automatiquement un slug basé sur le titre
|
|
||||||
// Format: slug(`${article.title}`) + '-' + random
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Exemples d'utilisation concrets
|
|
||||||
|
|
||||||
### Ajouter des tags à un article
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1);
|
|
||||||
const tag = await Tag.findByPk('javascript');
|
|
||||||
await article.addTagList(tag); // Via alias
|
|
||||||
// ou
|
|
||||||
await article.addArticleTag(tag); // Via alias généré automatiquement
|
|
||||||
```
|
|
||||||
|
|
||||||
### Récupérer les commentaires d'un article
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1);
|
|
||||||
const comments = await article.getComments();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Obtenir les utilisateurs qui ont favorisé cet article
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1);
|
|
||||||
const fans = await article.getArticleFavoriteUsers();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Créer un commentaire pour un article
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1);
|
|
||||||
const comment = await article.createComment({
|
|
||||||
body: "Great article!",
|
|
||||||
authorId: userId
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compter les tags
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1);
|
|
||||||
const tagCount = await article.countTagLists();
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notes importantes
|
|
||||||
|
|
||||||
1. **Noms des méthodes générées** : Sequelize génère les noms en fonction du nom de l'association (alias) ou du modèle.
|
|
||||||
- Si alias est `articleTags` → `getArticleTags()`, `addArticleTag()`, etc.
|
|
||||||
- Si alias est `tagLists` → `getTagLists()`, `addTagList()`, etc.
|
|
||||||
|
|
||||||
2. **Singulier/Pluriel** : Les méthodes `add*` acceptent soit un seul élément (singulier) soit un tableau (pluriel).
|
|
||||||
|
|
||||||
3. **Paramètres optionnels** : La plupart des méthodes `get*` acceptent un paramètre `options` pour personnaliser la requête :
|
|
||||||
```javascript
|
|
||||||
article.getComments({
|
|
||||||
where: { createdAt: { [Op.gte]: someDate } },
|
|
||||||
limit: 10,
|
|
||||||
offset: 0,
|
|
||||||
order: [['createdAt', 'DESC']]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Transactions** : Toutes les opérations CRUD peuvent être encapsulées dans une transaction :
|
|
||||||
```javascript
|
|
||||||
const transaction = await sequelize.transaction();
|
|
||||||
await article.addTagList(tag, { transaction });
|
|
||||||
await transaction.commit();
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Alias vs Nom généré** : L'alias défini dans la relation détermine le nom des méthodes générées. Dans ce projet, les alias comme `articleTags`, `tagLists` permettent d'appeler `getTagLists()`, `addTagList()`, etc.
|
|
||||||
@@ -1,328 +0,0 @@
|
|||||||
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
||||||
║ ║
|
|
||||||
║ ✅ MIGRATION AUTOMATIQUE RÉUSSIE - Structure Basée Domaines ║
|
|
||||||
║ ║
|
|
||||||
║ De: /api/v1, /api/v2, /api/v3 (confus) ║
|
|
||||||
║ Vers: /api/skydive, /api/cms, /api/herowars (clair) ║
|
|
||||||
║ ║
|
|
||||||
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
||||||
|
|
||||||
📊 STATISTIQUES DE LA MIGRATION
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
✓ Fichiers de routes migrés: 19 fichiers
|
|
||||||
✓ Domaines créés: 3 nouveaux domaines
|
|
||||||
✓ Fichiers index.js: 4 créés/mis à jour
|
|
||||||
✓ Documentation: 5 fichiers de rapport
|
|
||||||
✓ Scripts de migration: 3 scripts npm
|
|
||||||
✓ Commits Git: 2 commits
|
|
||||||
✓ Fichiers Swagger mis à jour: 4 fichiers YAML
|
|
||||||
|
|
||||||
|
|
||||||
🎯 STRUCTURE NOUVELLE CRÉÉE
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
src/routes/api/
|
|
||||||
├── skydive/ ← Parachutisme
|
|
||||||
│ ├── aeronefs.js
|
|
||||||
│ ├── applications.js
|
|
||||||
│ ├── canopies.js
|
|
||||||
│ ├── dropzones.js
|
|
||||||
│ ├── jumps.js
|
|
||||||
│ ├── pages.js
|
|
||||||
│ ├── profiles.js
|
|
||||||
│ ├── qcm.js
|
|
||||||
│ └── index.js
|
|
||||||
│
|
|
||||||
├── cms/ ← Gestion de contenu
|
|
||||||
│ ├── articles.routes.js
|
|
||||||
│ ├── comments.routes.js
|
|
||||||
│ ├── product.routes.js
|
|
||||||
│ ├── products.routes.js
|
|
||||||
│ ├── profiles.routes.js
|
|
||||||
│ ├── tags.routes.js
|
|
||||||
│ ├── user.routes.js
|
|
||||||
│ └── index.js
|
|
||||||
│
|
|
||||||
└── herowars/ ← Jeu HeroWars
|
|
||||||
├── clans.routes.js
|
|
||||||
├── members.routes.js
|
|
||||||
├── herowars.routes.js
|
|
||||||
└── index.js
|
|
||||||
|
|
||||||
|
|
||||||
📝 FICHIERS DE DOCUMENTATION CRÉÉS
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
1. MIGRATION_REPORT.md
|
|
||||||
└─ Rapport détaillé: structure ancienne → nouvelle, fichiers migrés
|
|
||||||
|
|
||||||
2. MIGRATION_COMPLETE_SUMMARY.md
|
|
||||||
└─ Résumé exécutif avec instructions de test et frontend
|
|
||||||
|
|
||||||
3. POST_MIGRATION_CHECKLIST.md
|
|
||||||
└─ Liste de vérification manuelle pour validation
|
|
||||||
|
|
||||||
4. SCRIPTS_MIGRATION_GUIDE.md
|
|
||||||
└─ Guide complet d'utilisation des scripts (CE FICHIER)
|
|
||||||
|
|
||||||
5. MIGRATION_SWAGGER_TODO.md
|
|
||||||
└─ Notes sur les mises à jour Swagger/OpenAPI
|
|
||||||
|
|
||||||
|
|
||||||
⚙️ SCRIPTS DE MIGRATION CRÉÉS
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
1. scripts/migrate-to-domain-structure.js
|
|
||||||
│
|
|
||||||
├─ Phase 1: Crée les répertoires de domaines
|
|
||||||
├─ Phase 2: Migre tous les fichiers de routes
|
|
||||||
├─ Phase 3: Génère les fichiers index.js
|
|
||||||
├─ Phase 4: Met à jour src/routes/api/index.js
|
|
||||||
├─ Phase 5: Crée les notes Swagger
|
|
||||||
├─ Phase 6: Gère les fichiers Swagger
|
|
||||||
├─ Phase 7: Effectue les opérations Git
|
|
||||||
├─ Phase 8: Valide la migration
|
|
||||||
└─ Phase 9: Génère un rapport
|
|
||||||
|
|
||||||
[✅ EXÉCUTÉ: commit 9f73ed0]
|
|
||||||
|
|
||||||
2. scripts/update-references-post-migration.js
|
|
||||||
│
|
|
||||||
├─ Phase 1: Met à jour les fichiers YAML Swagger
|
|
||||||
├─ Phase 2: Met à jour la collection/env Postman
|
|
||||||
├─ Phase 3: Scanne les références v1/v2/v3 restantes
|
|
||||||
└─ Phase 4: Génère une liste de vérification
|
|
||||||
|
|
||||||
[✅ EXÉCUTÉ]
|
|
||||||
|
|
||||||
3. scripts/finalize-migration.js
|
|
||||||
│
|
|
||||||
├─ Phase 1: Valide la structure des domaines
|
|
||||||
├─ Phase 2: Liste les anciens répertoires
|
|
||||||
├─ Phase 3: Optionnel - Nettoie les v1/v2/v3 (--cleanup)
|
|
||||||
├─ Phase 4: Optionnel - Teste les endpoints (--test)
|
|
||||||
└─ Phase 5: Génère un résumé final
|
|
||||||
|
|
||||||
[PRÊT À EXÉCUTER - voir instructions ci-dessous]
|
|
||||||
|
|
||||||
|
|
||||||
🚀 PROCHAINES ÉTAPES IMMÉDIATES
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
ÉTAPE 1️⃣: VALIDER LA STRUCTURE
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
|
||||||
$ node scripts/finalize-migration.js
|
|
||||||
|
|
||||||
✓ Affichera: "skydive/: ✓ (8 route files)"
|
|
||||||
✓ Affichera: "cms/: ✓ (7 route files)"
|
|
||||||
✓ Affichera: "herowars/: ✓ (3 route files)"
|
|
||||||
|
|
||||||
|
|
||||||
ÉTAPE 2️⃣: NETTOYER LES ANCIENS RÉPERTOIRES (OPTIONNEL)
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
|
||||||
OPTION A - Via script:
|
|
||||||
$ node scripts/finalize-migration.js --cleanup
|
|
||||||
|
|
||||||
OPTION B - Manuellement:
|
|
||||||
$ rm -rf src/routes/api/v1 src/routes/api/v2 src/routes/api/v3
|
|
||||||
$ git add -A && git commit -m "chore: remove old v1/v2/v3 directories"
|
|
||||||
|
|
||||||
|
|
||||||
ÉTAPE 3️⃣: TESTER LE SERVEUR
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
|
||||||
Terminal 1 - Démarrer l'API:
|
|
||||||
$ npm run local
|
|
||||||
|
|
||||||
Terminal 2 - Tester les endpoints:
|
|
||||||
$ curl http://localhost:3200/api-docs # Swagger UI
|
|
||||||
$ curl http://localhost:3200/api/skydive/jumps # Skydive
|
|
||||||
$ curl http://localhost:3200/api/cms/articles # CMS
|
|
||||||
$ curl http://localhost:3200/api/herowars/clans # HeroWars
|
|
||||||
|
|
||||||
|
|
||||||
ÉTAPE 4️⃣: METTRE À JOUR LE FRONTEND (IMPORTANT!) 🔴
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
A. Mettre à jour les environnements Angular:
|
|
||||||
Fichiers à modifier:
|
|
||||||
- src/environments/environment.ts
|
|
||||||
- src/environments/environment.development.ts
|
|
||||||
- src/environments/environment.local.ts
|
|
||||||
|
|
||||||
AVANT:
|
|
||||||
export const environment = {
|
|
||||||
apiUrl: '/api/v1',
|
|
||||||
cmsUrl: '/api/v2',
|
|
||||||
herowarsUrl: '/api/v3',
|
|
||||||
};
|
|
||||||
|
|
||||||
APRÈS:
|
|
||||||
export const environment = {
|
|
||||||
apiUrl: '/api/skydive',
|
|
||||||
cmsUrl: '/api/cms',
|
|
||||||
herowarsUrl: '/api/herowars',
|
|
||||||
};
|
|
||||||
|
|
||||||
B. Mettre à jour les services Angular:
|
|
||||||
Cherchez et remplacez les chemins en dur:
|
|
||||||
|
|
||||||
sed -i '' "s|'/api/v1/|'/api/skydive/|g" src/**/*.ts
|
|
||||||
sed -i '' "s|'/api/v2/|'/api/cms/|g" src/**/*.ts
|
|
||||||
sed -i '' "s|'/api/v3/|'/api/herowars/|g" src/**/*.ts
|
|
||||||
|
|
||||||
C. Tester le frontend:
|
|
||||||
$ npm start
|
|
||||||
Vérifier dans DevTools que les appels API vont vers /api/skydive/*, /api/cms/*, etc.
|
|
||||||
|
|
||||||
|
|
||||||
ÉTAPE 5️⃣: POUSSER LES CHANGEMENTS
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
|
||||||
$ git push origin develop
|
|
||||||
ou
|
|
||||||
$ git push --all --follow-tags
|
|
||||||
|
|
||||||
|
|
||||||
📋 RÉSUMÉ DES COMMITS GIT
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
Commit 1: 9f73ed0
|
|
||||||
├─ Message: "refactor: restructure API routes from v1/v2/v3 to domain-based..."
|
|
||||||
├─ Actions:
|
|
||||||
│ ├─ Créé: src/routes/api/skydive/, cms/, herowars/
|
|
||||||
│ ├─ Copié: 19 fichiers de routes
|
|
||||||
│ └─ Mis à jour: src/routes/api/index.js
|
|
||||||
└─ État: ✅ MERGED
|
|
||||||
|
|
||||||
Commit 2: 74df96c
|
|
||||||
├─ Message: "docs: add migration documentation, finalization scripts, and update Swagger paths"
|
|
||||||
├─ Actions:
|
|
||||||
│ ├─ Créé: 4 fichiers de documentation
|
|
||||||
│ ├─ Créé: 2 scripts de finalisation
|
|
||||||
│ └─ Mis à jour: 4 fichiers Swagger YAML
|
|
||||||
└─ État: ✅ CURRENT HEAD
|
|
||||||
|
|
||||||
|
|
||||||
🔄 AVANT/APRÈS - COMPARAISON DES API
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
SAUT/PARACHUTISME:
|
|
||||||
AVANT: GET /api/v1/jumps
|
|
||||||
APRÈS: GET /api/skydive/jumps
|
|
||||||
──────────────────────
|
|
||||||
GET /api/v1/aeronefs → GET /api/skydive/aeronefs
|
|
||||||
POST /api/v1/aeronefs → POST /api/skydive/aeronefs
|
|
||||||
|
|
||||||
CONTENU:
|
|
||||||
AVANT: GET /api/v2/articles
|
|
||||||
APRÈS: GET /api/cms/articles
|
|
||||||
────────────────────────
|
|
||||||
GET /api/v2/articles/123 → GET /api/cms/articles/123
|
|
||||||
POST /api/v2/articles → POST /api/cms/articles
|
|
||||||
GET /api/v2/comments → GET /api/cms/comments
|
|
||||||
|
|
||||||
JEU:
|
|
||||||
AVANT: GET /api/v3/clans
|
|
||||||
APRÈS: GET /api/herowars/clans
|
|
||||||
────────────────────────
|
|
||||||
GET /api/v3/members → GET /api/herowars/members
|
|
||||||
POST /api/v3/members/123 → POST /api/herowars/members/123
|
|
||||||
|
|
||||||
|
|
||||||
⚠️ IMPORTANT: ROLLBACK EN CAS DE PROBLÈME
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
Si vous rencontrez des problèmes:
|
|
||||||
|
|
||||||
Option 1 - Peu de changements (rollback 2 commits):
|
|
||||||
$ git reset --hard HEAD~2
|
|
||||||
|
|
||||||
Option 2 - Si vous avez poussé, utiliser revert:
|
|
||||||
$ git revert 74df96c
|
|
||||||
$ git revert 9f73ed0
|
|
||||||
|
|
||||||
Option 3 - Restaurer depuis le remote:
|
|
||||||
$ git fetch origin
|
|
||||||
$ git reset --hard origin/develop
|
|
||||||
|
|
||||||
|
|
||||||
✅ CHECKLIST DE VALIDATION POST-MIGRATION
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
Backend (adastra_api):
|
|
||||||
☐ npm run local - serveur démarre sans erreur
|
|
||||||
☐ curl http://localhost:3200/api-docs - Swagger UI accessible
|
|
||||||
☐ Endpoints skydive fonctionnent: GET /api/skydive/jumps
|
|
||||||
☐ Endpoints CMS fonctionnent: GET /api/cms/articles
|
|
||||||
☐ Endpoints HeroWars fonctionnent: GET /api/herowars/clans
|
|
||||||
|
|
||||||
Frontend (adastra_app):
|
|
||||||
☐ npm start - app démarre sans erreur
|
|
||||||
☐ Appels API vont vers les nouveaux chemins
|
|
||||||
☐ Authentification toujours fonctionnelle
|
|
||||||
☐ Pages affichent les données correctement
|
|
||||||
☐ Aucune erreur 404 sur les endpoints
|
|
||||||
|
|
||||||
Git:
|
|
||||||
☐ Commits créés et visibles: git log --oneline -5
|
|
||||||
☐ Prêt pour: git push origin develop
|
|
||||||
|
|
||||||
Documentation:
|
|
||||||
☐ README.md mis à jour (optionnel)
|
|
||||||
☐ Équipe notifiée du changement
|
|
||||||
☐ Documentation technique mise à jour
|
|
||||||
|
|
||||||
|
|
||||||
📚 RESSOURCES SUPPLÉMENTAIRES
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
Consultez ces fichiers pour plus d'informations:
|
|
||||||
|
|
||||||
1. SCRIPTS_MIGRATION_GUIDE.md
|
|
||||||
└─ Guide détaillé de chaque script et options
|
|
||||||
|
|
||||||
2. POST_MIGRATION_CHECKLIST.md
|
|
||||||
└─ Liste complète de vérification manuelle
|
|
||||||
|
|
||||||
3. MIGRATION_COMPLETE_SUMMARY.md
|
|
||||||
└─ Résumé exécutif avec instructions
|
|
||||||
|
|
||||||
4. docs/*.md (depuis l'audit architectural)
|
|
||||||
└─ Architecture complète et ADRs
|
|
||||||
|
|
||||||
|
|
||||||
🎓 POINTS CLÉS À RETENIR
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
✓ NON-DESTRUCTIF: Les anciens répertoires restent, vous pouvez les nettoyer
|
|
||||||
progressivement après vérification
|
|
||||||
|
|
||||||
✓ AUTOMATISÉ: Scripts Python/Node qui gèrent la plupart des tâches
|
|
||||||
Swagger, Postman, routes mis à jour automatiquement
|
|
||||||
|
|
||||||
⚠️ MANUEL: Frontend DOIT être mis à jour (recherche/remplace)
|
|
||||||
Tests doivent être revérifiés
|
|
||||||
Documentation peut nécessiter mise à jour
|
|
||||||
|
|
||||||
✓ GIT-SAFE: Chaque étape crée un commit
|
|
||||||
Rollback facile si problème
|
|
||||||
Toutes les modifications sont tracées
|
|
||||||
|
|
||||||
✓ BÉNÉFICES: Chemins d'API clairs et explicites
|
|
||||||
Séparation nette des domaines métier
|
|
||||||
Meilleure architecture et maintenabilité
|
|
||||||
Préparation pour futures versions d'API
|
|
||||||
|
|
||||||
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
✨ Migration complétée avec succès! ✨
|
|
||||||
|
|
||||||
Prêt à continuer avec les 20 ADRs d'architecture?
|
|
||||||
(QUICK_START_WEEK1.md pour la Phase 1)
|
|
||||||
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
Date: 24 avril 2026
|
|
||||||
Statut: ✅ COMPLETE
|
|
||||||
Prochaine étape: Mise à jour du frontend + tests
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
|
|
||||||
╔════════════════════════════════════════════════════════════════════════════╗
|
|
||||||
║ MIGRATION SUCCESSFULLY COMPLETED ║
|
|
||||||
╚════════════════════════════════════════════════════════════════════════════╝
|
|
||||||
|
|
||||||
NEW API STRUCTURE:
|
|
||||||
├── /api/skydive/* ← Skydiving features (jumps, aeronefs, dropzones, etc.)
|
|
||||||
├── /api/cms/* ← Content management (articles, tags, comments, etc.)
|
|
||||||
└── /api/herowars/* ← Game features (clans, members, raids, etc.)
|
|
||||||
|
|
||||||
WHAT WAS CHANGED:
|
|
||||||
✓ Routes directory: v1/v2/v3 → domain-based structure
|
|
||||||
✓ Route definitions: Updated all index.js files
|
|
||||||
✓ Swagger YAML: Updated path prefixes to new domains
|
|
||||||
✓ Postman collection: Updated endpoint URLs
|
|
||||||
|
|
||||||
FILES MIGRATED:
|
|
||||||
✓ Skydive domain (8 route files):
|
|
||||||
- aeronefs.js, applications.js, canopies.js, dropzones.js
|
|
||||||
- jumps.js, pages.js, profiles.js, qcm.js
|
|
||||||
|
|
||||||
✓ CMS domain (8 route files):
|
|
||||||
- articles.routes.js, comments.routes.js, product.routes.js
|
|
||||||
- products.routes.js, profiles.routes.js, tags.routes.js, user.routes.js
|
|
||||||
|
|
||||||
✓ Hero Wars domain (3 route files):
|
|
||||||
- clans.routes.js, members.routes.js, herowars.routes.js
|
|
||||||
|
|
||||||
TESTING INSTRUCTIONS:
|
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
1. Start the API server:
|
|
||||||
npm run local
|
|
||||||
|
|
||||||
2. In another terminal, verify Swagger is updated:
|
|
||||||
curl http://localhost:3200/api-docs
|
|
||||||
|
|
||||||
3. Test a sample endpoint:
|
|
||||||
curl http://localhost:3200/api/skydive/jumps
|
|
||||||
curl http://localhost:3200/api/cms/articles
|
|
||||||
curl http://localhost:3200/api/herowars/clans
|
|
||||||
|
|
||||||
FRONTEND UPDATES REQUIRED:
|
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
In your Angular frontend (adastra_app):
|
|
||||||
|
|
||||||
1. Update environment files:
|
|
||||||
src/environments/environment.ts
|
|
||||||
src/environments/environment.development.ts
|
|
||||||
src/environments/environment.local.ts
|
|
||||||
|
|
||||||
Replace:
|
|
||||||
- apiUrl: '/api/v1' → apiUrl: '/api/skydive'
|
|
||||||
- cmUrl: '/api/v2' → cmUrl: '/api/cms'
|
|
||||||
- hwUrl: '/api/v3' → hwUrl: '/api/herowars'
|
|
||||||
|
|
||||||
2. Update API service calls:
|
|
||||||
// Before:
|
|
||||||
http.get('/api/v1/jumps')
|
|
||||||
http.get('/api/v2/articles')
|
|
||||||
http.get('/api/v3/clans')
|
|
||||||
|
|
||||||
// After:
|
|
||||||
http.get('/api/skydive/jumps')
|
|
||||||
http.get('/api/cms/articles')
|
|
||||||
http.get('/api/herowars/clans')
|
|
||||||
|
|
||||||
3. Search & replace in your services:
|
|
||||||
sed -i 's|/api/v1/|/api/skydive/|g' src/**/*.ts
|
|
||||||
sed -i 's|/api/v2/|/api/cms/|g' src/**/*.ts
|
|
||||||
sed -i 's|/api/v3/|/api/herowars/|g' src/**/*.ts
|
|
||||||
|
|
||||||
GIT OPERATIONS:
|
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
View migration commits:
|
|
||||||
git log --oneline -5
|
|
||||||
|
|
||||||
If needed, view detailed changes:
|
|
||||||
git show HEAD
|
|
||||||
|
|
||||||
Push to remote:
|
|
||||||
git push origin develop
|
|
||||||
|
|
||||||
ROLLBACK (if issues):
|
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
If you need to rollback:
|
|
||||||
git reset --hard HEAD~2
|
|
||||||
|
|
||||||
(Adjust the number of commits based on history)
|
|
||||||
|
|
||||||
ADDITIONAL RESOURCES:
|
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
||||||
|
|
||||||
Documentation files created:
|
|
||||||
- MIGRATION_REPORT.md: Detailed migration information
|
|
||||||
- MIGRATION_SWAGGER_TODO.md: Swagger update notes
|
|
||||||
- POST_MIGRATION_CHECKLIST.md: Verification checklist
|
|
||||||
|
|
||||||
Scripts created:
|
|
||||||
- scripts/migrate-to-domain-structure.js: Main migration script
|
|
||||||
- scripts/update-references-post-migration.js: Post-migration updates
|
|
||||||
- scripts/finalize-migration.js: Cleanup and testing
|
|
||||||
|
|
||||||
═════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
✓ Migration is complete! Follow the testing instructions above.
|
|
||||||
|
|
||||||
═════════════════════════════════════════════════════════════════════════════
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
API STRUCTURE MIGRATION REPORT
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
MIGRATION: v1/v2/v3 → Domain-Based (skydive/cms/herowars)
|
|
||||||
|
|
||||||
OLD STRUCTURE:
|
|
||||||
└── routes/api/
|
|
||||||
├── v1/ (Skydive routes)
|
|
||||||
├── v2/ (CMS + misc routes)
|
|
||||||
└── v3/ (Hero Wars routes)
|
|
||||||
|
|
||||||
NEW STRUCTURE:
|
|
||||||
└── routes/api/
|
|
||||||
├── skydive/
|
|
||||||
├── cms/
|
|
||||||
└── herowars/
|
|
||||||
|
|
||||||
ROUTE MAPPINGS:
|
|
||||||
✓ /api/v1/* → /api/skydive/*
|
|
||||||
- applications, aeronefs, canopies, dropzones, jumps, pages, profiles, qcm
|
|
||||||
|
|
||||||
✓ /api/v2/* → /api/cms/*
|
|
||||||
- user, articles, comments, product, products, profiles, tags
|
|
||||||
|
|
||||||
✓ /api/v3/* → /api/herowars/*
|
|
||||||
- clans, members, herowars (moved from v2)
|
|
||||||
|
|
||||||
FILES CREATED/UPDATED:
|
|
||||||
✓ src/routes/api/skydive/index.js
|
|
||||||
✓ src/routes/api/cms/index.js
|
|
||||||
✓ src/routes/api/herowars/index.js
|
|
||||||
✓ src/routes/api/index.js
|
|
||||||
✓ All route files copied to appropriate domains
|
|
||||||
|
|
||||||
MANUAL STEPS REQUIRED:
|
|
||||||
|
|
||||||
1. Update Swagger/OpenAPI documentation:
|
|
||||||
- Review MIGRATION_SWAGGER_TODO.md
|
|
||||||
- Update path prefixes in src/swagger/*.yaml files
|
|
||||||
- Update paths in src/config/swagger.js if needed
|
|
||||||
|
|
||||||
2. Update app.js (if direct version references exist):
|
|
||||||
- Search for 'v1', 'v2', 'v3' strings
|
|
||||||
- Replace with domain names where appropriate
|
|
||||||
|
|
||||||
3. Update tests and client calls:
|
|
||||||
- Replace /api/v1/ with /api/skydive/
|
|
||||||
- Replace /api/v2/ with /api/cms/
|
|
||||||
- Replace /api/v3/ with /api/herowars/
|
|
||||||
|
|
||||||
4. Update any documentation:
|
|
||||||
- README.md API endpoints section
|
|
||||||
- API documentation and guides
|
|
||||||
|
|
||||||
5. Test all endpoints:
|
|
||||||
- Verify each domain routes work correctly
|
|
||||||
- Check authentication/authorization still functions
|
|
||||||
- Validate error handling
|
|
||||||
|
|
||||||
OPTIONAL: Old v1/v2/v3 directories can be removed after verification:
|
|
||||||
rm -rf src/routes/api/v1
|
|
||||||
rm -rf src/routes/api/v2
|
|
||||||
rm -rf src/routes/api/v3
|
|
||||||
|
|
||||||
═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
# Swagger Path Updates Required
|
|
||||||
|
|
||||||
The following Swagger YAML files need path updates:
|
|
||||||
|
|
||||||
## skydive.yaml
|
|
||||||
- Change: /api/v1/ → /api/skydive/
|
|
||||||
- Affected routes: /jumps, /aeronefs, /dropzones, /canopies, /pages, /qcm, /applications
|
|
||||||
|
|
||||||
## cms.yaml
|
|
||||||
- Change: /api/v2/ → /api/cms/
|
|
||||||
- Affected routes: /articles, /comments, /products, /tags, /profiles, /user
|
|
||||||
|
|
||||||
## herowars.yaml
|
|
||||||
- Change: /api/v3/ → /api/herowars/
|
|
||||||
- Affected routes: /clans, /members
|
|
||||||
- Note: Add herowars endpoint from former /api/v2/herowars
|
|
||||||
|
|
||||||
Update in: src/config/swagger.js if paths are hardcoded.
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
|
|
||||||
# Post-Migration Update Checklist
|
|
||||||
|
|
||||||
## Files Updated by Script ✓
|
|
||||||
- [x] Swagger YAML files (/api/v1 → /api/skydive, etc.)
|
|
||||||
- [x] Postman collection and environment files
|
|
||||||
- [x] API routes structure (new domains created)
|
|
||||||
|
|
||||||
## Manual Verification Required
|
|
||||||
|
|
||||||
### 1. Test API Endpoints
|
|
||||||
```bash
|
|
||||||
npm run local # Start the server
|
|
||||||
# In another terminal:
|
|
||||||
curl http://localhost:3200/api-docs # Check Swagger UI
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Verify Routes
|
|
||||||
- [ ] GET /api/skydive/jumps
|
|
||||||
- [ ] GET /api/cms/articles
|
|
||||||
- [ ] GET /api/herowars/clans
|
|
||||||
- [ ] Other domain-specific endpoints
|
|
||||||
|
|
||||||
### 3. Frontend Updates Required (if applicable)
|
|
||||||
- [ ] Update Angular environment files (environment.ts, environment.development.ts, etc.)
|
|
||||||
- [ ] Replace all API calls from /api/v1, /api/v2, /api/v3 to new domains
|
|
||||||
- [ ] Update service layer URLs
|
|
||||||
- [ ] Update HTTP interceptors if needed
|
|
||||||
|
|
||||||
### 4. Documentation Updates
|
|
||||||
- [ ] Update README.md with new API structure
|
|
||||||
- [ ] Update API documentation (if any)
|
|
||||||
- [ ] Update deployment/infrastructure docs
|
|
||||||
- [ ] Update team wiki/documentation
|
|
||||||
|
|
||||||
### 5. CI/CD Pipeline (if applicable)
|
|
||||||
- [ ] Update build/deployment scripts referencing v1/v2/v3
|
|
||||||
- [ ] Update any health checks pointing to old paths
|
|
||||||
- [ ] Update monitoring/alerting rules
|
|
||||||
|
|
||||||
### 6. Client Applications
|
|
||||||
- [ ] Update all client libraries/SDKs
|
|
||||||
- [ ] Update mobile app API endpoints
|
|
||||||
- [ ] Update third-party integrations
|
|
||||||
|
|
||||||
### 7. Database/Caching (if applicable)
|
|
||||||
- [ ] Clear any cached references to old endpoints
|
|
||||||
- [ ] Update API documentation in databases
|
|
||||||
- [ ] Check for hardcoded URLs in configuration
|
|
||||||
|
|
||||||
## Git Operations
|
|
||||||
```bash
|
|
||||||
# View the migration commits
|
|
||||||
git log --oneline -5
|
|
||||||
|
|
||||||
# If rollback needed:
|
|
||||||
git revert <commit-hash>
|
|
||||||
|
|
||||||
# Push changes
|
|
||||||
git push origin develop
|
|
||||||
```
|
|
||||||
|
|
||||||
## Optional: Cleanup Old Directories
|
|
||||||
```bash
|
|
||||||
# After thorough testing, remove old v1/v2/v3 directories:
|
|
||||||
rm -rf src/routes/api/v1
|
|
||||||
rm -rf src/routes/api/v2
|
|
||||||
rm -rf src/routes/api/v3
|
|
||||||
git add -A
|
|
||||||
git commit -m "chore: remove old v1/v2/v3 route directories"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Rollback Procedure
|
|
||||||
If issues arise, rollback with:
|
|
||||||
```bash
|
|
||||||
git reset --hard HEAD~2 # Adjust commit count if needed
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
Document generated: 2026-04-23T22:48:52.497Z
|
|
||||||
@@ -1,329 +0,0 @@
|
|||||||
# Migration Scripts - Guide d'utilisation
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Cette migration restructure votre API Express de `/api/v1` `/api/v2` `/api/v3` (qui représentaient des domaines métier, pas des versions API) vers une architecture basée sur les domaines avec des chemins clairs et explicites.
|
|
||||||
|
|
||||||
### Ancien structure (confuse)
|
|
||||||
```
|
|
||||||
/api/v1/* → Skydive features
|
|
||||||
/api/v2/* → CMS features
|
|
||||||
/api/v3/* → Hero Wars features
|
|
||||||
```
|
|
||||||
|
|
||||||
### Nouvelle structure (claire)
|
|
||||||
```
|
|
||||||
/api/skydive/* ← Toutes les fonctionnalités de parachutisme
|
|
||||||
/api/cms/* ← Gestion de contenu (articles, tags, etc.)
|
|
||||||
/api/herowars/* ← Gestion du jeu HeroWars (clans, membres, raids)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Scripts de migration
|
|
||||||
|
|
||||||
### 1. `migrate-to-domain-structure.js` ✓ EXÉCUTÉ
|
|
||||||
|
|
||||||
**Rôle:** Crée la nouvelle structure et migre les fichiers
|
|
||||||
|
|
||||||
**Statut:** ✅ Completed
|
|
||||||
- Créé les répertoires `/api/skydive`, `/api/cms`, `/api/herowars`
|
|
||||||
- Copié tous les fichiers de routes vers les nouveaux emplacements
|
|
||||||
- Généré les nouveaux fichiers `index.js` pour chaque domaine
|
|
||||||
- Mis à jour `src/routes/api/index.js` pour utiliser les nouveaux chemins
|
|
||||||
- Créé un commit Git
|
|
||||||
|
|
||||||
**Fichiers modifiés:**
|
|
||||||
```
|
|
||||||
✓ src/routes/api/skydive/ (8 fichiers)
|
|
||||||
✓ src/routes/api/cms/ (8 fichiers)
|
|
||||||
✓ src/routes/api/herowars/ (3 fichiers)
|
|
||||||
✓ src/routes/api/index.js (mis à jour)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Rapports générés:**
|
|
||||||
- `MIGRATION_REPORT.md` - Détails complets de la migration
|
|
||||||
- `MIGRATION_SWAGGER_TODO.md` - Tâches pour Swagger
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. `update-references-post-migration.js` ✓ EXÉCUTÉ
|
|
||||||
|
|
||||||
**Rôle:** Met à jour les références aux chemins dans la documentation
|
|
||||||
|
|
||||||
**Statut:** ✅ Completed
|
|
||||||
- Mis à jour les fichiers YAML Swagger (`/api/v1/` → `/api/skydive/`, etc.)
|
|
||||||
- Mis à jour la collection et l'environnement Postman
|
|
||||||
- Scanné les fichiers clés pour les références restantes
|
|
||||||
|
|
||||||
**Rapports générés:**
|
|
||||||
- `POST_MIGRATION_CHECKLIST.md` - Liste de vérification manuelle
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. `finalize-migration.js`
|
|
||||||
|
|
||||||
**Rôle:** Valide, nettoie, et teste la migration
|
|
||||||
|
|
||||||
**Options disponibles:**
|
|
||||||
```bash
|
|
||||||
# Valider la structure sans rien faire
|
|
||||||
node scripts/finalize-migration.js
|
|
||||||
|
|
||||||
# Valider et nettoyer les anciens répertoires
|
|
||||||
node scripts/finalize-migration.js --cleanup
|
|
||||||
|
|
||||||
# Valider et tester les endpoints (nécessite le serveur en cours d'exécution)
|
|
||||||
node scripts/finalize-migration.js --test
|
|
||||||
|
|
||||||
# Mode complet: validation, nettoyage et résumé
|
|
||||||
node scripts/finalize-migration.js --full
|
|
||||||
```
|
|
||||||
|
|
||||||
**Statut:** ✅ Ready to run
|
|
||||||
|
|
||||||
**Rapport généré:**
|
|
||||||
- `MIGRATION_COMPLETE_SUMMARY.md` - Résumé final avec instructions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Guide étape par étape
|
|
||||||
|
|
||||||
### Étape 1: Vérifier la migration ✅
|
|
||||||
```bash
|
|
||||||
ls -la src/routes/api/
|
|
||||||
# Devrait afficher: cms/, herowars/, skydive/, v1/, v2/, v3/, index.js
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 2: Valider la structure
|
|
||||||
```bash
|
|
||||||
node scripts/finalize-migration.js
|
|
||||||
```
|
|
||||||
|
|
||||||
**Résultat attendu:**
|
|
||||||
```
|
|
||||||
✓ skydive/: ✓ (8 route files)
|
|
||||||
✓ cms/: ✓ (7 route files)
|
|
||||||
✓ herowars/: ✓ (3 route files)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 3: Nettoyer les anciens répertoires (OPTIONNEL)
|
|
||||||
```bash
|
|
||||||
# Option A: Via le script
|
|
||||||
node scripts/finalize-migration.js --cleanup
|
|
||||||
|
|
||||||
# Option B: Manuellement
|
|
||||||
rm -rf src/routes/api/v1 src/routes/api/v2 src/routes/api/v3
|
|
||||||
git add -A
|
|
||||||
git commit -m "chore: remove old v1/v2/v3 route directories"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 4: Mettre à jour le frontend (IMPORTANT)
|
|
||||||
|
|
||||||
**Fichiers à modifier dans `adastra_app/src/environments/`:**
|
|
||||||
|
|
||||||
#### `environment.ts`
|
|
||||||
```typescript
|
|
||||||
// AVANT:
|
|
||||||
export const environment = {
|
|
||||||
production: false,
|
|
||||||
apiUrl: '/api/v1',
|
|
||||||
cmsUrl: '/api/v2',
|
|
||||||
herowarsUrl: '/api/v3',
|
|
||||||
};
|
|
||||||
|
|
||||||
// APRÈS:
|
|
||||||
export const environment = {
|
|
||||||
production: false,
|
|
||||||
apiUrl: '/api/skydive',
|
|
||||||
cmsUrl: '/api/cms',
|
|
||||||
herowarsUrl: '/api/herowars',
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `environment.development.ts` et `environment.local.ts`
|
|
||||||
Applique les mêmes changements
|
|
||||||
|
|
||||||
**Mise à jour des services Angular:**
|
|
||||||
```typescript
|
|
||||||
// Dans vos services (par exemple, src/app/services/*.service.ts)
|
|
||||||
|
|
||||||
// AVANT:
|
|
||||||
this.http.get(environment.apiUrl + '/jumps')
|
|
||||||
this.http.get(environment.cmsUrl + '/articles')
|
|
||||||
this.http.get(environment.herowarsUrl + '/clans')
|
|
||||||
|
|
||||||
// APRÈS:
|
|
||||||
this.http.get(environment.apiUrl + '/jumps')
|
|
||||||
this.http.get(environment.cmsUrl + '/articles')
|
|
||||||
this.http.get(environment.herowarsUrl + '/clans')
|
|
||||||
// Pas de changement si vous utilisez les variables d'environnement!
|
|
||||||
// Sinon, cherchez/remplacez les chemins en dur
|
|
||||||
```
|
|
||||||
|
|
||||||
**Automatiser la mise à jour du frontend (macOS/Linux):**
|
|
||||||
```bash
|
|
||||||
cd adastra_app
|
|
||||||
sed -i '' "s|/api/v1|/api/skydive|g" src/**/*.ts
|
|
||||||
sed -i '' "s|/api/v2|/api/cms|g" src/**/*.ts
|
|
||||||
sed -i '' "s|/api/v3|/api/herowars|g" src/**/*.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 5: Tester les endpoints
|
|
||||||
|
|
||||||
**Démarrer le serveur API:**
|
|
||||||
```bash
|
|
||||||
cd adastra_api
|
|
||||||
npm run local
|
|
||||||
```
|
|
||||||
|
|
||||||
**Dans un autre terminal, tester les nouveaux chemins:**
|
|
||||||
```bash
|
|
||||||
# Tester Swagger UI
|
|
||||||
curl http://localhost:3200/api-docs
|
|
||||||
|
|
||||||
# Tester les endpoints des domaines
|
|
||||||
curl http://localhost:3200/api/skydive/jumps
|
|
||||||
curl http://localhost:3200/api/cms/articles
|
|
||||||
curl http://localhost:3200/api/herowars/clans
|
|
||||||
|
|
||||||
# Avec authentification si nécessaire
|
|
||||||
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:3200/api/skydive/jumps
|
|
||||||
```
|
|
||||||
|
|
||||||
### Étape 6: Tester le frontend
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd adastra_app
|
|
||||||
npm start
|
|
||||||
# Ou avec configuration spécifique
|
|
||||||
npm run local # ng serve --configuration local
|
|
||||||
```
|
|
||||||
|
|
||||||
Vérifier dans les DevTools que les appels API vont vers les nouveaux chemins.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Statistiques de la migration
|
|
||||||
|
|
||||||
| Métrique | Valeur |
|
|
||||||
|----------|--------|
|
|
||||||
| Nouveaux domaines créés | 3 (skydive, cms, herowars) |
|
|
||||||
| Fichiers de routes migrés | 19 |
|
|
||||||
| Fichiers index.js créés/mis à jour | 4 |
|
|
||||||
| Fichiers Swagger mis à jour | Oui |
|
|
||||||
| Fichiers Postman mis à jour | Oui |
|
|
||||||
| Commits Git créés | 1 (structure) + opt. 1 (nettoyage) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fichiers de rapport créés
|
|
||||||
|
|
||||||
| Fichier | Contenu |
|
|
||||||
|---------|---------|
|
|
||||||
| `MIGRATION_REPORT.md` | Rapport détaillé de la migration |
|
|
||||||
| `MIGRATION_SWAGGER_TODO.md` | Notes pour les mises à jour Swagger |
|
|
||||||
| `POST_MIGRATION_CHECKLIST.md` | Liste de vérification manuelle |
|
|
||||||
| `MIGRATION_COMPLETE_SUMMARY.md` | Résumé final et instructions |
|
|
||||||
| `SCRIPTS_MIGRATION_GUIDE.md` | Ce fichier |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Procédure de rollback
|
|
||||||
|
|
||||||
Si vous devez annuler la migration:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Voir l'historique
|
|
||||||
git log --oneline -10
|
|
||||||
|
|
||||||
# Annuler les changements (ajuster le nombre de commits)
|
|
||||||
git reset --hard HEAD~2
|
|
||||||
|
|
||||||
# Ou restaurer une branche spécifique
|
|
||||||
git reset --hard origin/develop
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Points clés à retenir
|
|
||||||
|
|
||||||
✅ **La migration est non-destructive:**
|
|
||||||
- Les anciens répertoires v1/v2/v3 existent toujours
|
|
||||||
- Vous pouvez les supprimer après vérification
|
|
||||||
|
|
||||||
✅ **Mises à jour automatisées:**
|
|
||||||
- Scripts: Oui ✓
|
|
||||||
- Swagger: Oui ✓
|
|
||||||
- Postman: Oui ✓
|
|
||||||
|
|
||||||
⚠️ **Mises à jour manuelles requises:**
|
|
||||||
- Frontend Angular (environnement + services)
|
|
||||||
- Tous les appels API en dur dans le code cliente
|
|
||||||
- Documentation externe
|
|
||||||
- Tests d'intégration
|
|
||||||
|
|
||||||
✅ **Git-safe:**
|
|
||||||
- Chaque étape crée un commit
|
|
||||||
- Rollback facile si problème
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Les endpoints retournent 404
|
|
||||||
- ✓ Vérifier que le serveur a redémarré après la migration
|
|
||||||
- ✓ Vérifier les chemins dans Swagger UI (http://localhost:3200/api-docs)
|
|
||||||
- ✓ Vérifier que le backend a bien recompilé (avec nodemon)
|
|
||||||
|
|
||||||
### Les routes ne sont pas trouvées
|
|
||||||
- ✓ Vérifier que `src/routes/api/index.js` a les bonnes références
|
|
||||||
- ✓ Vérifier que chaque domaine a un `index.js`
|
|
||||||
- ✓ Vérifier l'ordre des middlewares dans `app.js`
|
|
||||||
|
|
||||||
### Erreurs d'authentification
|
|
||||||
- ✓ Les middlewares d'auth ne sont pas affectés
|
|
||||||
- ✓ Les tokens JWT restent valides
|
|
||||||
- ✓ Les headers restent les mêmes
|
|
||||||
|
|
||||||
### Le frontend ne peut pas accéder à l'API
|
|
||||||
- ✓ Vérifier CORS dans `app.js`
|
|
||||||
- ✓ Vérifier les URLs dans les environnements Angular
|
|
||||||
- ✓ Vérifier les appels http dans les services
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prochaines étapes
|
|
||||||
|
|
||||||
1. ✅ Tester tous les endpoints du backend
|
|
||||||
2. ✅ Mettre à jour le frontend (environnement + services)
|
|
||||||
3. ✅ Tester le frontend avec le backend modifié
|
|
||||||
4. ✅ Mettre à jour la documentation
|
|
||||||
5. ✅ Nettoyer les anciens répertoires v1/v2/v3 (optionnel)
|
|
||||||
6. ✅ Déployer en staging/production
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ressources supplémentaires
|
|
||||||
|
|
||||||
- Documentation architecture: `ARCHITECTURE_DIAGRAMS.md`
|
|
||||||
- ADR (Architecture Decision Records): `ADR_INDEX.md`
|
|
||||||
- Configuration Swagger: `src/config/swagger.js`
|
|
||||||
- Routes configuration: `src/routes/api/index.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Pour des questions ou problèmes:
|
|
||||||
|
|
||||||
1. ✓ Consulter los fichiers de rapport (`POST_MIGRATION_CHECKLIST.md`, etc.)
|
|
||||||
2. ✓ Vérifier les logs du serveur: `npm run local` (output)
|
|
||||||
3. ✓ Vérifier Swagger UI: http://localhost:3200/api-docs
|
|
||||||
4. ✓ Exécuter la validation: `node scripts/finalize-migration.js`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Migration effectuée le:** 24 avril 2026
|
|
||||||
**Version API:** v1/v2/v3 → domain-based
|
|
||||||
**Status:** ✅ Complete
|
|
||||||
@@ -1,762 +0,0 @@
|
|||||||
# Méthodes disponibles sur les modèles MySQL (Sequelize)
|
|
||||||
|
|
||||||
Ce document liste toutes les méthodes automatiquement générées par Sequelize pour chaque modèle en fonction des associations définies dans `src/database/relationships/index.js`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Table des matières
|
|
||||||
|
|
||||||
1. [Article](#article)
|
|
||||||
2. [Tag](#tag)
|
|
||||||
3. [User](#user)
|
|
||||||
4. [Comment](#comment)
|
|
||||||
5. [Favorite](#favorite)
|
|
||||||
6. [Follower](#follower)
|
|
||||||
7. [Product](#product)
|
|
||||||
8. [Brand](#brand)
|
|
||||||
9. [Category](#category)
|
|
||||||
10. [Packaging](#packaging)
|
|
||||||
11. [TagList](#taglist)
|
|
||||||
12. [Role](#role)
|
|
||||||
13. [UserRoleXref](#userroleexref)
|
|
||||||
14. [ProductCategoryXref](#productcategoryxref)
|
|
||||||
15. [ProductTagXref](#producttagxref)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Article
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Tags via `TagList`
|
|
||||||
Alias: `articleTags`
|
|
||||||
```javascript
|
|
||||||
article.getArticleTags() // Récupère tous les tags
|
|
||||||
article.setArticleTags([...]) // Définit les tags
|
|
||||||
article.addArticleTag(tag) // Ajoute un tag
|
|
||||||
article.removeArticleTag(tag) // Retire un tag
|
|
||||||
article.countArticleTags() // Compte les tags
|
|
||||||
article.hasArticleTag(tag) // Vérifie si le tag est lié
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Users (Favoris) via `Favorite`
|
|
||||||
Alias: `articleFavoriteUsers` (cascade delete activé)
|
|
||||||
```javascript
|
|
||||||
article.getArticleFavoriteUsers() // Récupère les utilisateurs qui ont favorisé
|
|
||||||
article.setArticleFavoriteUsers([...]) // Définit les utilisateurs
|
|
||||||
article.addArticleFavoriteUser(user) // Ajoute un utilisateur
|
|
||||||
article.removeArticleFavoriteUser(user) // Retire un utilisateur
|
|
||||||
article.countArticleFavoriteUsers() // Compte les utilisateurs
|
|
||||||
article.hasArticleFavoriteUser(user) // Vérifie si l'utilisateur a favorisé
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### Comments (cascade delete activé)
|
|
||||||
```javascript
|
|
||||||
article.getComments() // Récupère tous les commentaires
|
|
||||||
article.setComments([...]) // Définit les commentaires
|
|
||||||
article.addComment(comment) // Ajoute un commentaire
|
|
||||||
article.removeComment(comment) // Retire un commentaire
|
|
||||||
article.countComments() // Compte les commentaires
|
|
||||||
article.hasComment(comment) // Vérifie si le commentaire existe
|
|
||||||
article.createComment({...}) // Crée un commentaire
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Favorites (cascade delete activé)
|
|
||||||
```javascript
|
|
||||||
article.getFavorites() // Récupère les enregistrements Favorite
|
|
||||||
article.setFavorites([...]) // Définit les favoris
|
|
||||||
article.addFavorite(favorite) // Ajoute un Favorite
|
|
||||||
article.removeFavorite(favorite) // Retire un Favorite
|
|
||||||
article.countFavorites() // Compte les Favorites
|
|
||||||
article.hasFavorite(favorite) // Vérifie si le Favorite existe
|
|
||||||
article.createFavorite({...}) // Crée un Favorite
|
|
||||||
```
|
|
||||||
|
|
||||||
#### TagLists (cascade delete activé)
|
|
||||||
```javascript
|
|
||||||
article.getTagLists() // Récupère les enregistrements TagList
|
|
||||||
article.setTagLists([...]) // Définit les TagLists
|
|
||||||
article.addTagList(tagList) // Ajoute un TagList
|
|
||||||
article.removeTagList(tagList) // Retire un TagList
|
|
||||||
article.countTagLists() // Compte les TagLists
|
|
||||||
article.hasTagList(tagList) // Vérifie si le TagList existe
|
|
||||||
article.createTagList({...}) // Crée un TagList
|
|
||||||
```
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Author (User)
|
|
||||||
```javascript
|
|
||||||
article.getAuthor() // Récupère l'auteur
|
|
||||||
article.setAuthor(user) // Définit l'auteur
|
|
||||||
article.createAuthor({...}) // Crée un auteur
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
article.toJSONFor() // Formate en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tag
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Articles via `TagList`
|
|
||||||
Alias: `articleIdArticleTagLists`
|
|
||||||
```javascript
|
|
||||||
tag.getArticleIdArticleTagLists() // Récupère les articles
|
|
||||||
tag.setArticleIdArticleTagLists([...])
|
|
||||||
tag.addArticleIdArticleTagList(article)
|
|
||||||
tag.removeArticleIdArticleTagList(article)
|
|
||||||
tag.countArticleIdArticleTagLists()
|
|
||||||
tag.hasArticleIdArticleTagList(article)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Products via `ProductTagXref`
|
|
||||||
Alias: `productIdProductProductTagXrefs`
|
|
||||||
```javascript
|
|
||||||
tag.getProductIdProductProductTagXrefs()
|
|
||||||
tag.setProductIdProductProductTagXrefs([...])
|
|
||||||
tag.addProductIdProductProductTagXref(product)
|
|
||||||
tag.removeProductIdProductProductTagXref(product)
|
|
||||||
tag.countProductIdProductProductTagXrefs()
|
|
||||||
tag.hasProductIdProductProductTagXref(product)
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### TagLists
|
|
||||||
```javascript
|
|
||||||
tag.getTagLists() // Récupère les enregistrements TagList
|
|
||||||
tag.setTagLists([...])
|
|
||||||
tag.addTagList(tagList)
|
|
||||||
tag.removeTagList(tagList)
|
|
||||||
tag.countTagLists()
|
|
||||||
tag.hasTagList(tagList)
|
|
||||||
tag.createTagList({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### ProductTagXrefs
|
|
||||||
```javascript
|
|
||||||
tag.getProductTagXrefs() // Récupère les ProductTagXrefs
|
|
||||||
tag.setProductTagXrefs([...])
|
|
||||||
tag.addProductTagXref(xref)
|
|
||||||
tag.removeProductTagXref(xref)
|
|
||||||
tag.countProductTagXrefs()
|
|
||||||
tag.hasProductTagXref(xref)
|
|
||||||
tag.createProductTagXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
tag.toJSONFor() // Formate en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## User
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Articles (Favoris) via `Favorite`
|
|
||||||
Alias: `articleIdArticles`
|
|
||||||
```javascript
|
|
||||||
user.getArticleIdArticles() // Récupère les articles favorisés
|
|
||||||
user.setArticleIdArticles([...])
|
|
||||||
user.addArticleIdArticle(article)
|
|
||||||
user.removeArticleIdArticle(article)
|
|
||||||
user.countArticleIdArticles()
|
|
||||||
user.hasArticleIdArticle(article)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Followers (ceux qui vous suivent) via `Follower`
|
|
||||||
Alias: `followerIdUsers`
|
|
||||||
```javascript
|
|
||||||
user.getFollowerIdUsers() // Récupère les followers
|
|
||||||
user.setFollowerIdUsers([...])
|
|
||||||
user.addFollowerIdUser(user)
|
|
||||||
user.removeFollowerIdUser(user)
|
|
||||||
user.countFollowerIdUsers()
|
|
||||||
user.hasFollowerIdUser(user)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Following (que vous suivez) via `Follower`
|
|
||||||
Alias: `userIdUserFollowers`
|
|
||||||
```javascript
|
|
||||||
user.getUserIdUserFollowers() // Récupère ceux que vous suivez
|
|
||||||
user.setUserIdUserFollowers([...])
|
|
||||||
user.addUserIdUserFollower(user)
|
|
||||||
user.removeUserIdUserFollower(user)
|
|
||||||
user.countUserIdUserFollowers()
|
|
||||||
user.hasUserIdUserFollower(user)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Roles via `UserRoleXref`
|
|
||||||
Alias: `roleIdRoles`
|
|
||||||
```javascript
|
|
||||||
user.getRoleIdRoles() // Récupère les rôles
|
|
||||||
user.setRoleIdRoles([...])
|
|
||||||
user.addRoleIdRole(role)
|
|
||||||
user.removeRoleIdRole(role)
|
|
||||||
user.countRoleIdRoles()
|
|
||||||
user.hasRoleIdRole(role)
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### Articles (créés par l'utilisateur)
|
|
||||||
```javascript
|
|
||||||
user.getArticles() // Récupère les articles créés
|
|
||||||
user.setArticles([...])
|
|
||||||
user.addArticle(article)
|
|
||||||
user.removeArticle(article)
|
|
||||||
user.countArticles()
|
|
||||||
user.hasArticle(article)
|
|
||||||
user.createArticle({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Comments (créés par l'utilisateur)
|
|
||||||
```javascript
|
|
||||||
user.getComments() // Récupère les commentaires créés
|
|
||||||
user.setComments([...])
|
|
||||||
user.addComment(comment)
|
|
||||||
user.removeComment(comment)
|
|
||||||
user.countComments()
|
|
||||||
user.hasComment(comment)
|
|
||||||
user.createComment({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Favorites (enregistrements)
|
|
||||||
```javascript
|
|
||||||
user.getFavorites() // Récupère les Favorites
|
|
||||||
user.setFavorites([...])
|
|
||||||
user.addFavorite(favorite)
|
|
||||||
user.removeFavorite(favorite)
|
|
||||||
user.countFavorites()
|
|
||||||
user.hasFavorite(favorite)
|
|
||||||
user.createFavorite({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Followers (enregistrements)
|
|
||||||
```javascript
|
|
||||||
user.getFollowers() // Récupère les Followers
|
|
||||||
user.setFollowers([...])
|
|
||||||
user.addFollower(follower)
|
|
||||||
user.removeFollower(follower)
|
|
||||||
user.countFollowers()
|
|
||||||
user.hasFollower(follower)
|
|
||||||
user.createFollower({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### FollowerFollowers (ceux qui vous suivent via enregistrement)
|
|
||||||
```javascript
|
|
||||||
user.getFollowerFollowers() // Récupère les FollowerFollowers
|
|
||||||
user.setFollowerFollowers([...])
|
|
||||||
user.addFollowerFollower(follower)
|
|
||||||
user.removeFollowerFollower(follower)
|
|
||||||
user.countFollowerFollowers()
|
|
||||||
user.hasFollowerFollower(follower)
|
|
||||||
user.createFollowerFollower({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Products (créés/possédés)
|
|
||||||
```javascript
|
|
||||||
user.getProducts() // Récupère les produits
|
|
||||||
user.setProducts([...])
|
|
||||||
user.addProduct(product)
|
|
||||||
user.removeProduct(product)
|
|
||||||
user.countProducts()
|
|
||||||
user.hasProduct(product)
|
|
||||||
user.createProduct({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### UserRoleXrefs
|
|
||||||
```javascript
|
|
||||||
user.getUserRoleXrefs() // Récupère les UserRoleXrefs
|
|
||||||
user.setUserRoleXrefs([...])
|
|
||||||
user.addUserRoleXref(xref)
|
|
||||||
user.removeUserRoleXref(xref)
|
|
||||||
user.countUserRoleXrefs()
|
|
||||||
user.hasUserRoleXref(xref)
|
|
||||||
user.createUserRoleXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
user.validPassword(password) // Valide le mot de passe
|
|
||||||
user.setPassword(password) // Définit le mot de passe (hash)
|
|
||||||
user.generateJWT() // Génère un JWT
|
|
||||||
user.toAuthJSON() // Retourne objet auth
|
|
||||||
user.toJSONFor() // Formate en JSON
|
|
||||||
user.toProfileJSONFor() // Formate profil en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Comment
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Article
|
|
||||||
```javascript
|
|
||||||
comment.getArticle() // Récupère l'article
|
|
||||||
comment.setArticle(article) // Définit l'article
|
|
||||||
comment.createArticle({...}) // Crée un article
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Author (User)
|
|
||||||
```javascript
|
|
||||||
comment.getAuthor() // Récupère l'auteur
|
|
||||||
comment.setAuthor(user) // Définit l'auteur
|
|
||||||
comment.createAuthor({...}) // Crée un auteur
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
comment.toJSONFor() // Formate en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Favorite
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### User
|
|
||||||
```javascript
|
|
||||||
favorite.getUser() // Récupère l'utilisateur
|
|
||||||
favorite.setUser(user) // Définit l'utilisateur
|
|
||||||
favorite.createUser({...}) // Crée un utilisateur
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Article
|
|
||||||
```javascript
|
|
||||||
favorite.getArticle() // Récupère l'article
|
|
||||||
favorite.setArticle(article) // Définit l'article
|
|
||||||
favorite.createArticle({...}) // Crée un article
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
favorite.toJSONFor() // Formate en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Follower
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### User (l'utilisateur suivi)
|
|
||||||
```javascript
|
|
||||||
follower.getUser() // Récupère l'utilisateur suivi
|
|
||||||
follower.setUser(user) // Définit l'utilisateur suivi
|
|
||||||
follower.createUser({...}) // Crée un utilisateur
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Follower (l'utilisateur qui suit) - alias 'follower'
|
|
||||||
```javascript
|
|
||||||
follower.getFollower() // Récupère celui qui suit
|
|
||||||
follower.setFollower(user) // Définit celui qui suit
|
|
||||||
follower.createFollower({...}) // Crée un utilisateur qui suit
|
|
||||||
```
|
|
||||||
|
|
||||||
### Instance Methods
|
|
||||||
```javascript
|
|
||||||
follower.toJSONFor() // Formate en JSON
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Product
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Categories via `ProductCategoryXref`
|
|
||||||
Alias: `productCategories`
|
|
||||||
```javascript
|
|
||||||
product.getProductCategories() // Récupère les catégories
|
|
||||||
product.setProductCategories([...])
|
|
||||||
product.addProductCategory(category)
|
|
||||||
product.removeProductCategory(category)
|
|
||||||
product.countProductCategories()
|
|
||||||
product.hasProductCategory(category)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Tags via `ProductTagXref`
|
|
||||||
Alias: `productTags`
|
|
||||||
```javascript
|
|
||||||
product.getProductTags() // Récupère les tags
|
|
||||||
product.setProductTags([...])
|
|
||||||
product.addProductTag(tag)
|
|
||||||
product.removeProductTag(tag)
|
|
||||||
product.countProductTags()
|
|
||||||
product.hasProductTag(tag)
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### ProductCategoryXrefs
|
|
||||||
```javascript
|
|
||||||
product.getProductCategoryXrefs() // Récupère les liens catégories
|
|
||||||
product.setProductCategoryXrefs([...])
|
|
||||||
product.addProductCategoryXref(xref)
|
|
||||||
product.removeProductCategoryXref(xref)
|
|
||||||
product.countProductCategoryXrefs()
|
|
||||||
product.hasProductCategoryXref(xref)
|
|
||||||
product.createProductCategoryXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
#### ProductTagXrefs
|
|
||||||
```javascript
|
|
||||||
product.getProductTagXrefs() // Récupère les liens tags
|
|
||||||
product.setProductTagXrefs([...])
|
|
||||||
product.addProductTagXref(xref)
|
|
||||||
product.removeProductTagXref(xref)
|
|
||||||
product.countProductTagXrefs()
|
|
||||||
product.hasProductTagXref(xref)
|
|
||||||
product.createProductTagXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Brand
|
|
||||||
```javascript
|
|
||||||
product.getBrand() // Récupère la marque
|
|
||||||
product.setBrand(brand) // Définit la marque
|
|
||||||
product.createBrand({...}) // Crée une marque
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Owner (User)
|
|
||||||
```javascript
|
|
||||||
product.getOwner() // Récupère le propriétaire
|
|
||||||
product.setOwner(user) // Définit le propriétaire
|
|
||||||
product.createOwner({...}) // Crée un propriétaire
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Packaging
|
|
||||||
```javascript
|
|
||||||
product.getPackaging() // Récupère l'emballage
|
|
||||||
product.setPackaging(packaging) // Définit l'emballage
|
|
||||||
product.createPackaging({...}) // Crée un emballage
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Brand
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### Products
|
|
||||||
```javascript
|
|
||||||
brand.getProducts() // Récupère les produits
|
|
||||||
brand.setProducts([...])
|
|
||||||
brand.addProduct(product)
|
|
||||||
brand.removeProduct(product)
|
|
||||||
brand.countProducts()
|
|
||||||
brand.hasProduct(product)
|
|
||||||
brand.createProduct({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Category
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Products via `ProductCategoryXref`
|
|
||||||
Alias: `productIdProducts`
|
|
||||||
```javascript
|
|
||||||
category.getProductIdProducts() // Récupère les produits
|
|
||||||
category.setProductIdProducts([...])
|
|
||||||
category.addProductIdProduct(product)
|
|
||||||
category.removeProductIdProduct(product)
|
|
||||||
category.countProductIdProducts()
|
|
||||||
category.hasProductIdProduct(product)
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### ProductCategoryXrefs
|
|
||||||
```javascript
|
|
||||||
category.getProductCategoryXrefs() // Récupère les liens produits
|
|
||||||
category.setProductCategoryXrefs([...])
|
|
||||||
category.addProductCategoryXref(xref)
|
|
||||||
category.removeProductCategoryXref(xref)
|
|
||||||
category.countProductCategoryXrefs()
|
|
||||||
category.hasProductCategoryXref(xref)
|
|
||||||
category.createProductCategoryXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Packaging
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### Products
|
|
||||||
```javascript
|
|
||||||
packaging.getProducts() // Récupère les produits
|
|
||||||
packaging.setProducts([...])
|
|
||||||
packaging.addProduct(product)
|
|
||||||
packaging.removeProduct(product)
|
|
||||||
packaging.countProducts()
|
|
||||||
packaging.hasProduct(product)
|
|
||||||
packaging.createProduct({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## TagList
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Article
|
|
||||||
```javascript
|
|
||||||
tagList.getArticle() // Récupère l'article
|
|
||||||
tagList.setArticle(article) // Définit l'article
|
|
||||||
tagList.createArticle({...}) // Crée un article
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Tag
|
|
||||||
Alias: `tagNameTag`
|
|
||||||
```javascript
|
|
||||||
tagList.getTagNameTag() // Récupère le tag
|
|
||||||
tagList.setTagNameTag(tag) // Définit le tag
|
|
||||||
tagList.createTagNameTag({...}) // Crée un tag
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Role
|
|
||||||
|
|
||||||
### Many-to-Many (belongsToMany)
|
|
||||||
|
|
||||||
#### Users via `UserRoleXref`
|
|
||||||
Alias: `userIdUserUserRoleXrefs`
|
|
||||||
```javascript
|
|
||||||
role.getUserIdUserUserRoleXrefs() // Récupère les utilisateurs
|
|
||||||
role.setUserIdUserUserRoleXrefs([...])
|
|
||||||
role.addUserIdUserUserRoleXref(user)
|
|
||||||
role.removeUserIdUserUserRoleXref(user)
|
|
||||||
role.countUserIdUserUserRoleXrefs()
|
|
||||||
role.hasUserIdUserUserRoleXref(user)
|
|
||||||
```
|
|
||||||
|
|
||||||
### One-to-Many (hasMany)
|
|
||||||
|
|
||||||
#### UserRoleXrefs
|
|
||||||
```javascript
|
|
||||||
role.getUserRoleXrefs() // Récupère les UserRoleXrefs
|
|
||||||
role.setUserRoleXrefs([...])
|
|
||||||
role.addUserRoleXref(xref)
|
|
||||||
role.removeUserRoleXref(xref)
|
|
||||||
role.countUserRoleXrefs()
|
|
||||||
role.hasUserRoleXref(xref)
|
|
||||||
role.createUserRoleXref({...})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## UserRoleXref
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### User
|
|
||||||
```javascript
|
|
||||||
xref.getUser() // Récupère l'utilisateur
|
|
||||||
xref.setUser(user) // Définit l'utilisateur
|
|
||||||
xref.createUser({...}) // Crée un utilisateur
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Role
|
|
||||||
```javascript
|
|
||||||
xref.getRole() // Récupère le rôle
|
|
||||||
xref.setRole(role) // Définit le rôle
|
|
||||||
xref.createRole({...}) // Crée un rôle
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ProductCategoryXref
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Product
|
|
||||||
```javascript
|
|
||||||
xref.getProduct() // Récupère le produit
|
|
||||||
xref.setProduct(product) // Définit le produit
|
|
||||||
xref.createProduct({...}) // Crée un produit
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Category
|
|
||||||
```javascript
|
|
||||||
xref.getCategory() // Récupère la catégorie
|
|
||||||
xref.setCategory(category) // Définit la catégorie
|
|
||||||
xref.createCategory({...}) // Crée une catégorie
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ProductTagXref
|
|
||||||
|
|
||||||
### Belongs-To
|
|
||||||
|
|
||||||
#### Product
|
|
||||||
```javascript
|
|
||||||
xref.getProduct() // Récupère le produit
|
|
||||||
xref.setProduct(product) // Définit le produit
|
|
||||||
xref.createProduct({...}) // Crée un produit
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Tag
|
|
||||||
Alias: `tagNameTag`
|
|
||||||
```javascript
|
|
||||||
xref.getTagNameTag() // Récupère le tag
|
|
||||||
xref.setTagNameTag(tag) // Définit le tag
|
|
||||||
xref.createTagNameTag({...}) // Crée un tag
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Notes générales
|
|
||||||
|
|
||||||
1. **Paramètres `options`** : Presque toutes les méthodes `get*()` acceptent un objet `options` pour personnaliser la requête :
|
|
||||||
```javascript
|
|
||||||
model.getAssociated({
|
|
||||||
where: { createdAt: { [Op.gte]: someDate } },
|
|
||||||
limit: 10,
|
|
||||||
offset: 0,
|
|
||||||
order: [['createdAt', 'DESC']]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Transactions** : Encapsulez les opérations dans une transaction :
|
|
||||||
```javascript
|
|
||||||
const transaction = await sequelize.transaction();
|
|
||||||
await model.addAssociated(associated, { transaction });
|
|
||||||
await transaction.commit();
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Eager Loading** : Utilisez `include` pour charger les associations :
|
|
||||||
```javascript
|
|
||||||
const article = await Article.findByPk(1, {
|
|
||||||
include: [
|
|
||||||
{ model: Tag, as: 'articleTags' },
|
|
||||||
{ model: User, as: 'author' },
|
|
||||||
{ model: Comment, as: 'comments' }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Alias vs Nom généré** : Le nom des méthodes dépend de l'alias défini. Exemple :
|
|
||||||
- Alias `articleTags` → `getArticleTags()`, `addArticleTag()`
|
|
||||||
- Alias `tagLists` → `getTagLists()`, `addTagList()`
|
|
||||||
|
|
||||||
5. **Toutes les méthodes de manipulation** acceptent un paramètre `options` final :
|
|
||||||
```javascript
|
|
||||||
await article.addTagList(tag, { transaction, validate: true });
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Seeders
|
|
||||||
|
|
||||||
### Seeder Articles (20251127-add-articles.js)
|
|
||||||
|
|
||||||
Ce seeder ajoute automatiquement 3 articles avec du contenu Lorem Ipsum et les associe à des tags d'animaux.
|
|
||||||
|
|
||||||
#### Exécution
|
|
||||||
```bash
|
|
||||||
# Exécuter tous les seeders
|
|
||||||
npx sequelize-cli db:seed:all
|
|
||||||
|
|
||||||
# Annuler un seeder spécifique
|
|
||||||
npx sequelize-cli db:seed:undo --seed 20251127-add-articles.js
|
|
||||||
|
|
||||||
# Annuler tous les seeders
|
|
||||||
npx sequelize-cli db:seed:undo:all
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Articles créés
|
|
||||||
|
|
||||||
| Titre | Tags | Slug |
|
|
||||||
|-------|------|------|
|
|
||||||
| Introduction aux écosystèmes marins | Dolphin, Eagle, Wolf | introduction-aux-ecosystemes-marins |
|
|
||||||
| Les prédateurs de la savane africaine | Lion, Tiger, Wolf | les-predateurs-de-la-savane-africaine |
|
|
||||||
| L'intelligence animale au-delà de nos attentes | Eagle, Dolphin, Lion | lintelligence-animale-au-dela-de-nos-attentes |
|
|
||||||
|
|
||||||
#### Tags disponibles
|
|
||||||
- Lion
|
|
||||||
- Eagle
|
|
||||||
- Dolphin
|
|
||||||
- Tiger
|
|
||||||
- Wolf
|
|
||||||
|
|
||||||
#### Fonctionnalités du seeder
|
|
||||||
- ✅ Crée automatiquement les 5 tags s'ils n'existent pas
|
|
||||||
- ✅ Génère des slugs uniques pour chaque article
|
|
||||||
- ✅ Associe 3 tags à chaque article via la table `tagList`
|
|
||||||
- ✅ Utilise les transactions pour l'intégrité des données
|
|
||||||
- ✅ Support du rollback via `db:seed:undo`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Migrations et Schéma
|
|
||||||
|
|
||||||
### Migration initiale (20251127000000-initial-schema.js)
|
|
||||||
|
|
||||||
Crée tous les 15 tables avec les contraintes CASCADE appropriées :
|
|
||||||
|
|
||||||
**Tables avec CASCADE delete activé :**
|
|
||||||
- `article` → `comment` (foreignKey: `articleId`)
|
|
||||||
- `article` → `favorite` (foreignKey: `articleId`)
|
|
||||||
- `article` → `tagList` (foreignKey: `articleId`)
|
|
||||||
- `user` → `article` (foreignKey: `authorId`)
|
|
||||||
- `user` → `comment` (foreignKey: `authorId`)
|
|
||||||
- `tag` → `tagList` (foreignKey: `tagName`)
|
|
||||||
|
|
||||||
**Exécution**
|
|
||||||
```bash
|
|
||||||
# Appliquer les migrations
|
|
||||||
npx sequelize-cli db:migrate
|
|
||||||
|
|
||||||
# Voir le statut des migrations
|
|
||||||
npx sequelize-cli db:migrate:status
|
|
||||||
|
|
||||||
# Annuler les migrations
|
|
||||||
npx sequelize-cli db:migrate:undo:all
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configuration de la base de données
|
|
||||||
|
|
||||||
### Variables d'environnement
|
|
||||||
|
|
||||||
Le fichier `.env.development` doit contenir :
|
|
||||||
```
|
|
||||||
DB_HOST=localhost
|
|
||||||
DB_USER=root
|
|
||||||
DB_PASS=password
|
|
||||||
DB_NAME=adastra
|
|
||||||
DB_DIALECT=mysql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Validation du schéma au démarrage
|
|
||||||
|
|
||||||
L'application valide automatiquement la présence du schéma au démarrage :
|
|
||||||
- ✅ Si le schéma est absent, l'app échoue avec un message d'erreur
|
|
||||||
- ✅ Si le schéma est présent, les associations sont créées
|
|
||||||
- ✅ Message d'aide fourni pour exécuter les migrations manquantes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Démarrer l'app (validera le schéma)
|
|
||||||
npm run local # Développement avec nodemon
|
|
||||||
npm run dev # Développement
|
|
||||||
npm start # Production
|
|
||||||
```
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
# Guide Swagger - Documentation OpenAPI pour Adastra API
|
|
||||||
|
|
||||||
## Accès à la documentation
|
|
||||||
Une fois le serveur lancé, accédez à : **http://localhost:3200/api-docs**
|
|
||||||
|
|
||||||
## Exemple de documentation pour une route
|
|
||||||
|
|
||||||
Voici un exemple de comment documenter une GET route avec des paramètres de query :
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /api/v1/articles:
|
|
||||||
* get:
|
|
||||||
* summary: Récupère la liste des articles
|
|
||||||
* description: Retourne une liste paginée de tous les articles
|
|
||||||
* tags:
|
|
||||||
* - Articles
|
|
||||||
* parameters:
|
|
||||||
* - in: query
|
|
||||||
* name: page
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* default: 1
|
|
||||||
* description: Numéro de page
|
|
||||||
* - in: query
|
|
||||||
* name: limit
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* default: 10
|
|
||||||
* description: Nombre d'articles par page
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Liste des articles récupérée avec succès
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* data:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* title:
|
|
||||||
* type: string
|
|
||||||
* content:
|
|
||||||
* type: string
|
|
||||||
* total:
|
|
||||||
* type: integer
|
|
||||||
* 400:
|
|
||||||
* description: Erreur de validation
|
|
||||||
* 401:
|
|
||||||
* description: Non authentifié
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur
|
|
||||||
*/
|
|
||||||
router.get('/', async (req, res) => {
|
|
||||||
// ... logique du contrôleur
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Exemple avec POST et authentification
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /api/v1/articles:
|
|
||||||
* post:
|
|
||||||
* summary: Crée un nouvel article
|
|
||||||
* description: Crée un nouvel article avec les données fournies
|
|
||||||
* tags:
|
|
||||||
* - Articles
|
|
||||||
* security:
|
|
||||||
* - bearerAuth: []
|
|
||||||
* requestBody:
|
|
||||||
* required: true
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* required:
|
|
||||||
* - title
|
|
||||||
* - content
|
|
||||||
* properties:
|
|
||||||
* title:
|
|
||||||
* type: string
|
|
||||||
* example: "Mon Article"
|
|
||||||
* content:
|
|
||||||
* type: string
|
|
||||||
* example: "Contenu de l'article"
|
|
||||||
* tags:
|
|
||||||
* type: array
|
|
||||||
* items:
|
|
||||||
* type: string
|
|
||||||
* example: ["tag1", "tag2"]
|
|
||||||
* responses:
|
|
||||||
* 201:
|
|
||||||
* description: Article créé avec succès
|
|
||||||
* content:
|
|
||||||
* application/json:
|
|
||||||
* schema:
|
|
||||||
* type: object
|
|
||||||
* properties:
|
|
||||||
* id:
|
|
||||||
* type: integer
|
|
||||||
* title:
|
|
||||||
* type: string
|
|
||||||
* content:
|
|
||||||
* type: string
|
|
||||||
* 400:
|
|
||||||
* description: Données invalides
|
|
||||||
* 401:
|
|
||||||
* description: Non authentifié
|
|
||||||
*/
|
|
||||||
router.post('/', authenticate, async (req, res) => {
|
|
||||||
// ... logique du contrôleur
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Exemple avec paramètres URL
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
/**
|
|
||||||
* @swagger
|
|
||||||
* /api/v1/articles/{id}:
|
|
||||||
* get:
|
|
||||||
* summary: Récupère un article par ID
|
|
||||||
* tags:
|
|
||||||
* - Articles
|
|
||||||
* parameters:
|
|
||||||
* - in: path
|
|
||||||
* name: id
|
|
||||||
* required: true
|
|
||||||
* schema:
|
|
||||||
* type: integer
|
|
||||||
* description: ID de l'article
|
|
||||||
* responses:
|
|
||||||
* 200:
|
|
||||||
* description: Article récupéré avec succès
|
|
||||||
* 404:
|
|
||||||
* description: Article non trouvé
|
|
||||||
* 500:
|
|
||||||
* description: Erreur serveur
|
|
||||||
*/
|
|
||||||
router.get('/:id', async (req, res) => {
|
|
||||||
// ... logique du contrôleur
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Types de schémas courants
|
|
||||||
|
|
||||||
### Objets simples
|
|
||||||
```javascript
|
|
||||||
schema: {
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id: { type: integer }
|
|
||||||
name: { type: string }
|
|
||||||
email: { type: string, format: email }
|
|
||||||
age: { type: integer, minimum: 0 }
|
|
||||||
isActive: { type: boolean }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Arrays
|
|
||||||
```javascript
|
|
||||||
schema: {
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id: { type: integer }
|
|
||||||
name: { type: string }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enums
|
|
||||||
```javascript
|
|
||||||
schema: {
|
|
||||||
type: string
|
|
||||||
enum: ["pending", "approved", "rejected"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tags disponibles
|
|
||||||
Les tags disponibles dans la config Swagger sont :
|
|
||||||
- **Articles** - Gestion des articles
|
|
||||||
- **Users** - Gestion des utilisateurs
|
|
||||||
- **Products** - Gestion des produits
|
|
||||||
- **Clans** - Gestion des clans
|
|
||||||
- **Hero Wars** - Données Hero Wars
|
|
||||||
|
|
||||||
## Instructions générales
|
|
||||||
|
|
||||||
1. **Placez les commentaires JSDoc directement au-dessus de la définition de la route**
|
|
||||||
2. **Utilisez le tag `@swagger`** pour indiquer que c'est de la documentation OpenAPI
|
|
||||||
3. **Commencez par le chemin d'accès** : `/api/v1/articles`, `/api/v1/articles/{id}`, etc.
|
|
||||||
4. **Spécifiez la méthode HTTP** : `get`, `post`, `put`, `delete`, `patch`
|
|
||||||
5. **Incluez toujours** : `summary`, `description`, `tags`, `responses`
|
|
||||||
6. **Pour les routes protégées**, utilisez `security: [{ bearerAuth: [] }]` ou `security: [{ apiKeyAuth: [] }]`
|
|
||||||
|
|
||||||
## Pour plus de détails
|
|
||||||
Consultez la documentation officielle : https://swagger.io/specification/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Note** : Une fois que vous aurez ajouté les commentaires Swagger à vos routes, redémarrez le serveur et accédez à `/api-docs` pour voir la documentation mise à jour.
|
|
||||||
Reference in New Issue
Block a user