feat(v3.0): implémentation Phases 0-8 — RBAC, lifecycle, multi-org, plans, dashboards

Phase 0 : @RolesAllowed SUPER_ADMIN sur POST/DELETE organisations ; AuthenticationFilter pages super-admin
Phase 2 : OrganisationModuleService, @RequiresModule, ModuleAccessFilter, RoleService, PermissionChecker
Phase 3 : multi-org context switching (OrganisationContextFilter, headers X-Active-Organisation-Id / X-Active-Role)
Phase 4 : feature-gating navigation par typeOrganisation (web MenuBean + mobile MorePage)
Phase 5 : MemberLifecycleService — 8 transitions (activer/suspendre/radier/archiver/inviter/accepter/expirer/rappels)
Phase 6 : FormuleAbonnement Option C (planCommercial, apiAccess, federationAccess, quotas) + SouscriptionOrganisation méthodes quota
Phase 7 : DashboardResource SUPER_ADMIN ajouté ; DashboardBean.checkAccessAndRedirect() ; dashboards distincts par rôle
Phase 8 : MembreResourceLifecycleRbacTest, SouscriptionQuotaOptionCTest, OrganisationContextHolderTest, OrganisationContextFilterMultiOrgTest, MemberLifecycleServiceTest
This commit is contained in:
dahoud
2026-04-06 16:49:47 +00:00
parent 39e98a9cb3
commit aef5548e87
34 changed files with 823 additions and 86 deletions

View File

@@ -5,6 +5,7 @@ import dev.lions.unionflow.server.api.dto.mutuelle.credit.DemandeCreditResponse;
import dev.lions.unionflow.server.api.enums.mutuelle.credit.StatutDemandeCredit;
import dev.lions.unionflow.server.service.mutuelle.credit.DemandeCreditService;
import dev.lions.unionflow.server.security.RequiresModule;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
@@ -20,13 +21,14 @@ import java.util.UUID;
@Path("/api/v1/mutuelle/credits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RequiresModule("CREDIT")
public class DemandeCreditResource {
@Inject
DemandeCreditService demandeCreditService;
@POST
@RolesAllowed({ "membre_actif" })
@RolesAllowed({ "MEMBRE", "USER" })
public Response soumettreDemande(@Valid DemandeCreditRequest request) {
DemandeCreditResponse response = demandeCreditService.soumettreDemande(request);
return Response.status(Response.Status.CREATED).entity(response).build();
@@ -34,7 +36,7 @@ public class DemandeCreditResource {
@GET
@Path("/{id}")
@RolesAllowed({ "admin", "admin_organisation", "mutuelle_resp", "membre_actif" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getDemandeById(@PathParam("id") UUID id) {
DemandeCreditResponse response = demandeCreditService.getDemandeById(id);
return Response.ok(response).build();
@@ -42,7 +44,7 @@ public class DemandeCreditResource {
@GET
@Path("/membre/{membreId}")
@RolesAllowed({ "admin", "admin_organisation", "mutuelle_resp", "membre_actif" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getDemandesByMembre(@PathParam("membreId") UUID membreId) {
List<DemandeCreditResponse> response = demandeCreditService.getDemandesByMembre(membreId);
return Response.ok(response).build();
@@ -50,7 +52,7 @@ public class DemandeCreditResource {
@PATCH
@Path("/{id}/statut")
@RolesAllowed({ "admin", "admin_organisation", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response changerStatut(
@PathParam("id") UUID id,
@QueryParam("statut") StatutDemandeCredit statut,
@@ -64,7 +66,7 @@ public class DemandeCreditResource {
@POST
@Path("/{id}/approbation")
@RolesAllowed({ "admin", "admin_organisation", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response approuver(
@PathParam("id") UUID id,
@QueryParam("montant") BigDecimal montant,
@@ -77,7 +79,7 @@ public class DemandeCreditResource {
@POST
@Path("/{id}/decaissement")
@RolesAllowed({ "admin", "admin_organisation", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response decaisser(
@PathParam("id") UUID id,
@QueryParam("datePremiereEcheance") String datePremiereEcheance) {

View File

@@ -5,6 +5,7 @@ import dev.lions.unionflow.server.api.dto.mutuelle.epargne.CompteEpargneResponse
import dev.lions.unionflow.server.api.enums.mutuelle.epargne.StatutCompteEpargne;
import dev.lions.unionflow.server.service.mutuelle.epargne.CompteEpargneService;
import dev.lions.unionflow.server.security.RequiresModule;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
@@ -18,13 +19,14 @@ import java.util.UUID;
@Path("/api/v1/epargne/comptes")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RequiresModule("EPARGNE")
public class CompteEpargneResource {
@Inject
CompteEpargneService compteEpargneService;
@POST
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response creerCompte(@Valid CompteEpargneRequest request) {
CompteEpargneResponse compte = compteEpargneService.creerCompte(request);
return Response.status(Response.Status.CREATED).entity(compte).build();
@@ -32,7 +34,7 @@ public class CompteEpargneResource {
@GET
@Path("/{id}")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "membre_actif", "MEMBRE", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getCompteById(@PathParam("id") UUID id) {
CompteEpargneResponse compte = compteEpargneService.getCompteById(id);
return Response.ok(compte).build();
@@ -40,7 +42,7 @@ public class CompteEpargneResource {
@GET
@Path("/mes-comptes")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "membre_actif", "MEMBRE", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getMesComptes() {
List<CompteEpargneResponse> comptes = compteEpargneService.getMesComptes();
return Response.ok(comptes).build();
@@ -48,7 +50,7 @@ public class CompteEpargneResource {
@GET
@Path("/membre/{membreId}")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "membre_actif", "MEMBRE", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getComptesByMembre(@PathParam("membreId") UUID membreId) {
List<CompteEpargneResponse> comptes = compteEpargneService.getComptesByMembre(membreId);
return Response.ok(comptes).build();
@@ -56,7 +58,7 @@ public class CompteEpargneResource {
@GET
@Path("/organisation/{organisationId}")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response getComptesByOrganisation(@PathParam("organisationId") UUID organisationId) {
List<CompteEpargneResponse> comptes = compteEpargneService.getComptesByOrganisation(organisationId);
return Response.ok(comptes).build();
@@ -64,7 +66,7 @@ public class CompteEpargneResource {
@PATCH
@Path("/{id}/statut")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP" })
public Response changerStatut(@PathParam("id") UUID id, @QueryParam("statut") StatutCompteEpargne statut) {
if (statut == null) {
return Response.status(Response.Status.BAD_REQUEST).entity("Le statut est requis").build();

View File

@@ -4,6 +4,7 @@ import dev.lions.unionflow.server.api.dto.mutuelle.epargne.TransactionEpargneReq
import dev.lions.unionflow.server.api.dto.mutuelle.epargne.TransactionEpargneResponse;
import dev.lions.unionflow.server.service.mutuelle.epargne.TransactionEpargneService;
import dev.lions.unionflow.server.security.RequiresModule;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
@@ -17,13 +18,14 @@ import java.util.UUID;
@Path("/api/v1/epargne/transactions")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RequiresModule("EPARGNE")
public class TransactionEpargneResource {
@Inject
TransactionEpargneService transactionEpargneService;
@POST
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "MEMBRE", "MEMBRE_ACTIF", "membre_actif", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response executerTransaction(@Valid TransactionEpargneRequest request) {
TransactionEpargneResponse transaction = transactionEpargneService.executerTransaction(request);
return Response.status(Response.Status.CREATED).entity(transaction).build();
@@ -31,7 +33,7 @@ public class TransactionEpargneResource {
@POST
@Path("/transfert")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "membre_actif", "MEMBRE_ACTIF", "MEMBRE", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response transferer(@Valid TransactionEpargneRequest request) {
TransactionEpargneResponse transaction = transactionEpargneService.transferer(request);
return Response.status(Response.Status.CREATED).entity(transaction).build();
@@ -39,7 +41,7 @@ public class TransactionEpargneResource {
@GET
@Path("/compte/{compteId}")
@RolesAllowed({ "admin", "admin_organisation", "ADMIN", "ADMIN_ORGANISATION", "mutuelle_resp", "membre_actif", "MEMBRE_ACTIF", "MEMBRE", "USER" })
@RolesAllowed({ "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION", "MUTUELLE_RESP", "MEMBRE", "USER" })
public Response getTransactionsByCompte(@PathParam("compteId") UUID compteId) {
List<TransactionEpargneResponse> transactions = transactionEpargneService.getTransactionsByCompte(compteId);
return Response.ok(transactions).build();