Skip to content

Audit 02 — Domain-Driven Design (DDD)

Objectif : verifier que le code respecte les principes DDD — bounded contexts clairs, entites et value objects bien definis, ubiquitous language coherent, et separation des responsabilites metier.

Cible : document-parser/domain/, document-parser/services/, frontend/src/features/, frontend/src/shared/types.ts


Checklist

2.1 Bounded Contexts

# Item Poids
2.1.1 Les contextes metier sont clairement identifies et isoles (document, analysis, chunking) 3
2.1.2 Chaque contexte a ses propres modeles — pas de modele "god object" partage entre contextes 3
2.1.3 Les frontieres entre contextes sont explicites — la communication passe par des contrats definis (DTOs, events), pas par des imports directs de modeles internes d'un autre contexte 2
2.1.4 Le frontend respecte les memes bounded contexts (features = contextes) 2

2.2 Entites et Value Objects

# Item Poids
2.2.1 Les entites ont une identite unique (id) et un cycle de vie (Document, AnalysisJob) 2
2.2.2 Les value objects sont immutables et definis par leurs attributs, pas par une identite (ConversionResult, ChunkingOptions, BoundingBox) 2
2.2.3 Les value objects ne contiennent pas de logique de persistence (pas de save(), update()) 3
2.2.4 Les entites ne sont pas de simples "sacs de donnees" — elles portent du comportement metier quand c'est pertinent 1

2.3 Ubiquitous Language

# Item Poids
2.3.1 Le vocabulaire metier est coherent entre domain, services, API et frontend (ex: "analysis" partout, pas "job" d'un cote et "analysis" de l'autre) 2
2.3.2 Les noms de classes/fonctions/variables refletent le langage du domaine, pas des termes techniques generiques (pas de DataProcessor, Handler, Manager sans contexte) 1
2.3.3 Les statuts metier utilisent un vocabulaire explicite (PENDING, RUNNING, COMPLETED, FAILED) 1

2.4 Agregats et invariants

# Item Poids
2.4.1 Chaque agregat a une racine claire (Document est la racine de son agregat, AnalysisJob de son agregat) 2
2.4.2 Les invariants metier sont proteges dans le domaine — pas de creation d'etats invalides depuis l'exterieur 3
2.4.3 Les modifications d'un agregat passent par sa racine, pas par manipulation directe de ses composants internes 2

2.5 Repositories et anti-corruption

# Item Poids
2.5.1 Les repositories (persistence/) manipulent des entites du domaine, pas des dictionnaires bruts ou des Row objects 2
2.5.2 La couche anti-corruption (schemas Pydantic) transforme les donnees externes (HTTP) en objets du domaine 2
2.5.3 Les adaptateurs infra (infra/) ne leakent pas leurs types internes vers les services (pas de types Docling exposes aux services) 3

Commandes de verification

# 2.1.2 — Chercher un modele omniscient
wc -l document-parser/domain/models.py

# 2.2.2 — Value objects mutables (setters, attributs reassignes)
grep -rn "\..*=" document-parser/domain/value_objects.py | grep -v "self\." | grep -v "__"

# 2.3.1 — Incoherences de vocabulaire (job vs analysis)
grep -rni "\bjob\b" document-parser/api/ document-parser/services/ --include="*.py" | grep -v "AnalysisJob"
grep -rni "\bjob\b" frontend/src/ --include="*.ts" --include="*.vue" | grep -v "node_modules"

# 2.5.3 — Types Docling qui leakent vers services
grep -rn "from docling\|import docling" document-parser/services/ --include="*.py"

Regles de notation

  • Tout item de poids 3 non conforme = ecart [CRIT]
  • Tout item de poids 2 non conforme = ecart [MAJ]
  • Tout item de poids 1 non conforme = ecart [MIN]