Ajouter une fonctionnalité
Recette type, illustrée par un exemple : ajouter des « Bourses externes » (organisme financeur) visibles par l'étudiant.
1. Modèle (backend)#
Choisissez l'app du domaine (ici paiements). Dans models.py :
class BourseExterne(models.Model):
etudiant = models.ForeignKey("etudiants.Etudiant", on_delete=models.CASCADE, related_name="bourses_externes")
organisme = models.CharField(max_length=150)
montant = models.DecimalField(max_digits=12, decimal_places=2)
annee_academique = models.ForeignKey("academique.AnneeAcademique", on_delete=models.PROTECT)
def clean(self): # règle métier ICI, pas dans la vue ni le frontend
if self.montant <= 0:
raise ValidationError({"montant": "Le montant doit être positif."})
python manage.py makemigrations paiements
python manage.py migrate
Committez le fichier de migration avec le code.
2. API#
serializers.py: unModelSerializer; appelezinstance.clean()dansvalidate()si la règle est dans le modèle (voiremploidutemps/serializers.py).views.py: unModelViewSet; contrôlez les droits dansperform_create/update/destroyavecuser_has_write_access(request.user, "can_manage_finance").- Filtrez par année :
get_current_academic_year_id()(academique.middleware). urls.py:router.register("bourses-externes", BourseExterneViewSet).
3. Droits et portails#
- Route d'administration : ajoutez sa règle dans
REGLES(users/acces_personnel.py), par exemple(r"^/api/bourses-externes(/|$)", (FIN, ET), (FIN,)). Sans règle, seule l'administration y accède. Elle est automatiquement interdite aux comptes portail. - Route lue par le portail étudiant (ex.
/api/paiements/me/bourses-externes/) : ajoutez-la àPORTAL_RULES["etudiant"]dansusers/middleware.pyet filtrez surrequest.userdans la vue. Voir Permissions.
4. Écran (frontend)#
- Endpoint dans
src/services/api/endpoints.js, service danssrc/services/api/services.js(réutilisezcreateCrudService). - Page dans
src/app/(dashboard)/<chemin>/page.js(ou un composant danssrc/components/<domaine>/). - Entrée de menu dans
src/config/routes.js; si elle dépend d'un domaine de droits, ajoutez son libellé au bon groupe danscomponents/layout/Sidebar.js. - Masquez les boutons d'écriture selon
useUserPermissions()(utils/permissions.js) — le serveur reste juge. - Affichez les erreurs serveur (
getApiErrorMessage(err)) dans unSnackbar.
5. Tests#
Ajoutez un scénario dans back-istc/tests/ (voir Tests) :
- le cas nominal (création, effet attendu) ;
- un cas refusé (validation, droits insuffisants) ;
- la route de portail dans
ROUTES_ETUDIANT, la route d'admin dansROUTES_ADMINISTRATION.
6. Documentation#
- Guide utilisateur : la page du module dans
docs/guide/…(noms exacts des boutons, procédure pas à pas, messages d'erreur). docs/developpeurs/applications.mdsi une app ou un préfixe d'URL est ajouté.docs/installation/configuration.mdsi une variable.envest ajoutée (etback-istc/.env.example).
Liste de contrôle avant la pull request#
- Migration générée et committée
- Règle métier dans le modèle / un service, testée
- Droits contrôlés côté serveur (règle ajoutée dans
REGLES) -
PORTAL_RULESmis à jour si la route sert un portail -
python -m pytest -qvert,npm run lintsans erreur,npm run buildOK - Guide utilisateur mis à jour