Trésorerie — Prélèvement & Destruction de Monnaie Électronique
Date : 2026-03-13 Version : 2.0.0 Status : 📋 Spécification — En attente d'implémentation
Vue d'Ensemble
Deux nouvelles fonctionnalités complètent le cycle de vie de la monnaie électronique :
| Feature | Description | Impact masse monétaire |
|---|---|---|
| Prélèvement | Retrait de fonds disponibles d'un compte vers la trésorerie | Aucun (mouvement interne) |
| Destruction | Sortie de fonds hors du système (rachat de monnaie électronique) | Réduit la masse |
Cycle complet de la monnaie électronique
Création : Virement bancaire entrant → SUSPENSE → TREASURY (+masse)
[Implémenté via ReconciliationService]
Circulation : TREASURY ↔ comptes utilisateurs (neutre)
[Distributions + Prélèvements]
Destruction : TREASURY → BLACK_ACCOUNT (hors système) (-masse)
[Nouvelle feature — virement bancaire sortant réel requis]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);Feature 2 — Destruction de Monnaie Électronique
Description
Opération de sortie définitive de fonds hors du système, correspondant à un virement bancaire sortant réel. Réduit la masse monétaire électronique en circulation. La trésorerie est débitée au profit d'un compte black dédié (BLACK_ACCOUNT) qui accumule toutes les destructions — garantissant la traçabilité et l'intégrité comptable à partie double.
Pourquoi un compte black
AVANT (approche rejetée) APRÈS (approche retenue)
DÉBIT : TREASURY DÉBIT : TREASURY
CRÉDIT : ∅ (vide) CRÉDIT : BLACK_ACCOUNT
Problème : double-entrée Avantage : double-entrée
incomplète parfaite
BLACK_ACCOUNT.balance
= total de toute la monnaie détruite
→ indicateur clé pour compliance BEACComptes système — Nouveau compte
// À ajouter dans system-accounts.constants.ts
export enum SystemAccountType {
SUSPENSE = 'suspense',
TREASURY = 'treasury',
FEE_COLLECTION = 'fee_collection',
BLACK_ACCOUNT = 'black_account', // NOUVEAU
}
export const SYSTEM_ACCOUNT_IDS = {
SUSPENSE_XAF: '00000000-0000-0000-0000-000000000201',
TREASURY_XAF: '00000000-0000-0000-0000-000000000202',
FEE_COLLECTION_XAF: '00000000-0000-0000-0000-000000000203',
BLACK_ACCOUNT_XAF: '00000000-0000-0000-0000-000000000204', // NOUVEAU
}5 fichiers à modifier de façon cohérente :
AccountTypeenum →BLACK_ACCOUNT = 'black_account'SystemAccountTypeenum →BLACK_ACCOUNT = 'black_account'SYSTEM_ACCOUNT_IDS→BLACK_ACCOUNT_XAFSYSTEM_ACCOUNTS_CONFIG→ entrée de configurationAccountTypesByEntity.system→ ajouterAccountType.BLACK_ACCOUNT
Workflow
PENDING_APPROVAL
(Backoffice initie : montant, motif, référence bancaire sortante, banque)
↓
APPROVED
(Backoffice différent approuve)
↓
EXECUTED
(Débit TREASURY → Crédit BLACK_ACCOUNT, écriture ledger standard)
↘ REJECTED (possible depuis PENDING_APPROVAL)Flux comptable
AVANT
┌─────────────────┐ ┌─────────────────┐
│ TREASURY │ │ BLACK_ACCOUNT │
│ balance: T │ │ balance: D │
└─────────────────┘ └─────────────────┘
APRÈS EXECUTION
┌─────────────────┐ ┌─────────────────┐
│ TREASURY │ │ BLACK_ACCOUNT │
│ balance: T-X │ │ balance: D+X │
└─────────────────┘ └─────────────────┘
Écriture ledger (double-entrée standard) :
DÉBIT : TREASURY_XAF (X XAF)
CRÉDIT : BLACK_ACCOUNT_XAF (X XAF)
Référence : externalBankReference (virement sortant réel)Motifs (DestructionReason)
BANK_TRANSFER_OUT — Virement bancaire sortant standard
REGULATORY_ADJUSTMENT — Ajustement réglementaire (BEAC)
SETTLEMENT_PARTNER — Règlement partenaire externe
END_OF_DAY_SETTLEMENT — Règlement de fin de journéeRègles métier
externalBankReferenceobligatoire et unique dans le système- Initiateur ≠ approbateur (admin peut cumuler en phase initiale)
- Re-vérification
availableBalance >= amountà l'exécution - Une destruction EXECUTED est irréversible
- Le BLACK_ACCOUNT n'est jamais débité (lecture + crédit uniquement)
Entité MoneyDestructionRecord
{
id: string
amount: number
currencyCode: string
reason: DestructionReason
description?: string
externalBankReference: string // UNIQUE — référence virement sortant
externalBankName: string
status: MoneyDestructionStatus
initiatedBy: string
initiatedAt: Date
approvedBy?: string
approvedAt?: Date
rejectedBy?: string
rejectedAt?: Date
rejectionReason?: string
executedAt?: Date
treasuryLedgerTransactionId?: string // Pointe vers l'écriture TREASURY → BLACK_ACCOUNT
metadata?: Record<string, unknown>
}Architecture backend
services/ledger-wallets/src/destruction/
├── destruction.module.ts
├── destruction.service.ts
└── entities/
└── money-destruction.entity.ts
services/orchestrator/src/application/use-cases/treasury/destruction/
├── initiate-money-destruction.use-case.ts
├── approve-money-destruction.use-case.ts
├── reject-money-destruction.use-case.ts
└── execute-money-destruction.use-case.ts
services/orchestrator/src/presentation/controllers/
└── destruction.controller.tsRoutes orchestrateur
POST /treasury/destructions — Initier
GET /treasury/destructions — Lister (filtres : status, dates, banque)
GET /treasury/destructions/:id — Détail
POST /treasury/destructions/:id/approve — Approuver
POST /treasury/destructions/:id/reject — Rejeter
POST /treasury/destructions/:id/execute — ExécuterArchitecture CMMS
apps/cmms/app/pages/treasury/destructions.vue — Nouvelle page
apps/cmms/app/stores/destruction.ts — Nouveau store
apps/cmms/app/components/treasury/
├── DestructionInitiateModal.vue
├── DestructionApproveModal.vue
└── DestructionRejectModal.vue
apps/cmms/app/utils/models/destruction.model.tsPage system-accounts : le BLACK_ACCOUNT apparaît en lecture seule, badge "Monnaie détruite", sans action de distribution possible depuis ce compte.
Migration SQL (Feature 2)
CREATE TABLE ledger_wallet.money_destructions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
amount DECIMAL(20, 4) NOT NULL,
currency_code VARCHAR(3) NOT NULL,
reason VARCHAR(50) NOT NULL,
description TEXT,
external_bank_reference VARCHAR(255) NOT NULL UNIQUE,
external_bank_name VARCHAR(100) NOT NULL,
status VARCHAR(30) NOT NULL DEFAULT 'pending_approval',
initiated_by VARCHAR(255) NOT NULL,
initiated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
approved_by VARCHAR(255),
approved_at TIMESTAMPTZ,
rejected_by VARCHAR(255),
rejected_at TIMESTAMPTZ,
rejection_reason TEXT,
executed_at TIMESTAMPTZ,
treasury_ledger_transaction_id UUID,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX idx_destruction_bank_ref
ON ledger_wallet.money_destructions (external_bank_reference);Récapitulatif des Impacts
Backend — Fichiers créés ou modifiés
| Service | Fichier | Type |
|---|---|---|
ledger-wallets | recalls/recalls.service.ts | Nouveau |
ledger-wallets | recalls/entities/recall-request.entity.ts | Nouveau |
ledger-wallets | destruction/destruction.service.ts | Nouveau |
ledger-wallets | destruction/entities/money-destruction.entity.ts | Nouveau |
ledger-wallets | common/enums/account-type.enum.ts | Modifié |
ledger-wallets | common/constants/system-accounts.constants.ts | Modifié |
ledger-wallets | seeders/system-accounts.seeder.ts | Modifié |
orchestrator | use-cases/treasury/recalls/*.use-case.ts (×6) | Nouveau |
orchestrator | use-cases/treasury/destruction/*.use-case.ts (×4) | Nouveau |
orchestrator | controllers/recalls.controller.ts | Nouveau |
orchestrator | controllers/destruction.controller.ts | Nouveau |
CMMS — Fichiers créés ou modifiés
| Fichier | Type |
|---|---|
pages/treasury/withdrawals.vue | Nouveau |
pages/treasury/destructions.vue | Nouveau |
pages/treasury.vue (navigation) | Modifié |
stores/treasury.ts (+recall direct) | Modifié |
stores/destruction.ts | Nouveau |
components/treasury/RecallRequestModal.vue | Nouveau |
components/treasury/RecallDirectModal.vue | Nouveau |
components/treasury/DestructionInitiateModal.vue | Nouveau |
components/treasury/DestructionApproveModal.vue | Nouveau |
components/treasury/DestructionRejectModal.vue | Nouveau |
pages/treasury/system-accounts.vue (BLACK_ACCOUNT) | Modifié |
utils/models/recall.model.ts | Nouveau |
utils/models/destruction.model.ts | Nouveau |
Mobile Pro — Fichiers créés
| Fichier | Type |
|---|---|
app/recalls/index.tsx | Nouveau |
app/recalls/new.tsx | Nouveau |
app/recalls/[id]/index.tsx | Nouveau |
app/recalls/[id]/sign.tsx | Nouveau |
Infrastructure — Migrations
| Fichier | Type |
|---|---|
CreateRecallRequestsTable.js | Nouveau |
CreateMoneyDestructionsTable.js | Nouveau |
Document créé le : 2026-03-13 Version : 2.0.0
Annexe — Tickets Jira (suivi opérationnel)
Projet : NEX Référence technique :
infrastructure/docs/TRESORERIE_PRELEVEMENT_DESTRUCTION.md
Vue d'ensemble
| # | Titre | Persona | Dépend de |
|---|---|---|---|
| T1 | Création d'une demande de prélèvement par le back-office | Opérateur back-office | — |
| T2 | Initiation d'une demande de prélèvement depuis l'app mobile | Titulaire de compte | — |
| T3 | Signature électronique d'une demande de prélèvement | Titulaire de compte | T1 ou T2 |
| T4 | Approbation et exécution d'une demande de prélèvement | Opérateur back-office | T3 |
| T5 | Prélèvement direct pour corrections comptables | Responsable trésorerie | — |
| T6 | Initiation d'une destruction de monnaie électronique | Responsable trésorerie | — |
| T7 | Approbation et exécution d'une destruction de monnaie | Responsable conformité | T6 |
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 NxPay, 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
T6 — Initiation d'une destruction de monnaie électronique
Titre : Initiation d'une opération de destruction de monnaie électronique
Description
En tant que Responsable trésorerie
Je veux Pouvoir initier la sortie définitive d'un montant de la trésorerie hors du système, en y associant la référence du virement bancaire sortant réel
Afin de Assurer la conformité réglementaire lors du rachat de monnaie électronique, en maintenant à tout moment une correspondance entre les flux bancaires réels et la masse monétaire électronique en circulation
Règles de gestion
RG1 : Chaque destruction doit être associée à une référence de virement bancaire sortant unique — il est impossible d'utiliser deux fois la même référence
RG2 : La banque destinataire du virement doit être renseignée
RG3 : Après initiation, la destruction est en statut "En attente d'approbation" — aucun mouvement de fonds n'est effectué à ce stade
RG4 : Le responsable qui initie la destruction voit le solde disponible de la trésorerie au moment de la saisie
RG5 : Si le montant dépasse le solde disponible de la trésorerie, la création est refusée avec un message d'erreur
RG6 : L'historique de toutes les destructions (tous statuts confondus) est consultable, filtrable par période, statut et banque
RG7 : Le back-office peut consulter pour chaque destruction : montant, motif, référence bancaire, banque, initiateur, dates de chaque étape du workflow
Critères d'acceptation
- [ ] Une section "Destructions" est accessible depuis le menu Trésorerie
- [ ] Le formulaire affiche le solde disponible de la trésorerie en temps réel
- [ ] La référence bancaire sortante est obligatoire et unique — un doublon est refusé immédiatement
- [ ] La banque destinataire est obligatoire
- [ ] Un montant supérieur au solde de la trésorerie est bloqué
- [ ] Après création, le statut "En attente d'approbation" est visible dans la liste
- [ ] L'historique complet est filtrable par statut, banque et période
T7 — Approbation et exécution d'une destruction de monnaie
Titre : Approbation et exécution d'une destruction de monnaie électronique
Description
En tant que Responsable conformité / Administrateur trésorerie (différent de l'initiateur)
Je veux Pouvoir approuver ou rejeter une destruction initiée, puis l'exécuter pour déclencher le mouvement définitif hors du système
Afin de Garantir un double contrôle sur toute opération irréversible affectant la masse monétaire électronique, conformément aux exigences de la réglementation BEAC
Règles de gestion
RG1 : L'opérateur qui approuve doit être différent de celui qui a initié la destruction
RG2 : En cas de rejet, un motif est obligatoire
RG3 : Entre l'approbation et l'exécution, le solde de la trésorerie est re-vérifié — si le solde est devenu insuffisant, l'exécution est bloquée
RG4 : L'exécution transfère définitivement les fonds de la trésorerie vers le compte de destruction (compte black), qui accumule l'ensemble de la monnaie électronique détruite depuis l'ouverture du système
RG5 : Le solde du compte black est consultable à tout moment et représente le total cumulé de toute la monnaie électronique sortie du système
RG6 : Une destruction exécutée est irréversible — aucune annulation possible
RG7 : Le compte black est affiché en lecture seule sur la page des comptes système — aucune distribution ne peut être initiée depuis ce compte
Critères d'acceptation
- [ ] Les destructions en statut "En attente d'approbation" affichent les actions 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
- [ ] Les destructions approuvées affichent l'action "Exécuter"
- [ ] Si le solde de la trésorerie est insuffisant à l'exécution, l'opération est annulée avec un message d'erreur
- [ ] Après exécution, le solde de la trésorerie est réduit du montant détruit
- [ ] Le compte black affiche le solde cumulé mis à jour
- [ ] Le compte black est visible en lecture seule sur la page des comptes système, sans action possible
- [ ] L'audit complet (qui a initié, approuvé, exécuté, quand) est consultable pour chaque destruction
Document créé le : 2026-03-13 Version : 2.0.0