En tant qu' utilisateur du système SEKOUH (Administrateur ou Comptable),
je souhaite définir et valider les tarifs scolaires (inscription, scolarité) par niveau,
afin d' automatiser la facturation et le suivi des échéances pour l'ensemble des élèves.
Résumé de la tâche
L'objectif est de mettre en place l'interface et la logique métier permettant de paramétrer la
grille tarifaire de l'année scolaire active. Le système doit contrôler la validité des montants,
empêcher les doublons et gérer les avertissements en cas de modification de frais alors que
des paiements ont déjà été perçus.
Critères d'Acceptation
● Persistance des Frais : Création d'un endpoint POST /api/finances/config-
frais pour enregistrer une configuration (Niveau, Type de frais, Montant, Date
d'échéance).
● Validation de l'Année Active : Le service doit interdire toute configuration de frais
pour un niveau rattaché à une année scolaire inactive ou clôturée.
● Contrôle d'Intégrité : Le système doit rejeter la création si une configuration existe
déjà pour le triplet {level_id, fee_type, school_year_id} (Code 409
Conflict).
● Calcul des Échéances : La date d'échéance doit être enregistrée et validée comme
étant postérieure ou égale à la date de début de l'année scolaire en cours.
● Service de Consultation : Fournir un endpoint GET /api/finances/config-
frais/levels/{levelId} pour retourner la grille tarifaire complète d'un niveau.
Cas d'Erreur & Réponses API
Scénario Validation Backend Code HTTP
Montant ≤ 0 Vérification du champ amount. 400 Bad Request
Contrainte d'unicité sur le triplet
Doublon de métier. 409 Conflict
configuration
Vérification de l'existence de la clé
Niveau inexistant étrangère. 404 Not Found
Vérification du statut de l'année liée
Année inactive au niveau. 422 Unprocessable
Entity
Résultats Attendus
● Intégrité de la Base de Données : Une nouvelle entrée est créée dans la table
fee_configs avec les types de frais (enum: INSCRIPTION, SCOLARITE), le
montant exact en BigDecimal et la date d'échéance.
● Calcul Automatique des Soldes : Suite à l'enregistrement, le champ total_due
(total dû) dans les comptes financiers des élèves rattachés au niveau est mis à jour
dynamiquement via un événement interne.
● Exactitude des Réponses API : En cas de succès, le serveur renvoie l'objet créé
avec son ID technique et les métadonnées d'audit. En cas d'erreur, un objet JSON
standardisé détaille la cause du rejet (ex: "Montant invalide").
● Disponibilité pour le Module Paiement : Les données configurées sont
immédiatement exploitables par l'API de paiement pour valider que les versements
des élèves correspondent aux tarifs en vigueur.
Règles Métier
● Application Immédiate : L'enregistrement d'un frais déclenche un événement de
domaine (Domain Event) pour recalculer le solde (balance) de tous les élèves
inscrits dans le niveau concerné.
● Avertissement de Modification : En cas de PUT/PATCH, le service doit vérifier si
des enregistrements de la table Payment sont déjà liés à cette FeeConfig. Si oui,
le système autorise la modification mais génère un log d'audit spécifique
("Modification de frais avec paiements existants").
● Immuabilité Transactionnelle : Toutes les opérations (création de frais + mise à
jour des soldes élèves) doivent être encapsulées dans une transaction unique
(@Transactional).
● Habilitation (RBAC) : Seuls les tokens JWT contenant les rôles ADMIN ou
ACCOUNTANT sont autorisés à appeler les méthodes d'écriture.
Definition of Done (DoD)
● Validation de la contrainte d'unicité : Un test d'intégration confirme qu'il est
impossible d'insérer deux fois le type SCOLARITE pour le même niveau sur la même
année.
● Calcul de solde vérifié : Un test unitaire prouve qu'ajouter un frais de 50 000 XAF
augmente immédiatement le total_due des élèves rattachés de 50 000 XAF.
● Intégrité Transactionnelle : La création du frais et la mise à jour des soldes élèves
échouent ensemble si une erreur survient (Rollback @Transactional).
● Sécurité Keycloak : Un test de sécurité confirme que le rôle SECRETARY est rejeté
(403) lors d'une tentative de configuration.
● Audit Log financier : La table de logs contient l'ID de l'auteur et l'ancien montant en
cas de modification de la configuration.
● Contrat API (Swagger) : Les schémas de données pour FeeConfig sont à jour et
conformes aux types de la base PostgreSQL.