Configuration — Patterns API et intégration inter-services
Conventions HTTP communes à tous les endpoints du service Configuration et exemples d'intégration depuis les autres microservices. Pour la vue d'ensemble, voir Configuration — overview.
CRUD standard
Chaque entite expose un ensemble standardise de routes :
POST /v1/{entite} Creer
GET /v1/{entite} Lister (pagination : ?page=1&limit=20)
GET /v1/{entite}/active Lister les actifs uniquement
GET /v1/{entite}/:id Obtenir par ID
GET /v1/{entite}/code/:code Obtenir par code
PATCH /v1/{entite}/:id Mettre a jour
PATCH /v1/{entite}/:id/activate Activer
PATCH /v1/{entite}/:id/deactivate Desactiver
DELETE /v1/{entite}/:id SupprimerRecherche avancee
Toutes les entites supportent POST /v1/{entite}/search avec :
{
"name": "dollar", // Recherche ILIKE (insensible a la casse)
"code": "usd",
"is_active": true,
"created_after": "2025-01-01",
"created_before": "2025-12-31",
"page": 1,
"limit": 20,
"sort_by": "code",
"sort_order": "ASC"
}Operations en masse
Les entites supportent des operations bulk :
// POST /v1/{entite}/bulk-activate ou bulk-deactivate
{ "ids": ["uuid1", "uuid2", "uuid3"] }
// Reponse
{ "success": 2, "failed": 1, "errors": [{ "id": "uuid3", "error": "Not found" }] }
// POST /v1/{entite}/bulk-update
{ "updates": [{ "id": "uuid1", "name": "Nouveau nom" }, { "id": "uuid2", "is_active": false }] }Gestion des periodes (effective dating)
Les entites temporelles (frais, limites, seuils, regles) supportent :
| Champ | Comportement |
|---|---|
effective_from | Date de debut de validite (defaut : aujourd'hui) |
effective_to | Date de fin de validite (null = pas de fin) |
scheduled_status | scheduled (futur), active (en cours), cancelled (annule) |
Routes dediees :
GET /v1/{entite}/scheduled Configurations planifiees
GET /v1/{entite}/:id/active Configuration active actuelle
GET /v1/{entite}/:id/versions Historique des versions
PATCH /v1/{entite}/:id/cancel Annuler une configuration planifiee
POST /v1/{entite}/validate Valider avant enregistrementFormat de reponse
Toutes les reponses suivent le format standardise :
// Succes
{
"success": true,
"code": "SUCCESS",
"data": { /* entite ou tableau */ },
"meta": { "total": 100, "page": 1, "limit": 20 }
}
// Erreur
{
"success": false,
"code": "CONFLICT",
"data": null,
"errors": ["A currency with this code already exists"]
}Codes d'erreur metier
| Code | HTTP | Description |
|---|---|---|
SUCCESS | 200 | Reussite |
CREATED | 201 | Entite creee |
BAD_REQUEST | 400 | Donnees invalides |
RESOURCE_NOT_FOUND | 404 | Entite introuvable |
CONFLICT | 409 | Violation d'unicite (code, pair deja existante) |
VALIDATION_ERROR | 422 | Erreur de validation metier |
DATABASE_ERROR | 500 | Erreur base de donnees |
Seeding des donnees de reference
cd services/configuration
npm run seed:countries # 195+ pays
npm run seed:cities # Villes Congo/Cameroun (avec GPS)
npm run seed:activity-sectors # 12 secteurs economiques
npm run seed:zones # Zones geographiquesSeeds SQL supplementaires dans tools/database/seeds/ :
commission-rules-seed.sqlidentity-document-types-seed.sqlnotification-channels-seed.sqlsystem-service-types-seed.sql
Tous les seeders sont idempotents (ON CONFLICT DO NOTHING).
14. Exemples d'integration inter-services
Le service Configuration est consomme par les autres microservices via des appels HTTP internes. Voici les flux d'integration reels du projet.
Services consommateurs
| Service | Pattern d'integration | Donnees consommees |
|---|---|---|
| Orchestrator | HTTP Adapter (Clean Architecture) | Transaction types, frais, paliers, limites, devises |
| Ledger-Wallets | Appels HTTP directs | Types de moyens de paiement |
Variable d'environnement : CONFIGURATION_SERVICE_URL (defaut : http://configuration:3000)
14.1 Transfert P2P — Flux complet
Ce diagramme montre le workflow complet d'un transfert d'argent entre deux utilisateurs, incluant la resolution du type de transaction, le calcul des frais, et la validation des limites.
Appels Configuration dans ce flux :
GET /v1/transaction-types/code/TRANSFER
GET /v1/currencies/code/XAF
GET /v1/transaction-limits/applicable/{typeId}?entityType=user&entityId={senderId}
GET /v1/transaction-type-fees/transaction-type/{typeId}
GET /v1/fee-tiers/transaction-type-fee/{feeId}14.2 Cash-In Agent — Flux avec resolution de devise
14.3 Calcul des frais — 3 methodes de calcul
Exemple concret — Frais degressifs sur TRANSFER :
// 1. GET /v1/transaction-type-fees/transaction-type/{transferTypeId}
// Reponse :
{
"success": true,
"data": [{
"id": "fee-uuid-1",
"fee_type": { "code": "SERVICE_FEE", "name": "Frais de service" },
"calculation_method": "tiered",
"paid_by": "sender",
"effective_from": "2025-01-01",
"scheduled_status": "active"
}]
}
// 2. GET /v1/fee-tiers/transaction-type-fee/fee-uuid-1
// Reponse :
{
"success": true,
"data": [
{ "tier_order": 1, "min_amount": 0, "max_amount": 10000, "fixed_amount": 200, "percentage": null },
{ "tier_order": 2, "min_amount": 10000, "max_amount": 100000, "fixed_amount": null, "percentage": 0.015 },
{ "tier_order": 3, "min_amount": 100000, "max_amount": null, "fixed_amount": null, "percentage": 0.01 }
]
}
// Calcul pour un transfert de 50 000 FCFA :
// → Palier 2 applicable (10000 <= 50000 < 100000)
// → Frais = 50000 × 1.5% = 750 FCFA14.4 Resolution de moyen de paiement — Ledger-Wallets
Le service Ledger-Wallets appelle directement le service Configuration (sans adapter) pour resoudre les types de moyens de paiement.
Endpoints appeles par Ledger-Wallets :
GET /v1/payment-method-types/code/{code} # Resolution par code
GET /v1/payment-method-types/{id} # Resolution par ID14.5 Validation des limites — Hierarchie d'application
Exemple de reponse :
// GET /v1/transaction-limits/applicable/{typeId}?entityType=user&entityId=uuid-user-1
{
"success": true,
"data": {
"perTransaction": { "id": "lim-1", "amount": 500000, "entity_type": "global" },
"daily": { "id": "lim-2", "amount": 2000000, "entity_type": "role" },
"monthly": { "id": "lim-3", "amount": 10000000, "entity_type": "global" },
"limits": [
{ "id": "lim-1", "limit_type": "per_transaction", "entity_type": "global", "amount": 500000 },
{ "id": "lim-2", "limit_type": "daily", "entity_type": "role", "amount": 2000000 },
{ "id": "lim-3", "limit_type": "monthly", "entity_type": "global", "amount": 10000000 }
]
}
}14.6 Configuration complete d'un pays — Endpoint d'agregation
Cet endpoint retourne toutes les donnees de configuration d'un pays en un seul appel. Utile pour l'initialisation d'un client mobile.
Reponse type :
{
"success": true,
"data": {
"country": { "code": "CG", "name": "Congo", "risk_level": "low" },
"currencies": [
{ "code": "XAF", "symbol": "FCFA", "is_primary": true }
],
"paymentMethods": [
{ "code": "MTN_CG", "category": "external", "can_pay": true, "can_fund": true }
],
"transactionTypes": [
{ "code": "TRANSFER", "min_amount": 100, "max_amount": 5000000 },
{ "code": "CASH_IN", "min_amount": 500, "max_amount": 2000000 }
],
"limits": [
{ "transaction_type": "TRANSFER", "limit_type": "per_transaction", "amount": 500000 }
],
"rules": [
{ "to_country": "CM", "transaction_type": "TRANSFER", "is_allowed": true }
],
"thresholds": [
{ "threshold_type": "unverified_user", "amount": 50000, "currency": "XAF" }
],
"fees": [
{ "transaction_type": "TRANSFER", "calculation_method": "tiered", "tiers": [...] }
]
}
}14.7 Mapping snake_case / camelCase
L'adapter HTTP de l'Orchestrator transforme les reponses du service Configuration (snake_case) vers le format interne (camelCase) :
Configuration API (snake_case) Orchestrator interne (camelCase)
───────────────────────────── ──────────────────────────────────
min_amount → minAmount
max_amount → maxAmount
transaction_type_id → transactionTypeId
fee_type_id → feeTypeId
calculation_method → calculationMethod
effective_from → effectiveFrom
scheduled_status → scheduledStatus
minor_unit → minorUnit14.8 Resilience — Valeurs par defaut
Si le service Configuration est indisponible, l'Orchestrator utilise des limites par defaut pour ne pas bloquer les transactions :
{
"perTransaction": 500000,
"daily": 1000000,
"weekly": 5000000,
"monthly": 20000000
}Attention : Ce mecanisme de fallback ne s'applique qu'aux limites. Si la resolution du type de transaction ou de la devise echoue, la transaction est rejetee.