Commit Graph

60 Commits

Author SHA1 Message Date
dahoud
e81c75b828 fix(db): V30/V31 aligner membres_roles avec entité + rendre colonnes notifications legacy nullables
- V30: ajoute membre_organisation_id/organisation_id/date_debut/fin/commentaire si absents,
  rend membre_id nullable (legacy V1), remplace uk_membre_role par uk_mr_membre_org_role,
  ajoute indexes. Idempotent via DO blocks.
- V31: rend destinataire_id, titre, nombre_tentatives nullables dans notifications
  (colonnes legacy V1 que l'entité n'utilise plus, bloquaient les INSERT).
2026-04-15 20:05:36 +00:00
dahoud
6bd3f6bc18 fix(admin): supprimer @Provider de JwtPropagationFilter
@Provider enregistre le filtre GLOBALEMENT sur tous les REST clients.
JwtPropagationFilter s'exécutait après AdminServiceTokenHeadersFactory et
écrasait le token de service account avec le JWT utilisateur mobile
→ LUM recevait un token du realm unionflow (kid inconnu) → 401.

La propagation JWT est déjà gérée par OidcTokenPropagationHeadersFactory
sur UserServiceClient/RoleServiceClient via @RegisterClientHeaders.
JwtPropagationFilter est conservé sans @Provider pour référence future.
2026-04-12 15:27:38 +00:00
dahoud
e107d2ecce fix(admin): AdminUserService doit utiliser AdminUserServiceClient et AdminRoleServiceClient
Le service admin injectait UserServiceClient/RoleServiceClient (propagation du token
utilisateur unionflow) au lieu des clients Admin dédiés (service account lions-user-manager).
Résultat : le token JWT de l'utilisateur mobile était envoyé à LUM → 401 car LUM ne
connaît pas les clés du realm unionflow.

Correctif :
- AdminUserService -> AdminUserServiceClient + AdminRoleServiceClient (service account)
- UserServiceClient + RoleServiceClient remis à OidcTokenPropagationHeadersFactory
  (ces clients non-admin propagent le token utilisateur pour des usages futurs)
2026-04-12 15:22:09 +00:00
dahoud
0b79a2ee68 fix(admin): utiliser AdminServiceTokenHeadersFactory pour UserServiceClient et RoleServiceClient
Les appels vers lions-user-manager nécessitent un token du realm lions-user-manager
(service account). OidcTokenPropagationHeadersFactory transmettait le token utilisateur
du realm unionflow → 401 systématique. AdminServiceTokenHeadersFactory injecte le bon
token via l'OIDC client admin-service.
2026-04-12 15:00:34 +00:00
dahoud
dfd883b27c fix(dev): corriger config OIDC issuer + supprimer tables fantômes pré-consolidation
- application-dev.properties : token.issuer utilise ${DEV_HOST:localhost} pour valider
  les JWT émis par Keycloak via l'IP LAN (mobile physique sur réseau local)
- .env : DEV_HOST=192.168.1.13 — source unique côté backend, en sync avec
  android/local.properties → dev.host côté mobile
- V24 : suppression des 8 tables fantômes issues des migrations pré-consolidation
  (document, permission, favori, ticket, suggestion, suggestion_vote, configuration,
  role_permission) — toutes vides, les entités JPA pointaient déjà vers les tables
  plurielles correctes. Les contraintes uk_role_permission et uk_suggestion_vote
  sont maintenant sur les vraies tables (roles_permissions, suggestion_votes).
2026-04-12 14:51:22 +00:00
dahoud
f7f0a65f56 fix: correct builder method names for boolean fields in response DTOs
ConversationResponse/MessageResponse fields (muted, pinned, archived,
edited, deleted) are primitive booleans — Lombok @Builder generates
.muted() not .isMuted(). Also use Boolean.TRUE.equals() for null-safe
unboxing from entity Boolean wrapper fields.
2026-04-11 03:01:28 +00:00
dahoud
272525aa4d fix(tests): replace record-style accessors with JavaBean getters
MembreDashboardServiceTest and OrganisationServiceTest used record
accessor syntax (e.g. result.nom()) on DTO classes that were converted
from records to @Data classes — now using getters (result.getNom()).
2026-04-11 02:07:33 +00:00
dahoud
1a5138b87a fix(impl): version parent 1.0.4 + server-api 1.0.4 2026-04-11 02:01:05 +00:00
dahoud
31e8d5534c fix: kafka dev standalone, OIDC realm LUM, Flyway out-of-order, shutdown guard, TypeRef categorie/modules
- docker-compose.dev.yml: retire le service kafka (standalone existant sur :9092), kafka-ui pointe host.docker.internal:9092
- application-dev.properties: OIDC admin-service realm corrigé lions-user-manager (fix AUTH changement mdp)
- application-prod.properties: nouvelle var KEYCLOAK_LUM_AUTH_SERVER_URL + fallback KEYCLOAK_CLIENT_SECRET
- application.properties: quarkus.flyway.out-of-order=true (évite échec si migration hors-séquence)
- V10 renommé V10_1 (évite conflit avec historique Flyway existant)
- AlertMonitoringService: guard Arc.container().isRunning() pour éviter NPE au shutdown
- TypeOrganisationReferenceResource: forward categorie + modulesRequis au service
- Tests: coverage TypeOrganisationReferenceResource + TypeReferenceService
2026-04-11 01:25:45 +00:00
dahoud
065b0008b0 feat: ajout Kafka 4.0.0 (KRaft) + kafka-ui dev dans docker-compose.dev.yml 2026-04-11 00:04:25 +00:00
dahoud
bc95f24c35 fix: StatutMembre.SUSPENDU (enum, pas String) dans desactiverMembre() 2026-04-10 23:43:11 +00:00
dahoud
a6ad4c9aea fix: BUG-01 + AUTH + DATA-01 UnionFlow
BUG-01: BudgetService.toResponse() — remplace doubleValue()>0 par
compareTo(BigDecimal.ZERO)>0 (précision BigDecimal) ; ajoute 2 tests
couvrant varianceRate=0 (totalPlanned=0) et varianceRate=-40%

AUTH: MembreKeycloakSyncService.changerMotDePassePremierLogin() — élargit
le catch de ForbiddenException vers WebApplicationException avec vérification
du statut HTTP (le REST client MicroProfile ne garantit pas la sous-classe)

DATA-01: MembreService.desactiverMembre() — décrémente nombreMembres sur
toutes les orgs actives du membre et passe le statutMembre à DESACTIVE
2026-04-10 20:53:19 +00:00
dahoud
5e21ef9573 fix: V10 migration — corriger type colonne version dans modules_disponibles
La colonne version était VARCHAR(20) au lieu de BIGINT, causant une erreur
Hibernate validate au démarrage. L'entité ModuleDisponible n'a pas de champ
version propre — la colonne était orpheline et conflicte avec BaseEntity @Version.

Fix idempotent : suppression VARCHAR + ajout BIGINT DEFAULT 0 (table vide).
2026-04-10 15:48:32 +00:00
dahoud
7d68caef40 fix: corriger id repository Gitea (gitea → gitea-lionsdev) pour auth Maven 2026-04-09 15:16:25 +00:00
dahoud
44ebad3f6b fix: ajouter repository Gitea dans pom.xml pour résolution parent en CI 2026-04-09 15:10:58 +00:00
dahoud
f700ec9c2d feat: mapper categorie/modulesRequis dans TypeReferenceService (server-api 1.0.3)
- creer(): builder inclut categorie et modulesRequis depuis la requête
- toResponse(): builder expose categorie et modulesRequis de l'entité
- appliquerMiseAJour(): patch null-safe pour categorie et modulesRequis
- pom.xml: unionflow-server-api 1.0.0 → 1.0.3 (nouveaux champs DTO)
2026-04-09 15:08:28 +00:00
dahoud
b676e003e4 fix: initialiser modulesActifs/categorieType depuis types_reference à la création d'org
- TypeReference: ajout des champs categorie et modulesRequis (colonnes DB existantes depuis V18
  mais non mappées en JPA — Hibernate validate échouait silencieusement)
- OrganisationService.creerOrganisation(): lit types_reference.modules_requis pour initialiser
  Organisation.modulesActifs, au lieu de dépendre uniquement du switch hardcodé dans
  OrganisationModuleService.getModulesParType()

Avant: un type créé via CRUD (ex: TANTANPION) tombait dans le default du switch → aucun
module métier → rôles métier assignables mais menus jamais affichés.
Après: tout type avec modules_requis renseigné dans types_reference active correctement
ses modules à la création de l'organisation.
2026-04-09 14:09:46 +00:00
dahoud
c79a393d6e revert: hibernate back to validate mode (schema stabilized) 2026-04-08 21:42:03 +00:00
dahoud
b4d9936b6b temp: hibernate update mode for fresh DB migration (revert to validate after startup) 2026-04-08 19:17:47 +00:00
dahoud
971b7d2178 fix: permissions table schema in V1 (add ressource, action, libelle; remove nom) 2026-04-08 19:16:24 +00:00
dahoud
13da0d07bd fix: apply plural table renames to V17-V23 migrations 2026-04-08 19:00:09 +00:00
dahoud
139642c4cd fix: apply plural table name renames to all migrations V2-V16
Same rename applied to V1 must propagate to V2-V16 which referenced
old singular table names (compte_comptable, suggestion, etc.)
2026-04-08 17:32:48 +00:00
dahoud
e6627ab45d fix: rename all V1 table names to match entity @Table names (plural)
Hibernate validate mode in prod requires exact table names.
V1 used singular names (permission, document, suggestion, etc.)
but entities use plural names (permissions, documents, suggestions, etc.).
Hibernate update mode was masking this by auto-creating plural tables.

Renamed 23 tables to match entities.
2026-04-08 17:23:29 +00:00
dahoud
3c1e5c6a2d fix: SystemAlert @PrePersist override + types_reference complete schema in V1
- SystemAlert.onCreate() now calls super.onCreate() to set dateCreation (was null → NOT NULL violation every minute)
- V1: types_reference updated with full schema (domaine, est_defaut, est_systeme, ordre_affichage, modules_requis, organisation_id)
- V9: idempotent guard for categorie nullable ALTER (already nullable in updated V1)
2026-04-08 17:01:58 +00:00
dahoud
771755dce8 fix(build): déplacer ErrorResponse vers package local pour éviter split package Quarkus 2026-04-07 21:10:13 +00:00
dahoud
121506da6b fix(build): PermitAll jakarta.annotation + ErrorResponse locale pour pipeline CI 2026-04-07 21:00:49 +00:00
dahoud
a2dfae9a0b fix(security): audit RBAC complet v3.0 — rôles normalisés, lifecycle, changement mdp mobile
RBAC:
- HealthResource: @PermitAll
- RoleResource: @RolesAllowed ADMIN/SUPER_ADMIN/ADMIN_ORGANISATION class-level
- PropositionAideResource: @RolesAllowed MEMBRE/USER class-level
- AuthCallbackResource: @PermitAll
- EvenementResource: @PermitAll /publics et /test, count restreint
- BackupResource/LogsMonitoringResource/SystemResource: MODERATOR → MODERATEUR
- AnalyticsResource: MANAGER/MEMBER → ADMIN_ORGANISATION/MEMBRE
- RoleConstant.java: constantes de rôles centralisées

Cycle de vie membres:
- MemberLifecycleService: ajouterMembre()/retirerMembre() sur activation/radiation/archivage
- MembreResource: endpoint GET /numero/{numeroMembre}
- MembreService: méthode trouverParNumeroMembre()

Changement mot de passe:
- CompteAdherentResource: endpoint POST /auth/change-password (mobile)
- MembreKeycloakSyncService: changerMotDePasseDirectKeycloak() via API Admin Keycloak directe
- Fallback automatique si lions-user-manager indisponible

Workflow:
- Flyway V17-V23: rôles, types org, formules Option C, lifecycle columns, bareme cotisation
- Nouvelles classes: MemberLifecycleService, OrganisationModuleService, scheduler
- Security: OrganisationContextFilter, OrganisationContextHolder, ModuleAccessFilter
2026-04-07 20:52:26 +00:00
dahoud
c74ae25ad6 fix(tests): rôles @TestSecurity en majuscules + NPE Map.of() dans MembreResource
14 fichiers de tests : rôles passés en majuscules dans @TestSecurity(roles={...})
pour correspondre exactement aux valeurs @RolesAllowed du backend.
Mapping : "admin"→"ADMIN", "admin_organisation"→"ADMIN_ORGANISATION",
"membre_actif"→"MEMBRE", "tontine_resp"→"TONTINE_RESP", etc.
Un rôle en minuscules produit un 403 silencieux sans erreur Quarkus.

MembreResource : activerAdhesion/suspendrAdhesion/radierAdhesion/archiverAdhesion
remplacent Map.of() par HashMap pour accepter dateChangementStatut null
(Map.of() lève NullPointerException sur valeur null → HTTP 500).
2026-04-06 16:50:03 +00:00
dahoud
aef5548e87 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
2026-04-06 16:49:47 +00:00
dahoud
39e98a9cb3 feat(organisations): endpoint GET /{id}/membres/count pour le nombre reel de membres actifs 2026-04-05 13:37:42 +00:00
dahoud
8352ea1669 fix(entity): @Column name explicite sur BackupConfig/BackupRecord
Sans @Column(name=...), Hibernate génère des noms camelCase (includedatabase)
alors que V16 a créé les colonnes en snake_case (include_database).
Alignement explicite avec les conventions des autres entités.
2026-04-05 11:51:41 +00:00
dahoud
f22b3472a8 fix(flyway): V4 RENAME COLUMN conditionnel + V6 CREATE TABLE IF NOT EXISTS
V4: system_logs colonnes niveau/stacktrace déjà renommées en prod
→ RENAME COLUMN enveloppé dans DO blocks IF EXISTS

V6: conversations/messages/conversation_participants existent déjà en prod
→ CREATE TABLE + CREATE INDEX → IF NOT EXISTS
2026-04-05 11:24:15 +00:00
dahoud
93fc69ec22 feat(auth): premier login via AppAuth — remédiation automatique des anciens comptes
- MembreKeycloakSyncService: completerPremierLogin retourne un enum PremierLoginResultat
  (COMPLETE / REAUTH_REQUIS / NON_APPLICABLE) au lieu d'un boolean
- Détection automatique des anciens comptes (sans UPDATE_PASSWORD ni marqueur KC):
  assigne UPDATE_PASSWORD + attribut premiere_password_pending dans Keycloak
  et retourne REAUTH_REQUIS pour que Flutter re-déclenche AppAuth
- Détection du mot de passe changé: marqueur présent + UPDATE_PASSWORD absent → COMPLETE
- createUserDTOFromMembre: ajoute l'attribut premiere_password_pending=true à la création
- CompteAdherentResource.getMonStatut: retourne reAuthRequired=true quand REAUTH_REQUIS
2026-04-05 11:11:53 +00:00
dahoud
6bcec363ce fix(flyway): V2 conditional ALTER TABLE pour tables absentes en prod
formule_abonnement et souscription_organisation n'existent pas dans la DB
prod (nommées formules_abonnement/souscriptions_organisation dans l'ancien
schema). Remplacé par des DO blocks conditionnels (IF EXISTS).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 16:56:14 +00:00
dahoud
437f3c819e fix(prod): ignore missing Flyway migrations + disable file logging
- quarkus.flyway.ignore-migration-patterns=*:missing — migrations V1.2/V1.3
  appliquées en DB mais absentes localement (après consolidation V1-V10)
- quarkus.log.file.enable=false — /var/log/unionflow/ absent dans le container

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 16:38:25 +00:00
dahoud
e00a9301d8 feat: BackupService real pg_dump, OrganisationService region stats, SystemConfigService overrides
- BackupService: DB-persisted metadata (BackupRecord/BackupConfig entities + V16 Flyway migration),
  real pg_dump execution via ProcessBuilder, soft-delete on deleteBackup, pg_restore manual guidance
- OrganisationService: repartitionRegion now queries Adresse entities (was Map.of() stub)
- SystemConfigService: in-memory config overrides via AtomicReference (no DB dependency)
- SystemMetricsService: null-guard on MemoryMXBean in getSystemStatus() (fixes test NPE)
- Souscription workflow: SouscriptionService, SouscriptionResource, FormuleAbonnementRepository,
  V11 Flyway migration, admin REST clients
- Flyway V8-V15: notes membres, types référence, type orga constraint, seed roles,
  première connexion, Wave checkout URL, Wave telephone column length fix
- .gitignore: added uploads/ and .claude/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 16:14:30 +00:00
dahoud
9c66909eff Refactoring - Version stable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 17:07:11 +00:00
dahoud
40a2dd9728 Refactoring - Version stable 2026-03-28 16:51:14 +00:00
dahoud
4d096a4791 Refactoring - Version stable 2026-03-28 15:15:24 +00:00
dahoud
607d31d2fc Refactoring - Version stable 2026-03-28 14:37:57 +00:00
dahoud
a740c172ef Refactoring - Version stable 2026-03-28 14:21:30 +00:00
dahoud
00b981c510 fix(backend): corriger format log UUID dans OrganisationResource
Erreur corrigée : UUID passé à %d (entier) au lieu de %s (string)
- OrganisationResource.java:227 : LOG.infof(..., %s, id)

Note : 36 tests échouent encore (problèmes d'auth, validation, NPE)
Couverture actuelle : 50% (objectif 100% reporté)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-18 02:08:27 +00:00
dahoud
d15324bd41 feat(backend): ajout export PDF pour les membres
Nouveau format d'export :
- GET /api/membres/export?format=PDF - Export membres en PDF (OpenPDF)
- Support formats : EXCEL, CSV, PDF (dans MembreResource)

MembreImportExportService :
- exporterVersPDF() : 193 lignes, génération PDF professionnelle
  * Document A4 landscape pour + de colonnes
  * Titre + métadonnées (date, total)
  * Table avec colonnes configurables (PERSO, CONTACT, ADHESION, ORGANISATION)
  * Styles : headers (bleu foncé, blanc), données (noir, aligné)
  * Page statistiques optionnelle (total, actifs/inactifs/suspendus, orgs)
- Méthodes helper : createHeaderCell, createDataCell, createStatsCell, ajouterStatistiquesPDF

MembreService :
- exporterVersPDF() : délégation vers MembreImportExportService

MembreResource :
- Mise à jour endpoint /export : if ("PDF".equalsIgnoreCase(format))
- Content-Type: application/pdf
- Filename: membres_export_YYYY-MM-DD.pdf

Correctifs imports :
- Résolution conflits OpenPDF vs Apache POI (List, Row, Font)
- Imports spécifiques : com.lowagie.text.Font, Document, PdfPTable, etc.
- Qualification complète pour éviter ambiguïtés (java.util.List vs com.lowagie.text.List)

Résultat : Export membres en 3 formats (EXCEL, CSV, PDF) 

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-17 08:40:29 +00:00
dahoud
1c096f0ee1 feat(backend): ajout 8 endpoints manquants workflow financier
Endpoints ajoutés :
- POST /api/finance/approvals - requestApproval (avec organizationId)
- GET /api/finance/approvals/history - historique filtrable
- PUT /api/finance/budgets/{id} - updateBudget (name, description, status)
- DELETE /api/finance/budgets/{id} - deleteBudget (soft delete)
- GET /api/finance/stats - statistiques workflow global
- GET /api/finance/audit-logs - logs d'audit filtrables
- GET /api/finance/audit-logs/anomalies - détection anomalies
- POST /api/finance/audit-logs/export - export CSV/PDF

Services :
- ApprovalService.requestApproval() : logique niveaux LEVEL1/2/3 selon montant
- ApprovalService.getApprovalsHistory() : filtres date + statut
- BudgetService.updateBudget() : validation statut + approbation
- BudgetService.deleteBudget() : soft delete (actif=false)

Notes :
- Niveau approbation : <100K=NONE, 100K-1M=LEVEL1, 1M-5M=LEVEL2, >5M=LEVEL3
- organizationId optionnel dans requestApproval (pas de récup auto depuis Membre)
- FinanceWorkflowResource créé pour stats/audit (implémentation stub)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 21:17:18 +00:00
dahoud
a7bcaf9277 feat(backend): endpoints inscriptions + feedback événements
Ajoute infrastructure complète pour gérer inscriptions et feedbacks événements.

## Entités
- FeedbackEvenement : note 1-5, commentaire, modération (PUBLIE/EN_ATTENTE/REJETE)
- InscriptionEvenement : déjà existait, utilisation ajoutée

## Repositories
- InscriptionEvenementRepository : findByMembreAndEvenement, findByEvenement, countConfirmees, isMembreInscrit
- FeedbackEvenementRepository : findByMembreAndEvenement, findPubliesByEvenement, calculateAverageNote

## Service (EvenementService)
Inscriptions :
- inscrireEvenement() : vérifie capacité, crée inscription CONFIRMEE
- desinscrireEvenement() : soft delete inscription
- getParticipants() : liste inscriptions confirmées
- getMesInscriptions() : inscriptions du membre connecté

Feedbacks :
- soumetteFeedback() : note 1-5 + commentaire, vérifie participation, événement terminé
- getFeedbacks() : liste feedbacks publiés
- getStatistiquesFeedback() : note moyenne + nombre feedbacks

## REST Endpoints (6 total)
Inscriptions :
- POST /api/evenements/{id}/inscriptions - S'inscrire
- DELETE /api/evenements/{id}/inscriptions - Se désinscrire
- GET /api/evenements/{id}/participants - Liste participants
- GET /api/evenements/mes-inscriptions - Mes inscriptions

Feedbacks :
- POST /api/evenements/{id}/feedback - Soumettre feedback (note+commentaire)
- GET /api/evenements/{id}/feedbacks - Liste feedbacks + stats

## Database
- Migration V7 : table feedbacks_evenement
- Contrainte unique: un feedback par membre/événement
- Index: membre_id, evenement_id, date_feedback, moderation_statut

Débloquer fonctionnalités événements mobile.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 20:11:03 +00:00
dahoud
3be01e28a7 feat(backend): implémentation complète du système de messagerie
Ajoute l'infrastructure backend complète pour les conversations et messages :

## Entités
- Conversation : conversations individuelles, groupes, broadcast, annonces
- Message : messages avec statut, priorité, pièces jointes, soft delete

## Repositories
- ConversationRepository : findByParticipant, findByIdAndParticipant (sécurité)
- MessageRepository : findByConversation, countUnread, markAsRead

## Services
- ConversationService : CRUD conversations, archive, mute, pin
- MessageService : send, edit, delete, getMessages

## REST Endpoints (12 total)
- GET /api/conversations - Lister mes conversations
- GET /api/conversations/{id} - Récupérer une conversation
- POST /api/conversations - Créer conversation
- PUT /api/conversations/{id}/archive - Archiver
- PUT /api/conversations/{id}/mark-read - Marquer comme lu
- PUT /api/conversations/{id}/toggle-mute - Activer/désactiver son
- PUT /api/conversations/{id}/toggle-pin - Épingler
- GET /api/messages?conversationId=X - Lister messages
- POST /api/messages - Envoyer message
- PUT /api/messages/{id} - Éditer message
- DELETE /api/messages/{id} - Supprimer message

## Database
- Migration V6 : tables conversations, messages, conversation_participants
- Indexes sur organisation, type, archived, deleted pour performance

## Sécurité
- SecuriteHelper.resolveMembreId() : résolution membre depuis JWT
- Vérification accès conversation avant toute opération
- @RolesAllowed sur tous les endpoints

Débloquer la fonctionnalité Communication mobile (actuellement 100% stubs).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 06:39:39 +00:00
dahoud
f5271cc29e feat(admin): sécurité ADMIN_ORGANISATION pour import/création membres
Implémente la sécurité au niveau Resource pour ADMIN_ORGANISATION :
les utilisateurs avec ce rôle ne peuvent gérer que les membres
de leurs organisations.

MembreService.java:
- Ajout listerMembresParOrganisations(orgIds, page, sort)
  * Filtre membres par liste d'organisations avec JOIN
  * Support pagination et tri
  * Retourne liste vide si orgIds vide

- Ajout lierMembreOrganisationEtIncrementerQuota(membre, orgId, typeMembreDefaut)
  * Crée MembreOrganisation avec statut ACTIF ou EN_ATTENTE_VALIDATION
  * Incrémente quota si souscription active existe
  * Gère statut selon typeMembreDefaut fourni

MembreResource.java:
- Injection OrganisationService + import Organisation entity

- GET /api/membres: sécurisé pour ADMIN_ORGANISATION
  * ADMIN_ORGANISATION: filtre par ses organisations uniquement
  * Utilise listerMembresParOrganisations()
  * ADMIN/SUPER_ADMIN: accès complet (inchangé)

- POST /api/membres: sécurisé pour ADMIN_ORGANISATION
  * @RolesAllowed: ADMIN, SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE
  * ADMIN_ORGANISATION: require organisationId + validation accès
  * Appelle lierMembreOrganisationEtIncrementerQuota()
  * ADMIN/SUPER_ADMIN: fonctionnement inchangé

- POST /api/membres/import: sécurisé pour ADMIN_ORGANISATION
  * ADMIN_ORGANISATION: require organisationId + validation accès
  * Retourne 403 si tentative d'accès à org non autorisée
  * Retourne 400 si organisationId manquant

Spec: admin-org-membres-import-quota.md
Critères acceptation: 8/8 
- Filtrage liste membres par organisation
- Création membre avec organisationId obligatoire
- Import Excel avec orgId obligatoire
- Validation accès organisation
- Format Excel validé (déjà implémenté)
- Quota vérifié (déjà implémenté)
- Membres liés à org (déjà implémenté)
- Quota incrémenté (déjà implémenté)

Tâche: #56 - Implémenter Spec Admin Import Membres

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 06:07:56 +00:00
dahoud
8a3dd8632b test(dashboard): amélioration des tests dashboard avec données réelles
Remplace les tests "placeholders" qui acceptaient anyOf(200, 500)
par des tests robustes avec assertions sur le contenu JSON.

Modifications:
- DashboardResourceTest: 6 → 8 tests avec setup de données réelles
  * Ajout BeforeEach avec création Organisation + Membre de test
  * Validation du contenu JSON (organizationId, stats, activities, events)
  * Tests cas d'erreur (params manquants, UUIDs invalides)

- MembreDashboardResourceTest: 2 → 5 tests
  * Tests ajustés pour fonctionner sans données seed
  * Ajout test authentification (401)
  * Tests 404 pour membre inexistant

- MembreDashboardServiceTest: ajusté pour absence de données seed
  * Tests 404/NotFoundException au lieu d'attendre des données seed

- application-test.properties: fix wave.api.key/secret vides
  * Valeurs factices pour éviter erreur config en tests

Résultat: 17 tests dashboard, 100% de réussite (0 erreurs, 0 échecs)

Tâche: #57 - Remplacer tests placeholders dashboard

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 06:07:20 +00:00
dahoud
347d89cc02 feat(backend): consolidation finale Spec 001 LCB-FT + Flyway V1-V5
Migrations Flyway (consolidées) :
- V1 : Schéma complet (69 tables, 1322 lignes)
- V2 : Colonnes BaseEntity (cree_par, modifie_par)
- V3 : Colonnes métier manquantes (adresses, alert_configuration)
- V4 : Correction system_logs (renommage colonnes, ajout timestamp)
- V5 : Nettoyage alert_configuration (suppression colonnes obsolètes)
- Suppression V2-V6 obsolètes (fragmentés)

Entités LCB-FT :
- AlerteLcbFt : Alertes anti-blanchiment
- AlertConfiguration : Configuration alertes
- SystemAlert : Alertes système
- SystemLog : Logs techniques (DÉJÀ COMMITÉE avec super.onCreate fix)

Services LCB-FT (T015, T016) :
- AlerteLcbFtService + Resource : Dashboard alertes admin
- AlertMonitoringService : Surveillance transactions
- SystemLoggingService : Logs centralisés
- FileStorageService : Upload documents

Repositories :
- AlerteLcbFtRepository
- AlertConfigurationRepository
- SystemAlertRepository
- SystemLogRepository

Tests :
- GlobalExceptionMapperTest : 17 erreurs corrigées (toResponse())

Spec 001 : 27/27 tâches (100%)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 05:15:17 +00:00
dahoud
d8e3f23ec4 fix(entity): appeler super.onCreate() dans SystemLog pour peupler dateCreation
Problème : SystemLog override @PrePersist sans appeler parent
Conséquence : dateCreation restait NULL → erreur PostgreSQL constraint violation
Solution : Ajout super.onCreate() pour déclencher BaseEntity.onCreate()

Fixes: null value in column date_creation violates not-null constraint

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-16 05:14:04 +00:00