docs: add backend documentation files

Reference guides (Sequelize model methods, Swagger) and migration reports
from the MongoDB-to-MySQL and domain-based route structure migrations.
This commit is contained in:
2026-04-26 16:54:56 +02:00
parent 83216e96be
commit 097e11be1b
9 changed files with 2116 additions and 0 deletions
+762
View File
@@ -0,0 +1,762 @@
# 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
```