feat(sprint-10 api 2026-04-25): bump 1.0.8 + DTOs UBO/audit-trail/délégation + UpdateOrganisationRequest enrichi
Pré-requis pour exposer les features Sprints 1-2 via REST. Architecture stricte : DTOs en module api (contrat public), aucune logique métier. Version : 1.0.7 → 1.0.8 DTOs UBO (Instr. BCEAO 003-03-2025) - CreateBeneficiaireEffectifRequest : validation pays ISO-3, regex natureControle (5 valeurs), pourcentages 0-100 - UpdateBeneficiaireEffectifRequest : tous optionnels (PATCH partiel) - BeneficiaireEffectifResponse : vue read-only DTOs audit trail (Sprint 1) - AuditTrailOperationResponse : payloadAvant/payloadApres/metadata en String JSONB DTOs délégation rôles (Sprint 2) - CreateRoleDelegationRequest : regex rôle uppercase + dates futures - RoleDelegationResponse : statut + estActive (calculé) Enrich UpdateOrganisationRequest - referentielComptable (regex SYSCOHADA|SYCEBNL|PCSFD_UMOA) - complianceOfficerId UUID (Instr. BCEAO 001-03-2025) À publier sur Gitea via script/publish-api.sh — user action requise.
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>dev.lions.unionflow</groupId>
|
||||
<artifactId>unionflow-server-api</artifactId>
|
||||
<version>1.0.7</version>
|
||||
<version>1.0.8</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>UnionFlow Server API</name>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.lions.unionflow.server.api.dto.audit.response;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Vue d'une opération d'audit trail enrichi (Sprint 1, exposée Sprint 10).
|
||||
*
|
||||
* <p>Les payloads JSONB ({@code payloadAvant}, {@code payloadApres}, {@code metadata})
|
||||
* sont sérialisés en string ; le frontend les parse selon les besoins.
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10)
|
||||
*/
|
||||
@Builder
|
||||
public record AuditTrailOperationResponse(
|
||||
UUID id,
|
||||
UUID userId,
|
||||
String userEmail,
|
||||
String roleActif,
|
||||
UUID organisationActiveId,
|
||||
String actionType,
|
||||
String entityType,
|
||||
UUID entityId,
|
||||
String description,
|
||||
String ipAddress,
|
||||
String userAgent,
|
||||
UUID requestId,
|
||||
String payloadAvant,
|
||||
String payloadApres,
|
||||
String metadata,
|
||||
Boolean sodCheckPassed,
|
||||
String sodViolations,
|
||||
LocalDateTime operationAt
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package dev.lions.unionflow.server.api.dto.delegation.request;
|
||||
|
||||
import jakarta.validation.constraints.Future;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Requête de création d'une délégation de rôle temporaire.
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10 — service existant Sprint 2)
|
||||
*/
|
||||
@Builder
|
||||
public record CreateRoleDelegationRequest(
|
||||
@NotNull(message = "L'organisation est obligatoire")
|
||||
UUID organisationId,
|
||||
|
||||
@NotNull(message = "Le déléguant est obligatoire")
|
||||
UUID delegantUserId,
|
||||
|
||||
@NotNull(message = "Le délégataire est obligatoire")
|
||||
UUID delegataireUserId,
|
||||
|
||||
@NotBlank(message = "Le rôle délégué est obligatoire")
|
||||
@Pattern(regexp = "^[A-Z_]{3,50}$", message = "Format de rôle invalide (uppercase + underscore)")
|
||||
String roleDelegue,
|
||||
|
||||
@NotNull(message = "La date de début est obligatoire")
|
||||
LocalDateTime dateDebut,
|
||||
|
||||
@NotNull(message = "La date de fin est obligatoire")
|
||||
@Future(message = "La date de fin doit être future")
|
||||
LocalDateTime dateFin,
|
||||
|
||||
@Size(max = 500)
|
||||
String motif
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.lions.unionflow.server.api.dto.delegation.response;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Vue d'une délégation de rôle.
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10)
|
||||
*/
|
||||
@Builder
|
||||
public record RoleDelegationResponse(
|
||||
UUID id,
|
||||
UUID organisationId,
|
||||
UUID delegantUserId,
|
||||
UUID delegataireUserId,
|
||||
String roleDelegue,
|
||||
LocalDateTime dateDebut,
|
||||
LocalDateTime dateFin,
|
||||
String motif,
|
||||
String statut,
|
||||
LocalDateTime dateRevocation,
|
||||
LocalDateTime dateCreation,
|
||||
boolean estActive
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package dev.lions.unionflow.server.api.dto.kyc.request;
|
||||
|
||||
import dev.lions.unionflow.server.api.enums.membre.TypePieceIdentite;
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Création d'un Bénéficiaire Effectif (UBO) — Instruction BCEAO 003-03-2025.
|
||||
*
|
||||
* <p>Lié à un {@code KycDossier} d'entreprise. Au moins un identifiant cible est requis :
|
||||
* {@code kycDossierId} pour KYC personne morale, ou {@code organisationCibleId} +
|
||||
* {@code membreId} pour membre individuel à risque.
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10)
|
||||
*/
|
||||
@Builder
|
||||
public record CreateBeneficiaireEffectifRequest(
|
||||
UUID kycDossierId,
|
||||
UUID organisationCibleId,
|
||||
UUID membreId,
|
||||
|
||||
@NotBlank(message = "Le nom est obligatoire")
|
||||
@Size(max = 100)
|
||||
String nom,
|
||||
|
||||
@NotBlank(message = "Les prénoms sont obligatoires")
|
||||
@Size(max = 200)
|
||||
String prenoms,
|
||||
|
||||
@NotNull(message = "La date de naissance est obligatoire")
|
||||
LocalDate dateNaissance,
|
||||
|
||||
@Size(max = 200)
|
||||
String lieuNaissance,
|
||||
|
||||
@NotBlank(message = "La nationalité est obligatoire (ISO-3)")
|
||||
@Pattern(regexp = "^[A-Z]{3}$", message = "Code ISO-3 (ex: CIV, FRA)")
|
||||
String nationalite,
|
||||
|
||||
@Pattern(regexp = "^[A-Z]{3}$|^$", message = "Code ISO-3")
|
||||
String paysResidence,
|
||||
|
||||
TypePieceIdentite typePieceIdentite,
|
||||
|
||||
@Size(max = 50)
|
||||
String numeroPieceIdentite,
|
||||
|
||||
LocalDate dateExpirationPiece,
|
||||
|
||||
@DecimalMin(value = "0.00")
|
||||
@DecimalMax(value = "100.00")
|
||||
BigDecimal pourcentageCapital,
|
||||
|
||||
@DecimalMin(value = "0.00")
|
||||
@DecimalMax(value = "100.00")
|
||||
BigDecimal pourcentageDroitsVote,
|
||||
|
||||
@NotBlank(message = "La nature du contrôle est obligatoire")
|
||||
@Pattern(regexp = "^(DETENTION_CAPITAL|DROITS_VOTE|CONTROLE_DE_FAIT|BENEFICIAIRE_ULTIME|MANDAT_REPRESENTATION)$",
|
||||
message = "Nature du contrôle invalide")
|
||||
String natureControle,
|
||||
|
||||
Boolean estPep,
|
||||
@Size(max = 100) String pepCategorie,
|
||||
@Pattern(regexp = "^[A-Z]{3}$|^$") String pepPays,
|
||||
@Size(max = 200) String pepFonction,
|
||||
|
||||
Boolean presenceListesSanctions,
|
||||
@Size(max = 1000) String detailsListesSanctions
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package dev.lions.unionflow.server.api.dto.kyc.request;
|
||||
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Mise à jour partielle d'un Bénéficiaire Effectif (UBO).
|
||||
* Tous les champs sont optionnels — seul ce qui est fourni est mis à jour.
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10)
|
||||
*/
|
||||
@Builder
|
||||
public record UpdateBeneficiaireEffectifRequest(
|
||||
@Size(max = 100) String nom,
|
||||
@Size(max = 200) String prenoms,
|
||||
LocalDate dateNaissance,
|
||||
@Size(max = 200) String lieuNaissance,
|
||||
@Pattern(regexp = "^[A-Z]{3}$|^$") String nationalite,
|
||||
@Pattern(regexp = "^[A-Z]{3}$|^$") String paysResidence,
|
||||
|
||||
@DecimalMin("0.00") @DecimalMax("100.00") BigDecimal pourcentageCapital,
|
||||
@DecimalMin("0.00") @DecimalMax("100.00") BigDecimal pourcentageDroitsVote,
|
||||
|
||||
@Pattern(regexp = "^(DETENTION_CAPITAL|DROITS_VOTE|CONTROLE_DE_FAIT|BENEFICIAIRE_ULTIME|MANDAT_REPRESENTATION)?$")
|
||||
String natureControle,
|
||||
|
||||
Boolean estPep,
|
||||
@Size(max = 100) String pepCategorie,
|
||||
@Pattern(regexp = "^[A-Z]{3}$|^$") String pepPays,
|
||||
@Size(max = 200) String pepFonction,
|
||||
|
||||
Boolean presenceListesSanctions,
|
||||
@Size(max = 1000) String detailsListesSanctions
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.lions.unionflow.server.api.dto.kyc.response;
|
||||
|
||||
import dev.lions.unionflow.server.api.enums.membre.TypePieceIdentite;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
|
||||
/**
|
||||
* Vue d'un Bénéficiaire Effectif (UBO).
|
||||
*
|
||||
* @since 2026-04-25 (Sprint 10)
|
||||
*/
|
||||
@Builder
|
||||
public record BeneficiaireEffectifResponse(
|
||||
UUID id,
|
||||
UUID kycDossierId,
|
||||
UUID organisationCibleId,
|
||||
UUID membreId,
|
||||
String nom,
|
||||
String prenoms,
|
||||
LocalDate dateNaissance,
|
||||
String lieuNaissance,
|
||||
String nationalite,
|
||||
String paysResidence,
|
||||
TypePieceIdentite typePieceIdentite,
|
||||
String numeroPieceIdentite,
|
||||
LocalDate dateExpirationPiece,
|
||||
BigDecimal pourcentageCapital,
|
||||
BigDecimal pourcentageDroitsVote,
|
||||
String natureControle,
|
||||
boolean estPep,
|
||||
String pepCategorie,
|
||||
String pepPays,
|
||||
String pepFonction,
|
||||
boolean presenceListesSanctions,
|
||||
String detailsListesSanctions,
|
||||
LocalDateTime dateCreation,
|
||||
LocalDateTime dateModification,
|
||||
Boolean actif
|
||||
) {
|
||||
}
|
||||
@@ -2,9 +2,11 @@ package dev.lions.unionflow.server.api.dto.organisation.request;
|
||||
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@@ -51,5 +53,13 @@ public record UpdateOrganisationRequest(
|
||||
@Size(max = 100) String pays,
|
||||
@Size(max = 20) String codePostal,
|
||||
Boolean organisationPublique,
|
||||
Boolean accepteNouveauxMembres) {
|
||||
Boolean accepteNouveauxMembres,
|
||||
|
||||
/** Référentiel comptable applicable (Sprint 1) — SYSCOHADA / SYCEBNL / PCSFD_UMOA. */
|
||||
@Pattern(regexp = "^(SYSCOHADA|SYCEBNL|PCSFD_UMOA)?$",
|
||||
message = "Référentiel comptable invalide")
|
||||
String referentielComptable,
|
||||
|
||||
/** UUID du Compliance Officer désigné (Instr. BCEAO 001-03-2025). */
|
||||
UUID complianceOfficerId) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user