# Prompt p08 — Ventes & CRM (web)
*Contextes requis : ctx-global.md + ctx-web-nextjs.md + ctx-laravel-bff.md*

---

## Profil & Accès
- **Rôle** : COM (Responsable Commercial)
- **Nombre d'utilisateurs** : 2
- **Accès** : tous les clients B2B, toutes les stations, pipeline commercial complet
- **Session** : 8h, OTP à la connexion

---

## Fichiers à créer

```
app/(erp)/ventes/page.tsx
app/(erp)/ventes/clients/page.tsx
app/(erp)/ventes/clients/[id]/page.tsx
app/(erp)/ventes/crm/page.tsx
app/(erp)/ventes/devis/page.tsx
app/(erp)/ventes/devis/[id]/page.tsx
app/(erp)/ventes/commandes/page.tsx
app/(erp)/ventes/contrats/page.tsx
app/(erp)/ventes/tarifs-b2b/page.tsx
components/ventes/DashboardVentes.tsx
components/ventes/CrmKanban.tsx
components/ventes/CrmKanbanColumn.tsx
components/ventes/CrmKanbanCard.tsx
components/ventes/ClientTable.tsx
components/ventes/DevisForm.tsx
components/ventes/PipelineChart.tsx
hooks/useVentes.ts
hooks/useCrm.ts
```

---

## Spec UX condensée

```
┌─────────────────────────────────────────────────────────────────────┐
│ FLOWUP ERP          Ventes & CRM                       [COM]        │
├─────────────────────────────────────────────────────────────────────┤
│ [Dashboard][Clients][CRM Kanban][Devis][Commandes][Contrats][Tarifs]│
├─────────────────────────────────────────────────────────────────────┤
│                    DASHBOARD COMMERCIAL                              │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│ │ CA Jour  │ │CA Semaine│ │ CA Mois  │ │Nb Ventes │ │Pipeline  │  │
│ │12,4M GNF │ │78,2M GNF │ │312M GNF  │ │   1 847  │ │ 8 devis  │  │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘  │
│                                                                      │
│ ┌──────────────────────────┐  ┌────────────────────────────────┐   │
│ │  TOP CLIENTS B2B (5)     │  │  PIPELINE CONTRATS (barre)     │   │
│ │  1. Guinée Bauxite  89M  │  │  PROSPECT         ████ 12      │   │
│ │  2. Africab Taxi    67M  │  │  QUALIFIÉ         ███  8       │   │
│ │  3. Transguinée     54M  │  │  DEVIS_ENVOYÉ     ██   5       │   │
│ │  4. BTP Soguipah    41M  │  │  NÉGOCIATION      █    3       │   │
│ │  5. Hôtel Kakimbo   38M  │  │  GAGNÉ            ██   6       │   │
│ └──────────────────────────┘  └────────────────────────────────┘   │
├─────────────────────────────────────────────────────────────────────┤
│                    CRM KANBAN                                        │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────┐ ┌──────┐    │
│ │ PROSPECT   │ │  QUALIFIÉ  │ │DEVIS_ENVOYÉ│ │NÉGOC.│ │GAGNÉ │    │
│ │     12     │ │     8      │ │     5      │ │  3   │ │  6   │    │
│ ├────────────┤ ├────────────┤ ├────────────┤ ├──────┤ ├──────┤    │
│ │ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │ │ ...  │ │ ...  │    │
│ │ │Conarail│ │ │ │G.Bauxite│ │ │ │Africab │ │ │      │ │      │    │
│ │ │Contact:│ │ │ │50M GNF │ │ │ │67M GNF │ │ │      │ │      │    │
│ │ │Diallo  │ │ │ │J+15    │ │ │ │Devis 3 │ │ │      │ │      │    │
│ │ │[→]     │ │ │ │[→][✉]  │ │ │ │[→][✉]  │ │ │      │ │      │    │
│ │ └────────┘ │ │ └────────┘ │ │ └────────┘ │ │      │ │      │    │
│ └────────────┘ └────────────┘ └────────────┘ └──────┘ └──────┘    │
└─────────────────────────────────────────────────────────────────────┘
```

### Modules clés
- **DashboardVentes** : 5 KPIs (CA Jour/Semaine/Mois, Nb ventes, Pipeline actif). Graphique CA mensuel + top 5 clients B2B + pipeline funnel.
- **CrmKanban** : colonnes glissantes (dnd-kit). Colonnes : PROSPECT → QUALIFIÉ → DEVIS_ENVOYÉ → NÉGOCIATION → GAGNÉ / PERDU. Cards avec nom client, montant potentiel, contact, délai. Drag & drop change le statut via API.
- **ClientTable** : liste paginée avec filtres (secteur, volume, statut contrat), recherche instantanée. Clic = fiche client détaillée (historique, devis, contrats, factures).
- **DevisForm** : sélection client + produits + volumes + tarif B2B + remise + conditions paiement. Preview PDF avant envoi.
- **Tarifs B2B** : grille tarifaire par client (prix négociés vs prix pompe public). Saisie des remises en % ou montant absolu.

---

## Endpoints BFF

```
GET /api/ventes/dashboard
  Query : ?periode=jour|semaine|mois
  Réponse : {
    ca_jour: "12400000",      // VARCHAR
    ca_semaine: "78200000",   // VARCHAR
    ca_mois: "312000000",     // VARCHAR
    nb_ventes: 1847,
    pipeline_actif: 8,
    top_clients: [{ id: INT, nom: "Guinée Bauxite", ca: "89000000" }],
    pipeline: { prospect: 12, qualifie: 8, devis_envoye: 5, negociation: 3, gagne: 6 }
  }

GET /api/clients
  Query : ?search={q}&secteur={s}&page={n}&per_page=20
  Réponse : {
    data: [{ id: INT, nom: "Guinée Bauxite", secteur: "Industrie",
             ca_total: "89000000", statut_crm: "QUALIFIÉ",
             contrat_actif: true }],
    meta: { total: INT, page: INT, last_page: INT }
  }

GET /api/clients/{id}
  Réponse : { id: INT, nom: "...", contacts: [...], adresse: "...",
             historique_ventes: [...], devis: [...], contrats: [...] }

GET /api/crm/opportunites
  Query : ?statut=prospect|qualifie|devis_envoye|negociation|gagne|perdu
  Réponse : [{ id: INT, client_nom: "...", montant_potentiel: "50000000",
               statut: "QUALIFIÉ", contact_nom: "Diallo", echeance: "2026-06-15" }]

PUT /api/crm/opportunites/{id}/statut
  Body : { statut: "QUALIFIÉ"|"DEVIS_ENVOYÉ"|"NÉGOCIATION"|"GAGNÉ"|"PERDU",
           commentaire: "..." }
  Réponse : { id: INT, statut: "..." }

POST /api/devis
  Body : {
    client_id: INT,
    lignes: [{ produit_id: INT, volume: "1000", prix_unitaire: "5900",
               remise_pct: "2" }],
    conditions_paiement: "30j",
    validite_jours: 30
  }
  Réponse : { id: INT, reference: "DEV-2026-0047", montant_total: "5782000",
              pdf_url: "..." }

GET /api/contrats
  Query : ?statut=actif|expire|suspendu&client_id={id}
  Réponse : [{ id: INT, reference: "CTR-2026-0012", client_nom: "...",
               montant_annuel: "...", debut: "...", fin: "...", statut: "..." }]

GET /api/ventes/tarifs-b2b
  Query : ?client_id={id}
  Réponse : [{ produit_id: INT, produit_nom: "Gasoil",
               prix_pompe: "6000", prix_b2b: "5900", remise_pct: "1.67" }]
```

---

## Règles spécifiques

- **RGCOM-01** : Le drag & drop CRM (dnd-kit) appelle immédiatement `PUT /api/crm/opportunites/{id}/statut`. En cas d'erreur API, la card revient à sa colonne d'origine (rollback optimiste).
- **RGCOM-02** : Un devis ne peut être créé que pour un client au statut CRM ≥ QUALIFIÉ.
- **RGCOM-03** : Montants = VARCHAR(255) partout. Calculs dans `utils/calcul-devis.ts` via `Decimal.js`.
- **RGCOM-04** : Le PDF devis est généré côté BFF (endpoint séparé) — le bouton "Prévisualiser PDF" ouvre un nouvel onglet avec l'URL signée du PDF.
- **RGCOM-05** : Les tarifs B2B sont confidentiels — ils ne sont visibles que par le rôle COM. Aucune donnée de tarif B2B dans les réponses API accessibles aux autres rôles.
- **RGCOM-06** : IDs = `number` (INT UNSIGNED). Soft delete = `statut: 3` pour les opportunités perdues/archivées (ne pas afficher en Kanban).
- **RGCOM-07** : Recherche client instantanée avec debounce 300ms sur l'input — pas de rechargement de page.
- **RGCOM-08** : La colonne PERDU du Kanban est masquée par défaut avec un toggle "Afficher les perdus".

---

## Tâche Claude

Génère le code complet Next.js 15 TypeScript pour le module Ventes & CRM FlowUp ERP.

**Contraintes techniques absolues :**
- Palette navy `#1A2157`, blue `#1E5EFF`, cyan `#00C8C0` — Inter + JetBrains Mono
- Montants = VARCHAR(255) → `string` dans les types TS. Calculs via `Decimal.js`
- IDs = `number` (INT UNSIGNED)
- dnd-kit pour le Kanban (pas react-beautiful-dnd)
- SWR pour les fetches, mutation optimiste sur le drag & drop

**Génère dans cet ordre :**
1. Types TypeScript (`types/ventes-crm.ts`)
2. Hook `useVentes.ts` (dashboard, clients, contrats)
3. Hook `useCrm.ts` (opportunités, mutation statut)
4. `CrmKanbanCard.tsx`, `CrmKanbanColumn.tsx`, `CrmKanban.tsx` (dnd-kit)
5. `ClientTable.tsx` (pagination SWR + recherche debounce)
6. `DevisForm.tsx` (lignes dynamiques, calcul Decimal.js)
7. `DashboardVentes.tsx` (KPIs + graphiques recharts)
8. `PipelineChart.tsx` (funnel horizontal)
9. Pages : `page.tsx` (dashboard), `clients/page.tsx`, `clients/[id]/page.tsx`, `crm/page.tsx`, `devis/page.tsx`, `devis/[id]/page.tsx`, `commandes/page.tsx`, `contrats/page.tsx`, `tarifs-b2b/page.tsx`
