Aller au contenu

Story CP-012: Admin Console — Tenant List + Payment Confirmation + 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


Objective

Build the core ALTARYS operator admin console — a separate React application (desktop-only, no offline) for managing tenants, confirming bank transfer payments, and suspending/reactivating tenants. This story establishes the admin app shell (AdminLayout, routing, auth), the tenant list with filtering/pagination, tenant detail view, pending payments dashboard, and suspension/reactivation flows. Module override, country config, and metrics are handled in CP-029.


Backend Scope

API Endpoints (Admin-only)

All endpoints require PLATFORM_ADMIN role (Keycloak-managed, separate from tenant roles).

Method Path Request Body Response 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 (soft delete) 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 Cross-tenant audit query Page PLATFORM_ADMIN

Tenant suspension: Sets status=SUSPENDED, requires reason text, creates audit entry, sends ACCOUNT_SUSPENDED email.

Multi-Tenant Considerations

  • Admin endpoints are NOT tenant-scoped — they query across ALL tenants
  • Admin console uses a separate Keycloak client with PLATFORM_ADMIN role
  • All admin actions recorded in audit trail with admin's user_id

Frontend Scope (Separate React App)

Application Setup

  • Separate React app: frontend-admin/ directory (Vite + TypeScript + React 19) — separate monorepo top-level directory alongside frontend/ (Papillon) and future frontend-enterprise/ (Decision D3)
  • Desktop-only: min-width 1024px, no mobile layouts
  • No offline: no PWA, no service workers, no IndexedDB
  • Design language: Corporate navy/blue (NOT Papillon warm amber)
  • Primary: #1E3A5F, Accent: #2563EB, Background: #F9FAFB
  • Typography: Inter 14px body (denser than Papillon 16px)
  • See design spec §15.1 for full admin token set

Pages & Routes

  • /dashboard — Tenant list with KPI summary cards
  • /tenants/:id — Tenant detail (tabbed: Informations, Modules, Paiements, Audit, Actions)
  • /payments — Pending payments dashboard

Components

  • AdminLayout.tsx — Sidebar nav (200px) + main content
  • TenantListPage.tsx — Data table with filters, sorting, pagination
  • TenantDetailPage.tsx — Tabbed detail view
  • PendingPaymentsPage.tsx — Grouped tables (bank transfers, failed, overdue)

UI States

Tenant List:

State Behavior French Copy
Loading Table skeleton
Empty "Aucun tenant trouvé"
Error Error banner above table "Erreur de chargement"
Success Data table with pagination

Key Interactions

Tenant list: Dense table. Columns: Status, Entreprise, Segment, Employés, Canal, Créé, Paiement. Row click → tenant detail. Filters: Status dropdown, Segment dropdown, Canal dropdown, Date range. Search bar. Export CSV button.

Pending payments: Auto-refresh every 5 minutes. "Confirmer" button → confirmation dialog → invoice PAID → tenant status updated → email sent. "Relancer" sends payment reminder email.

Tenant suspension: Requires typed reason. Confirmation dialog. Sends ACCOUNT_SUSPENDED email.

Status icons in tenant table:

Status Icon Color
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

Acceptance Criteria

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

OHADA & Regulatory Rules

  • Admin actions (suspend, payment confirmation) are logged in the audit trail — satisfies accountability requirements.
  • Payment confirmation creates a legal record of the transaction.

Standards & Conventions

  • docs/standards/react-typescript-guidelines.md — §Data tables, §Admin patterns
  • docs/standards/api-guidelines.md — §Admin endpoints, §Pagination, §Filtering

Testing Requirements

Unit Tests

  • Admin API authorization: PLATFORM_ADMIN required for all endpoints
  • Suspension: reason required, status transition valid
  • Payment confirmation: invoice status transition

Integration Tests

  • Full admin flow: list → detail → suspend → reactivate
  • Payment confirmation: invoice + tenant status update
  • Cross-tenant queries (admin can see all tenants)
  • Authorization: non-admin user → 403 on admin endpoints

What QA Will Validate

  • Tenant list displays correctly with all columns
  • Filters and sorting work
  • Payment confirmation flow end-to-end
  • Suspension flow with reason
  • Admin console only accessible with PLATFORM_ADMIN role

Out of Scope

  • Module override, country config editor, metrics dashboard — CP-029
  • Channel C (admin creates tenant) — V2
  • Bulk operations (suspend multiple, etc.) — V2
  • Automated alerts (email to admin on suspicious activity) — V2
  • Advanced reporting/analytics — V2
  • Mobile admin view — Not planned (desktop-only tool)
  • Admin console offline mode — Not needed

Definition of Done

  • [ ] All backend endpoints implemented and returning correct responses
  • [ ] All frontend pages render correctly at 1024px+ (desktop-only)
  • [ ] All UI states implemented (loading, empty, error, success) — no offline state needed
  • [ ] French copy correct
  • [ ] All acceptance criteria pass manually
  • [ ] Unit tests written and passing
  • [ ] Integration tests written and passing
  • [ ] Multi-tenant isolation verified — admin can see all, tenants cannot see admin
  • [ ] Offline write+sync works — N/A (admin console always online)
  • [ ] No TypeScript any — all types explicit
  • [ ] No Java raw types — all generics explicit
  • [ ] API responses follow standard envelope format
  • [ ] Audit trail entries created for every admin action