Aller au contenu

AML · Batch Screening

Module : aml-svc · fonction Batch Screening. Complémentaire au screening unitaire (POST /aml/screen) et au transaction monitoring (cf. AML Transaction Monitoring).

Le batch screening rescanne en masse la base cliente d’un tenant contre l’ensemble des listes AML (sanctions, PEP, adverse media) pour détecter les hits nouveaux ou évolutifs. C’est une exigence obligatoire côté conformité BCT, AMF, BaFin et FATF.


Cas d’usageFréquenceDéclencheur
Initial screening — première fois que l’IF onboarde VitaKYC : screener tout le stock existant (50 k à 10 M clients)One-shotMise en service
Rescreening périodique — conformité LCB-FT exige une revue régulière du portefeuilleMensuel / trimestrielPlanification
Delta rescreening — rescanne uniquement les clients contre les ajouts / changements de listes des dernières 24 hQuotidienUpdate des sources
Full rescreening après nouvelle source — quand le tenant active une nouvelle liste (ex : ajoute HMT ou SEPBLAC)PonctuelConfig tenant
Rescreening ciblé — sous-ensemble (ex : clients haute-valeur, clients d’un pays) pour audit interne ou contrôle BCTÀ la demandeCompliance officer
Audit externe / contrôle régulateur — réponse ponctuelle à une demande BCT / CRF / AMFExceptionnelRégulateur

Différence clé avec l’ongoing monitoring :

  • Ongoing monitoring (push, déjà dans le MVP §4.2.2) : Temporal cron 24 h, détecte les hits nouveaux sur les subjects déjà abonnés au monitoring, un à un.
  • Batch screening : job massivement parallélisé sur une cohorte définie (tout, ou un subset), génère un rapport complet (hits + clears) adapté à la production d’une preuve documentaire.


Le plus courant pour initial screening et audits. Upload direct via back-office ou API.

Format attendu (CSV UTF-8, en-tête obligatoire) :

external_id,full_name,full_name_ar,dob,nationality,country_residence,type
CUST-001,Mohamed Ben Ali,محمد بن علي,1985-03-12,TN,TN,individual
CUST-002,ACME Trading SARL,شركة أكمي للتجارة,,TN,TN,business
CUST-003,Sophia Boulouma,,1992-07-02,FR,FR,individual

Colonnes acceptées : external_id (obligatoire), full_name (obligatoire), full_name_ar, first_name, last_name, dob, dob_range (ex 1985-01:1985-12), nationality, country_residence, type (individual|business), gender, national_id.

Limite : 10 M lignes / fichier ; compression GZIP acceptée.

Pour intégrations programmatiques :

Fenêtre de terminal
curl -X POST https://api.vitakyc.io/v1/aml/batches \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Rescreening mensuel avril 2026",
"mode": "full",
"lists": ["OFAC","UN","EU","HMT","BCT_LOCAL"],
"include_pep": true,
"include_adverse_media": true,
"subjects": [
{ "external_id": "CUST-001", "full_name": "Mohamed Ben Ali",
"dob": "1985-03-12", "nationality": "TN" },
{ "external_id": "CUST-002", "full_name": "ACME Trading SARL",
"type": "business", "country_residence": "TN" }
]
}'

3.3 Query contre la base cliente du tenant (option avancée)

Section intitulée « 3.3 Query contre la base cliente du tenant (option avancée) »

Pour les tenants ayant connecté VitaKYC à leur référentiel client (via kyb_case / kyc_case persistés) :

Fenêtre de terminal
curl -X POST https://api.vitakyc.io/v1/aml/batches \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "Rescreening TN residents haute valeur",
"mode": "delta",
"source": {
"type": "query",
"filter": {
"kyc_case.status": "approved",
"kyc_case.risk_tier": ["high","very_high"],
"subject.country_residence": "TN"
}
},
"since": "2026-01-01T00:00:00Z"
}'
ModeDescription
fullScreening complet de la cohorte contre toutes les listes sélectionnées
deltaScreening uniquement contre les ajouts/changements de listes depuis since (par défaut : dernier batch du même nom)
listsdeltaLes subjects ne changent pas, mais on rescanne contre les nouveaux items ajoutés aux listes depuis le dernier batch
newlistActivation d’une nouvelle liste : rescanner toute la cohorte contre cette liste uniquement

  • Chunk size : 1 000 subjects par message Kafka.
  • Partitioning : hash sha256(tenant_id || external_id)[0..5] → partitions (32 par défaut).
  • Workers : autoscaling horizontal 1-20 pods selon la profondeur de file (HPA custom metric).
  • Idempotence : (batch_id, external_id) est la clé primaire ; rejouer un chunk est sans effet secondaire.
  • Throughput cible :
    • MVP : 500 k subjects / heure (avec 8 workers)
    • V1 : 5 M subjects / heure (avec 32 workers + cache liste en mémoire)

4.3 Matching engine (partagé avec screening sync)

Section intitulée « 4.3 Matching engine (partagé avec screening sync) »

Même moteur qu’en sync (cf. aml-svc matching fuzzy) :

  • Normalisation (casing, suppression diacritiques latins, NFKC unicode).
  • Translittération arabe ↔ latin via bibliothèque custom (محمد → Mohamed / Mohammed / Muhammad / Mohd).
  • Matching fuzzy Jaro-Winkler + phonetic (Metaphone, Beider-Morse).
  • Boost si correspondance DOB ± tolérance, nationality, national_id.
  • Seuils configurables par tenant :
    • auto_clear_threshold: 0.60 — sous ce seuil, pas de hit
    • review_threshold: 0.85 — entre les deux : revue manuelle
    • auto_match_threshold: 0.95 — au-delà : match fort, dossier priorisé

table: aml_batch
batch_id UUID PK
tenant_id UUID FK
name VARCHAR(255)
mode VARCHAR(16) -- full | delta | listsdelta | newlist
lists TEXT[]
include_pep BOOLEAN
include_adverse_media BOOLEAN
source_type VARCHAR(16) -- csv | json | query
source_ref TEXT -- MinIO key ou requête serialized
subjects_total INT
subjects_processed INT
subjects_with_hits INT
chunks_total INT
chunks_completed INT
status VARCHAR(16) -- queued | running | completed | failed | canceled
progress_pct NUMERIC(5,2)
requested_by UUID FK user
requested_at TIMESTAMPTZ
started_at TIMESTAMPTZ
completed_at TIMESTAMPTZ
report_csv_url TEXT
report_xlsx_url TEXT
report_pdf_url TEXT
webhook_delivered BOOLEAN
table: aml_batch_subject -- partitionné par batch_id
batch_subject_id UUID PK
batch_id UUID FK
tenant_id UUID FK
external_id VARCHAR(128)
subject_data JSONB -- snapshot input
hits_count INT
decision VARCHAR(32) -- auto_clear | review | match
processed_at TIMESTAMPTZ
UNIQUE (batch_id, external_id)
table: aml_batch_hit -- partitionné par batch_id
hit_id UUID PK
batch_subject_id UUID FK
list_source VARCHAR(32)
record_id VARCHAR(128)
match_score NUMERIC(5,4)
match_type VARCHAR(32) -- sanction | pep | adverse_media | rca
payload JSONB
decision VARCHAR(16) -- pending | true_positive | false_positive
reviewer_id UUID FK user
reviewed_at TIMESTAMPTZ
notes TEXT

POST /v1/aml/batches
Authorization: Bearer <token>
Idempotency-Key: <uuid>
{ "name": "...", "mode": "full", "lists": [...], "subjects": [...] }
202 Accepted
{ "batch_id": "...", "status": "queued", "subjects_total": 125000,
"estimated_completion": "2026-04-22T12:30:00Z" }
POST /v1/aml/batches/csv
Content-Type: multipart/form-data
name=Rescreening Q2 + lists=OFAC,UN,EU + file=@subjects.csv
→ 202 Accepted { "batch_id": "..." }
GET /v1/aml/batches/{batch_id}
→ 200 OK
{ "batch_id": "...", "status": "running", "progress_pct": 42.5,
"subjects_processed": 53125, "subjects_with_hits": 387, ... }
GET /v1/aml/batches/{batch_id}/hits?decision=pending&cursor=...&limit=100
→ 200 OK { "data": [ {hit}, {hit}, ... ], "next_cursor": "..." }
PATCH /v1/aml/batches/{batch_id}/hits/{hit_id}
{ "decision": "false_positive", "notes": "Homonymie confirmée, DOB différent" }
GET /v1/aml/batches/{batch_id}/report?format=xlsx
GET /v1/aml/batches/{batch_id}/report?format=pdf
GET /v1/aml/batches/{batch_id}/report?format=csv
{
"event": "aml.batch.completed",
"timestamp": "2026-04-22T12:28:14Z",
"data": {
"batch_id": "...",
"subjects_total": 125000,
"subjects_processed": 125000,
"subjects_with_hits": 1203,
"hits_total": 1840,
"report_csv_url": "https://.../report.csv",
"report_xlsx_url": "https://.../report.xlsx",
"report_pdf_url": "https://.../report.pdf"
}
}

┌──────────────────────────────────────────────────────────────────────────────┐
│ AML · Batch Screening [+ Nouveau batch] │
├──────────────────────────────────────────────────────────────────────────────┤
│ Rechercher : [_______________] Statut : [Tous ▾] Période : [Avril 2026 ▾] │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ Nom │ Mode │ Subjects │ Hits │ Statut │ Actions │ │
│ ├──────────────────────────────────────────────────────────────────────────┤ │
│ │ Rescreening Avril │ delta │ 125 030 │ 1203 │ ✅ Terminé │ [👁] [📥] [🔁] │ │
│ │ Initial screening │ full │ 854 120 │ 8914 │ ✅ Terminé │ [👁] [📥] │ │
│ │ Audit BCT Q1 │ full │ 125 030 │ 1188 │ ✅ Terminé │ [👁] [📥] │ │
│ │ Rescreening Mai │ delta │ 126 410 │ — │ ⏳ 42 % │ [👁] [⏹ Stop] │ │
│ │ Nouvelle liste HMT│ newlist│ 125 030 │ — │ ⏳ En file │ [👁] │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘
  • Barre de progression temps réel.
  • Histogramme des hits par liste source.
  • Table paginée des hits avec filtre (pending, true_positive, false_positive).
  • Workflow de revue : pour chaque hit, bouton Vrai positif / Faux positif / Escalader.
  • Export CSV / XLSX / PDF pour transmission contrôleurs BCT.
  • Option Planifier un rescreening récurrent (cron mensuel / trimestriel) en un clic.

Interface cron-friendly pour programmer des rescreenings automatiques :

[x] Rescreening mensuel le 1er à 02h00
[x] Delta rescreening quotidien à 05h00 contre les mises à jour de listes
[ ] Rescreening trimestriel du portefeuille haute-valeur

Chaque batch produit 3 formats de rapport :

FormatUsage
CSVIngestion dans un SIEM ou un outil compliance (Excel, Tableau, Power BI)
XLSXRevue par le compliance officer, avec feuilles séparées (subjects, hits, listes, stats)
PDFDossier signé pour audit BCT / AMF / BaFin — inclut une attestation de screening avec hash du fichier d’entrée, timestamp, listes utilisées, seuils appliqués, et preuve cryptographique
┌───────────────────────────────────────────────────────────┐
│ ATTESTATION DE SCREENING AML │
│ │
│ Tenant : Banque Exemple Tunisie │
│ Batch : Rescreening mensuel avril 2026 │
│ Batch ID : 7d3e9c2a-... │
│ Mode : Delta rescreening │
│ Période : 2026-04-01 → 2026-04-30 │
│ │
│ Source d'entrée │
│ Fichier : subjects_avril.csv.gz │
│ Lignes : 125 030 │
│ SHA-256 : 4f2a8... (empreinte fichier) │
│ │
│ Listes consultées │
│ OFAC SDN · snapshot 2026-04-22T06:00:00Z │
│ OFAC Cons. · snapshot 2026-04-22T06:00:00Z │
│ UN 1267 · snapshot 2026-04-22T06:00:00Z │
│ EU Consol. · snapshot 2026-04-22T06:00:00Z │
│ HMT UK · snapshot 2026-04-22T06:00:00Z │
│ BCT local · snapshot 2026-04-22T06:00:00Z │
│ PEP ComplyAdv · snapshot 2026-04-22T06:00:00Z │
│ Adverse media · snapshot 2026-04-22T06:00:00Z │
│ │
│ Résultats │
│ Subjects screenés : 125 030 │
│ Subjects avec hits : 1 203 (0,96 %) │
│ Hits totaux : 1 840 │
│ dont Sanctions : 42 │
│ dont PEP : 1 108 │
│ dont Adverse media : 690 │
│ │
│ Déroulement │
│ Démarrage : 2026-04-22 02:00:00 UTC │
│ Achèvement : 2026-04-22 02:17:42 UTC │
│ Durée : 17 min 42 s │
│ │
│ Attestation cryptographique │
│ Report hash SHA-256 : 8a4c1e... (empreinte rapport) │
│ Attestation signée : Ed25519 VitaKYC │
│ │
│ Certifie l'exactitude et la complétude du screening │
│ ci-dessus. │
│ │
│ Document généré le 2026-04-22 02:18:05 UTC │
└───────────────────────────────────────────────────────────┘

Volume base clienteModeTemps estimé MVP (8 workers)Temps estimé V1 (32 workers)
10 000full30 s10 s
100 000full5 min1,5 min
1 000 000full45 min12 min
10 000 000full7 h 302 h
100 000 000delta2 h30 min

Stratégie de warm cache pour accélérer : garder les listes AML en RAM des workers entre batches (évite de relire la liste OFAC à chaque chunk).


  • Rétention : résultats batch + rapports conservés 10 ans minimum (WORM) conformément LCB-FT.
  • Preuve de screening : l’attestation PDF est signée Ed25519 par VitaKYC pour preuve cryptographique auprès des régulateurs.
  • Droit à l’oubli GDPR : si un subject est effacé côté tenant, les hits le concernant sont purgés sauf si une enquête active est ouverte.
  • Chiffrement au repos : aml_batch_subject.subject_data chiffré en envelope encryption (KMS par tenant).
  • Multi-tenant : batches strictement isolés par tenant_id via RLS PostgreSQL (cf. ADR-002).

Le batch screening est inclus :

PlanInclusOver-usage
Starter10 k subjects/mois
Growth100 k subjects/mois0,05 €/subject
Enterprise1 M subjects/mois0,03 €/subject
Regulated On-Premillimité (inclus dans licence)

Les planifications récurrentes sont illimitées dans chaque plan.


  1. Batch screening est une exigence réglementaire (LCB-FT, BCT, FATF) — à livrer au MVP même si réduit en volume.
  2. Même moteur de matching qu’en sync → pas de code dupliqué, maintenance simplifiée.
  3. 3 modes d’entrée : CSV (le plus courant pour initial screening), JSON API, query base cliente (pour les tenants avancés).
  4. 4 modes d’exécution : full, delta, listsdelta, newlist — couvre tous les cas réglementaires.
  5. Parallélisation Kafka : chunking à 1 k subjects, autoscaling workers K8s, 500 k subjects/h au MVP → 5 M subjects/h en V1.
  6. Rapports tri-format (CSV + XLSX + PDF attestation cryptographique) — le PDF signé est le livrable audit à montrer aux régulateurs.
  7. Planification intégrée au back-office : un clic pour rescreenings récurrents.
  8. Rétention WORM 10 ans non négociable.

Document vivant · à enrichir avec les premières runs de volume réelles chez les pilotes.