feat: WebSocket temps réel + Finance Workflow + corrections

- Task #6: WebSocket /ws/dashboard + Kafka events (5 topics)
  * Backend: KafkaEventProducer, KafkaEventConsumer
  * Mobile: WebSocketService (reconnection, heartbeat, typed events)
  * DashboardBloc: Auto-refresh depuis WebSocket events

- Finance Workflow: approbations + budgets (backend + mobile)
  * Backend: entities, services, resources, migrations Flyway V6
  * Mobile: features finance_workflow complète avec BLoC

- Corrections DI: interfaces IRepository partout
  * IProfileRepository, IOrganizationRepository, IMembreRepository
  * GetIt configuré avec @injectable

- Spec-Kit: constitution + templates mis à jour
  * .specify/memory/constitution.md enrichie
  * Templates agent, plan, spec, tasks, checklist

- Nettoyage: fichiers temporaires supprimés

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 02:12:17 +00:00
parent bbc409de9d
commit e8ad874015
635 changed files with 58160 additions and 20674 deletions

View File

@@ -0,0 +1,329 @@
# Configuration Keycloak pour UnionFlow
# Crée les rôles et les comptes de test pour MUKEFI et MESKA
$ErrorActionPreference = "Stop"
# Configuration
$KEYCLOAK_URL = "http://localhost:8180"
$REALM_NAME = "unionflow"
$ADMIN_USERNAME = "admin"
$ADMIN_PASSWORD = "admin"
$TEST_PASSWORD = "Test@123"
function Write-Header {
param([string]$Text)
Write-Host ""
Write-Host "=" -NoNewline -ForegroundColor Cyan
Write-Host (" " * 68) -NoNewline
Write-Host "=" -ForegroundColor Cyan
Write-Host $Text -ForegroundColor White
Write-Host "=" -NoNewline -ForegroundColor Cyan
Write-Host (" " * 68) -NoNewline
Write-Host "=" -ForegroundColor Cyan
}
function Get-KeycloakAdminToken {
Write-Host "`n📡 Connexion à Keycloak..." -ForegroundColor Yellow
$tokenUrl = "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token"
$body = @{
client_id = "admin-cli"
username = $ADMIN_USERNAME
password = $ADMIN_PASSWORD
grant_type = "password"
}
try {
$response = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
Write-Host "✅ Connecté à Keycloak Admin API" -ForegroundColor Green
return $response.access_token
}
catch {
Write-Host "❌ Erreur connexion Keycloak: $_" -ForegroundColor Red
Write-Host " Vérifiez que Keycloak est démarré sur $KEYCLOAK_URL" -ForegroundColor Yellow
return $null
}
}
function Get-Headers {
param([string]$Token)
return @{
"Authorization" = "Bearer $Token"
"Content-Type" = "application/json"
}
}
function Get-RealmUsers {
param([string]$Token)
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users"
try {
return Invoke-RestMethod -Uri $url -Method Get -Headers $headers
}
catch {
Write-Host " ⚠️ Erreur récupération utilisateurs: $_" -ForegroundColor Yellow
return @()
}
}
function Remove-RealmUser {
param([string]$Token, [string]$UserId, [string]$Username)
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$UserId"
try {
Invoke-RestMethod -Uri $url -Method Delete -Headers $headers | Out-Null
Write-Host " ✅ Supprimé: $Username" -ForegroundColor Green
return $true
}
catch {
Write-Host " ❌ Erreur suppression $Username : $_" -ForegroundColor Red
return $false
}
}
function Get-RealmRoles {
param([string]$Token)
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles"
try {
return Invoke-RestMethod -Uri $url -Method Get -Headers $headers
}
catch {
Write-Host " ⚠️ Erreur récupération rôles: $_" -ForegroundColor Yellow
return @()
}
}
function New-RealmRole {
param([string]$Token, [string]$Name, [string]$Description)
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles"
$body = @{
name = $Name
description = $Description
composite = $false
clientRole = $false
} | ConvertTo-Json
try {
Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body | Out-Null
Write-Host " ✅ Rôle créé: $Name" -ForegroundColor Green
return $true
}
catch {
if ($_.Exception.Response.StatusCode.value__ -eq 409) {
Write-Host " ⚠️ Rôle existe déjà: $Name" -ForegroundColor Yellow
return $true
}
Write-Host " ❌ Erreur création rôle $Name : $_" -ForegroundColor Red
return $false
}
}
function New-RealmUser {
param(
[string]$Token,
[string]$Username,
[string]$Email,
[string]$FirstName,
[string]$LastName,
[string]$Password,
[string[]]$Roles
)
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users"
$body = @{
username = $Username
email = $Email
firstName = $FirstName
lastName = $LastName
enabled = $true
emailVerified = $true
credentials = @(
@{
type = "password"
value = $Password
temporary = $false
}
)
} | ConvertTo-Json -Depth 10
try {
$response = Invoke-WebRequest -Uri $url -Method Post -Headers $headers -Body $body
if ($response.StatusCode -eq 201) {
# Récupérer l'ID de l'utilisateur
$location = $response.Headers.Location
if ($location) {
$userId = $location.Split('/')[-1]
}
else {
# Chercher l'utilisateur par username
$users = Get-RealmUsers -Token $Token
$user = $users | Where-Object { $_.username -eq $Username }
if ($user) {
$userId = $user.id
}
}
if ($userId) {
# Assigner les rôles
Add-RolesToUser -Token $Token -UserId $userId -RoleNames $Roles
Write-Host " ✅ Utilisateur créé: $Username ($Email)" -ForegroundColor Green
return $userId
}
}
}
catch {
if ($_.Exception.Response.StatusCode.value__ -eq 409) {
Write-Host " ⚠️ Utilisateur existe déjà: $Username" -ForegroundColor Yellow
}
else {
Write-Host " ❌ Erreur création utilisateur $Username : $_" -ForegroundColor Red
}
return $null
}
}
function Add-RolesToUser {
param([string]$Token, [string]$UserId, [string[]]$RoleNames)
# Récupérer les objets de rôle
$allRoles = Get-RealmRoles -Token $Token
$rolesToAssign = $allRoles | Where-Object { $RoleNames -contains $_.name }
if ($rolesToAssign.Count -eq 0) {
return
}
$headers = Get-Headers -Token $Token
$url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$UserId/role-mappings/realm"
$body = $rolesToAssign | ConvertTo-Json -Depth 10 -AsArray
try {
Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body | Out-Null
Write-Host " → Rôles assignés: $($RoleNames -join ', ')" -ForegroundColor Cyan
}
catch {
Write-Host " ⚠️ Erreur assignation rôles: $_" -ForegroundColor Yellow
}
}
# ============================================================================
# MAIN
# ============================================================================
Write-Header "🔧 Configuration Keycloak pour UnionFlow"
# 1. Connexion
$token = Get-KeycloakAdminToken
if (-not $token) {
Write-Host "`n❌ Impossible de se connecter à Keycloak. Script arrêté." -ForegroundColor Red
exit 1
}
# 2. Audit de l'existant
Write-Host "`n📋 Audit de l'état actuel..." -ForegroundColor Yellow
$existingUsers = Get-RealmUsers -Token $token
$existingRoles = Get-RealmRoles -Token $token
Write-Host " • Utilisateurs existants: $($existingUsers.Count)" -ForegroundColor White
foreach ($user in $existingUsers) {
Write-Host " - $($user.username) ($($user.email))" -ForegroundColor Gray
}
Write-Host " • Rôles existants: $($existingRoles.Count)" -ForegroundColor White
foreach ($role in $existingRoles) {
Write-Host " - $($role.name)" -ForegroundColor Gray
}
# 3. Suppression des utilisateurs existants
Write-Host "`n🗑️ Suppression des utilisateurs existants..." -ForegroundColor Yellow
foreach ($user in $existingUsers) {
Remove-RealmUser -Token $token -UserId $user.id -Username $user.username
}
# 4. Création de la structure de rôles
Write-Host "`n👥 Création de la structure de rôles..." -ForegroundColor Yellow
$rolesToCreate = @(
@{name="SUPER_ADMIN"; description="Super administrateur - Accès total plateforme multi-organisations"},
@{name="ADMIN_ORGANISATION"; description="Administrateur d'une organisation - Accès total à son organisation"},
@{name="TRESORIER"; description="Trésorier - Gestion financière, comptabilité, épargne/crédit"},
@{name="SECRETAIRE"; description="Secrétaire - Gestion administrative, membres, adhésions, documents"},
@{name="RESPONSABLE_SOCIAL"; description="Responsable social - Gestion aide sociale et solidarité"},
@{name="RESPONSABLE_EVENEMENTS"; description="Responsable événements - Gestion événements et logistique"},
@{name="RESPONSABLE_CREDIT"; description="Responsable crédit - Gestion épargne/crédit (mutuelles)"},
@{name="MEMBRE_BUREAU"; description="Membre du bureau - Accès étendu consultation et actions"},
@{name="MEMBRE_ACTIF"; description="Membre actif - Consultation et actions de base"},
@{name="MEMBRE_SIMPLE"; description="Membre simple - Consultation uniquement"},
@{name="MEMBRE"; description="Rôle technique - Membre base"},
@{name="ADMIN"; description="Rôle technique - Admin base"},
@{name="USER"; description="Rôle technique - Utilisateur base"}
)
foreach ($role in $rolesToCreate) {
New-RealmRole -Token $token -Name $role.name -Description $role.description
}
# 5. Création des comptes de test
Write-Host "`n👤 Création des comptes de test..." -ForegroundColor Yellow
Write-Host " Mot de passe pour tous: $TEST_PASSWORD`n" -ForegroundColor Cyan
$usersToCreate = @(
# Super-Admin
@{username="superadmin"; email="superadmin@unionflow.test"; firstName="Super"; lastName="Admin"; roles=@("SUPER_ADMIN", "ADMIN", "USER")},
# MUKEFI
@{username="admin.mukefi"; email="admin.mukefi@unionflow.test"; firstName="Administrateur"; lastName="MUKEFI"; roles=@("ADMIN_ORGANISATION", "ADMIN", "USER")},
@{username="tresorier.mukefi"; email="tresorier.mukefi@unionflow.test"; firstName="Trésorier"; lastName="MUKEFI"; roles=@("TRESORIER", "MEMBRE", "USER")},
@{username="secretaire.mukefi"; email="secretaire.mukefi@unionflow.test"; firstName="Secrétaire"; lastName="MUKEFI"; roles=@("SECRETAIRE", "MEMBRE", "USER")},
@{username="credit.mukefi"; email="credit.mukefi@unionflow.test"; firstName="Responsable Crédit"; lastName="MUKEFI"; roles=@("RESPONSABLE_CREDIT", "MEMBRE", "USER")},
@{username="membre.mukefi"; email="membre.mukefi@unionflow.test"; firstName="Membre"; lastName="MUKEFI"; roles=@("MEMBRE_ACTIF", "MEMBRE", "USER")},
# MESKA
@{username="admin.meska"; email="admin.meska@unionflow.test"; firstName="Administrateur"; lastName="MESKA"; roles=@("ADMIN_ORGANISATION", "ADMIN", "USER")},
@{username="secretaire.meska"; email="secretaire.meska@unionflow.test"; firstName="Secrétaire"; lastName="MESKA"; roles=@("SECRETAIRE", "MEMBRE", "USER")},
@{username="social.meska"; email="social.meska@unionflow.test"; firstName="Responsable Social"; lastName="MESKA"; roles=@("RESPONSABLE_SOCIAL", "MEMBRE", "USER")},
@{username="evenements.meska"; email="evenements.meska@unionflow.test"; firstName="Responsable Événements"; lastName="MESKA"; roles=@("RESPONSABLE_EVENEMENTS", "MEMBRE", "USER")},
@{username="membre.meska"; email="membre.meska@unionflow.test"; firstName="Membre"; lastName="MESKA"; roles=@("MEMBRE_ACTIF", "MEMBRE", "USER")}
)
foreach ($user in $usersToCreate) {
New-RealmUser -Token $token -Username $user.username -Email $user.email `
-FirstName $user.firstName -lastName $user.lastName `
-Password $TEST_PASSWORD -Roles $user.roles
}
# 6. Résumé final
Write-Header "✅ Configuration Keycloak terminée avec succès !"
Write-Host "`n📊 Résumé:" -ForegroundColor Yellow
Write-Host "$($rolesToCreate.Count) rôles créés" -ForegroundColor White
Write-Host "$($usersToCreate.Count) utilisateurs créés" -ForegroundColor White
Write-Host " • Mot de passe: $TEST_PASSWORD" -ForegroundColor Cyan
Write-Host "`n👥 Comptes créés:" -ForegroundColor Yellow
Write-Host "`n 🔧 Super-Admin:" -ForegroundColor Magenta
Write-Host " → superadmin@unionflow.test" -ForegroundColor White
Write-Host "`n 🏦 MUKEFI (Mutuelle):" -ForegroundColor Magenta
Write-Host " → admin.mukefi@unionflow.test (Admin)" -ForegroundColor White
Write-Host " → tresorier.mukefi@unionflow.test (Trésorier)" -ForegroundColor White
Write-Host " → secretaire.mukefi@unionflow.test (Secrétaire)" -ForegroundColor White
Write-Host " → credit.mukefi@unionflow.test (Responsable Crédit)" -ForegroundColor White
Write-Host " → membre.mukefi@unionflow.test (Membre Actif)" -ForegroundColor White
Write-Host "`n 🤝 MESKA (Association):" -ForegroundColor Magenta
Write-Host " → admin.meska@unionflow.test (Admin)" -ForegroundColor White
Write-Host " → secretaire.meska@unionflow.test (Secrétaire)" -ForegroundColor White
Write-Host " → social.meska@unionflow.test (Responsable Social)" -ForegroundColor White
Write-Host " → evenements.meska@unionflow.test (Responsable Événements)" -ForegroundColor White
Write-Host " → membre.meska@unionflow.test (Membre Actif)" -ForegroundColor White
Write-Host "`n🌐 Accès Keycloak:" -ForegroundColor Yellow
Write-Host " • Console Admin: $KEYCLOAK_URL/admin" -ForegroundColor Cyan
Write-Host " • Realm: $REALM_NAME" -ForegroundColor Cyan
Write-Host ""