# Prompt p09 — Workflow Paiements (web)
*Contextes requis : ctx-global.md + ctx-web-nextjs.md + ctx-laravel-bff.md*

---

## Profil & Accès
- **Rôle TRE** : Trésorier — initiation + validation seuil <5M GNF auto
- **Rôle CFO** : validation seuil 5M–500M GNF + OTP
- **Rôle DG** : validation seuil 500M–1Mds GNF + OTP
- **Rôle CEO** : validation seuil >1Mds GNF + OTP
- **Rôle CPT** : Comptable — lecture seule (suivi des paiements validés)
- **Nombre d'utilisateurs** : 5 (1 par rôle)

---

## Fichiers à créer

```
app/(erp)/paiements/page.tsx
app/(erp)/paiements/[id]/page.tsx
app/(erp)/paiements/nouveau/page.tsx
components/paiements/PaiementForm.tsx
components/paiements/MatriceSeuils.tsx
components/paiements/CircuitValidation.tsx
components/paiements/OtpValidationModal.tsx
components/paiements/PaiementCard.tsx
components/paiements/TablePaiements.tsx
components/paiements/TypePaiementSelector.tsx
hooks/usePaiements.ts
hooks/useOtpValidation.ts
```

---

## Spec UX condensée

```
┌─────────────────────────────────────────────────────────────────────┐
│ FLOWUP ERP          Workflow Paiements                  [TRE/CFO]   │
├─────────────────────────────────────────────────────────────────────┤
│ [+ Nouveau paiement]    [En attente (7)] [Tous]    Filtres ▾        │
├─────────────────────────────────────────────────────────────────────┤
│ MATRICE DES SEUILS (info)                                           │
│ < 5M GNF        → Auto (Trésorier initie, validation automatique)  │
│ 5M – 50M GNF    → Trésorier approuve                               │
│ 50M – 500M GNF  → CFO approuve + OTP                               │
│ 500M – 1Mds GNF → DG approuve + OTP                                │
│ > 1Mds GNF      → CEO approuve + OTP                               │
├─────────────────────────────────────────────────────────────────────┤
│ LISTE PAIEMENTS EN ATTENTE                                          │
│ ┌───────────────────────────────────────────────────────────────┐   │
│ │ REF           │ TYPE        │ BÉNÉF.    │ MONTANT  │ STATUT  │   │
│ ├───────────────────────────────────────────────────────────────┤   │
│ │ PAY-2026-0147 │ Fournisseur │ TotalGin. │ 480M GNF │ ⏳ CFO  │   │
│ │ PAY-2026-0148 │ Salaires    │ Personnel │  89M GNF │ ⏳ CFO  │   │
│ │ PAY-2026-0149 │ Transport   │ Log.Afric │  12M GNF │ ⏳ TRE  │   │
│ │ PAY-2026-0150 │ Taxes       │ DGI       │   4M GNF │ ✓ AUTO  │   │
│ └───────────────────────────────────────────────────────────────┘   │
├─────────────────────────────────────────────────────────────────────┤
│ DÉTAIL PAIEMENT PAY-2026-0147                                       │
│ ┌──────────────────────────────┐  CIRCUIT DE VALIDATION             │
│ │ Type   : Fournisseur         │  ① Initiation TRE   ✓ 13/05 09:00 │
│ │ Bénéf. : TotalGin. SA        │  ② Validation TRE   ✓ 13/05 09:05 │
│ │ Montant: 480 000 000 GNF     │  ③ Validation CFO   ⏳ En attente  │
│ │ IBAN   : GN0120...           │  ④ OTP CFO          ○              │
│ │ Réf.   : FACT-2026-TG-089    │  ⑤ Exécution        ○              │
│ │ Motif  : Livraison Apr.2026  │                                     │
│ └──────────────────────────────┘  [VALIDER + OTP] [REJETER]         │
└─────────────────────────────────────────────────────────────────────┘
```

### 7 types de paiement
1. Fournisseurs (carburant, lubrifiant)
2. Salaires et charges sociales
3. Taxes et impôts (DGI, CNSS)
4. Transport et logistique
5. Maintenance et équipements
6. HSE (Hygiène, Sécurité, Environnement)
7. Divers

### Circuit complet
- **Initiation** : TRE saisit le paiement (type, bénéficiaire, montant, IBAN, référence facture, motif, pièces jointes)
- **Validation Trésorier** : TRE valide lui-même si <50M GNF
- **Validation CFO** : si 50M–500M GNF, CFO voit la file d'attente + OTP
- **Validation DG** : si 500M–1Mds GNF
- **Validation CEO** : si >1Mds GNF
- **Exécution** : passage en statut EXÉCUTÉ + génération ordre virement signé

---

## Endpoints BFF

```
GET /api/paiements
  Query : ?statut=en_attente|valide|execute|rejete&type={type}&page={n}
  Réponse : {
    data: [{
      id: INT,
      reference: "PAY-2026-0147",
      type: "fournisseur"|"salaires"|"taxes"|"transport"|"maintenance"|"hse"|"divers",
      beneficiaire_nom: "TotalGin. SA",
      montant: "480000000",        // VARCHAR (GNF)
      statut: "EN_ATTENTE_CFO"|"VALIDÉ"|"EXÉCUTÉ"|"REJETÉ",
      validateur_actuel: "CFO",
      created_at: "..."
    }],
    meta: { total: INT, en_attente: INT }
  }

GET /api/paiements/{id}
  Réponse : {
    id: INT,
    reference: "PAY-2026-0147",
    type: "fournisseur",
    beneficiaire_nom: "TotalGin. SA",
    beneficiaire_iban: "GN0120...",
    montant: "480000000",          // VARCHAR
    reference_facture: "FACT-2026-TG-089",
    motif: "Livraison carburant Avril 2026",
    pieces_jointes: ["url1", "url2"],
    seuil_validateur: "CFO",
    circuit: [{
      etape: "INITIATION",
      acteur: "TRE Bah",
      statut: "fait",
      date: "2026-05-13T09:00:00Z",
      commentaire: null
    }]
  }

POST /api/paiements
  Body : {
    type: "fournisseur",
    beneficiaire_nom: "TotalGin. SA",
    beneficiaire_iban: "GN0120...",
    montant: "480000000",          // VARCHAR
    reference_facture: "FACT-2026-TG-089",
    motif: "Livraison carburant Avril 2026",
    pieces_jointes_ids: [INT]
  }
  Réponse : { id: INT, reference: "PAY-2026-0147",
              seuil_validateur: "CFO", statut: "EN_ATTENTE_TRE" }

PUT /api/paiements/{id}/valider
  Body : { decision: "VALIDE"|"REJETE", commentaire: "...", otp: "123456"|null }
  Réponse : { id: INT, statut: "...", prochain_validateur: "DG"|null }

POST /api/paiements/otp/envoyer
  Body : { paiement_id: INT }
  Réponse : { sent: true, expire_in: 300 }

GET /api/paiements/stats
  Réponse : { en_attente_tre: INT, en_attente_cfo: INT, en_attente_dg: INT,
              en_attente_ceo: INT, execute_ce_mois: "...", total_ce_mois: "..." }
```

---

## Règles spécifiques

- **RGPAY-01** : La matrice des seuils est non modifiable dans l'UI standard — seul l'ADM peut la modifier depuis le module Administration. Affichage informatif uniquement.
- **RGPAY-02** : Montants = VARCHAR(255). La comparaison pour déterminer le seuil se fait côté BFF (jamais côté client). Le client envoie le montant en string, le BFF détermine le validateur.
- **RGPAY-03** : OTP requis pour toute validation ≥ 50M GNF. L'OTP expire en 5 minutes. Bouton "Renvoyer OTP" disponible après 60s.
- **RGPAY-04** : Le bouton "VALIDER + OTP" est `disabled + spinner` pendant le POST. Il ne se réactive que si la validation échoue.
- **RGPAY-05** : Un paiement rejeté peut être modifié et re-soumis par le TRE (retour au statut BROUILLON avec le commentaire de rejet visible).
- **RGPAY-06** : Les pièces jointes (factures scannées) sont uploadées séparément (`POST /api/documents`) avant la création du paiement. Le formulaire supporte le glisser-déposer.
- **RGPAY-07** : IDs = `number` (INT UNSIGNED). Soft delete = `statut: 3` (annulation par le TRE avant soumission).
- **RGPAY-08** : Chaque rôle ne voit que les paiements dans sa file d'attente par défaut. Un filtre "Tous" permet de voir l'historique complet (lecture seule pour les paiements hors de sa file).

---

## Tâche Claude

Génère le code complet Next.js 15 TypeScript pour le module Workflow Paiements FlowUp ERP.

**Contraintes techniques absolues :**
- Palette navy `#1A2157`, blue `#1E5EFF`, cyan `#00C8C0` — Inter + JetBrains Mono
- Montants = VARCHAR(255) → `string` dans les types TS
- IDs = `number` (INT UNSIGNED)
- La MatriceSeuils est un composant d'information statique (pas de saisie)
- OTP : input 6 chiffres avec auto-focus, paste support, timer 5min
- Affichage conditionnel des boutons d'action selon le rôle du JWT

**Génère dans cet ordre :**
1. Types TypeScript (`types/paiements.ts`)
2. Hook `usePaiements.ts` (liste, détail, SWR)
3. Hook `useOtpValidation.ts` (envoi, timer, vérification)
4. `MatriceSeuils.tsx` (tableau informatif statique)
5. `TypePaiementSelector.tsx` (7 types)
6. `CircuitValidation.tsx` (timeline étapes)
7. `OtpValidationModal.tsx` (OTP 6 chiffres, timer)
8. `PaiementForm.tsx` (initiation TRE, upload PJ)
9. `PaiementCard.tsx`, `TablePaiements.tsx`
10. Pages : `page.tsx` (liste), `[id]/page.tsx` (détail + validation), `nouveau/page.tsx`
