Story CP-012 : Console Admin — Liste des Tenants + Confirmation de Paiement + Suspension¶
Module : control-plane Slice : Slice 12a from architecture (split from original CP-012) Brand context : ALTARYS ENTERPRISE (Admin Console — corporate, data-dense, desktop-only) Priority : 12 Depends on : CP-001, CP-002, CP-003, CP-004, CP-005, CP-006, CP-007, CP-008, CP-009, CP-010 Estimated complexity : L
Objectif¶
Construire la console d'administration centrale de l'opérateur ALTARYS — une application React séparée (bureau uniquement, pas de hors ligne) pour gérer les tenants, confirmer les paiements par virement bancaire et suspendre/réactiver les tenants. Cette story établit le shell de l'application admin (AdminLayout, routing, auth), la liste des tenants avec filtrage/pagination, la vue détail tenant, le tableau de bord des paiements en attente et les flux de suspension/réactivation. Le remplacement de modules, la configuration pays et les métriques sont dans CP-029.
Périmètre Backend¶
Endpoints API (Admin uniquement)¶
Tous les endpoints nécessitent le rôle PLATFORM_ADMIN (géré par Keycloak, distinct des rôles tenant).
| Méthode | Chemin | Corps de requête | Réponse | Auth |
|---|---|---|---|---|
| GET | /api/v1/admin/tenants | ?status=&segment=&channel=&search= | Page |
PLATFORM_ADMIN |
| GET | /api/v1/admin/tenants/{id} | — | AdminTenantDetailResponse | PLATFORM_ADMIN |
| POST | /api/v1/admin/tenants/{id}/suspend | {reason} |
204 | PLATFORM_ADMIN |
| POST | /api/v1/admin/tenants/{id}/reactivate | — | 204 | PLATFORM_ADMIN |
| DELETE | /api/v1/admin/tenants/{id} | — | 204 (suppression logique) | PLATFORM_ADMIN |
| GET | /api/v1/admin/payments/pending | — | List |
PLATFORM_ADMIN |
| POST | /api/v1/admin/payments/{id}/confirm | — | 204 | PLATFORM_ADMIN |
| GET | /api/v1/admin/audit | Requête d'audit inter-tenant | Page |
PLATFORM_ADMIN |
Suspension de tenant : Définit status=SUSPENDED, nécessite un texte de raison, crée une entrée d'audit, envoie l'email ACCOUNT_SUSPENDED.
Considérations multi-tenant¶
- Les endpoints admin ne sont PAS tenant-scopés — ils interrogent TOUS les tenants
- La console admin utilise un client Keycloak séparé avec le rôle PLATFORM_ADMIN
- Toutes les actions admin sont enregistrées dans le journal d'audit avec le user_id de l'admin
Périmètre Frontend (Application React Séparée)¶
Configuration de l'application¶
- Application React séparée : répertoire
frontend-admin/(Vite + TypeScript + React 19) — répertoire de niveau supérieur distinct dans le monorepo, aux côtés defrontend/(Papillon) et futurfrontend-enterprise/(Décision D3) - Bureau uniquement : min-width 1024px, pas de layout mobile
- Pas de hors ligne : pas de PWA, pas de service workers, pas d'IndexedDB
- Design : bleu marine corporate (PAS l'ambre chaud de Papillon)
- Primary :
#1E3A5F, Accent :#2563EB, Background :#F9FAFB - Typographie : Inter 14px corps (plus dense que Papillon 16px)
- Voir spec design §15.1 pour le jeu de tokens admin complet
Pages & Routes¶
/dashboard— Liste des tenants avec cartes de synthèse KPI/tenants/:id— Détail tenant (onglets : Informations, Modules, Paiements, Audit, Actions)/payments— Tableau de bord des paiements en attente
Composants¶
AdminLayout.tsx— Navigation en sidebar (200px) + contenu principalTenantListPage.tsx— Tableau de données avec filtres, tri, paginationTenantDetailPage.tsx— Vue détail avec ongletsPendingPaymentsPage.tsx— Tableaux groupés (virements bancaires, échoués, en retard)
États UI¶
Liste des tenants :
| État | Comportement | Texte en Français |
|---|---|---|
| Loading | Squelette de tableau | — |
| Empty | "Aucun tenant trouvé" | — |
| Error | Bannière d'erreur au-dessus du tableau | "Erreur de chargement" |
| Success | Tableau de données avec pagination | — |
Interactions principales¶
Liste des tenants : Tableau dense. Colonnes : Statut, Entreprise, Segment, Employés, Canal, Créé, Paiement. Clic sur ligne → détail tenant. Filtres : dropdown Statut, dropdown Segment, dropdown Canal, plage de dates. Barre de recherche. Bouton Export CSV.
Paiements en attente : Rafraîchissement automatique toutes les 5 minutes. Bouton "Confirmer" → dialogue de confirmation → facture PAID → statut tenant mis à jour → email envoyé. "Relancer" envoie un email de rappel de paiement.
Suspension de tenant : Nécessite une raison saisie. Dialogue de confirmation. Envoie l'email ACCOUNT_SUSPENDED.
Icônes de statut dans le tableau des tenants :
| Statut | Icône | Couleur |
|---|---|---|
| ACTIVE | ● |
--admin-success (#059669) |
| TRIAL | ◐ |
--admin-accent (#2563EB) |
| ACTIVE_INCOMPLETE | ● |
--admin-warning (#D97706) |
| ACTIVE_PAYMENT_PENDING | ⚠ |
--admin-warning |
| PAYMENT_REQUIRED | ⚠ |
--admin-warning |
| SUSPENDED | ✕ |
--admin-error (#DC2626) |
| DELETED | ◌ |
--admin-text-secondary |
| PENDING | ◌ |
--admin-text-secondary |
| PENDING_VERIFICATION | ◌ |
--admin-text-secondary |
Critères d'acceptation¶
AC-095: Admin sees all tenants
Given 142 tenants exist on the platform
When the admin views the tenant list
Then all 142 are listed with pagination (20 per page)
And filters work for status, segment, channel, date
AC-096: Admin confirms bank transfer payment
Given a tenant has status ACTIVE_PAYMENT_PENDING
When the admin clicks "Confirmer le paiement"
Then the invoice is marked PAID
And the tenant status transitions to ACTIVE (or ACTIVE_INCOMPLETE)
And a PAYMENT_RECEIVED email is sent to the tenant admin
AC-097: Admin suspends tenant with reason
Given a tenant with status ACTIVE
When the admin suspends with reason "Non-paiement persistant"
Then the tenant status is SUSPENDED
And the reason is recorded in audit trail
And an ACCOUNT_SUSPENDED email is sent
Règles OHADA & Réglementaires¶
- Les actions admin (suspension, confirmation de paiement) sont enregistrées dans le journal d'audit — satisfait les exigences de responsabilité.
- La confirmation de paiement crée un enregistrement légal de la transaction.
Standards & Conventions¶
docs/standards/react-typescript-guidelines.md— §Tableaux de données, §Patterns admindocs/standards/api-guidelines.md— §Endpoints admin, §Pagination, §Filtrage
Exigences de test¶
Tests unitaires¶
- Autorisation API admin : PLATFORM_ADMIN requis pour tous les endpoints
- Suspension : raison obligatoire, transition de statut valide
- Confirmation de paiement : transition de statut de facture
Tests d'intégration¶
- Flux admin complet : liste → détail → suspension → réactivation
- Confirmation de paiement : mise à jour du statut facture + tenant
- Requêtes inter-tenant (l'admin peut voir tous les tenants)
- Autorisation : utilisateur non-admin → 403 sur les endpoints admin
Ce que le QA validera¶
- La liste des tenants s'affiche correctement avec toutes les colonnes
- Les filtres et le tri fonctionnent
- Flux de confirmation de paiement de bout en bout
- Flux de suspension avec raison
- La console admin est uniquement accessible avec le rôle PLATFORM_ADMIN
Hors périmètre¶
- Remplacement de module, éditeur de config pays, tableau de bord métriques — CP-029
- Canal C (création de tenant par l'admin) — V2
- Opérations en masse (suspendre plusieurs tenants, etc.) — V2
- Alertes automatisées (email à l'admin sur activité suspecte) — V2
- Reporting/analytics avancés — V2
- Vue admin mobile — Non prévu (outil bureau uniquement)
- Mode hors ligne de la console admin — Non nécessaire
Définition de Done¶
- [ ] Tous les endpoints backend implémentés et retournant les réponses correctes
- [ ] Toutes les pages frontend s'affichent correctement à 1024px+ (bureau uniquement)
- [ ] Tous les états UI implémentés (loading, empty, error, success) — pas d'état hors ligne nécessaire
- [ ] Textes français corrects
- [ ] Tous les critères d'acceptation passent manuellement
- [ ] Tests unitaires écrits et passants
- [ ] Tests d'intégration écrits et passants
- [ ] Isolation multi-tenant vérifiée — l'admin peut tout voir, les tenants ne peuvent pas voir l'admin
- [ ] Écriture hors ligne + sync — N/A (console admin toujours en ligne)
- [ ] Pas de
anyTypeScript — tous les types explicites - [ ] Pas de types Java bruts — tous les génériques explicites
- [ ] Les réponses API respectent le format d'enveloppe standard
- [ ] Entrées d'audit créées pour chaque action admin