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 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 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 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 listerParOrganisation(@PathParam("organisationId") UUID organisationId); @GET @Path("/actifs") List listerActifs(); @GET @Path("/inactifs") List 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 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 obtenirVilles(@QueryParam("query") String query); @GET @Path("/mes-organisations") List mesOrganisations(); // ── Cycle de vie des adhésions ───────────────────────────────────────── @GET @Path("/{membreId}/adhesion") @SuppressWarnings("unchecked") java.util.Map getAdhesionStatut(@PathParam("membreId") UUID membreId, @QueryParam("organisationId") UUID organisationId); @PUT @Path("/{membreId}/inviter-organisation") java.util.Map inviterMembreOrg(@PathParam("membreId") UUID membreId, @QueryParam("organisationId") UUID organisationId, @QueryParam("roleOrg") String roleOrg); @POST @Path("/accepter-invitation/{token}") java.util.Map accepterInvitation(@PathParam("token") String token); @PUT @Path("/{membreId}/adhesion/activer") java.util.Map activerAdhesion(@PathParam("membreId") UUID membreId, @QueryParam("organisationId") UUID organisationId, java.util.Map body); @PUT @Path("/{membreId}/adhesion/suspendre") java.util.Map suspendrAdhesion(@PathParam("membreId") UUID membreId, @QueryParam("organisationId") UUID organisationId, java.util.Map body); @PUT @Path("/{membreId}/adhesion/radier") java.util.Map radierAdhesion(@PathParam("membreId") UUID membreId, @QueryParam("organisationId") UUID organisationId, java.util.Map body); @GET @Path("/autocomplete/professions") List obtenirProfessions(@QueryParam("query") String query); @POST @Path("/export/selection") @Consumes(MediaType.APPLICATION_JSON) @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") byte[] exporterSelection( List 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 erreurs; public List 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 getErreurs() { return erreurs; } public void setErreurs(List erreurs) { this.erreurs = erreurs; } public List getMembresImportes() { return membresImportes; } public void setMembresImportes(List membresImportes) { this.membresImportes = membresImportes; } } }