Sync: code local unifié

Synchronisation du code source local (fait foi).

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 16:25:40 +00:00
parent e82dc356f3
commit 75a19988b0
730 changed files with 53599 additions and 13145 deletions

View File

@@ -1,10 +1,13 @@
package dev.lions.unionflow.server.resource;
import dev.lions.unionflow.server.api.dto.organisation.OrganisationDTO;
import dev.lions.unionflow.server.api.dto.organisation.request.CreateOrganisationRequest;
import dev.lions.unionflow.server.api.dto.organisation.request.UpdateOrganisationRequest;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.service.KeycloakService;
import dev.lions.unionflow.server.service.OrganisationService;
import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
@@ -37,7 +40,7 @@ import org.jboss.logging.Logger;
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Organisations", description = "Gestion des organisations")
@RolesAllowed({"ADMIN", "MEMBRE", "USER"})
@RolesAllowed({"SUPER_ADMIN", "ADMIN", "ADMIN_ORGANISATION", "MEMBRE", "USER"})
public class OrganisationResource {
private static final Logger LOG = Logger.getLogger(OrganisationResource.class);
@@ -46,6 +49,39 @@ public class OrganisationResource {
@Inject KeycloakService keycloakService;
@Inject SecurityIdentity securityIdentity;
/** Récupère les organisations du membre connecté (pour admin d'organisation) */
@GET
@Path("/mes")
@Authenticated
@Operation(
summary = "Mes organisations",
description = "Liste les organisations auxquelles le membre connecté appartient (pour ADMIN_ORGANISATION)")
@APIResponses({
@APIResponse(
responseCode = "200",
description = "Liste des organisations du membre",
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(type = SchemaType.ARRAY, implementation = OrganisationResponse.class)))
})
public Response listerMesOrganisations() {
String email = securityIdentity.getPrincipal() != null
? securityIdentity.getPrincipal().getName()
: null;
if (email == null || email.isBlank()) {
return Response.ok(List.of()).build();
}
List<Organisation> organisations = organisationService.listerOrganisationsPourUtilisateur(email);
List<OrganisationResponse> dtos = organisations.stream()
.map(organisationService::convertToResponse)
.collect(Collectors.toList());
LOG.infof("Mes organisations pour %s: %d", email, dtos.size());
return Response.ok(dtos).build();
}
/** Crée une nouvelle organisation */
@POST
@RolesAllowed({"ADMIN", "MEMBRE"})
@@ -60,19 +96,19 @@ public class OrganisationResource {
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(implementation = OrganisationDTO.class))),
schema = @Schema(implementation = OrganisationResponse.class))),
@APIResponse(responseCode = "400", description = "Données invalides"),
@APIResponse(responseCode = "409", description = "Organisation déjà existante"),
@APIResponse(responseCode = "401", description = "Non authentifié"),
@APIResponse(responseCode = "403", description = "Non autorisé")
})
public Response creerOrganisation(@Valid OrganisationDTO organisationDTO) {
LOG.infof("Création d'une nouvelle organisation: %s", organisationDTO.getNom());
public Response creerOrganisation(@Valid CreateOrganisationRequest request) {
LOG.infof("Création d'une nouvelle organisation: %s", request.nom());
try {
Organisation organisation = organisationService.convertFromDTO(organisationDTO);
Organisation organisationCreee = organisationService.creerOrganisation(organisation);
OrganisationDTO dto = organisationService.convertToDTO(organisationCreee);
Organisation organisation = organisationService.convertFromCreateRequest(request);
Organisation organisationCreee = organisationService.creerOrganisation(organisation, "system");
OrganisationResponse dto = organisationService.convertToResponse(organisationCreee);
return Response.created(URI.create("/api/organisations/" + organisationCreee.getId()))
.entity(dto)
@@ -103,7 +139,7 @@ public class OrganisationResource {
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(type = SchemaType.ARRAY, implementation = OrganisationDTO.class))),
schema = @Schema(type = SchemaType.ARRAY, implementation = OrganisationResponse.class))),
@APIResponse(responseCode = "401", description = "Non authentifié"),
@APIResponse(responseCode = "403", description = "Non autorisé")
})
@@ -126,15 +162,35 @@ public class OrganisationResource {
try {
List<Organisation> organisations;
if (recherche != null && !recherche.trim().isEmpty()) {
// Admin d'organisation (sans rôle ADMIN/SUPER_ADMIN) : ne retourner que ses organisations
java.util.Set<String> roles = securityIdentity.getRoles() != null ? securityIdentity.getRoles() : java.util.Set.of();
boolean onlyOrgAdmin = roles.contains("ADMIN_ORGANISATION")
&& !roles.contains("ADMIN")
&& !roles.contains("SUPER_ADMIN");
if (onlyOrgAdmin && securityIdentity.getPrincipal() != null) {
String email = securityIdentity.getPrincipal().getName();
organisations = organisationService.listerOrganisationsPourUtilisateur(email);
if (recherche != null && !recherche.trim().isEmpty()) {
String term = recherche.trim().toLowerCase();
organisations = organisations.stream()
.filter(o -> (o.getNom() != null && o.getNom().toLowerCase().contains(term))
|| (o.getNomCourt() != null && o.getNomCourt().toLowerCase().contains(term)))
.collect(Collectors.toList());
}
// Pagination en mémoire pour /mes
int from = Math.min(page * size, organisations.size());
int to = Math.min(from + size, organisations.size());
organisations = organisations.subList(from, to);
LOG.infof("ADMIN_ORGANISATION: retour de %d organisation(s) pour %s", organisations.size(), email);
} else if (recherche != null && !recherche.trim().isEmpty()) {
organisations = organisationService.rechercherOrganisations(recherche.trim(), page, size);
} else {
organisations = organisationService.listerOrganisationsActives(page, size);
}
List<OrganisationDTO> dtos =
List<OrganisationResponse> dtos =
organisations.stream()
.map(organisationService::convertToDTO)
.map(organisationService::convertToResponse)
.collect(Collectors.toList());
return Response.ok(dtos).build();
@@ -160,7 +216,7 @@ public class OrganisationResource {
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(implementation = OrganisationDTO.class))),
schema = @Schema(implementation = OrganisationResponse.class))),
@APIResponse(responseCode = "404", description = "Organisation non trouvée"),
@APIResponse(responseCode = "401", description = "Non authentifié"),
@APIResponse(responseCode = "403", description = "Non autorisé")
@@ -174,7 +230,7 @@ public class OrganisationResource {
.trouverParId(id)
.map(
organisation -> {
OrganisationDTO dto = organisationService.convertToDTO(organisation);
OrganisationResponse dto = organisationService.convertToResponse(organisation);
return Response.ok(dto).build();
})
.orElse(
@@ -198,7 +254,7 @@ public class OrganisationResource {
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(implementation = OrganisationDTO.class))),
schema = @Schema(implementation = OrganisationResponse.class))),
@APIResponse(responseCode = "400", description = "Données invalides"),
@APIResponse(responseCode = "404", description = "Organisation non trouvée"),
@APIResponse(responseCode = "409", description = "Conflit de données"),
@@ -207,15 +263,15 @@ public class OrganisationResource {
})
public Response mettreAJourOrganisation(
@Parameter(description = "UUID de l'organisation", required = true) @PathParam("id") UUID id,
@Valid OrganisationDTO organisationDTO) {
@Valid UpdateOrganisationRequest request) {
LOG.infof("Mise à jour de l'organisation ID: %s", id);
try {
Organisation organisationMiseAJour = organisationService.convertFromDTO(organisationDTO);
Organisation organisationMiseAJour = organisationService.convertFromUpdateRequest(request);
Organisation organisation =
organisationService.mettreAJourOrganisation(id, organisationMiseAJour, "system");
OrganisationDTO dto = organisationService.convertToDTO(organisation);
OrganisationResponse dto = organisationService.convertToResponse(organisation);
return Response.ok(dto).build();
} catch (NotFoundException e) {
@@ -289,7 +345,7 @@ public class OrganisationResource {
content =
@Content(
mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(type = SchemaType.ARRAY, implementation = OrganisationDTO.class))),
schema = @Schema(type = SchemaType.ARRAY, implementation = OrganisationResponse.class))),
@APIResponse(responseCode = "401", description = "Non authentifié"),
@APIResponse(responseCode = "403", description = "Non autorisé")
})
@@ -311,9 +367,9 @@ public class OrganisationResource {
organisationService.rechercheAvancee(
nom, typeOrganisation, statut, ville, region, pays, page, size);
List<OrganisationDTO> dtos =
List<OrganisationResponse> dtos =
organisations.stream()
.map(organisationService::convertToDTO)
.map(organisationService::convertToResponse)
.collect(Collectors.toList());
return Response.ok(dtos).build();
@@ -346,7 +402,7 @@ public class OrganisationResource {
try {
Organisation organisation = organisationService.activerOrganisation(id, "system");
OrganisationDTO dto = organisationService.convertToDTO(organisation);
OrganisationResponse dto = organisationService.convertToResponse(organisation);
return Response.ok(dto).build();
} catch (NotFoundException e) {
return Response.status(Response.Status.NOT_FOUND)
@@ -381,7 +437,7 @@ public class OrganisationResource {
try {
Organisation organisation = organisationService.suspendreOrganisation(id, "system");
OrganisationDTO dto = organisationService.convertToDTO(organisation);
OrganisationResponse dto = organisationService.convertToResponse(organisation);
return Response.ok(dto).build();
} catch (NotFoundException e) {
return Response.status(Response.Status.NOT_FOUND)