Prélèvement de compte vers trésorerie
Procédure de prélèvement des soldes utilisateurs vers les comptes de trésorerie Nex (corrections comptables, sorties de fonds maîtrisées). Pour la vue d'ensemble et les impacts comptables, voir Trésorerie & destruction — overview.
Feature 1 — Prélèvement de compte vers trésorerie
Description
Deux chemins coexistent :
- Recall Request (formel) — Demande de prélèvement avec cycle de vie, document de validation et signature électronique. Peut être initiée par le backoffice ou par le titulaire du compte depuis l'app mobile-pro.
- Recall Direct — Prélèvement immédiat sans workflow, réservé aux corrections comptables et régularisations internes.
Chemin 1 — Recall Request (formel)
Deux initiateurs possibles
INITIATEUR A : Backoffice
→ Crée la demande au nom d'un titulaire de compte
→ Saisit : compte source, montant, motif, description
INITIATEUR B : Titulaire du compte (mobile-pro)
→ Crée sa propre demande depuis l'application
→ Saisit : montant, motif, description
→ Son compte est automatiquement résoluWorkflow complet
DRAFT
(Backoffice OU titulaire via mobile-pro)
↓
PENDING_SIGNATURE
(Document de validation généré et envoyé au titulaire)
↓
SIGNED
(Titulaire signe électroniquement depuis l'app mobile-pro)
↓
APPROVED
(Backoffice approuve — doit être différent de l'initiateur si backoffice)
↓
EXECUTED
(Débit availableBalance → TREASURY, écriture ledger créée)
↘ REJECTED (possible depuis PENDING_SIGNATURE, SIGNED ou APPROVED)Document de validation & signature électronique
À l'étape DRAFT → PENDING_SIGNATURE :
- Un document PDF est généré (résumé : titulaire, compte, montant, motif, date)
- Stocké via le file-service (
fileIdenregistré dans le RecallRequest) - Une notification push est envoyée au titulaire (via le notifications service)
À l'étape PENDING_SIGNATURE → SIGNED (sur mobile-pro) :
- Le titulaire consulte le document depuis l'app
- Il signe en confirmant son PIN (mécanisme d'authentification existant)
- La signature est horodatée, le
signedAtetsignedDocumentIdsont enregistrés
Motifs (RecallRequestReason)
RECALL — Rappel de fonds (distribution erronée)
RECOUVREMENT — Recouvrement de créance
FRAUDE — Compte bloqué pour fraudeRègles métier
- Prélèvement sur
availableBalanceuniquement (fonds non gelés) - Refus total si balance insuffisante — re-vérification au moment de l'exécution (balance peut avoir changé depuis le DRAFT)
- Initiateur backoffice ≠ approbateur backoffice
- Le titulaire doit signer avant l'approbation
- Un RecallRequest EXECUTED est irréversible
Entité RecallRequest
{
id: string
sourceAccountId: string // Compte à débiter
sourceAccountHolderPersonId: string // Titulaire du compte
amount: number
currencyCode: string
reason: RecallRequestReason
description?: string
status: RecallRequestStatus // DRAFT | PENDING_SIGNATURE | SIGNED | APPROVED | EXECUTED | REJECTED
initiatedBy: string // operatorId (backoffice) OU personId (mobile)
initiatedAt: Date
initiatorType: 'backoffice' | 'account_holder'
validationDocumentId?: string // fileId (file-service)
signedDocumentId?: string // fileId document signé
signedAt?: Date
approvedBy?: string
approvedAt?: Date
rejectedBy?: string
rejectedAt?: Date
rejectionReason?: string
executedAt?: Date
recallLedgerTransactionId?: string
metadata?: Record<string, unknown>
}Architecture backend
services/ledger-wallets/src/recalls/
├── recalls.module.ts
├── recalls.service.ts
└── entities/
└── recall-request.entity.ts
services/orchestrator/src/application/use-cases/treasury/recalls/
├── create-recall-request.use-case.ts
├── generate-recall-document.use-case.ts
├── sign-recall-request.use-case.ts
├── approve-recall-request.use-case.ts
├── reject-recall-request.use-case.ts
└── execute-recall-request.use-case.ts
services/orchestrator/src/presentation/controllers/
└── recalls.controller.tsRoutes orchestrateur
POST /treasury/recalls — Créer une demande (backoffice OU mobile-pro)
GET /treasury/recalls — Lister (filtres : status, account, dates)
GET /treasury/recalls/:id — Détail
POST /treasury/recalls/:id/sign — Signer (titulaire via mobile-pro)
POST /treasury/recalls/:id/approve — Approuver (backoffice)
POST /treasury/recalls/:id/reject — Rejeter
POST /treasury/recalls/:id/execute — Exécuter (backoffice)Architecture CMMS
Nouvelle page /treasury/withdrawals
Onglet 1 : Demandes de prélèvement
→ Liste des RecallRequests avec badges de statut
→ Actions contextuelles : Approuver / Rejeter / Exécuter
→ Créer une demande (au nom d'un titulaire)
→ Consulter le document de validation signé
Onglet 2 : Prélèvements directs
→ Historique des recalls directs (corrections comptables)
→ Bouton "Prélèvement direct" (CORRECTION_COMPTABLE, MANUAL_DEBIT uniquement)Architecture Mobile Pro
Nouvelle section app/recalls/
app/recalls/index.tsx — Historique des demandes (statuts, montants, dates)
app/recalls/new.tsx — Créer une nouvelle demande
app/recalls/[id]/index.tsx — Détail d'une demande
app/recalls/[id]/sign.tsx — Écran de signature du document (PIN + preview PDF)Notifications push : changements de statut (APPROVED, REJECTED, EXECUTED)
Chemin 2 — Recall Direct (corrections comptables)
Description
Opération immédiate sans workflow ni document. Réservée aux opérations internes de régularisation.
Motifs (RecallDirectReason)
MANUAL_DEBIT — Débit manuel
CORRECTION_COMPTABLE — Correction comptableFlux comptable
DÉBIT : compte source (availableBalance)
CRÉDIT : TREASURY
→ Opération atomique avec lock pessimiste
→ Refus total si availableBalance < montantRoutes orchestrateur
POST /treasury/recalls/direct — Exécuter un recall direct
GET /treasury/recalls/direct — Historique des recalls directsMigration SQL (Feature 1)
CREATE TABLE ledger_wallet.recall_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_account_id UUID NOT NULL,
source_account_holder_person_id UUID NOT NULL,
amount DECIMAL(20, 4) NOT NULL,
currency_code VARCHAR(3) NOT NULL,
reason VARCHAR(50) NOT NULL,
description TEXT,
status VARCHAR(30) NOT NULL DEFAULT 'draft',
initiated_by VARCHAR(255) NOT NULL,
initiated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
initiator_type VARCHAR(20) NOT NULL DEFAULT 'backoffice',
validation_document_id UUID,
signed_document_id UUID,
signed_at TIMESTAMPTZ,
approved_by VARCHAR(255),
approved_at TIMESTAMPTZ,
rejected_by VARCHAR(255),
rejected_at TIMESTAMPTZ,
rejection_reason TEXT,
executed_at TIMESTAMPTZ,
recall_ledger_transaction_id UUID,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_recall_req_account ON ledger_wallet.recall_requests (source_account_id);
CREATE INDEX idx_recall_req_holder ON ledger_wallet.recall_requests (source_account_holder_person_id);
CREATE INDEX idx_recall_req_status ON ledger_wallet.recall_requests (status);Tickets de mise en œuvre
T1 — Création d'une demande de prélèvement par le back-office
Titre : Création d'une demande de prélèvement sur un compte depuis le back-office
Description
En tant que Opérateur back-office / Responsable trésorerie
Je veux Pouvoir créer une demande de prélèvement sur le compte d'un titulaire (client, agent, marchand ou organisation), en précisant le montant, le motif et le compte cible
Afin de Initier formellement un rappel de fonds suite à une erreur de distribution, un recouvrement de créance ou la détection d'une fraude, avec une traçabilité complète de chaque étape
Règles de gestion
RG1 : Le back-office peut créer une demande sur n'importe quel type de compte actif (client, agent, marchand, organisation, compte commission)
RG2 : Seuls les fonds disponibles (solde disponible) du compte sont prélevables — les fonds gelés ne peuvent pas être ciblés
RG3 : Si le solde disponible du compte est inférieur au montant demandé au moment de la création, la demande est refusée immédiatement avec un message d'erreur explicite (pas de prélèvement partiel)
RG4 : Le motif est obligatoire et limité aux cas suivants : Rappel de fonds, Recouvrement de créance, Fraude
RG5 : Après création, la demande passe automatiquement en statut "En attente de signature" et un document de validation est généré et transmis au titulaire du compte pour signature
RG6 : L'opérateur qui crée la demande ne peut pas être celui qui l'approuve (séparation des responsabilités)
RG7 : Le back-office peut consulter toutes les demandes en cours et passées, filtrées par statut, compte ou période
Critères d'acceptation
- [ ] Une demande de prélèvement peut être créée depuis la page Trésorerie > Prélèvements
- [ ] La sélection du compte affiche le solde disponible en temps réel
- [ ] Un montant supérieur au solde disponible est bloqué avec un message d'erreur
- [ ] Le motif est une liste fermée (Rappel, Recouvrement, Fraude)
- [ ] Après création, le statut affiché est "En attente de signature"
- [ ] La demande apparaît dans la liste avec toutes ses informations (titulaire, compte, montant, motif, date, statut)
- [ ] L'historique complet des demandes est consultable et filtrable
T2 — Initiation d'une demande de prélèvement depuis l'app mobile
Titre : Demande de prélèvement sur son propre compte depuis l'app mobile-pro
Description
En tant que Titulaire de compte (agent, marchand, responsable d'organisation) connecté à l'application mobile-pro
Je veux Pouvoir soumettre moi-même une demande de prélèvement sur mon compte, en précisant le montant et le motif
Afin de Initier de façon autonome le rappel de fonds depuis mon compte vers la trésorerie Nex, sans avoir à contacter le back-office
Règles de gestion
RG1 : La demande porte uniquement sur le compte du titulaire connecté — il ne peut pas cibler un autre compte
RG2 : Le montant ne peut pas dépasser le solde disponible affiché au moment de la saisie
RG3 : Le titulaire voit son solde disponible en temps réel avant de soumettre la demande
RG4 : Après soumission, un document de validation est automatiquement généré et disponible dans l'app pour signature (voir T3)
RG5 : Le titulaire peut consulter l'historique de toutes ses demandes passées et en cours, avec le statut de chacune
RG6 : Le titulaire reçoit une notification push à chaque changement de statut de sa demande (approuvée, rejetée, exécutée)
RG7 : Une demande en statut "En attente de signature" ou "Signée" peut être annulée par le titulaire, tant qu'elle n'est pas encore approuvée
Critères d'acceptation
- [ ] Une section "Demandes de prélèvement" est accessible depuis l'app mobile-pro
- [ ] Le formulaire de création affiche le solde disponible du compte en temps réel
- [ ] La soumission est bloquée si le montant dépasse le solde disponible
- [ ] Après soumission, le statut "En attente de signature" est immédiatement visible
- [ ] L'historique des demandes est consultable avec statut, montant, motif et dates
- [ ] Les notifications push sont reçues à chaque changement de statut
- [ ] Une demande non encore approuvée peut être annulée depuis l'app
T3 — Signature électronique d'une demande de prélèvement
Titre : Signature électronique du document de validation d'une demande de prélèvement
Description
En tant que Titulaire du compte concerné par une demande de prélèvement
Je veux Pouvoir consulter le document de validation associé à la demande et le signer électroniquement depuis mon application mobile-pro via mon code PIN
Afin de Donner mon consentement formel, légalement traçable, avant que le prélèvement ne soit approuvé et exécuté par le back-office
Règles de gestion
RG1 : Seul le titulaire du compte concerné peut signer le document — aucun autre utilisateur ne peut signer à sa place
RG2 : Le document présente de façon claire : le nom du titulaire, le numéro de compte, le montant, le motif, la date et la référence de la demande
RG3 : La signature est validée par la saisie du code PIN du titulaire — le même mécanisme que pour les transactions
RG4 : La signature est horodatée et ne peut pas être rétractée une fois effectuée
RG5 : Après signature, la demande passe en statut "Signée" et le back-office est notifié pour procéder à l'approbation
RG6 : Si le titulaire n'a pas encore signé, il reçoit une notification push de rappel
RG7 : Le document signé est accessible en consultation dans l'historique de la demande, pour le titulaire comme pour le back-office
Critères d'acceptation
- [ ] Le document de validation est lisible depuis l'écran de détail de la demande dans l'app
- [ ] Un bouton "Signer" est disponible uniquement si le statut est "En attente de signature"
- [ ] La signature nécessite la saisie du code PIN valide — un PIN incorrect est refusé
- [ ] Après signature réussie, le statut passe à "Signée" et l'écran est mis à jour
- [ ] Le back-office voit le statut "Signée" et peut accéder au document signé
- [ ] La tentative de signature par un utilisateur autre que le titulaire est bloquée
T4 — Approbation et exécution d'une demande de prélèvement
Titre : Approbation, rejet et exécution d'une demande de prélèvement par le back-office
Description
En tant que Opérateur back-office (différent de celui qui a créé la demande)
Je veux Pouvoir approuver ou rejeter une demande de prélèvement signée par le titulaire, puis l'exécuter pour déclencher le mouvement de fonds
Afin de Garantir un contrôle à deux niveaux sur chaque prélèvement formel, en m'assurant que les fonds sont bien disponibles au moment de l'exécution
Règles de gestion
RG1 : Une demande ne peut être approuvée que si elle est en statut "Signée" — aucune approbation possible sans signature préalable du titulaire
RG2 : L'opérateur qui approuve doit être différent de celui qui a créé la demande
RG3 : En cas de rejet, un motif est obligatoire et communiqué au titulaire par notification
RG4 : Entre l'approbation et l'exécution, le solde disponible du compte est re-vérifié — si le solde est devenu insuffisant, l'exécution est bloquée et une alerte est remontée
RG5 : L'exécution déclenche le débit du solde disponible du compte source et le crédit de la trésorerie de façon atomique
RG6 : Une demande exécutée est irréversible — aucune annulation possible après l'exécution
RG7 : Le titulaire reçoit une notification push dès que la demande est approuvée, rejetée ou exécutée
Critères d'acceptation
- [ ] Les demandes en statut "Signée" apparaissent avec une action "Approuver / Rejeter"
- [ ] L'approbation est bloquée si l'opérateur connecté est le même que l'initiateur
- [ ] Le rejet nécessite un motif obligatoire et notifie le titulaire
- [ ] Les demandes approuvées affichent une action "Exécuter"
- [ ] Si le solde est insuffisant au moment de l'exécution, l'opération est annulée avec un message d'erreur clair
- [ ] Après exécution, les balances du compte source et de la trésorerie sont mises à jour
- [ ] L'historique complet (approbations, rejets, exécutions) est consultable et auditable
T5 — Prélèvement direct pour corrections comptables
Titre : Prélèvement immédiat sur un compte pour correction d'écart comptable
Description
En tant que Responsable trésorerie / Comptable back-office
Je veux Effectuer un prélèvement immédiat et sans workflow sur un compte, pour corriger un écart comptable ou régulariser un débit manuel
Afin de Résoudre rapidement des anomalies de solde internes sans bloquer les équipes avec un workflow de validation formel
Règles de gestion
RG1 : Le prélèvement direct est limité à deux motifs : Correction comptable, Débit manuel — tout autre motif doit passer par le workflow de demande formelle (T1)
RG2 : L'opération est immédiate et irréversible — le solde du compte est débité et la trésorerie créditée en temps réel
RG3 : Si le solde disponible du compte est insuffisant, l'opération est entièrement refusée — aucun prélèvement partiel
RG4 : Chaque prélèvement direct est enregistré avec : opérateur, date, compte débité, montant, motif et description libre
RG5 : L'historique de tous les prélèvements directs est accessible et consultable par le back-office, filtrable par période, compte et motif
Critères d'acceptation
- [ ] Un bouton "Prélèvement direct" est accessible depuis la page Trésorerie > Prélèvements (onglet dédié)
- [ ] Les motifs disponibles sont limités à "Correction comptable" et "Débit manuel"
- [ ] Le solde disponible du compte sélectionné est affiché avant confirmation
- [ ] Un montant supérieur au solde disponible est bloqué avec un message d'erreur
- [ ] Après exécution, les balances sont mises à jour immédiatement
- [ ] L'opération apparaît dans l'historique des prélèvements directs avec tous ses détails
- [ ] L'historique est filtrable par période, compte et motif