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>
|
<groupId>dev.lions.unionflow</groupId>
|
||||||
<artifactId>unionflow-server-api</artifactId>
|
<artifactId>unionflow-server-api</artifactId>
|
||||||
<version>1.0.7</version>
|
<version>1.0.8</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>UnionFlow Server API</name>
|
<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.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
|
||||||
@@ -51,5 +53,13 @@ public record UpdateOrganisationRequest(
|
|||||||
@Size(max = 100) String pays,
|
@Size(max = 100) String pays,
|
||||||
@Size(max = 20) String codePostal,
|
@Size(max = 20) String codePostal,
|
||||||
Boolean organisationPublique,
|
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