Story AB-016 : Déclaration de Maternité (Backend + Frontend)¶
Module : absence-management Tranche : VS-AB-009 de l'architecture Contexte de marque : [LES DEUX] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priorité : 16 Dépend de : AB-012 Peut se développer en parallèle avec : AB-014, AB-015 Ordre de fusion : Après AB-012 Complexité estimée : M PRD User Stories : US-ABS-004
Objectif¶
Permettre aux responsables RH et aux DG de créer des déclarations de maternité qui génèrent automatiquement un bloc de congé de 14 semaines : 6 semaines prénatales + 8 semaines postnatales (Art. 25.8 Code du Travail, 98 jours calendaires au total). Le congé est AUTO_APPROVED — aucune étape d'approbation manager n'est requise. Les congés annuels qui se chevauchent sont détectés et recrédités automatiquement via BalanceMutationService.
Périmètre Backend¶
Entités et Enregistrements¶
MaternityDeclaration (depuis AB-002) :
public class MaternityDeclaration {
private UUID id;
private UUID tenantId;
private UUID employeeId;
private LocalDate expectedDeliveryDate;
private LocalDate actualDeliveryDate; // nullable — renseigné via PATCH
private LocalDate startDate; // calculé : expectedDeliveryDate - 42 jours
private LocalDate endDate; // calculé : expectedDeliveryDate + 56 jours (ou actualDeliveryDate + 56 jours après mise à jour)
private UUID leaveRequestId; // FK vers le LeaveRequest créé automatiquement
private UUID supportingDocumentId; // attestation médicale — obligatoire
private Instant createdAt;
private Instant updatedAt;
}
LeaveRequest (status=AUTO_APPROVED, type=MATERNITY) — utilise l'entité existante d'AB-002.
Enregistrements de requête :
public record CreateMaternityDeclarationRequest(
@NotNull UUID employeeId,
@NotNull LocalDate expectedDeliveryDate,
@NotNull UUID supportingDocumentId // attestation médicale — blocage dur
) {}
public record UpdateMaternityDeclarationRequest(
@NotNull LocalDate actualDeliveryDate
) {}
Couche Repository¶
MaternityDeclarationRepository.java :
- save(MaternityDeclaration declaration) — insertion ou mise à jour
- findById(UUID id) — recherche d'une déclaration unique
- findByTenantIdAndEmployeeId(UUID tenantId, UUID employeeId) — toutes les déclarations d'un employé
- existsOverlapping(UUID tenantId, UUID employeeId, LocalDate startDate, LocalDate endDate) — vérifie le chevauchement avec des déclarations de maternité existantes
Couche Service¶
MaternityService.java :
createDeclaration(UUID employeeId, LocalDate expectedDeliveryDate, UUID supportingDocumentId):- Calculer la période :
startDate = expectedDeliveryDate - 42 jours,endDate = expectedDeliveryDate + 56 jours - Valider qu'il n'existe aucune déclaration de maternité chevauchante pour l'employé
- Créer un LeaveRequest avec
status=AUTO_APPROVED,type=MATERNITY - Détecter les congés annuels APPROVED qui se chevauchent avec la période de maternité
- Pour chaque chevauchement : recréditer les jours de congé annuel chevauchants via une entrée de grand livre
OVERLAP_CREDITen utilisant BalanceMutationService - Notifier l'employé + le manager (publier un événement de notification)
- Publier
LeaveApprovedavec{ leaveType=MATERNITY, isPaid=true, payRate=100 } -
Persister MaternityDeclaration et retourner la réponse
-
updateActualDeliveryDate(UUID declarationId, LocalDate actualDate): - Charger la déclaration existante
- Définir
actualDeliveryDate - Recalculer la période post-accouchement :
newEndDate = actualDate + 56 jours - La période pré-accouchement reste telle qu'initialement prise (FR-ABS-093)
- Mettre à jour la date de fin du LeaveRequest associé
- Réévaluer les crédits de chevauchement si la date de fin est étendue
- Publier un
LeaveApprovedmis à jour
Points de terminaison API¶
| Méthode | Chemin | Corps de la requête | Réponse | Auth |
|---|---|---|---|---|
| POST | /api/v1/absence/maternity-declarations |
CreateMaternityDeclarationRequest |
ApiResponse<MaternityDeclarationResponse> (201) |
HR_MANAGER, DG |
| PATCH | /api/v1/absence/maternity-declarations/:id |
UpdateMaternityDeclarationRequest |
ApiResponse<MaternityDeclarationResponse> |
HR_MANAGER, DG |
Règles de validation¶
- L'employé doit être ACTIVE (validé via la recherche dans le service employé)
expectedDeliveryDatedoit être dans le futur — 422"La date presumee d'accouchement doit etre dans le futur."supportingDocumentId(attestation médicale) est obligatoire — 422"L'attestation medicale est obligatoire."- Impossible de créer des déclarations de maternité chevauchantes pour le même employé — 409
"Une declaration de maternite existe deja pour cette periode." actualDeliveryDatesur PATCH doit être une date valide (passée ou aujourd'hui) — 422"La date d'accouchement doit etre dans le passe ou aujourd'hui."- La vérification du genre n'est PAS appliquée par le système (conception inclusive)
Considérations Multi-Tenant¶
- Toutes les requêtes incluent
tenantIddepuisScopedValue<TenantContext> - La table MaternityDeclaration possède une colonne
tenant_id - La détection de chevauchement est limitée au tenant + employé
- Fonctionne avec les 4 profils de base de données (conçu pour BYO-DB en priorité)
Périmètre Frontend¶
RAPPEL SYNCHRONISATION HORS LIGNE (Papillon — CRITIQUE) : La déclaration de maternité est une action en ligne uniquement — elle nécessite un accès RH/DG et le téléversement d'un document. Le formulaire est bloqué hors connexion avec un message clair.
Pages et Routes¶
| Route | Page | Description |
|---|---|---|
/absences/maternite/nouvelle |
MaternityDeclarationPage | Formulaire de déclaration de maternité réservé aux RH/DG |
Composants¶
InfoBanner— Bandeau d'information (bg=info-light) expliquant les droits à la maternitéFormField+Select(recherchable) — Recherche d'employéFormField+DatePicker— Date présumée d'accouchement (DPA)MaternityPeriodSummary— Carte de résumé auto-calculé (bg=primary-subtle) affichant le début, la fin et la duréeOverlapNotice— Texte d'information orange pour le recrédit de congé annuel chevauchantFileUpload— Zone de téléversement de l'attestation médicale (obligatoire)Button— Bouton d'envoi (primary, lg, fullWidth)HelperText— Texte d'aide sous le bouton d'envoi
États UI (TOUS REQUIS)¶
| État | Comportement | Copie Française |
|---|---|---|
| Chargement | Squelette pour le select employé | — |
| Vide | N/A (formulaire toujours disponible) | — |
| Erreur (validation) | Erreurs inline sur les champs | Divers messages de validation |
| Erreur (API) | Toast | "Impossible d'enregistrer la declaration." |
| Hors ligne | Formulaire bloqué (action en ligne uniquement) | "Cette action necessite une connexion internet" |
| Succès | Animation confetti + Toast + navigation retour | "Declaration enregistree — conge cree automatiquement" |
Comportement Responsive¶
Mobile (360px — Papillon en priorité) : - Mise en page formulaire plein écran, colonne unique - Bandeau d'information en haut (bg=info-light) : "La maternite est un droit legal. Ce formulaire cree automatiquement un conge de 14 semaines." - FormField + Select (recherchable) pour l'employé : placeholder "Rechercher une employee..." - FormField + DatePicker pour la DPA : label "Date presumee d'accouchement" - Carte de résumé auto-calculé (bg=primary-subtle) : "Debut : {date} (DPA - 42 jours) / Fin : {date} (DPA + 56 jours) / Duree : 14 semaines (98 jours)" - Si chevauchement détecté : texte d'information orange : "{n} jours de conge annuel approuve seront recredites automatiquement." - Zone FileUpload : label "Attestation medicale" (obligatoire) - Bouton d'envoi : "Enregistrer la declaration" (primary, lg, fullWidth) - Aide : "L'employee et son manager seront notifies automatiquement." - Toutes les cibles tactiles >= 48px
Desktop (1024px+ — Enterprise en priorité) : - Modal ou panneau latéral, même flux de formulaire, max-width 600px - Espacement plus compact, même ordre de composants
Interactions¶
- Recherche d'employé : recherche prédictive avec debounce (300ms), affiche le nom + matricule de l'employé
- Sélection de la DPA : quand la date est sélectionnée, MaternityPeriodSummary calcule et s'affiche automatiquement
- Détection de chevauchement : le client vérifie si un avertissement de chevauchement est nécessaire (l'API fournit le nombre de chevauchements lors du changement de DPA)
- FileUpload : appuyer pour ouvrir le sélecteur de fichiers (mobile), glisser-déposer également supporté (desktop)
- Envoi : valide tous les champs obligatoires côté client, puis POST vers l'API
- Succès : animation confetti (200ms), toast, navigation vers
/absences
Micro-Copie Française¶
maternity.info: "La maternite est un droit legal. Ce formulaire cree automatiquement un conge de 14 semaines."maternity.employee: "Employee"maternity.search: "Rechercher une employee..."maternity.dpa: "Date presumee d'accouchement"maternity.summary: "Resume du conge"maternity.start: "Debut : {date} (DPA - 42 jours)"maternity.end: "Fin : {date} (DPA + 56 jours)"maternity.duration: "Duree : 14 semaines (98 jours)"maternity.overlap: "{n} jours de conge annuel approuve seront recredites automatiquement."maternity.attestation: "Attestation medicale"maternity.submit: "Enregistrer la declaration"maternity.notify: "L'employee et son manager seront notifies automatiquement."maternity.error.future_date: "La date presumee d'accouchement doit etre dans le futur."maternity.error.attestation_required: "L'attestation medicale est obligatoire."maternity.error.overlap: "Une declaration de maternite existe deja pour cette periode."maternity.error.save: "Impossible d'enregistrer la declaration."maternity.offline: "Cette action necessite une connexion internet"maternity.success: "Declaration enregistree — conge cree automatiquement"
Critères d'Acceptation¶
AC-051 : La maternité crée automatiquement un bloc de congé de 14 semaines
Étant donné que je saisis une date présumée d'accouchement
Quand j'enregistre la déclaration de maternité
Alors le système crée un bloc de congé de 14 semaines (6 semaines avant l'accouchement prévu + 8 semaines après)
AC-052 : Le congé maternité est auto-approuvé
Étant donné qu'un congé maternité est créé
Quand je le consulte
Alors il affiche le statut AUTO_APPROVED — aucune étape d'approbation manager n'est requise
AC-053 : Les jours de congé annuel chevauchants sont recrédités
Étant donné que l'employée a d'autres congés approuvés qui chevauchent la période de maternité
Quand la maternité est créée
Alors les jours de congé annuel chevauchants sont recrédités sur le solde de l'employée
Règles OHADA et Réglementaires¶
- FR-ABS-090 : Maternité = 14 semaines (6 avant + 8 après l'accouchement)
- FR-ABS-091 : Le RH saisit la date présumée d'accouchement ; le système calcule automatiquement la période de congé
- FR-ABS-092 : Calcul automatique et création automatique avec résolution des chevauchements
- FR-ABS-093 : La mise à jour de la date d'accouchement réelle recalcule uniquement la période post-accouchement — la période pré-accouchement reste telle qu'initialement prise
- FR-ABS-094 : L'employeur paie 100%, demande le remboursement CNPS (TV-ABS-01)
- FR-ABS-095 : L'employée est protégée contre le licenciement pendant toute la période de maternité
Standards et Conventions¶
docs/standards/java-spring-guidelines.md— §Patterns REST controller, §Application Events, §Patterns couche servicedocs/standards/database-guidelines.md— §Pattern repository multi-tenant, §Isolation tenant dans chaque requêtedocs/standards/api-guidelines.md— §Patterns endpoints POST/PATCH, §Enveloppe ApiResponse, §201 Created, §Erreurs de validation 422docs/standards/react-typescript-guidelines.md— §Patterns de composants, §CSS Modules, §i18n, §Patterns de formulairesdocs/standards/design-system.md— §Select (recherchable), §DatePicker, §FileUpload, §Button, §Card, §InfoBannerdocs/standards/offline-sync-guidelines.md— §Actions en ligne uniquement, §Pattern de blocage hors lignedocs/standards/multi-datasource-patterns.md— §Requêtes repository limitées au tenant
Exigences de Test¶
Tests Unitaires¶
MaternityService.createDeclaration(): entrée valide → crée un LeaveRequest avec AUTO_APPROVED + MaternityDeclarationMaternityService.createDeclaration(): calcule start = DPA - 42 jours, end = DPA + 56 joursMaternityService.createDeclaration(): congé annuel approuvé chevauchant (5 jours) → 5 entrées de grand livre OVERLAP_CREDITMaternityService.createDeclaration(): aucun congé annuel chevauchant → aucune entrée de recréditMaternityService.createDeclaration(): une déclaration de maternité chevauchante existe → 409MaternityService.createDeclaration(): expectedDeliveryDate dans le passé → 422MaternityService.createDeclaration(): supportingDocumentId manquant → 422MaternityService.updateActualDeliveryDate(): recalcule end = actualDate + 56 jours, start inchangéMaternityService.updateActualDeliveryDate(): date de fin étendue déclenche la réévaluation des crédits de chevauchement
Tests d'Intégration¶
- POST déclaration de maternité valide → 201, LeaveRequest créé avec AUTO_APPROVED
- POST avec expectedDeliveryDate dans le passé → 422
- POST sans supportingDocumentId → 422
- POST avec une déclaration chevauchante existante → 409
- PATCH avec actualDeliveryDate → 200, date de fin recalculée
- Multi-tenant : la déclaration du tenant A n'affecte pas le tenant B
Ce que QA Validera¶
- Le formulaire s'affiche à 360px avec le bandeau d'information, la recherche d'employé, le sélecteur de date, le téléversement de fichier
- La sélection de la DPA déclenche le calcul automatique du résumé de période
- L'avis de chevauchement apparaît le cas échéant
- Envoi avec données valides → confetti + toast + navigation
- Envoi sans attestation → erreur inline
- Hors ligne → formulaire bloqué avec "Cette action necessite une connexion internet"
- Desktop : mise en page modal/panneau, max-width 600px
Hors Périmètre¶
- Suivi du remboursement CNPS (processus comptable)
- Application de la protection contre le licenciement (module Gestion des Employés)
- Flux de congé paternité (utilise le flux de demande standard avec pré-remplissage de 2 jours via AB-010)
- Extension de maternité pour complications médicales (V2)
- Suivi de la réduction d'heures pour allaitement (V2)
Définition de Done¶
- [ ] Tous les endpoints backend implémentés et retournant les réponses correctes
- [ ] Toutes les pages frontend s'affichent correctement à 360px, 768px, 1024px
- [ ] Les 5 états UI implémentés (chargement, vide, erreur, hors ligne, succès)
- [ ] La micro-copie française correspond exactement à la spécification design
- [ ] Tous les critères d'acceptation passent manuellement
- [ ] Tests unitaires écrits et passants
- [ ] Tests d'intégration écrits et passants
- [ ] Isolation multi-tenant vérifiée — déclarations limitées au tenant, vérification des chevauchements par tenant+employé
- [ ] Comportement hors ligne vérifié — formulaire bloqué avec message (Papillon) / N/A (Enterprise)
- [ ] Pas de
anyTypeScript - [ ] Pas de types bruts Java — tous les génériques explicites
- [ ] Les réponses API suivent le format d'enveloppe standard
- [ ] Entrées de piste d'audit pour chaque mutation de données — LeaveApproved publié avec leaveType=MATERNITY