Architecture technique
Version : 1.0 Date : 22 avril 2026 Auteur : Chaouki Barkia Documents liés :
Sommaire
Section intitulée « Sommaire »- Objectifs du document et hors-périmètre
- Principes d’architecture
- Vue macro de la plateforme
- Catalogue des services
- Modèle de données
- API publique
- Parcours critiques — diagrammes de séquence
- Gestion des licences modulaires
- Déploiement SaaS vs On-Premise
- Sécurité détaillée
- Observabilité et SLOs
- Capacity planning et sizing
- Exemple concret — générateur FATCA XML v2.0
- Plan de test et qualité
- Annexes
1. Objectifs du document et hors-périmètre
Section intitulée « 1. Objectifs du document et hors-périmètre »Ce document traduit le cahier des charges fonctionnel en une architecture technique actionnable : catalogue de services, contrats d’API, modèle de données, parcours, topologie de déploiement. Il vise à servir de référence pour l’équipe d’ingénierie dès le kickoff du MVP.
Hors périmètre (à produire ultérieurement) :
- Plan de test détaillé par cas (fichier QA dédié) ;
- Modèles ML et jeux d’entraînement OCR / liveness ;
- Guides ops (runbooks par incident) ;
- Dossier conformité audit (ISO 27001, SOC 2) ;
- Code source (le présent document décrit, ne code pas — sauf extraits illustratifs §13).
Les choix de stack rappelés dans ce document proviennent de la section 6 du cahier des charges. Toute divergence ultérieure doit être tracée par un ADR (Architecture Decision Record) dans le dépôt code.
2. Principes d’architecture
Section intitulée « 2. Principes d’architecture »| # | Principe | Implication |
|---|---|---|
| 1 | Un codebase, deux modes | SaaS et on-prem s’appuient sur la même image OCI et le même Helm chart ; la différence est dans les values. |
| 2 | API-first | Chaque capacité métier est exposée par API interne avant toute UI. La console back-office est un client API comme un autre. |
| 3 | Event-driven pour les traitements async | Kafka transporte les événements métier (document uploadé, décision KYC, alerte AML). Les services consomment ce qui les concerne. |
| 4 | Stateless services + état externalisé | Chaque service est scalable horizontalement ; l’état persiste dans PostgreSQL, Redis, MinIO, Kafka. |
| 5 | Isolation tenant par défaut | tenant_id en clé logique partout, clé de chiffrement dédiée par tenant, row-level security PostgreSQL. |
| 6 | Sécurité par défaut | mTLS service-à-service, OIDC pour utilisateurs, chiffrement au repos et en transit, secrets via Vault. |
| 7 | Observabilité native | Chaque service émet traces OpenTelemetry, métriques Prometheus, logs JSON structurés. |
| 8 | Pas de dépendance propriétaire cloud | Tout composant a un équivalent OSS utilisable on-prem (MinIO pour S3, Vault pour KMS, Keycloak pour IAM). |
| 9 | Composants vétustes remplaçables | Les contrats entre services sont versionnés ; remplacer un service (ex : OCR engine) n’impacte pas les autres. |
| 10 | Mesure du coût unitaire | Chaque vérification porte une étiquette de coût (cost_unit) remontée aux analytics pour calculer la marge par check. |
3. Vue macro de la plateforme
Section intitulée « 3. Vue macro de la plateforme »4. Catalogue des services
Section intitulée « 4. Catalogue des services »4.1 Services métier (domaines)
Section intitulée « 4.1 Services métier (domaines) »| Service | Responsabilité | Langage | Dépendances | Criticité |
|---|---|---|---|---|
| identity-svc | Gestion users, tenants, rôles, clés API, consentements ; intégration Keycloak | Kotlin / Spring Boot | PostgreSQL, Keycloak | P0 |
| kyc-svc | Orchestration d’un dossier KYC (individu + entreprise), état, décision | Kotlin / Spring Boot | PostgreSQL, Kafka, Temporal | P0 |
| aml-svc | Screening sanctions/PEP/adverse media, ongoing monitoring, risk scoring | Kotlin / Spring Boot | PostgreSQL, OpenSearch, Kafka, Temporal | P0 |
| tcr-svc | Tax Compliance & Reporting : classification, formulaires, reporting FATCA/CRS | Kotlin / Spring Boot | PostgreSQL, MinIO, Kafka | P1 (P0 pour clients banque) |
| workflow-svc | Moteur de règles d’orchestration no-code + états de workflow configurables | Kotlin / Spring Boot | PostgreSQL, Temporal | P0 |
| case-svc | Case management back-office : queue agent, assignation, commentaires, SLA | Kotlin / Spring Boot | PostgreSQL, Kafka | P1 |
| audit-svc | Journal d’audit immutable (WORM + hash chain) ; export SIEM | Kotlin / Spring Boot | PostgreSQL + table append-only, OpenSearch | P0 |
| report-svc | Génération XML FATCA v2.0, XML CRS, rapports PDF, exports | Kotlin / Spring Boot | PostgreSQL, MinIO | P1 |
4.2 Services IA / ML
Section intitulée « 4.2 Services IA / ML »| Service | Responsabilité | Langage | Modèle de déploiement |
|---|---|---|---|
| ocr-svc | OCR documents (passeport, CNI, justificatifs) ; arabe + latin + hindi | Python / FastAPI / ONNX Runtime | CPU par défaut, GPU optionnel (auto-scaling sur demande) |
| liveness-svc | Détection de vie (passive niveau 2, fallback actif) | Python / FastAPI / ONNX Runtime | GPU recommandé en SaaS, CPU suffisant en on-prem faible volume |
| face-match-svc | Comparaison biométrique faciale document ↔ selfie | Python / FastAPI / ONNX Runtime | CPU (latence tolérable) |
| voice-svc (V2) | Biométrie vocale | Python / FastAPI | GPU |
| nlp-aml-svc | NLP adverse media (classification, extraction) | Python / FastAPI | GPU pour fine-tuning, CPU pour inference |
4.3 Services transverses
Section intitulée « 4.3 Services transverses »| Service | Responsabilité |
|---|---|
| doc-store | Wrapper stockage fichiers avec chiffrement per-tenant (KMS), signed URLs, retention, legal hold |
| webhook-dispatcher | Signature HMAC, retries exponentiels, dead-letter queue, replay manuel |
| license-svc | Vérification clé Ed25519, feature flags, rate limiting par licence, phone-home on-prem optionnel |
| notification-svc | Email (SMTP externalisé), SMS (provider au choix), push mobile, templates par tenant |
| connector-rne | Adaptateur RNE Tunisie (services KYC + UBO) avec cache Redis, fallback, circuit breaker |
| connector-ides | Adaptateur IDES/DGI Tunisie (dépôt FATCA, récupération AD/RE) |
| connector-data | Adaptateurs data enrichment (World-Check, Dow Jones, D&B…) via couche d’abstraction |
4.4 Services d’infrastructure
Section intitulée « 4.4 Services d’infrastructure »| Composant | Choix | Justification |
|---|---|---|
| API Gateway | Kong | Plugins matures, OSS, runtime léger. Alternative : Envoy. |
| Service mesh (mTLS) | Linkerd | Plus léger qu’Istio, mTLS natif, observabilité native. |
| Bus événements | Kafka (SaaS) / Redpanda (on-prem léger) | Exactly-once, partitionnement par tenant, retention pour audit. |
| Workflow engine | Temporal.io | Durabilité, retry natif, long-running (ongoing monitoring AML, revalidation FATCA à 3 ans). |
| Cache & locks | Redis 7 (ou Valkey OSS) | Pub/Sub, distributed locks (Redlock), rate limiting. |
| Recherche | OpenSearch | Full-text multilingue (arabe), analytics dashboards, SIEM export. |
| IAM | Keycloak | OIDC, SAML, SCIM, portable cloud/on-prem. |
| Secrets | HashiCorp Vault | KV v2, dynamic secrets DB, PKI interne, rotation auto. |
| Object storage | S3 API (AWS S3 / GCS / MinIO on-prem) | Portabilité totale. |
| CI/CD | GitHub Actions + ArgoCD | GitOps, auditabilité. |
5. Modèle de données
Section intitulée « 5. Modèle de données »5.1 Stratégie multi-tenant
Section intitulée « 5.1 Stratégie multi-tenant »- Modèle choisi : shared schema, row-level isolation via colonne
tenant_idobligatoire sur toute table métier + Row Level Security (RLS) PostgreSQL activée. - Clé de chiffrement par tenant (colonne
tenant_encryption_key_id→ HashiCorp Vault Transit engine). Les champs PII (documents, données de naissance, TIN) sont chiffrés côté application. - Isolation renforcée pour clients Enterprise / Regulated : schémas dédiés par tenant (option), voire base dédiée.
- On-prem : la notion de tenant est conservée (pour une future extension) mais dégénérée à un seul tenant actif.
5.2 Schémas principaux
Section intitulée « 5.2 Schémas principaux »5.2.1 Identity & tenant
Section intitulée « 5.2.1 Identity & tenant »table: tenant tenant_id UUID PK code VARCHAR(64) UNIQUE name VARCHAR(255) deployment_mode ENUM('saas_shared', 'saas_dedicated', 'on_premise') residency_region VARCHAR(32) -- 'eu-west', 'mena', ... encryption_key_id VARCHAR(128) -- ref Vault Transit license_id UUID FK status ENUM('active', 'suspended', 'terminated') created_at, updated_at
table: user user_id UUID PK tenant_id UUID FK email CITEXT keycloak_subject VARCHAR(64) -- sub OIDC role ENUM('agent','supervisor','admin','auditor','api_client') status ENUM('active','invited','disabled') last_login_at created_at, updated_at UNIQUE(tenant_id, email)
table: api_key api_key_id UUID PK tenant_id UUID FK key_hash BYTEA -- argon2id scopes TEXT[] -- ex: kyc.read, tcr.write expires_at TIMESTAMPTZ created_by UUID FK user created_at, revoked_at5.2.2 KYC
Section intitulée « 5.2.2 KYC »table: kyc_case case_id UUID PK tenant_id UUID FK external_ref VARCHAR(128) -- reference client subject_type ENUM('individual','business') status ENUM('created','in_progress','auto_approved', 'manual_review','approved','rejected','expired') decision_reason TEXT risk_score NUMERIC(5,2) opened_at, closed_at expires_at TIMESTAMPTZ -- validité KYC (réglementaire) workflow_instance_id VARCHAR(128) -- Temporal workflow ID created_at, updated_at
table: kyc_individual case_id UUID PK FK first_name BYTEA -- chiffré last_name BYTEA -- chiffré dob BYTEA -- chiffré nationality CHAR(2) place_of_birth_country CHAR(2) -- indicia FATCA (dérivés pour scoring rapide) : fatca_indicia_count SMALLINT -- ...
table: kyc_business case_id UUID PK FK tenant_id UUID FK -- identifiants rne_id VARCHAR(16) -- identifiantUnique RNE (7 chiffres + 1 lettre) registration_number VARCHAR(64) -- num_REGISTRE_INTERNE RNE ou équivalent registration_country CHAR(2) -- dénominations (bilingue) legal_name_fr VARCHAR(255) -- denomination_FR legal_name_ar VARCHAR(255) -- denomination_AR trade_name_fr VARCHAR(255) -- nom_COMMERCIAL_FR trade_name_ar VARCHAR(255) brand_fr VARCHAR(255) -- enseigne_FR brand_ar VARCHAR(255) -- structure légale legal_form_fr VARCHAR(150) -- forme_JURIDIQUE_FR legal_form_ar VARCHAR(150) entity_type CHAR(1) -- 'P' (Physique) | 'M' (Morale) category VARCHAR(32) -- A/S/E (PM) ; A/C/M (PP) auto_entrepreneur BOOLEAN -- capital capital_amount NUMERIC(30,3) capital_currency CHAR(3) DEFAULT 'TND' last_balance_year SMALLINT -- dernier_BILAN_DEPOSE -- statut status VARCHAR(32) -- mappé : active | suspended | closed (depuis NORMAL / RADIE_PROVISOIREMENT / RADIE_DEFINITIVEMENT) date_start_activity DATE date_registration DATE -- date_ENREGISTREMENT_RNE date_publication DATE date_radiation DATE date_last_update DATE -- date_DERNIERE_MAJ -- adresses (siège et activité) address_head JSONB -- {gouvernorat, ville, rue, code_postal} × {ar, fr} address_activity JSONB -- activités NAT 1996 primary_activity JSONB -- {codeActivite, detailActiviteArabe, detailActiviteLatin} secondary_activities JSONB -- UBO déclarés has_ubo_declaration BOOLEAN -- declaration_BENEFICIAIRES_EFFECTIFS -- métadonnées fournisseur source VARCHAR(32) -- 'RNE_WS_KYC' | 'MANUAL' | 'INFOGREFFE' | ... source_fetched_at TIMESTAMPTZ raw_payload JSONB -- payload brut pour audit
table: kyc_business_officer -- direction (dirigeants) officer_id UUID PK case_id UUID FK rne_gestion_id VARCHAR(16) -- IDENTIFIANT_UNIQUE_GESTION national_id VARCHAR(40) -- NUM_PIECE_IDENTITE_GESTION national_id_date DATE first_name_fr VARCHAR(100) first_name_ar VARCHAR(100) last_name_fr VARCHAR(100) last_name_ar VARCHAR(100) full_name_fr VARCHAR(255) -- NOM_PRENOM_GESTION_FR (pour matching) full_name_ar VARCHAR(255) gender CHAR(2) nationality_fr VARCHAR(50) nationality_ar VARCHAR(50) dob DATE birth_country_fr VARCHAR(100) birth_country_ar VARCHAR(100) role_fr VARCHAR(100) -- QUALITE_GESTION_FR (Commissaire aux Comptes, Directeur Général, ...) role_ar VARCHAR(100) is_statutory BOOLEAN -- STATUTAIRE nomination_from DATE -- DATE_NOMINATION nomination_to DATE -- DATE_FIN_NOMINATION address JSONB powers JSONB -- pouvoirs[{libelle_fr, libelle_ar}] -- AML aml_subject_id UUID -- lien vers aml_subject pour screening
table: kyc_business_ubo -- bénéficiaires effectifs (WS-BE) ubo_id UUID PK case_id UUID FK declaration_number VARCHAR(40) -- NUM_DECLARATION type VARCHAR(32) -- 'detention_capital' | 'gestion' | 'pouvoir' full_name_fr VARCHAR(255) -- NP_PERSONNE_FR full_name_ar VARCHAR(255) nationality VARCHAR(50) national_id VARCHAR(40) -- NID_PERSONNE resident BOOLEAN -- RESIDENT : true si Résident capital_direct NUMERIC(10,3) -- % détenu directement capital_indirect NUMERIC(10,3) voting_rights NUMERIC(10,3) -- DROIT_VOTE declaration_date DATE -- DATE_DECLARATION beneficiary_start DATE -- DATE_DEBUT_ETRE_BENEFICIAIRE status VARCHAR(16) -- 'ACTIF' | 'INACTIF' -- AML aml_subject_id UUID
table: rne_subscription -- gestion des abonnements RNE par tenant subscription_id SERIAL PK tenant_id UUID FK rne_subscription_id INT -- fourni par le RNE rne_subscriber_id INT -- fourni par le RNE rne_code_motif INT -- motif WS-BE bearer_token_ref VARCHAR(128) -- ref Vault outbound_ip INET -- IP déclarée au RNE balance_remaining INT -- cache informatif active BOOLEAN created_at, updated_at
table: kyc_document document_id UUID PK case_id UUID FK type ENUM('passport','id_card','drivers_license', 'proof_address','trade_license','rne_extract', ...) object_key VARCHAR(512) -- clé MinIO/S3 (chiffré SSE-KMS) ocr_status ENUM('pending','done','failed') ocr_payload JSONB -- champs extraits verification_status ENUM('pending','valid','invalid','suspicious') created_at
table: kyc_biometric_check check_id UUID PK case_id UUID FK kind ENUM('liveness_passive','liveness_active','face_match','voice') score NUMERIC(5,4) passed BOOLEAN details JSONB performed_at5.2.3 AML
Section intitulée « 5.2.3 AML »table: aml_subject subject_id UUID PK tenant_id UUID FK case_id UUID FK kyc_case full_name_norm VARCHAR(512) -- normalisé (translittération, minuscules) dob DATE nationality CHAR(2) status ENUM('clear','alert','blocked') last_screened_at
table: aml_screening screening_id UUID PK subject_id UUID FK screened_at TIMESTAMPTZ sources TEXT[] -- ex: OFAC, UN, EU, HMT, BCT, adverse_media hits_count INT decision ENUM('auto_clear','manual_review','escalate','block')
table: aml_hit hit_id UUID PK screening_id UUID FK list_source VARCHAR(64) list_record_id VARCHAR(128) match_score NUMERIC(5,4) match_type ENUM('sanction','pep','adverse_media','rca') raw_payload JSONB
table: aml_monitoring_subscription subscription_id UUID PK subject_id UUID FK frequency ENUM('daily','weekly','on_list_update') active BOOLEAN last_run_at
table: aml_alert alert_id UUID PK tenant_id UUID FK subject_id UUID FK triggered_at TIMESTAMPTZ kind ENUM('new_sanction_hit','pep_update','adverse_media_new', ...) severity ENUM('low','medium','high','critical') status ENUM('open','assigned','resolved','false_positive') assignee_user_id UUID FK user resolved_at5.2.4 TCR (Tax Compliance & Reporting)
Section intitulée « 5.2.4 TCR (Tax Compliance & Reporting) »table: tcr_classification classification_id UUID PK tenant_id UUID FK case_id UUID FK kyc_case us_person BOOLEAN -- FATCA fatca_category VARCHAR(16) -- ex: FATCA102 (EENF passive) holder_type ENUM('Individual','Organisation') tax_residences JSONB -- [{country, tin, certified_at, expires_at}] indicia JSONB -- détail indicia détectés classified_at classified_by ENUM('auto','manual')
table: tcr_form form_id UUID PK tenant_id UUID FK case_id UUID FK type ENUM('W-8BEN','W-8BEN-E','W-9') version VARCHAR(16) -- ex: rev_oct_2021 prefilled_payload JSONB pdf_object_key VARCHAR(512) signed_object_key VARCHAR(512) -- post e-signature signed_at TIMESTAMPTZ expires_at TIMESTAMPTZ -- typiquement +3 ans status ENUM('draft','sent','signed','expired','revoked')
table: tcr_declaration -- fichier FATCA XML v2.0 généré declaration_id UUID PK tenant_id UUID FK reporting_fi_giin VARCHAR(32) -- GIIN de l'IF déclarante reporting_period VARCHAR(4) -- exercice (ex: 2025) type ENUM('FATCA1','FATCA2','FATCA3','FATCA4','NilReport') message_ref_id VARCHAR(200) UNIQUE corr_message_ref_id VARCHAR(200) -- chaînage xml_object_key VARCHAR(512) file_hash_sha256 CHAR(64) generated_at TIMESTAMPTZ submitted_at TIMESTAMPTZ -- dépôt IDES ides_reference VARCHAR(128) -- référence DGI status ENUM('draft','generated','submitted','accepted', 'rejected','cancelled')
table: tcr_account_report account_report_id UUID PK declaration_id UUID FK doc_ref_id VARCHAR(200) UNIQUE corr_doc_ref_id VARCHAR(200) account_number VARCHAR(128) account_number_type VARCHAR(16) -- OECD601..605, NANUM account_balance NUMERIC(18,2) account_balance_ccy CHAR(3) account_closed BOOLEAN holder_type VARCHAR(8) -- FATCA102/103/104 holder_subject_id UUID -- lien KYC payloads JSONB -- AdditionalData
table: tcr_ides_acknowledgement ack_id UUID PK declaration_id UUID FK kind ENUM('deposit','error_report','irs_notification') received_at TIMESTAMPTZ payload JSONB irs_error_code VARCHAR(32) -- ex: 8008, 8009, 8011 (ICMM) actionable BOOLEAN5.2.5 Audit trail (WORM + hash chain)
Section intitulée « 5.2.5 Audit trail (WORM + hash chain) »table: audit_event event_id UUID PK tenant_id UUID FK actor_type ENUM('user','system','api_client','agent') actor_id VARCHAR(128) action VARCHAR(64) -- ex: KYC_CASE.DECISION_MADE target_type VARCHAR(64) target_id VARCHAR(128) payload JSONB occurred_at TIMESTAMPTZ previous_hash BYTEA -- chaînage event_hash BYTEA -- SHA-256(previous_hash || event_data) -- Partitionné par mois, table INSERT-only, policy Postgres empêchant UPDATE/DELETE5.3 Stratégie d’indexation
Section intitulée « 5.3 Stratégie d’indexation »- Index composite
(tenant_id, <colonne business>)sur toutes les tables métier (discrimination tenant toujours en premier). - Index partiel sur statuts actifs :
WHERE status IN ('in_progress','manual_review'). - Index GIN sur JSONB
payloadetindiciapour recherche ad hoc. - Pour OpenSearch : index
aml_hits_{tenant_id}miroir du matching fuzzy multilingue.
6. API publique
Section intitulée « 6. API publique »6.1 Principes
Section intitulée « 6.1 Principes »- REST + OpenAPI 3.1 en première intention ; endpoints asynchrones exposent des webhooks.
- Versioning par URL :
/v1/…. Un breaking change →/v2/…, cohabitation 12 mois minimum. - Authentification :
Authorization: Bearer <jwt>(OIDC) ouX-API-Key: <key>pour intégrations machine. - Multi-tenant implicite : le token porte le
tenant_id— jamais dans le path. - Idempotence : header
Idempotency-Keyobligatoire sur tous lesPOSTmutatifs, TTL 24 h. - Rate limiting : par clé API, configurable par tenant (défaut : 100 rps burst, 20 rps sustained).
- Webhooks signés : header
X-VitaKYC-Signature: t=<ts>,v1=<hmac>, rotation des secrets possible sans interruption. - Pagination cursor-based (
?cursor=…&limit=50) ; jamais d’offset/limit sur des gros volumes. - Format d’erreur : RFC 9457 (Problem Details).
6.2 Extraits d’endpoints clés
Section intitulée « 6.2 Extraits d’endpoints clés »Les exemples ci-dessous illustrent le style ; un spec OpenAPI complet est produit en parallèle dans openapi/vitakyc.yaml.
6.2.1 Créer un dossier KYC individuel
Section intitulée « 6.2.1 Créer un dossier KYC individuel »POST /v1/kyc/casesContent-Type: application/jsonAuthorization: Bearer <jwt>Idempotency-Key: 7d3e9c2a-...
{ "external_ref": "CLIENT-2026-00123", "subject_type": "individual", "locale": "fr-TN", "workflow_code": "default-tn-v1", "initial_data": { "email": "client@example.tn", "phone": "+21698XXXXXX" }, "tags": ["retail", "tn-residence"]}
→ 201 Created{ "case_id": "c9e1...", "status": "created", "embed_url": "https://kyc.vitakyc.io/s/eyJhbGci...", "expires_at": "2026-04-23T14:30:00Z"}6.2.2 Screening AML synchrone
Section intitulée « 6.2.2 Screening AML synchrone »POST /v1/aml/screenContent-Type: application/jsonAuthorization: Bearer <jwt>
{ "case_id": "c9e1...", "subject": { "full_name": "محمد بن علي", "full_name_transliterations": ["Mohamed Ben Ali","Muhammad Ibn Ali"], "dob": "1985-03-12", "nationality": "TN" }, "lists": ["OFAC","UN","EU","HMT","BCT_LOCAL"], "include_pep": true, "include_adverse_media": true}
→ 200 OK{ "screening_id": "aa12...", "hits_count": 1, "decision": "manual_review", "hits": [ { "list_source":"OFAC", "match_score":0.86, "match_type":"sanction", "record_id":"SDN-1234" } ]}6.2.3 Générer et soumettre une déclaration FATCA
Section intitulée « 6.2.3 Générer et soumettre une déclaration FATCA »POST /v1/tcr/declarationsContent-Type: application/jsonAuthorization: Bearer <jwt>
{ "reporting_fi_giin": "00Z148.00027.ME.788", "reporting_period": "2025", "type": "FATCA1", "filer_category": "FATCA601", "accounts_filter": { "reporting_year": 2025 }, "auto_submit_ides": false}
→ 202 Accepted{ "declaration_id": "d1a2...", "status": "generating", "estimated_completion": "2026-04-22T10:12:00Z"}Webhook asynchrone tcr.declaration.generated :
{ "event": "tcr.declaration.generated", "timestamp": "2026-04-22T10:11:47Z", "data": { "declaration_id": "d1a2...", "message_ref_id": "00Z148.00027.ME.788-20260422T101147-...", "xml_download_url": "https://api.vitakyc.io/v1/tcr/declarations/d1a2.../xml", "file_hash_sha256": "4f2a8...", "record_count": 187 }}6.2.4 Consulter un bénéficiaire effectif via RNE
Section intitulée « 6.2.4 Consulter un bénéficiaire effectif via RNE »POST /v1/kyb/rne/lookupContent-Type: application/jsonAuthorization: Bearer <jwt>
{ "rne_identifier": "B0123456", "services": ["kyc","ubo"]}
→ 200 OK{ "kyc": { "legal_name": "ACME TUNISIE SA", "capital_amount": 500000.00, "capital_currency": "TND", "registration_date": "2012-06-14", "status": "active", "officers": [...] }, "ubo": [ { "individual_id": "P9876", "full_name": "...", "ownership_pct": 42.5, "control_nature": "direct" } ], "source": "rne.e-rne.tn", "retrieved_at": "2026-04-22T09:57:21Z", "cache_ttl_hours": 24}7. Parcours critiques — diagrammes de séquence
Section intitulée « 7. Parcours critiques — diagrammes de séquence »7.1 Onboarding KYC individu (happy path)
Section intitulée « 7.1 Onboarding KYC individu (happy path) »7.2 Ongoing monitoring AML (async récurrent)
Section intitulée « 7.2 Ongoing monitoring AML (async récurrent) »7.3 KYB avec consultation RNE Tunisie
Section intitulée « 7.3 KYB avec consultation RNE Tunisie »Fallback : si le service RNE est indisponible (timeout 5 s ou erreur 5xx), connector-rne bascule sur un état degraded ; kyc-svc passe le dossier en branche « capture manuelle d’extrait RNE + OCR ».
7.4 TCR FATCA — cycle FATCA 1 puis correction FATCA 3 + FATCA 1
Section intitulée « 7.4 TCR FATCA — cycle FATCA 1 puis correction FATCA 3 + FATCA 1 »8. Gestion des licences modulaires
Section intitulée « 8. Gestion des licences modulaires »8.1 Structure de la clé de licence
Section intitulée « 8.1 Structure de la clé de licence »Format : JWT signé Ed25519 (pas de chiffrement, car le contenu est non sensible — c’est la signature qui compte).
{ "iss": "license-svc.vitakyc.io", "sub": "tenant:<tenant_id>|installation:<installation_id>", "iat": 1745309880, "exp": 1776845880, "aud": "vitakyc-runtime", "modules": { "kyc": { "features": ["kyc-p","kyb","nfc"], "limit_per_month": 50000 }, "aml": { "features": ["screening","ongoing"], "limit_per_month": 50000 }, "tcr": { "features": ["fatca","crs","templates-tn","templates-fr"], "limit_per_year": 2 } }, "deployment": "on_premise", "regions": ["tn","fr"], "support_tier": "enterprise", "phone_home": false}8.2 Vérification
Section intitulée « 8.2 Vérification »- SaaS :
license-svcmaintient la vérité en base ; vérification via appel RPC interne, cache 5 min. - On-prem : chaque service charge la clé publique Ed25519 (embarquée dans l’image), vérifie la signature localement. Re-vérification toutes les 24 h. Si
phone_homeactivé, ping quotidien vers un endpoint VitaKYC pour rafraîchir la licence (révocation). - Dégradation : passée la date
exp, grâce de 30 jours avec bannière dans la console. Au-delà, mode lecture seule.
8.3 Feature flags
Section intitulée « 8.3 Feature flags »- Chaque module expose des feature flags évalués en temps réel :
kyc.video-kyc,tcr.dac6,aml.transaction-monitoring. - Table
feature_flag_overridepour les activations ponctuelles (trials, beta) par tenant. - Flag library : Unleash (OSS) en SaaS, embarqué en on-prem.
9. Déploiement SaaS vs On-Premise
Section intitulée « 9. Déploiement SaaS vs On-Premise »9.1 Packaging
Section intitulée « 9.1 Packaging »- Chaque service est une image OCI signée (cosign) publiée sur un registre privé VitaKYC.
- Versioning SemVer (
vitakyc/kyc-svc:1.12.3), release cadence bi-hebdo SaaS, trimestrielle on-prem. - SBOM (CycloneDX) embarqué dans chaque image.
- Images distroless quand possible (UBI9-minimal sinon, pour compatibilité RHEL/OpenShift).
9.2 Helm chart unifié
Section intitulée « 9.2 Helm chart unifié »Un seul chart vitakyc-platform avec des values.yaml profiles :
charts/vitakyc-platform/├── Chart.yaml├── values.yaml # defaults├── values-saas-multi-tenant.yaml├── values-saas-dedicated.yaml├── values-on-prem-small.yaml # jusqu'à 100 k checks/mois├── values-on-prem-medium.yaml # jusqu'à 1 M checks/mois├── values-on-prem-large.yaml└── templates/ ├── api-gateway/ ├── identity-svc/ ├── kyc-svc/ ├── aml-svc/ ├── tcr-svc/ ├── ... (tous les services) └── dependencies/ # sub-charts : postgres, kafka, redis, minio, keycloak, vaultExemple d’extrait values-on-prem-small.yaml :
global: deploymentMode: on_premise licenseKeyPath: /var/run/secrets/vitakyc/license.jwt airGap: false # true pour clients sans accès Internet dataResidency: tn defaultStorageClass: fast-ssd
postgresql: enabled: true # déploiement embarqué (vs external: true pour Oracle existant du client) replicaCount: 2 storage: 500Gi
kafka: mode: redpanda # ou "kafka" pour vrai Kafka replicaCount: 3
ocr: inferenceMode: cpu # vs gpu replicas: 2 resources: limits: { cpu: "4", memory: "8Gi" }9.3 Topologie de référence
Section intitulée « 9.3 Topologie de référence »SaaS multi-tenant (AWS Frankfurt par défaut) :
- 3 AZ, cluster EKS.
- RDS PostgreSQL Multi-AZ + read replica cross-region (DR).
- MSK (Kafka managé) 3 brokers.
- S3 avec chiffrement SSE-KMS.
- ElastiCache Redis.
- CloudFront + WAF.
- Secrets via AWS KMS + HashiCorp Vault pour les secrets applicatifs.
On-premise banque tier 2 tunisienne (scénario type AO La Poste Tunisienne) :
- Cluster Kubernetes (OpenShift préféré si déjà en place) 3 masters + 5-8 workers.
- PostgreSQL managé par le client (Oracle supporté) en HA.
- Kafka ou Redpanda 3 brokers sur nœuds dédiés.
- MinIO 4 nœuds erasure-coded.
- Keycloak fédéré à l’AD/LDAP existant.
- Vault cluster Raft 3 nœuds.
- Accès Internet sortant autorisé uniquement vers endpoints de listes AML (ou mode fichier signé en air-gap).
10. Sécurité détaillée
Section intitulée « 10. Sécurité détaillée »10.1 Threat model synthétique (STRIDE)
Section intitulée « 10.1 Threat model synthétique (STRIDE) »| Menace | Exemple concret | Mitigation |
|---|---|---|
| Spoofing | Attaque sur le parcours client (faux selfie généré) | Liveness niveau 2 + anti-deepfake V2 + signature device attestation |
| Tampering | Modification d’un dossier clos | Table audit WORM + hash chain ; RLS PostgreSQL ; approvals multi-rôles |
| Repudiation | Client conteste avoir signé un W-8BEN | E-signature horodatée + hash fichier + journal d’audit ; preuve cryptographique |
| Information disclosure | Leak données client cross-tenant | RLS PostgreSQL par tenant_id ; clé de chiffrement par tenant ; tests automatisés de cloisonnement |
| Denial of service | Flood endpoint OCR | Rate limiting par API key + par tenant ; isolation ressources par tenant ; shadow traffic détection |
| Elevation of privilege | Agent se donne rôle admin | RBAC strict, séparation des devoirs, audit sur toute action de gestion |
10.2 Contrôles clés
Section intitulée « 10.2 Contrôles clés »- Chiffrement : TLS 1.3 partout, AES-256-GCM au repos, clés rotées tous les 90 jours via Vault Transit.
- PII protection : colonnes sensibles chiffrées niveau application (envelope encryption).
- Secrets : jamais en ConfigMap. Vault dynamic secrets pour DB (credentials TTL 1 h).
- Access control : OIDC + MFA obligatoire pour users back-office. API keys avec scopes explicites.
- Supply chain : images signées cosign, admission controller (Kyverno) rejetant les images non signées.
- Vuln management : scan Trivy à chaque build, bloquant sur CVE critical.
- Pen tests : externes annuels ; bug bounty en continu (YesWeHack après la V1).
10.3 Audit trail cryptographique
Section intitulée « 10.3 Audit trail cryptographique »- Chaque événement audité est haché :
event_hash = SHA-256(previous_hash || canonical_json(event)). previous_hash= hash du précédent event du même tenant (chaîne).- Publication périodique (hebdo) du dernier hash de chaque tenant dans un journal immutable (blockchain publique optionnelle pour clients régulés exigeants) — roadmap V2.
- Vérification offline : tout auditeur peut reconstituer la chaîne et détecter toute altération.
11. Observabilité et SLOs
Section intitulée « 11. Observabilité et SLOs »11.1 Instrumentation
Section intitulée « 11.1 Instrumentation »- Traces : OpenTelemetry auto-instrumentation JVM + spans manuels sur les décisions métier.
- Métriques : Prometheus ; conventions OTEL sémantique + métriques métier (
kyc_case_decisions_total{tenant,decision},fatca_declaration_generation_seconds). - Logs : JSON structuré, champ
trace_idobligatoire, shipping Loki.
11.2 SLOs de référence (SaaS)
Section intitulée « 11.2 SLOs de référence (SaaS) »| Indicateur | SLO | Fenêtre | Action si raté |
|---|---|---|---|
| Disponibilité API publique | 99,9 % | 30 jours glissants | Incident P1 |
Latence P95 POST /v1/kyc/cases | < 600 ms | 7 jours | Incident P2 |
| Latence P95 OCR bout-en-bout | < 3 s | 7 jours | Investigation |
| Taux de succès livraison webhooks (tentatives < 5) | ≥ 99,5 % | 7 jours | Audit infra |
| Auto-approval rate (indicateur qualité, pas SLO) | ≥ 85 % | 30 jours | Itération modèle |
11.3 Dashboards Grafana de référence
Section intitulée « 11.3 Dashboards Grafana de référence »- Santé plateforme — disponibilité, taux erreur HTTP 5xx, queue Kafka lag, RPS API gateway.
- Dossiers KYC — volumes, drop-off par étape, temps de décision P50/P95/P99.
- AML operations — alertes ouvertes, time-to-close par sévérité, SLA agent.
- TCR compliance — déclarations générées, soumissions IDES, erreurs ICMM.
- Cost per check — coût infra + IA / check décomposé par module et tenant.
12. Capacity planning et sizing
Section intitulée « 12. Capacity planning et sizing »12.1 Sizing t-shirt on-prem
Section intitulée « 12.1 Sizing t-shirt on-prem »| Taille | Checks / mois | Nœuds K8s | RAM totale | Stockage | Remarques |
|---|---|---|---|---|---|
| S | 100 k | 3 masters + 3 workers | 64 Go / worker | 2 To | PostgreSQL embarqué ; OCR CPU |
| M | 1 M | 3 + 6 | 128 Go / worker | 8 To | Kafka 3 brokers ; OCR 2-4 GPU selon mix |
| L | 10 M | 3 + 12 | 256 Go / worker | 40 To | DB externe client recommandée ; OCR 4-8 GPU |
| XL | 50 M+ | 3 + 24 | — | — | Architecture à calibrer au projet |
12.2 SaaS — stratégie de scale
Section intitulée « 12.2 SaaS — stratégie de scale »- Auto-scaling horizontal (HPA) sur services stateless sur 2 signaux : CPU + files d’attente Kafka lag.
- Services IA : KEDA sur longueur de file « inference jobs ».
- PostgreSQL : lecture via read replicas, partitionnement par mois pour
audit_event, tablestcr_*partitionnées parreporting_period. - Backpressure : si saturation, passage en mode
429contrôlé plutôt que timeouts.
13. Exemple concret — générateur FATCA XML v2.0
Section intitulée « 13. Exemple concret — générateur FATCA XML v2.0 »13.1 Objectif
Section intitulée « 13.1 Objectif »Produire un fichier XML FATCA v2.0 conforme au cahier des charges DGI Tunisie V1.0-2019 et au schéma FatcaXML_v2.0.xsd (IRS Publication 5124).
13.2 Contrat du module report-svc
Section intitulée « 13.2 Contrat du module report-svc »- Entrée :
declaration_id(UUID). - Étapes :
- Charger la déclaration, le
reporting_fiet sesaccount_report. - Construire un
MessageSpec(unique dans l’espace/temps). - Construire le bloc
FATCA(ReportingFI + ReportingGroup). - Sérialiser via JAXB avec validation XSD stricte.
- Appliquer les échappements
&,<,>,',"(JAXB par défaut OK). - Générer le fichier
<MF>-<exercice>.xmlen UTF-8 sans BOM. - Compresser GZIP si
> seuil. - Calculer SHA-256, stocker dans
tcr_declaration.file_hash_sha256. - Publier l’URL signée MinIO, évènement Kafka
tcr.declaration.generated.
- Charger la déclaration, le
13.3 Extrait Kotlin (illustratif — pas de production)
Section intitulée « 13.3 Extrait Kotlin (illustratif — pas de production) »class FatcaDeclarationBuilder( private val crypto: HashService, private val clock: Clock,) { fun build(ctx: FatcaBuildContext): FatcaDeclarationArtifact { val now = clock.instant() val messageRefId = buildMessageRefId(ctx.reportingFI.giin, now)
val messageSpec = MessageSpecType().apply { sendingCompanyIN = ctx.reportingFI.giin transmittingCountry = "TN" receivingCountry = "US" messageType = "FATCA" messageRefID = messageRefId reportingPeriod = "${ctx.reportingPeriod}-12-31" timestamp = now if (ctx.type != FatcaType.FATCA1) { corrMessageRefID = ctx.parentMessageRefId } }
val reportingFi = CorrectableReportOrganisationType().apply { resCountryCode = listOf("TN") tin = TINType(ctx.reportingFI.giin, "US") // GIIN émis par l'IRS name = listOf(NameOrganisationType(ctx.reportingFI.legalName)) address = buildAddress(ctx.reportingFI) filerCategory = ctx.filerCategory.code // ex: "FATCA601" docSpec = buildDocSpec(ctx.reportingFI.giin, ctx.type, ctx.parentDocRefId) }
val reportingGroup = ReportingGroup().apply { when (ctx.type) { FatcaType.NIL -> nilReport = buildNilReport(ctx) else -> accountReports.addAll(ctx.accounts.map { buildAccount(it, ctx) }) } }
val fatca = FatcaType().apply { this.reportingFI = reportingFi this.reportingGroups.add(reportingGroup) }
val root = FatcaOecd().apply { this.version = "2.0" this.messageSpec = messageSpec this.fatca.add(fatca) }
val xmlBytes = marshallWithStrictSchemaValidation(root) val fileName = "${ctx.reportingFI.matriculeFiscal}-${ctx.reportingPeriod}.xml" val hash = crypto.sha256(xmlBytes) return FatcaDeclarationArtifact(xmlBytes, fileName, hash, messageRefId) }
/** * DGI Tunisie: <GIIN>-<ISO8601 UTC à la seconde>-<GUID> * Garantit l'unicité dans l'espace et le temps, conformément à RG2.2. */ private fun buildMessageRefId(giin: String, now: Instant): String { val ts = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss").format(now.atZone(UTC)) val guid = UUID.randomUUID().toString().replace("-", "") return "$giin-$ts-$guid" }
/** * DocRefID : <GIIN>.<numéro unique>. Min 21 max 200 chars, [A-Za-z0-9.-] uniquement. * Chaque ReportingFI / AccountReport / NilReport doit avoir un DocRefID distinct. */ private fun buildDocSpec(giin: String, type: FatcaType, parentDocRef: String?): DocSpec { val docRefId = "$giin.${UUID.randomUUID().toString().replace("-", "")}" return DocSpec( docTypeIndic = type.indicativeCode, // "FATCA1", "FATCA2", ... docRefID = docRefId, corrMessageRefID = parentDocRef?.let { /* parent message */ }, corrDocRefID = parentDocRef ) }}13.4 Exemple de fichier XML généré (abrégé)
Section intitulée « 13.4 Exemple de fichier XML généré (abrégé) »Fichier : 0005623A-2025.xml — UTF-8 sans BOM.
<?xml version="1.0" encoding="UTF-8"?><ftc:FATCA_OECD version="2.0" xmlns:ftc="urn:oecd:ties:fatca:v2" xmlns:sfa="urn:oecd:ties:stffatcatypes:v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oecd:ties:fatca:v2 FatcaXML_v2.0.xsd">
<sfa:MessageSpec> <sfa:SendingCompanyIN>00Z148.00027.ME.788</sfa:SendingCompanyIN> <sfa:TransmittingCountry>TN</sfa:TransmittingCountry> <sfa:ReceivingCountry>US</sfa:ReceivingCountry> <sfa:MessageType>FATCA</sfa:MessageType> <sfa:MessageRefId>00Z148.00027.ME.788-20260422T101147-406abc8a1830490e847890ba3b13a646</sfa:MessageRefId> <sfa:ReportingPeriod>2025-12-31</sfa:ReportingPeriod> <sfa:Timestamp>2026-04-22T10:11:47Z</sfa:Timestamp> </sfa:MessageSpec>
<ftc:FATCA> <ftc:ReportingFI> <sfa:ResCountryCode>TN</sfa:ResCountryCode> <sfa:TIN issuedBy="US">00Z148.00027.ME.788</sfa:TIN> <sfa:Name>BANQUE EXEMPLE DE TUNISIE</sfa:Name> <sfa:Address> <sfa:CountryCode>TN</sfa:CountryCode> <sfa:AddressFix> <sfa:Street>Avenue Habib Bourguiba</sfa:Street> <sfa:BuildingIdentifier>25</sfa:BuildingIdentifier> <sfa:PostCode>1000</sfa:PostCode> <sfa:City>Tunis</sfa:City> </sfa:AddressFix> </sfa:Address> <ftc:FilerCategory>FATCA601</ftc:FilerCategory> <ftc:DocSpec> <sfa:DocTypeIndic>FATCA1</sfa:DocTypeIndic> <sfa:DocRefId>00Z148.00027.ME.788.406abc8a1830490e847890ba3b13a646</sfa:DocRefId> </ftc:DocSpec> </ftc:ReportingFI>
<ftc:ReportingGroup> <ftc:AccountReport> <ftc:DocSpec> <sfa:DocTypeIndic>FATCA1</sfa:DocTypeIndic> <sfa:DocRefId>00Z148.00027.ME.788.b2e6a3d9c4e14bfe9b3b9c14f58b0b11</sfa:DocRefId> </ftc:DocSpec> <ftc:AccountNumber AcctNumberType="OECD601">TN59 1000 1234 5678 9012 3456</ftc:AccountNumber> <ftc:AccountHolder> <ftc:Individual> <sfa:ResCountryCode>US</sfa:ResCountryCode> <sfa:TIN issuedBy="US">123-45-6789</sfa:TIN> <sfa:Name> <sfa:FirstName>JOHN</sfa:FirstName> <sfa:LastName>SMITH</sfa:LastName> </sfa:Name> <sfa:Address> <sfa:CountryCode>TN</sfa:CountryCode> <sfa:AddressFix> <sfa:Street>Rue de la Liberte</sfa:Street> <sfa:PostCode>2045</sfa:PostCode> <sfa:City>La Marsa</sfa:City> </sfa:AddressFix> </sfa:Address> <sfa:BirthInfo> <sfa:BirthDate>1980-06-15</sfa:BirthDate> <sfa:CountryInfo> <sfa:CountryCode>US</sfa:CountryCode> </sfa:CountryInfo> </sfa:BirthInfo> </ftc:Individual> </ftc:AccountHolder> <ftc:AccountBalance currCode="USD">125430.75</ftc:AccountBalance> </ftc:AccountReport> </ftc:ReportingGroup> </ftc:FATCA></ftc:FATCA_OECD>13.5 Checklist de conformité DGI avant dépôt
Section intitulée « 13.5 Checklist de conformité DGI avant dépôt »- Encodage UTF-8 sans BOM vérifié
- Taille < 100 Mo avant compression
- Nommage
<MF>-<exercice>.xmlrespecté (caractères autorisés uniquement) - Aucune séquence
--,/*,&#dans le contenu -
MessageRefIdunique (GIIN + timestamp seconde + GUID) -
DocRefIdunique parReportingFI,AccountReport,NilReport(21–200 chars, format<GIIN>.<id>) -
FilerCategoryvalide (FATCA601 pour IF étrangère participante par défaut) - TIN titulaire : neuf A si inconnu + personne physique ; neuf 0 si EENF passive
- Chaînage
CorrMessageRefId/CorrDocRefIdrenseigné pour FATCA 2 / 3 / 4 - Validation XSD locale avant dépôt (schéma
FatcaXML_v2.0.xsd) - Hash SHA-256 calculé et stocké
- Pour FATCA 3+1 : déposer FATCA 1 uniquement après la fenêtre DGI → IRS de FATCA 3
14. Plan de test et qualité
Section intitulée « 14. Plan de test et qualité »14.1 Pyramide de tests
Section intitulée « 14.1 Pyramide de tests »- Unitaire (60 %) : JUnit 5 + AssertJ + MockK (Kotlin) ;
pytestpour services Python. - Contrat (15 %) : Pact ou Spring Cloud Contract entre services critiques.
- Intégration (15 %) : Testcontainers (PostgreSQL, Kafka, Redis, MinIO réels).
- End-to-end (8 %) : Playwright pour parcours UI +
k6pour scénarios API. - Performance (2 %) :
k6scénarios cibles sur staging (cf. SLOs).
14.2 Tests FATCA spécifiques
Section intitulée « 14.2 Tests FATCA spécifiques »- Corpus d’échantillons XML fournis par l’IRS (fichiers de tests Publication 5124).
- Tests de non-régression XSD sur chaque release.
- Test de chaînage : matrice 4×4 (type courant × type parent).
- Test air-gap : génération + compression + dépôt manuel simulé sans réseau.
14.3 Tests multi-tenant
Section intitulée « 14.3 Tests multi-tenant »- Script automatisé vérifiant qu’un tenant A ne peut jamais voir les données d’un tenant B (via API, via SQL direct avec mauvais contexte, via Kafka).
- Test exécuté à chaque PR touchant
identity-svcou les politiques RLS.
15. Annexes
Section intitulée « 15. Annexes »15.1 Correspondance Cahier des charges → Architecture
Section intitulée « 15.1 Correspondance Cahier des charges → Architecture »| CdC | Document technique |
|---|---|
| §4.1 KYC individuel | §4 services kyc-svc, ocr-svc, liveness-svc, face-match-svc ; §7.1 parcours |
| §4.2 AML | §4 service aml-svc ; §7.2 ongoing monitoring |
| §4.3 TCR | §4 service tcr-svc, report-svc ; §7.4 cycle correction ; §13 exemple concret |
| §5 Licensing modulaire | §8 clé Ed25519 + feature flags |
| §6 Stack technique | §4.4 choix d’infra ; §9 déploiement |
| §7 Déploiement hybride | §9 Helm chart unifié + topologies |
| §10 Sécurité | §10 threat model + contrôles ; §5 chiffrement par tenant |
| §12 Intégrations | §4 connectors ; §7.3 parcours RNE ; §13 FATCA IDES |
15.2 ADR à produire en priorité par l’équipe tech
Section intitulée « 15.2 ADR à produire en priorité par l’équipe tech »- ADR-001 — Choix Temporal vs Camunda 8 pour workflows.
- ADR-002 — Stratégie multi-tenant (shared schema + RLS) vs schema-per-tenant.
- ADR-003 — Moteur OCR : stack build interne vs fallback commercial.
- ADR-004 — Choix du framework de règles métier (OPA ? DMN ? règles Kotlin ?).
- ADR-005 — Stockage des documents : MinIO vs abstraction cloud-native.
- ADR-006 — Stratégie de gestion des listes AML (formats, refresh, air-gap).
15.3 Documents sources
Section intitulée « 15.3 Documents sources »VitaKYC_Cahier_des_Charges.mdVitaKYC_Etude_Concurrentielle.mdCC- AO N12-UCA-DAI-2025 E-KYC- V final.pdf— AO La Poste TunisienneCahier_des_charges-1.pdf— Cahier des charges DGI Tunisie FATCA V1.0-2019 (schéma V3.7)- IRS Publication 5124 — FATCA XML Schema v2.0 User Guide
- IRS Publication 5189 — ICMM Notification User Guide
- IRS Form 8966 XML Schema
FatcaXML_v2.0.xsd+ typesisofatcatypes_v1.1.xsd,oecdtypes_v4.2.xsd,stffatcatypes_v2.0.xsd
Fin du Dossier d’Architecture Technique.