> ## Documentation Index
> Fetch the complete documentation index at: https://docs.colismove.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Happy paths Yaoundé↔Paris

> Sc 1 et Sc 2 — parcours nominaux complets, du booking à la livraison validée par QR.

Les deux happy paths couvrent les sens **Yaoundé→Paris** (Sc 1) et **Paris→Yaoundé** (Sc 2). Ils sont identiques en machine à états et en effets de bord, seules les coordonnées GPS et la devise diffèrent.

## Sc 1 — Yaoundé → Paris

### États traversés

```mermaid theme={null}
stateDiagram-v2
    [*] --> EN_ATTENTE_PAIEMENT
    EN_ATTENTE_PAIEMENT --> RESERVATION_PAYEE : Stripe captured
    RESERVATION_PAYEE --> EN_ATTENTE : auto
    EN_ATTENTE --> ACCEPTEE : carrier accepts
    ACCEPTEE --> EN_COURS_DE_LIVRAISON : QR dépôt
    EN_COURS_DE_LIVRAISON --> LIVREE : QR livraison
    LIVREE --> [*]
```

### Séquence détaillée

```mermaid theme={null}
sequenceDiagram
    actor S as Sender (Yaoundé)
    actor C as Carrier
    participant API as Backend
    participant Stripe
    participant PS as PackSentry
    actor R as Recipient (Paris)

    C->>API: POST /v1/api/announcements (trajet, dates, prix/kg)
    S->>API: GET /v1/api/announcements/search
    S->>API: POST /v1/api/bookings (5 kg, électronique)
    API->>Stripe: Checkout Session (escrow)
    Stripe-->>API: webhook checkout.session.completed
    Note over API: → RESERVATION_PAYEE → EN_ATTENTE
    C->>API: POST /v1/api/bookings/{id}/accept
    Note over API: → ACCEPTEE + QR dépôt
    S->>PS: Photo AVANT_DEPOT (mobile)
    S->>API: POST /v1/api/qrcode/process-depot
    Note over API: gate confirmerDepot OK → EN_COURS_DE_LIVRAISON
    Note over C: Trajet Yaoundé→Paris (J+3)
    C->>R: Livraison physique
    R->>API: POST /v1/api/qrcode/process-livraison
    Note over API: → LIVREE
    API->>Stripe: Transfer 85% au carrier (Connect)
    API-->>S: Email + push "Livré"
    API-->>C: Email + push "Paiement reçu"
```

### Acteurs et rôles

| Acteur         | Rôle                                       | Identification                              |
| -------------- | ------------------------------------------ | ------------------------------------------- |
| **Sender**     | Crée la réservation, paie, dépose le colis | Compte particulier KYC OK                   |
| **Carrier**    | Annonce le trajet, transporte le colis     | Compte verified user + Stripe Connect actif |
| **Recipient**  | Reçoit le colis, scanne QR livraison       | Pas de compte requis (page publique)        |
| **Backend**    | Orchestrateur, machine à états             | Spring Boot 3.4 hexagonal                   |
| **Stripe**     | Escrow + payout                            | Stripe Connect platform                     |
| **PackSentry** | Validation photos AVANT\_DEPOT/DEPOT       | Module hex `colismove-packsentry`           |

### Pré-requis carrier

* ✅ Compte vérifié (`ROLE_VERIFIED_USER` via Didit V2 ou Stripe Identity selon Pivot Flynanga)
* ✅ Stripe Connect onboarding complet (`charges_enabled = true`)
* ✅ Pays supporté (whitelist `colismove-finances`)
* ✅ Trajet annoncé non expiré

### Tests E2E

* `BookingFullJourneyIT` — couverture intégration full path
* Module : `colismove-app/src/test/java/.../scenarios/`

## Sc 2 — Paris → Yaoundé (sens inverse)

Identique à Sc 1 en logique métier. Différences :

* Coordonnées GPS inversées (origine Paris, destination Yaoundé)
* Devise unique (EUR) — pas de conversion (carrier facture en EUR, sender paie en EUR)
* Pays expéditeur ≠ pays destinataire ne change rien (pas de logique douanière dans MVP ColisMove)

Le test E2E réutilise `BookingFullJourneyIT` avec les coordonnées inversées.

## Effets de bord à chaque transition

| État cible              | Effets backend                                                              | Notifications                      |
| ----------------------- | --------------------------------------------------------------------------- | ---------------------------------- |
| `RESERVATION_PAYEE`     | Lock fonds Stripe, log `PaymentLog`                                         | —                                  |
| `EN_ATTENTE`            | Auto post-`RESERVATION_PAYEE`                                               | Push carrier "nouvelle résa"       |
| `ACCEPTEE`              | Génère QR dépôt (`QrCodeService.generateDepot`)                             | Push sender "QR prêt"              |
| `EN_COURS_DE_LIVRAISON` | Gate photos `confirmerDepot` (PackSentry), GPS tracking start               | Push sender "Colis pris en charge" |
| `LIVREE`                | `Stripe.transfers.create()` 85% au carrier, `WalletTransaction` enregistrée | Push + email + WhatsApp recipient  |

## Variantes Sc 1

Si l'un des éléments suivants se produit, le scénario bascule :

* Carrier refuse → **Sc 4** (REFUSEE)
* Sender annule pré-dépôt → **Sc 3** (ANNULEE refund)
* Sender annule post-dépôt → **Sc 5** (forcé LITIGE)
* Stripe refuse 3DS → **Sc 9** (ERREUR\_PAIEMENT)
* Recipient absent → **Sc 17** (3 tentatives max)
* Photo AVANT\_DEPOT manquante → **Sc 21** (HTTP 422)
* Photo DEPOT manquante au scan QR → **Sc 22** (HTTP 422 `PHOTO_DEPOT_MANQUANTE`)
