Files
unionflow-client-quarkus-pr…/src/main/java/dev/lions/unionflow/client/service/MembreService.java
dahoud ac0c5a67a1 fix(frontend): corrections workflow v3.0 — inscription événements, CreateMembreRequest, AJAX session expiry
Services:
- EvenementService: POST /inscriptions (sans membreId), DELETE /inscriptions, GET /recherche, GET /type/{type}
- MembreService: creer() accepte CreateMembreRequest au lieu de MembreResponse
- Nouveaux services: BackupService, EpargneService, FinanceApprovalService, LogsService, MessageService, OrganisationService, PaiementClientService

Beans:
- MembreInscriptionBean: construit CreateMembreRequest.builder() avec organisationId UUID
- EvenementsBean: inscrireParticipant(id) sans userId (backend infère depuis token)
- DashboardBean: checkAccessAndRedirect() SUPER_ADMIN en premier

Sécurité:
- AuthenticationFilter: gestion AJAX PrimeFaces (partial/ajax → XML partial-response redirect)
- PermissionChecker: vérification rôles côté bean
- k8s/: manifestes secrets SMTP et Wave (placeholders à remplir)

Pages XHTML: dashboards rôles, cotisations, membres, événements, organisations
2026-04-07 20:54:20 +00:00

381 lines
13 KiB
Java

package dev.lions.unionflow.client.service;
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
import dev.lions.unionflow.server.api.dto.membre.request.CreateMembreRequest;
import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse;
import dev.lions.unionflow.server.api.dto.membre.response.MembreSummaryResponse;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
import java.util.UUID;
@RegisterRestClient(configKey = "unionflow-api")
@RegisterClientHeaders(dev.lions.unionflow.client.security.AuthHeaderFactory.class)
@Path("/api/membres")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface MembreService {
@GET
PagedResponse<MembreSummaryResponse> listerTous(
@QueryParam("page") @DefaultValue("0") int page,
@QueryParam("size") @DefaultValue("20") int size);
/** Surcharge sans pagination — retourne jusqu'à 1000 membres (usage hors DataTable). */
default PagedResponse<MembreSummaryResponse> listerTous() {
return listerTous(0, 1000);
}
@GET
@Path("/{id}")
MembreResponse obtenirParId(@PathParam("id") UUID id);
@GET
@Path("/numero/{numeroMembre}")
MembreResponse obtenirParNumero(@PathParam("numeroMembre") String numeroMembre);
@GET
@Path("/me")
MembreResponse obtenirMembreConnecte();
@GET
@Path("/search")
List<MembreResponse> rechercher(
@QueryParam("nom") String nom,
@QueryParam("prenom") String prenom,
@QueryParam("email") String email,
@QueryParam("telephone") String telephone,
@QueryParam("statut") String statut,
@QueryParam("associationId") UUID associationId,
@QueryParam("page") @DefaultValue("0") int page,
@QueryParam("size") @DefaultValue("20") int size);
@POST
@Path("/search/advanced")
dev.lions.unionflow.server.api.dto.membre.MembreSearchResultDTO rechercherAvance(
dev.lions.unionflow.server.api.dto.membre.MembreSearchCriteria criteria,
@QueryParam("page") @DefaultValue("0") int page,
@QueryParam("size") @DefaultValue("20") int size,
@QueryParam("sort") @DefaultValue("nom") String sortField,
@QueryParam("direction") @DefaultValue("asc") String sortDirection);
@GET
@Path("/organisation/{organisationId}")
List<MembreResponse> listerParOrganisation(@PathParam("organisationId") UUID organisationId);
@GET
@Path("/actifs")
List<MembreResponse> listerActifs();
@GET
@Path("/inactifs")
List<MembreResponse> listerInactifs();
@POST
MembreResponse creer(CreateMembreRequest membre);
@PUT
@Path("/{id}")
MembreResponse modifier(@PathParam("id") UUID id, MembreResponse membre);
@DELETE
@Path("/{id}")
void supprimer(@PathParam("id") UUID id);
@PUT
@Path("/{id}/activer")
MembreResponse activer(@PathParam("id") UUID id);
@PUT
@Path("/{id}/desactiver")
MembreResponse desactiver(@PathParam("id") UUID id);
@PUT
@Path("/{id}/suspendre")
MembreResponse suspendre(@PathParam("id") UUID id);
@PUT
@Path("/{id}/radier")
MembreResponse radier(@PathParam("id") UUID id);
@GET
@Path("/stats")
StatistiquesMembreDTO obtenirStatistiques();
@GET
@Path("/export")
@Produces({ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "text/csv", "application/pdf",
"application/json" })
byte[] exporterExcel(
@QueryParam("format") @DefaultValue("EXCEL") String format,
@QueryParam("associationId") UUID associationId,
@QueryParam("statut") String statut,
@QueryParam("type") String type,
@QueryParam("dateAdhesionDebut") String dateAdhesionDebut,
@QueryParam("dateAdhesionFin") String dateAdhesionFin,
@QueryParam("colonnes") List<String> colonnesExport,
@QueryParam("inclureHeaders") @DefaultValue("true") boolean inclureHeaders,
@QueryParam("formaterDates") @DefaultValue("true") boolean formaterDates,
@QueryParam("inclureStatistiques") @DefaultValue("false") boolean inclureStatistiques,
@QueryParam("motDePasse") String motDePasse);
@GET
@Path("/export/count")
@Produces(MediaType.APPLICATION_JSON)
Long compterMembresPourExport(
@QueryParam("associationId") UUID associationId,
@QueryParam("statut") String statut,
@QueryParam("type") String type,
@QueryParam("dateAdhesionDebut") String dateAdhesionDebut,
@QueryParam("dateAdhesionFin") String dateAdhesionFin);
@POST
@Path("/import")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
ResultatImportDTO importerDonnees(MembreImportMultipartForm form);
@GET
@Path("/import/modele")
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
byte[] telechargerModeleImport();
@GET
@Path("/autocomplete/villes")
List<String> obtenirVilles(@QueryParam("query") String query);
@GET
@Path("/mes-organisations")
List<OrganisationSwitcherDTO> mesOrganisations();
// ── Cycle de vie des adhésions ─────────────────────────────────────────
@GET
@Path("/{membreId}/adhesion")
@SuppressWarnings("unchecked")
java.util.Map<String, Object> getAdhesionStatut(@PathParam("membreId") UUID membreId,
@QueryParam("organisationId") UUID organisationId);
@PUT
@Path("/{membreId}/inviter-organisation")
java.util.Map<String, Object> inviterMembreOrg(@PathParam("membreId") UUID membreId,
@QueryParam("organisationId") UUID organisationId,
@QueryParam("roleOrg") String roleOrg);
@POST
@Path("/accepter-invitation/{token}")
java.util.Map<String, Object> accepterInvitation(@PathParam("token") String token);
@PUT
@Path("/{membreId}/adhesion/activer")
java.util.Map<String, Object> activerAdhesion(@PathParam("membreId") UUID membreId,
@QueryParam("organisationId") UUID organisationId,
java.util.Map<String, String> body);
@PUT
@Path("/{membreId}/adhesion/suspendre")
java.util.Map<String, Object> suspendrAdhesion(@PathParam("membreId") UUID membreId,
@QueryParam("organisationId") UUID organisationId,
java.util.Map<String, String> body);
@PUT
@Path("/{membreId}/adhesion/radier")
java.util.Map<String, Object> radierAdhesion(@PathParam("membreId") UUID membreId,
@QueryParam("organisationId") UUID organisationId,
java.util.Map<String, String> body);
@GET
@Path("/autocomplete/professions")
List<String> obtenirProfessions(@QueryParam("query") String query);
@POST
@Path("/export/selection")
@Consumes(MediaType.APPLICATION_JSON)
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
byte[] exporterSelection(
List<UUID> membreIds,
@QueryParam("format") @DefaultValue("EXCEL") String format);
// Classes DTO internes pour les réponses spécialisées
/**
* DTO pour le sélecteur d'organisation (multi-org switcher).
* Mappé depuis GET /api/membres/mes-organisations.
*/
class OrganisationSwitcherDTO implements java.io.Serializable {
public String organisationId;
public String nom;
public String nomCourt;
public String typeOrganisation;
public String categorieType;
public String modulesActifs;
public String statut;
public String statutMembre;
public String roleOrg;
public String dateAdhesion;
public String getOrganisationId() { return organisationId; }
public void setOrganisationId(String v) { this.organisationId = v; }
public String getNom() { return nom; }
public void setNom(String v) { this.nom = v; }
public String getNomCourt() { return nomCourt; }
public void setNomCourt(String v) { this.nomCourt = v; }
public String getTypeOrganisation() { return typeOrganisation; }
public void setTypeOrganisation(String v) { this.typeOrganisation = v; }
public String getCategorieType() { return categorieType; }
public void setCategorieType(String v) { this.categorieType = v; }
public String getModulesActifs() { return modulesActifs; }
public void setModulesActifs(String v) { this.modulesActifs = v; }
public String getStatut() { return statut; }
public void setStatut(String v) { this.statut = v; }
public String getStatutMembre() { return statutMembre; }
public void setStatutMembre(String v) { this.statutMembre = v; }
public String getRoleOrg() { return roleOrg; }
public void setRoleOrg(String v) { this.roleOrg = v; }
public String getDateAdhesion() { return dateAdhesion; }
public void setDateAdhesion(String v) { this.dateAdhesion = v; }
/** Retourne le libellé court à afficher dans le switcher. */
public String getLibelleCourt() {
if (nomCourt != null && !nomCourt.isBlank()) return nomCourt;
if (nom != null && nom.length() > 25) return nom.substring(0, 22) + "";
return nom;
}
}
class StatistiquesMembreDTO {
public Long totalMembres;
public Long membresActifs;
public Long membresInactifs;
public Long membresSuspendus;
public Long membresRadies;
public Long nouveauxMembres30Jours;
public Double tauxActivite;
public Double tauxCroissance;
// Constructeurs
public StatistiquesMembreDTO() {
}
// Getters et setters
public Long getTotalMembres() {
return totalMembres;
}
public void setTotalMembres(Long totalMembres) {
this.totalMembres = totalMembres;
}
public Long getMembresActifs() {
return membresActifs;
}
public void setMembresActifs(Long membresActifs) {
this.membresActifs = membresActifs;
}
public Long getMembresInactifs() {
return membresInactifs;
}
public void setMembresInactifs(Long membresInactifs) {
this.membresInactifs = membresInactifs;
}
public Long getMembresSuspendus() {
return membresSuspendus;
}
public void setMembresSuspendus(Long membresSuspendus) {
this.membresSuspendus = membresSuspendus;
}
public Long getMembresRadies() {
return membresRadies;
}
public void setMembresRadies(Long membresRadies) {
this.membresRadies = membresRadies;
}
public Long getNouveauxMembres30Jours() {
return nouveauxMembres30Jours;
}
public void setNouveauxMembres30Jours(Long nouveauxMembres30Jours) {
this.nouveauxMembres30Jours = nouveauxMembres30Jours;
}
public Double getTauxActivite() {
return tauxActivite;
}
public void setTauxActivite(Double tauxActivite) {
this.tauxActivite = tauxActivite;
}
public Double getTauxCroissance() {
return tauxCroissance;
}
public void setTauxCroissance(Double tauxCroissance) {
this.tauxCroissance = tauxCroissance;
}
}
class ResultatImportDTO {
public Integer totalLignes;
public Integer lignesTraitees;
public Integer lignesErreur;
public List<String> erreurs;
public List<MembreResponse> membresImportes;
// Constructeurs
public ResultatImportDTO() {
}
// Getters et setters
public Integer getTotalLignes() {
return totalLignes;
}
public void setTotalLignes(Integer totalLignes) {
this.totalLignes = totalLignes;
}
public Integer getLignesTraitees() {
return lignesTraitees;
}
public void setLignesTraitees(Integer lignesTraitees) {
this.lignesTraitees = lignesTraitees;
}
public Integer getLignesErreur() {
return lignesErreur;
}
public void setLignesErreur(Integer lignesErreur) {
this.lignesErreur = lignesErreur;
}
public List<String> getErreurs() {
return erreurs;
}
public void setErreurs(List<String> erreurs) {
this.erreurs = erreurs;
}
public List<MembreResponse> getMembresImportes() {
return membresImportes;
}
public void setMembresImportes(List<MembreResponse> membresImportes) {
this.membresImportes = membresImportes;
}
}
}