fix(docs): resolve mkdocs strict mode build failure (#145)
- Add all process docs to mkdocs.yml nav (15 missing pages) - Replace relative links to files outside docs/ with absolute GitHub URLs - Add docs/audit/ directory (templates + reports) - Add validation config to allow unlisted audit reports as info-level
This commit is contained in:
parent
d8937ad916
commit
f6030bb2f1
33 changed files with 1819 additions and 17 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Available Processes
|
||||
****# Available Processes
|
||||
|
||||
Index of all documented processes in Docling Studio. Each process is a structured, repeatable workflow with a clear trigger and deliverable.
|
||||
|
||||
|
|
@ -30,9 +30,9 @@ Crée un ADR pour [la décision à documenter]
|
|||
| # | Process | Trigger / Command | Doc | Output |
|
||||
|---|---------|-------------------|-----|--------|
|
||||
| 5 | **Full Release Audit** | Before merging `release/*` to `main` | [docs/audit/master.md](audit/master.md) | 12 audit reports + summary in `reports/release-X.Y.Z/` |
|
||||
| 6 | **Single Audit** | Targeted check on one axis | [docs/audit/audits/*.md](audit/audits/) | Single audit report |
|
||||
| 6 | **Single Audit** | Targeted check on one axis | [docs/audit/audits/*.md](audit/audits/01-clean-architecture.md) | Single audit report |
|
||||
| 7 | **Re-Audit** | After fixing CRIT/MAJ findings | [docs/audit/master.md](audit/master.md) | Updated report |
|
||||
| 8 | **Automated Checks** | Quick validation before audit | [profiles/fastapi-vue/commands.sh](../profiles/fastapi-vue/commands.sh) | PASS/WARN/FAIL per check |
|
||||
| 8 | **Automated Checks** | Quick validation before audit | [profiles/fastapi-vue/commands.sh](https://github.com/scub-france/Docling-Studio/blob/main/profiles/fastapi-vue/commands.sh) | PASS/WARN/FAIL per check |
|
||||
|
||||
### How to invoke
|
||||
|
||||
|
|
@ -56,11 +56,11 @@ bash profiles/fastapi-vue/commands.sh
|
|||
|
||||
| # | Process | Trigger / Command | Doc | Output |
|
||||
|---|---------|-------------------|-----|--------|
|
||||
| 9 | **Release Gate** | Auto on push/PR `release/*` → `main` | [release-gate.yml](../.github/workflows/release-gate.yml) | GO / GO CONDITIONAL / NO-GO comment on PR |
|
||||
| 10 | **Release** | Feature freeze on `release/*` | [CONTRIBUTING.md](../CONTRIBUTING.md#release-process) | Tag `vX.Y.Z`, Docker images on ghcr.io |
|
||||
| 9 | **Release Gate** | Auto on push/PR `release/*` → `main` | [release-gate.yml](https://github.com/scub-france/Docling-Studio/blob/main/.github/workflows/release-gate.yml) | GO / GO CONDITIONAL / NO-GO comment on PR |
|
||||
| 10 | **Release** | Feature freeze on `release/*` | [CONTRIBUTING.md](https://github.com/scub-france/Docling-Studio/blob/main/CONTRIBUTING.md#release-process) | Tag `vX.Y.Z`, Docker images on ghcr.io |
|
||||
| 11 | **Deployment** | After release tag | [deployment-checklist.md](release/deployment-checklist.md) | Running instance at new version |
|
||||
| 12 | **Rollback** | Post-deploy failure detected | [rollback-playbook.md](release/rollback-playbook.md) | Reverted to last known good version |
|
||||
| 13 | **Hotfix** | Critical bug on released version | [CONTRIBUTING.md](../CONTRIBUTING.md#hotfix) | Patch release `vX.Y.Z+1` |
|
||||
| 13 | **Hotfix** | Critical bug on released version | [CONTRIBUTING.md](https://github.com/scub-france/Docling-Studio/blob/main/CONTRIBUTING.md#hotfix) | Patch release `vX.Y.Z+1` |
|
||||
|
||||
### Release Gate details
|
||||
|
||||
|
|
@ -170,10 +170,10 @@ These are not processes but reference documents used by the processes above:
|
|||
|
||||
| Document | Purpose |
|
||||
|----------|---------|
|
||||
| [CONTRIBUTING.md](../CONTRIBUTING.md) | Dev setup, branching, release, versioning |
|
||||
| [CONTRIBUTING.md](https://github.com/scub-france/Docling-Studio/blob/main/CONTRIBUTING.md) | Dev setup, branching, release, versioning |
|
||||
| [coding-standards.md](architecture/coding-standards.md) | Naming, style, architecture rules |
|
||||
| [e2e/CONVENTIONS.md](../e2e/CONVENTIONS.md) | Karate / Karate UI test conventions |
|
||||
| [e2e/CONVENTIONS.md](https://github.com/scub-france/Docling-Studio/blob/main/e2e/CONVENTIONS.md) | Karate / Karate UI test conventions |
|
||||
| [architecture.md](architecture.md) | System architecture (backend + frontend) |
|
||||
| [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md) | Community behavior standards |
|
||||
| [SECURITY.md](../SECURITY.md) | Vulnerability reporting policy |
|
||||
| [profiles/fastapi-vue/profile.md](../profiles/fastapi-vue/profile.md) | Stack layer mapping for audits |
|
||||
| [CODE_OF_CONDUCT.md](https://github.com/scub-france/Docling-Studio/blob/main/CODE_OF_CONDUCT.md) | Community behavior standards |
|
||||
| [SECURITY.md](https://github.com/scub-france/Docling-Studio/blob/main/SECURITY.md) | Vulnerability reporting policy |
|
||||
| [profiles/fastapi-vue/profile.md](https://github.com/scub-france/Docling-Studio/blob/main/profiles/fastapi-vue/profile.md) | Stack layer mapping for audits |
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ Conventions for writing consistent, readable code across the Docling Studio code
|
|||
|
||||
## Karate (E2E — `e2e/`)
|
||||
|
||||
See [e2e/CONVENTIONS.md](../../e2e/CONVENTIONS.md) for detailed rules.
|
||||
See [e2e/CONVENTIONS.md](https://github.com/scub-france/Docling-Studio/blob/main/e2e/CONVENTIONS.md) for detailed rules.
|
||||
|
||||
Key points:
|
||||
- Use `data-e2e` selectors, never CSS classes
|
||||
|
|
|
|||
68
docs/audit/audits/01-clean-architecture.md
Normal file
68
docs/audit/audits/01-clean-architecture.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Audit 01 — Clean Architecture
|
||||
|
||||
**Objectif** : verifier que le backend respecte le flux de dependances strict `api -> services -> domain` et que chaque couche a une responsabilite claire.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`, `__pycache__/`, `tests/`)
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 1.1 Domain (couche pure)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 1.1.1 | `domain/` n'importe ni FastAPI, ni aiosqlite, ni aucune lib infra | 3 |
|
||||
| 1.1.2 | Les modeles, value objects et ports ne font aucun I/O (file, HTTP, DB) | 3 |
|
||||
| 1.1.3 | Toute interaction avec l'exterieur passe par un protocole dans `domain/ports.py` | 3 |
|
||||
| 1.1.4 | Pas de Pydantic dans domain — le domain utilise des dataclasses | 2 |
|
||||
|
||||
### 1.2 Services (orchestration)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 1.2.1 | `services/` n'importe jamais `fastapi`, `Request`, `Response`, `Depends` | 3 |
|
||||
| 1.2.2 | Les services appellent les repos, jamais de requetes SQL directes | 3 |
|
||||
| 1.2.3 | Les regles metier vivent dans `domain/`, pas dans les services | 2 |
|
||||
| 1.2.4 | Les services recoivent leurs dependances par injection, pas par import direct de concretions | 2 |
|
||||
|
||||
### 1.3 API (couche HTTP)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 1.3.1 | Les routes n'importent pas `persistence/` directement | 3 |
|
||||
| 1.3.2 | Les transformations camelCase/snake_case restent dans `api/schemas.py` | 1 |
|
||||
| 1.3.3 | Les endpoints delegent toute la logique aux services | 2 |
|
||||
|
||||
### 1.4 Infra (adaptateurs)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 1.4.1 | Chaque adaptateur dans `infra/` implemente un protocole de `domain/ports.py` | 3 |
|
||||
| 1.4.2 | Les valeurs de config viennent de `infra/settings.py`, pas de constantes en dur | 2 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 1.1.1 — Domain ne doit importer aucune lib infra
|
||||
grep -rn "from fastapi\|from aiosqlite\|from pydantic\|import fastapi\|import aiosqlite" document-parser/domain/
|
||||
|
||||
# 1.2.1 — Services ne doivent pas importer FastAPI
|
||||
grep -rn "from fastapi\|import fastapi" document-parser/services/
|
||||
|
||||
# 1.3.1 — API ne doit pas importer persistence
|
||||
grep -rn "from persistence\|import persistence" document-parser/api/
|
||||
|
||||
# 1.4.2 — Constantes en dur dans infra (hors settings)
|
||||
grep -rn "= ['\"]http\|= [0-9]\{4,\}" document-parser/infra/ --include="*.py" | grep -v settings.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]`
|
||||
78
docs/audit/audits/02-ddd.md
Normal file
78
docs/audit/audits/02-ddd.md
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# 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
|
||||
|
||||
```bash
|
||||
# 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]`
|
||||
69
docs/audit/audits/03-clean-code.md
Normal file
69
docs/audit/audits/03-clean-code.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Audit 03 — Clean Code
|
||||
|
||||
**Objectif** : verifier la lisibilite, la clarte et la maintenabilite du code.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`, `__pycache__/`), `frontend/src/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 3.1 Nommage
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 3.1.1 | Les fonctions sont nommees avec des verbes d'action (`create_analysis`, `upload_document`) | 1 |
|
||||
| 3.1.2 | Les variables expriment l'intention (`remaining_pages` et non `rp`) | 1 |
|
||||
| 3.1.3 | Tout le code est en anglais — les traductions i18n sont dans `shared/i18n.ts` | 2 |
|
||||
| 3.1.4 | Pas d'abbreviations ambigues sauf conventions etablies (`dto`, `bbox`, `id`, `url`) | 1 |
|
||||
|
||||
### 3.2 Fonctions
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 3.2.1 | Chaque fonction fait une seule chose (Single Responsibility) | 2 |
|
||||
| 3.2.2 | Aucune fonction ne depasse 30 lignes (hors boilerplate inevitable) | 1 |
|
||||
| 3.2.3 | Aucune fonction n'a plus de 4 parametres | 1 |
|
||||
| 3.2.4 | Pas de flag arguments (booleen qui change le comportement) | 1 |
|
||||
| 3.2.5 | Une fonction `get_*` ne modifie pas d'etat (pas de side-effects caches) | 2 |
|
||||
|
||||
### 3.3 Fichiers et structure
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 3.3.1 | Aucun fichier source ne depasse 300 lignes | 1 |
|
||||
| 3.3.2 | Un seul concept par fichier — pas de fichier fourre-tout | 2 |
|
||||
| 3.3.3 | Imports ordonnes : stdlib, deps externes, imports internes | 1 |
|
||||
|
||||
### 3.4 Commentaires
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 3.4.1 | Le code est auto-documentant — les commentaires expliquent le "pourquoi", pas le "quoi" | 1 |
|
||||
| 3.4.2 | Pas de code commente laisse en place (dead code) | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 3.3.1 — Fichiers Python > 300 lignes
|
||||
find document-parser -name "*.py" -not -path "*/.venv/*" -not -path "*/__pycache__/*" -not -path "*/tests/*" | xargs wc -l | sort -rn | head -20
|
||||
|
||||
# 3.3.1 — Fichiers Vue/TS > 300 lignes
|
||||
find frontend/src -name "*.vue" -o -name "*.ts" | xargs wc -l | sort -rn | head -20
|
||||
|
||||
# 3.2.3 — Fonctions avec > 4 parametres (Python)
|
||||
grep -rn "def .*,.*,.*,.*,.*," document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=__pycache__ --exclude-dir=tests
|
||||
|
||||
# 3.4.2 — Code commente
|
||||
grep -rn "^[[:space:]]*#.*=\|^[[:space:]]*#.*def \|^[[:space:]]*#.*return\|^[[:space:]]*//.*=\|^[[:space:]]*//.*function" document-parser --include="*.py" --exclude-dir=.venv frontend/src --include="*.ts" --include="*.vue"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
43
docs/audit/audits/04-kiss.md
Normal file
43
docs/audit/audits/04-kiss.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Audit 04 — KISS (Keep It Simple, Stupid)
|
||||
|
||||
**Objectif** : verifier que le code reste simple et ne contient pas de sur-ingenierie.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`, `__pycache__/`), `frontend/src/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 4.1 | Pas de design pattern complexe la ou un simple `if` ou une fonction suffit (factory, strategy, observer superflus) | 2 |
|
||||
| 4.2 | Le code resout le probleme actuel, pas un probleme hypothetique futur (pas de genericite prematuree) | 2 |
|
||||
| 4.3 | Pas de fonction wrapper qui ne fait qu'appeler une autre fonction sans valeur ajoutee | 1 |
|
||||
| 4.4 | Utilisation des outils standard (Python stdlib, Vue composables natifs) avant de creer des solutions maison | 1 |
|
||||
| 4.5 | Configuration simple — pas de systeme de config complexe la ou une variable d'env suffit | 1 |
|
||||
| 4.6 | Pas d'indirection inutile — le chemin d'execution d'une requete ne traverse pas plus de couches que necessaire | 2 |
|
||||
| 4.7 | Pas de meta-programmation ou de magie (decorateurs complexes, metaclasses) sauf necessite avere | 2 |
|
||||
| 4.8 | Les structures de donnees utilisees sont les plus simples possibles (liste plutot que arbre si la liste suffit) | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 4.1 — Patterns potentiellement superflus
|
||||
grep -rn "class.*Factory\|class.*Strategy\|class.*Observer\|class.*Builder\|class.*Singleton" document-parser --include="*.py" --exclude-dir=.venv
|
||||
|
||||
# 4.7 — Meta-programmation
|
||||
grep -rn "__metaclass__\|type(.*,.*,.*)\|__init_subclass__\|__class_getitem__" document-parser --include="*.py" --exclude-dir=.venv
|
||||
|
||||
# 4.3 — Fonctions tres courtes (potentiels wrappers inutiles, < 3 lignes)
|
||||
# Verification manuelle recommandee sur les fonctions identifiees
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
45
docs/audit/audits/05-dry.md
Normal file
45
docs/audit/audits/05-dry.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Audit 05 — DRY (Don't Repeat Yourself)
|
||||
|
||||
**Objectif** : verifier l'absence de duplication significative dans le code.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`, `__pycache__/`), `frontend/src/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 5.1 | Aucun bloc de code identique ou quasi-identique n'apparait 3+ fois sans etre factorise | 2 |
|
||||
| 5.2 | Les interfaces/types partages sont centralises dans `shared/types.ts` (frontend) et `domain/models.py` (backend) | 2 |
|
||||
| 5.3 | Pas de magic numbers ou magic strings eparpilles — les constantes sont nommees et centralisees | 2 |
|
||||
| 5.4 | La logique reactive partagee est dans `shared/composables/` (frontend) | 1 |
|
||||
| 5.5 | Les appels API ne dupliquent pas la config HTTP (base URL, headers) — centralises dans `shared/api/http.ts` | 2 |
|
||||
| 5.6 | Les schemas Pydantic ne dupliquent pas les modeles du domain — ils transforment, ils ne redefinissent pas | 2 |
|
||||
| 5.7 | Les regles de validation ne sont definies qu'a un seul endroit (schema Pydantic OU frontend, pas les deux en desaccord) | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 5.3 — Magic numbers (backend)
|
||||
grep -rn "[^a-zA-Z_\"'][0-9]\{3,\}[^a-zA-Z_\"']" document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=tests --exclude-dir=__pycache__
|
||||
|
||||
# 5.3 — Magic strings repetees (backend)
|
||||
grep -rohn '"[a-z_]\{5,\}"' document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=tests | sort | uniq -c | sort -rn | head -20
|
||||
|
||||
# 5.5 — Appels fetch en dehors du client HTTP centralise
|
||||
grep -rn "fetch(" frontend/src/ --include="*.ts" --include="*.vue" | grep -v "http.ts\|api.ts\|node_modules"
|
||||
|
||||
# 5.6 — Champs dupliques entre schemas et models
|
||||
diff <(grep -o "[a-z_]*:" document-parser/api/schemas.py | sort -u) <(grep -o "[a-z_]*:" document-parser/domain/models.py | sort -u)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
72
docs/audit/audits/06-solid.md
Normal file
72
docs/audit/audits/06-solid.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Audit 06 — SOLID
|
||||
|
||||
**Objectif** : verifier le respect des 5 principes SOLID.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`, `__pycache__/`), `frontend/src/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 6.1 S — Single Responsibility Principle
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 6.1.1 | Chaque service a une responsabilite unique (`document_service` = documents, `analysis_service` = analyses) | 2 |
|
||||
| 6.1.2 | Chaque store Pinia gere un seul feature | 2 |
|
||||
| 6.1.3 | Les routes API sont groupees par ressource (`documents.py`, `analyses.py`) | 1 |
|
||||
| 6.1.4 | Aucune classe ou module ne cumule des responsabilites heterogenes (ex: un service qui fait du parsing ET de la persistence) | 2 |
|
||||
|
||||
### 6.2 O — Open/Closed Principle
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 6.2.1 | Les ports (`domain/ports.py`) permettent d'ajouter de nouveaux adaptateurs sans modifier le code existant | 2 |
|
||||
| 6.2.2 | Le systeme local/remote est extensible via `_build_converter()` sans modifier les services | 2 |
|
||||
| 6.2.3 | L'ajout d'un nouveau format d'export ne necessite pas de modifier les endpoints existants | 1 |
|
||||
|
||||
### 6.3 L — Liskov Substitution Principle
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 6.3.1 | `LocalConverter` et `ServeConverter` sont interchangeables (meme protocole, meme contrat de retour) | 3 |
|
||||
| 6.3.2 | Les implementations de ports ne lancent pas d'exceptions non prevues par le contrat | 2 |
|
||||
| 6.3.3 | Pas de `isinstance()` ou `type()` check pour differencier les implementations | 2 |
|
||||
|
||||
### 6.4 I — Interface Segregation Principle
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 6.4.1 | `DocumentConverter` et `DocumentChunker` sont des ports separes (pas une "god interface") | 2 |
|
||||
| 6.4.2 | Aucun port ne force une implementation a definir des methodes qu'elle n'utilise pas | 2 |
|
||||
|
||||
### 6.5 D — Dependency Inversion Principle
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 6.5.1 | Les services dependent de protocoles abstraits (ports), pas d'implementations concretes | 3 |
|
||||
| 6.5.2 | L'injection se fait dans `main.py` (composition root) | 2 |
|
||||
| 6.5.3 | Pas d'instanciation directe d'adaptateurs dans les services (`LocalConverter()` dans un service = violation) | 3 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 6.3.3 — isinstance checks sur les adaptateurs
|
||||
grep -rn "isinstance\|type(" document-parser/services/ --include="*.py"
|
||||
|
||||
# 6.5.3 — Instanciation directe d'adaptateurs dans services
|
||||
grep -rn "LocalConverter\|ServeConverter\|LocalChunker" document-parser/services/ --include="*.py"
|
||||
|
||||
# 6.5.1 — Imports directs d'infra dans services
|
||||
grep -rn "from infra\.\|import infra\." 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]`
|
||||
71
docs/audit/audits/07-decoupling.md
Normal file
71
docs/audit/audits/07-decoupling.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Audit 07 — Decouplage
|
||||
|
||||
**Objectif** : verifier le decouplage entre frontend et backend, entre features, et la clarte des contrats d'interface.
|
||||
|
||||
**Cible** : `document-parser/`, `frontend/src/`, `docker-compose.yml`, `nginx.conf`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 7.1 Decouplage Frontend / Backend
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 7.1.1 | Le frontend communique avec le backend uniquement via l'API REST — pas de couplage par fichier partage, DB partagee, ou import croise | 3 |
|
||||
| 7.1.2 | Le contrat API est stable — les types TypeScript frontend correspondent aux schemas Pydantic backend | 3 |
|
||||
| 7.1.3 | Le frontend peut tourner avec un mock du backend (les appels API sont isoles dans des fichiers `api.ts` par feature) | 2 |
|
||||
| 7.1.4 | Le backend peut etre teste sans le frontend (endpoints testables via `httpx` / `TestClient`) | 2 |
|
||||
| 7.1.5 | Pas de logique metier dupliquee entre front et back (ex: validation faite cote back ET reinventee cote front) | 2 |
|
||||
|
||||
### 7.2 Decouplage inter-features (Frontend)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 7.2.1 | Chaque feature (`features/analysis`, `features/document`, ...) a son propre store, API client et composants UI | 2 |
|
||||
| 7.2.2 | Les features ne s'importent pas mutuellement — la communication passe par `shared/` ou par les props/events Vue | 3 |
|
||||
| 7.2.3 | Les types partages entre features sont dans `shared/types.ts`, pas dans une feature specifique | 2 |
|
||||
| 7.2.4 | Un store Pinia n'accede pas directement au state d'un autre store (sauf via des getters exposes) | 2 |
|
||||
|
||||
### 7.3 Decouplage inter-couches (Backend)
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 7.3.1 | Les repos (`persistence/`) retournent des objets du domaine, pas des dicts ou des Row SQLite | 2 |
|
||||
| 7.3.2 | Les adaptateurs infra n'exposent pas les types de leurs libs internes aux services (pas de types `docling.*` dans les signatures de services) | 3 |
|
||||
| 7.3.3 | Le changement de base de donnees (SQLite -> PostgreSQL) ne necessite de modifier que `persistence/` | 2 |
|
||||
| 7.3.4 | Le changement de framework HTTP (FastAPI -> autre) ne necessite de modifier que `api/` et `main.py` | 2 |
|
||||
|
||||
### 7.4 Contrats et interfaces
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 7.4.1 | Les ports dans `domain/ports.py` definissent des signatures claires avec des types du domaine | 2 |
|
||||
| 7.4.2 | Les schemas Pydantic (`api/schemas.py`) documentent le contrat HTTP — pas de `dict` ou `Any` dans les responses | 2 |
|
||||
| 7.4.3 | Les reponses API ont un format coherent (enveloppe, codes d'erreur normalises) | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 7.2.2 — Imports croises entre features
|
||||
grep -rn "from.*features/" frontend/src/features/ --include="*.ts" --include="*.vue" | grep -v "node_modules" | grep -v "__tests__"
|
||||
|
||||
# 7.2.4 — Store qui accede au state d'un autre store
|
||||
grep -rn "useDocumentStore\|useAnalysisStore\|useChunkingStore\|useHistoryStore\|useSettingsStore" frontend/src/features/ --include="*.ts" | grep -v "index.ts"
|
||||
|
||||
# 7.3.2 — Types docling qui leakent
|
||||
grep -rn "from docling\|import docling" document-parser/services/ --include="*.py"
|
||||
|
||||
# 7.4.2 — dict ou Any dans les reponses API
|
||||
grep -rn "-> dict\|-> Any\|Dict\[str, Any\]" document-parser/api/ --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]`
|
||||
87
docs/audit/audits/08-security.md
Normal file
87
docs/audit/audits/08-security.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Audit 08 — Securite
|
||||
|
||||
**Objectif** : verifier l'absence de vulnerabilites courantes (OWASP Top 10) et le respect des bonnes pratiques de securite.
|
||||
|
||||
**Cible** : tout le projet
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 8.1 Secrets et credentials
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 8.1.1 | Aucune cle API, token, ou mot de passe en dur dans le code source | 3 |
|
||||
| 8.1.2 | Les fichiers `.env` sont dans `.gitignore` | 3 |
|
||||
| 8.1.3 | Les secrets Docker sont passes par variables d'environnement, pas en build args | 2 |
|
||||
|
||||
### 8.2 Validation des entrees
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 8.2.1 | Toutes les entrees utilisateur sont validees par des schemas Pydantic | 3 |
|
||||
| 8.2.2 | `MAX_FILE_SIZE_MB` est configuree et appliquee a l'upload | 3 |
|
||||
| 8.2.3 | Les types de fichiers acceptes sont valides (pas d'upload de `.exe`, `.sh`, etc.) | 2 |
|
||||
|
||||
### 8.3 Injection
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 8.3.1 | Les requetes SQL utilisent des parametres lies (`?`), jamais de string formatting/f-strings | 3 |
|
||||
| 8.3.2 | Pas de `eval()`, `exec()`, ou `os.system()` avec des entrees utilisateur | 3 |
|
||||
| 8.3.3 | Le frontend utilise DOMPurify pour tout rendu de contenu HTML/Markdown | 3 |
|
||||
|
||||
### 8.4 CORS et reseau
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 8.4.1 | Les origines CORS autorisees sont configurees explicitement, pas de `*` en production | 3 |
|
||||
| 8.4.2 | Le rate limiter est actif sur tous les endpoints sauf `/api/health` | 2 |
|
||||
| 8.4.3 | Nginx ne sert que les fichiers statiques prevus — pas de directory listing | 2 |
|
||||
|
||||
### 8.5 Dependances
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 8.5.1 | Pas de dependance avec des CVE critiques connues | 3 |
|
||||
| 8.5.2 | Les versions des dependances sont epinglees (pas de `>=` sans borne superieure) | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 8.1.1 — Secrets potentiels dans le code
|
||||
grep -rni "password\s*=\|secret\s*=\|api_key\s*=\|token\s*=" document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=tests
|
||||
grep -rni "password\|secret\|api.key\|token" frontend/src/ --include="*.ts" --include="*.vue"
|
||||
|
||||
# 8.1.2 — .env dans gitignore
|
||||
grep "\.env" .gitignore
|
||||
|
||||
# 8.3.1 — SQL injection (f-strings dans les requetes)
|
||||
grep -rn 'f".*SELECT\|f".*INSERT\|f".*UPDATE\|f".*DELETE\|f".*DROP' document-parser --include="*.py" --exclude-dir=.venv
|
||||
|
||||
# 8.3.2 — eval/exec/os.system
|
||||
grep -rn "eval(\|exec(\|os\.system(\|subprocess\.call(" document-parser --include="*.py" --exclude-dir=.venv
|
||||
|
||||
# 8.3.3 — DOMPurify usage
|
||||
grep -rn "DOMPurify\|v-html\|innerHTML" frontend/src/ --include="*.vue" --include="*.ts"
|
||||
|
||||
# 8.4.1 — CORS wildcard
|
||||
grep -rn 'allow_origins.*\*\|"*"' document-parser --include="*.py" --exclude-dir=.venv
|
||||
|
||||
# 8.5.1 — Audit npm
|
||||
cd frontend && npm audit --production 2>&1 | tail -10
|
||||
|
||||
# 8.5.1 — Audit pip (si pip-audit installe)
|
||||
cd document-parser && pip-audit 2>&1 | tail -10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
67
docs/audit/audits/09-tests.md
Normal file
67
docs/audit/audits/09-tests.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Audit 09 — Tests
|
||||
|
||||
**Objectif** : verifier la couverture, la qualite et la fiabilite de la suite de tests.
|
||||
|
||||
**Cible** : `document-parser/tests/`, `frontend/src/**/*.test.*`, `e2e/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 9.1 Execution
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 9.1.1 | Tous les tests backend passent (`pytest tests/ -v`) | 3 |
|
||||
| 9.1.2 | Tous les tests frontend passent (`npm run test:run`) | 3 |
|
||||
| 9.1.3 | Les tests e2e Karate UI passent | 2 |
|
||||
|
||||
### 9.2 Couverture
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 9.2.1 | Chaque endpoint API a au moins un test (happy path) | 2 |
|
||||
| 9.2.2 | Les cas d'erreur des endpoints sont testes (400, 404, 413, 429) | 2 |
|
||||
| 9.2.3 | Les services ont des tests unitaires couvrant la logique d'orchestration | 2 |
|
||||
| 9.2.4 | Les fonctions du domain (bbox, value objects) sont testees | 1 |
|
||||
| 9.2.5 | Les composants Vue critiques ont des tests (stores, composables) | 2 |
|
||||
|
||||
### 9.3 Qualite des tests
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 9.3.1 | Pas de `.only` ou `fdescribe` ou `fit` laisse par accident | 3 |
|
||||
| 9.3.2 | Pas de `@pytest.mark.skip` ou `.skip()` sans justification en commentaire | 1 |
|
||||
| 9.3.3 | Les tests sont deterministes — pas de dependance a l'heure, au reseau, ou a l'ordre d'execution | 2 |
|
||||
| 9.3.4 | Les tests d'integration testent le flux reel, pas un mock complet | 2 |
|
||||
| 9.3.5 | Les assertions sont specifiques (pas juste `assert result is not None`) | 1 |
|
||||
| 9.3.6 | Chaque test a un nom explicite qui decrit le comportement teste | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 9.1.1 — Tests backend
|
||||
cd document-parser && python -m pytest tests/ -v --tb=short 2>&1 | tail -30
|
||||
|
||||
# 9.1.2 — Tests frontend
|
||||
cd frontend && npm run test:run 2>&1 | tail -30
|
||||
|
||||
# 9.3.1 — .only / fdescribe / fit
|
||||
grep -rn "\.only\|fdescribe\|fit(" frontend/src/ --include="*.test.*"
|
||||
|
||||
# 9.3.2 — Skip sans commentaire
|
||||
grep -rn -B1 "@pytest.mark.skip\|\.skip(" document-parser/tests/ frontend/src/
|
||||
|
||||
# 9.3.5 — Assertions vagues
|
||||
grep -rn "assert.*is not None$\|assert.*!= None$\|expect.*toBeTruthy()$" document-parser/tests/ frontend/src/ --include="*.test.*" --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]`
|
||||
66
docs/audit/audits/10-ci-build.md
Normal file
66
docs/audit/audits/10-ci-build.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Audit 10 — CI / Build
|
||||
|
||||
**Objectif** : verifier que la pipeline CI est verte, que le build Docker fonctionne, et que les outils de qualite sont actifs.
|
||||
|
||||
**Cible** : `.github/`, `Dockerfile`, `docker-compose.yml`, `nginx.conf`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 10.1 Pipeline CI
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 10.1.1 | Toutes les GitHub Actions passent sur la branche de release | 3 |
|
||||
| 10.1.2 | Les warnings ESLint sont resolus (0 warning) | 1 |
|
||||
| 10.1.3 | Les warnings Ruff sont resolus (0 warning) | 1 |
|
||||
| 10.1.4 | Le type-check frontend passe (`vue-tsc --noEmit`) | 2 |
|
||||
| 10.1.5 | Le formatting est conforme (`ruff format --check`, `prettier --check`) | 1 |
|
||||
|
||||
### 10.2 Build Docker
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 10.2.1 | `docker compose build` reussit sans erreur | 3 |
|
||||
| 10.2.2 | Le container demarre et repond sur `/api/health` | 3 |
|
||||
| 10.2.3 | Les deux variantes (local/remote) buildent correctement | 2 |
|
||||
| 10.2.4 | Pas de fichier inutile dans l'image (node_modules frontend, .venv, .git) — `.dockerignore` est a jour | 1 |
|
||||
|
||||
### 10.3 Configuration
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 10.3.1 | Nginx route correctement `/api/*` vers le backend et sert le frontend sur `/` | 2 |
|
||||
| 10.3.2 | Les variables d'environnement sont documentees et ont des valeurs par defaut coherentes | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 10.1.2 + 10.1.3 — Lint
|
||||
cd document-parser && ruff check . 2>&1 | tail -5
|
||||
cd frontend && npx eslint src/ 2>&1 | tail -5
|
||||
|
||||
# 10.1.4 — Type check
|
||||
cd frontend && npx vue-tsc --noEmit 2>&1 | tail -5
|
||||
|
||||
# 10.1.5 — Formatting
|
||||
cd document-parser && ruff format --check . 2>&1 | tail -5
|
||||
cd frontend && npx prettier --check src/ 2>&1 | tail -5
|
||||
|
||||
# 10.2.1 — Build Docker
|
||||
docker compose build 2>&1 | tail -10
|
||||
|
||||
# 10.2.4 — .dockerignore
|
||||
cat .dockerignore 2>/dev/null || echo "ABSENT"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
63
docs/audit/audits/11-documentation.md
Normal file
63
docs/audit/audits/11-documentation.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Audit 11 — Documentation & Changelog
|
||||
|
||||
**Objectif** : verifier que la release est correctement documentee et versionnee.
|
||||
|
||||
**Cible** : `CHANGELOG.md`, `frontend/package.json`, `docs/`, code source
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 11.1 Changelog
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 11.1.1 | La section `[Unreleased]` a ete renommee en `[X.Y.Z] - YYYY-MM-DD` | 3 |
|
||||
| 11.1.2 | Toutes les modifications significatives de la release sont listees dans le changelog | 2 |
|
||||
| 11.1.3 | Les breaking changes sont clairement identifies | 3 |
|
||||
| 11.1.4 | Le format respecte [Keep a Changelog](https://keepachangelog.com/) | 1 |
|
||||
|
||||
### 11.2 Versioning
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 11.2.1 | `frontend/package.json` contient la bonne version X.Y.Z | 2 |
|
||||
| 11.2.2 | La version suit le Semantic Versioning | 2 |
|
||||
|
||||
### 11.3 Code propre
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 11.3.1 | Les `TODO` et `FIXME` restants sont volontaires et documentes (pas de TODO orphelin) | 1 |
|
||||
| 11.3.2 | Pas de `console.log` de debug laisse dans le code frontend | 2 |
|
||||
| 11.3.3 | Pas de `print()` de debug laisse dans le code backend (hors logging structure) | 2 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 11.1.1 — Section Unreleased encore presente
|
||||
grep -n "Unreleased" CHANGELOG.md
|
||||
|
||||
# 11.2.1 — Version dans package.json
|
||||
grep '"version"' frontend/package.json
|
||||
|
||||
# 11.3.1 — TODOs restants
|
||||
grep -rn "TODO\|FIXME\|HACK\|XXX" document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=__pycache__
|
||||
grep -rn "TODO\|FIXME\|HACK\|XXX" frontend/src --include="*.ts" --include="*.vue"
|
||||
|
||||
# 11.3.2 — console.log de debug
|
||||
grep -rn "console\.log\|console\.debug\|console\.warn" frontend/src/ --include="*.ts" --include="*.vue" | grep -v "node_modules"
|
||||
|
||||
# 11.3.3 — print() de debug
|
||||
grep -rn "^\s*print(" document-parser --include="*.py" --exclude-dir=.venv --exclude-dir=tests --exclude-dir=__pycache__
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
61
docs/audit/audits/12-performance.md
Normal file
61
docs/audit/audits/12-performance.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Audit 12 — Performance & Ressources
|
||||
|
||||
**Objectif** : verifier l'absence de problemes de performance evidents et la bonne gestion des ressources.
|
||||
|
||||
**Cible** : `document-parser/` (hors `.venv/`), `frontend/src/`
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### 12.1 Backend
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 12.1.1 | Pas de requete N+1 — les acces DB sont optimises (pas de boucle avec requete unitaire) | 2 |
|
||||
| 12.1.2 | Les fichiers uploades temporaires sont supprimes apres traitement | 2 |
|
||||
| 12.1.3 | `MAX_CONCURRENT_ANALYSES` est configuree et respectee (semaphore) | 2 |
|
||||
| 12.1.4 | Les operations longues (conversion Docling) sont asynchrones et ne bloquent pas l'event loop | 3 |
|
||||
| 12.1.5 | Pas de chargement de fichier entier en memoire sans necesssite (streaming si possible) | 2 |
|
||||
|
||||
### 12.2 Frontend
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 12.2.1 | Les watchers Vue ont leur cleanup (pas de memory leak) | 2 |
|
||||
| 12.2.2 | Les event listeners sont supprimes dans `onUnmounted` | 2 |
|
||||
| 12.2.3 | Les requetes API ont un mecanisme d'annulation ou de debounce quand pertinent | 1 |
|
||||
| 12.2.4 | Pas de re-render excessif — les computed sont utilises plutot que des fonctions dans le template | 1 |
|
||||
| 12.2.5 | Les assets lourds (images, fonts) sont optimises | 1 |
|
||||
|
||||
### 12.3 Infrastructure
|
||||
|
||||
| # | Item | Poids |
|
||||
|---|------|-------|
|
||||
| 12.3.1 | Nginx a une configuration de cache pour les fichiers statiques | 1 |
|
||||
| 12.3.2 | Les reponses API sont de taille raisonnable (pas d'envoi de donnees inutiles) | 1 |
|
||||
| 12.3.3 | Le health check est leger et ne charge pas le systeme | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Commandes de verification
|
||||
|
||||
```bash
|
||||
# 12.1.1 — Pattern N+1 (boucle avec requete DB)
|
||||
grep -rn -A5 "for.*in.*:" document-parser/persistence/ --include="*.py" | grep -i "select\|fetch\|execute"
|
||||
|
||||
# 12.1.4 — Appels bloquants dans du code async
|
||||
grep -rn "time\.sleep\|open(" document-parser/services/ --include="*.py"
|
||||
|
||||
# 12.2.1 + 12.2.2 — Watchers et listeners sans cleanup
|
||||
grep -rn "addEventListener\|watch(\|watchEffect(" frontend/src/ --include="*.vue" --include="*.ts" | grep -v "node_modules"
|
||||
grep -rn "onUnmounted\|onBeforeUnmount\|removeEventListener" frontend/src/ --include="*.vue" | grep -v "node_modules"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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]`
|
||||
206
docs/audit/master.md
Normal file
206
docs/audit/master.md
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
# Audit Master — Release Branch Quality Gate
|
||||
|
||||
Referentiel central d'audit qualite pour les branches `release/X.Y.Z` de Docling Studio.
|
||||
|
||||
Ce document est le **chef d'orchestre** : il definit les regles, commandite les audits unitaires, et normalise les rapports.
|
||||
|
||||
---
|
||||
|
||||
## 1. Perimetre
|
||||
|
||||
L'audit s'execute sur une branche `release/X.Y.Z` **apres feature freeze**, avant le merge dans `main`.
|
||||
|
||||
**Cibles :**
|
||||
|
||||
| Cible | Chemin |
|
||||
|-------|--------|
|
||||
| Backend (Python/FastAPI) | `document-parser/` (hors `.venv/`, `__pycache__/`, `tests/`) |
|
||||
| Frontend (Vue 3/TypeScript) | `frontend/src/` |
|
||||
| Tests backend | `document-parser/tests/` |
|
||||
| Tests frontend | `frontend/src/**/*.test.*` |
|
||||
| Tests e2e | `e2e/` |
|
||||
| Infrastructure | `Dockerfile`, `docker-compose.yml`, `nginx.conf`, `.github/` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Niveaux de criticite
|
||||
|
||||
Chaque ecart trouve lors d'un audit est classe selon ces 4 niveaux :
|
||||
|
||||
| Niveau | Tag | Description | Impact sur le GO/NO-GO |
|
||||
|--------|-----|-------------|------------------------|
|
||||
| **CRITICAL** | `[CRIT]` | Violation bloquante — faille de securite, corruption de donnees, violation d'architecture majeure | **Bloquant** — le release ne peut pas partir |
|
||||
| **MAJOR** | `[MAJ]` | Violation significative — couplage fort, dette technique importante, test manquant sur un chemin critique | Bloquant si > 3 ecarts MAJOR non resolus |
|
||||
| **MINOR** | `[MIN]` | Ecart de qualite — nommage, taille de fichier, duplication legere | Non bloquant — a corriger dans le prochain cycle |
|
||||
| **INFO** | `[INFO]` | Observation, suggestion d'amelioration, bonne pratique non respectee mais sans risque | Non bloquant — informatif |
|
||||
|
||||
---
|
||||
|
||||
## 3. Bareme de compliance
|
||||
|
||||
Chaque audit unitaire produit une **note de compliance sur 100**.
|
||||
|
||||
### Calcul
|
||||
|
||||
Chaque item de checklist a un **poids** defini dans la fiche d'audit :
|
||||
|
||||
| Poids | Signification |
|
||||
|-------|---------------|
|
||||
| 3 | Critique — violation = ecart CRITICAL |
|
||||
| 2 | Important — violation = ecart MAJOR |
|
||||
| 1 | Standard — violation = ecart MINOR |
|
||||
|
||||
**Formule :**
|
||||
|
||||
```
|
||||
score = (somme des poids des items conformes / somme totale des poids) * 100
|
||||
```
|
||||
|
||||
### Seuils de decision
|
||||
|
||||
| Score | Verdict | Action |
|
||||
|-------|---------|--------|
|
||||
| >= 80 | **GO** | Release autorisee |
|
||||
| 60 - 79 | **GO CONDITIONNEL** | Release autorisee si 0 CRITICAL, plan de remediation pour les MAJOR |
|
||||
| < 60 | **NO-GO** | Release bloquee — corriger et re-auditer |
|
||||
|
||||
**Regle absolue** : tout ecart `[CRIT]` non resolu = **NO-GO** quel que soit le score.
|
||||
|
||||
---
|
||||
|
||||
## 4. Liste des audits
|
||||
|
||||
Les audits sont executes dans l'ordre ci-dessous. Chacun est une fiche autonome dans `audits/`.
|
||||
|
||||
| # | Audit | Fichier | Focus |
|
||||
|---|-------|---------|-------|
|
||||
| 01 | Clean Architecture | [01-clean-architecture.md](audits/01-clean-architecture.md) | Respect des couches, flux de dependances |
|
||||
| 02 | DDD | [02-ddd.md](audits/02-ddd.md) | Bounded contexts, entites, value objects, ubiquitous language |
|
||||
| 03 | Clean Code | [03-clean-code.md](audits/03-clean-code.md) | Nommage, taille, lisibilite |
|
||||
| 04 | KISS | [04-kiss.md](audits/04-kiss.md) | Simplicite, pas de sur-ingenierie |
|
||||
| 05 | DRY | [05-dry.md](audits/05-dry.md) | Duplication, factorisation |
|
||||
| 06 | SOLID | [06-solid.md](audits/06-solid.md) | 5 principes SOLID |
|
||||
| 07 | Decouplage | [07-decoupling.md](audits/07-decoupling.md) | Front/back, inter-features, contrats |
|
||||
| 08 | Securite | [08-security.md](audits/08-security.md) | OWASP, secrets, injection, CORS |
|
||||
| 09 | Tests | [09-tests.md](audits/09-tests.md) | Couverture, qualite, e2e |
|
||||
| 10 | CI / Build | [10-ci-build.md](audits/10-ci-build.md) | Pipeline, Docker, health check |
|
||||
| 11 | Documentation | [11-documentation.md](audits/11-documentation.md) | Changelog, version, TODOs |
|
||||
| 12 | Performance | [12-performance.md](audits/12-performance.md) | N+1, memory, concurrence |
|
||||
|
||||
---
|
||||
|
||||
## 5. Format de rapport attendu
|
||||
|
||||
Chaque audit produit un rapport dans `reports/release-X.Y.Z/XX-nom.md` respectant ce format :
|
||||
|
||||
```markdown
|
||||
# Rapport d'audit : [Nom de l'audit]
|
||||
|
||||
**Release** : X.Y.Z
|
||||
**Date** : YYYY-MM-DD
|
||||
**Auditeur** : [nom ou "claude-code"]
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | XX / YY |
|
||||
| Score | XX / 100 |
|
||||
| Ecarts CRITICAL | N |
|
||||
| Ecarts MAJOR | N |
|
||||
| Ecarts MINOR | N |
|
||||
| Ecarts INFO | N |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [CRIT] Titre de l'ecart
|
||||
- **Localisation** : `chemin/fichier.py:ligne`
|
||||
- **Constat** : description factuelle
|
||||
- **Regle violee** : reference a l'item de checklist
|
||||
- **Remediation** : action corrective proposee
|
||||
|
||||
### [MAJ] Titre de l'ecart
|
||||
...
|
||||
|
||||
### [MIN] Titre de l'ecart
|
||||
...
|
||||
|
||||
### [INFO] Titre de l'ecart
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- ...
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO / GO CONDITIONNEL / NO-GO
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Rapport de synthese
|
||||
|
||||
Le fichier `reports/release-X.Y.Z/summary.md` consolide tous les audits :
|
||||
|
||||
```markdown
|
||||
# Synthese d'audit — Release X.Y.Z
|
||||
|
||||
**Date** : YYYY-MM-DD
|
||||
**Branche** : release/X.Y.Z
|
||||
|
||||
---
|
||||
|
||||
## Tableau de bord
|
||||
|
||||
| # | Audit | Score | CRIT | MAJ | MIN | INFO | Verdict |
|
||||
|---|-------|-------|------|-----|-----|------|---------|
|
||||
| 01 | Clean Architecture | XX | N | N | N | N | GO |
|
||||
| 02 | DDD | XX | N | N | N | N | GO |
|
||||
| ... | ... | ... | ... | ... | ... | ... | ... |
|
||||
|
||||
**Score global** : XX / 100 (moyenne ponderee)
|
||||
**Ecarts CRITICAL totaux** : N
|
||||
**Ecarts MAJOR totaux** : N
|
||||
|
||||
---
|
||||
|
||||
## Ecarts CRITICAL (tous audits confondus)
|
||||
|
||||
1. [audit] description — fichier:ligne
|
||||
|
||||
---
|
||||
|
||||
## Verdict final : GO / GO CONDITIONNEL / NO-GO
|
||||
|
||||
Conditions (si GO CONDITIONNEL) :
|
||||
- ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Execution
|
||||
|
||||
### Lancer un audit complet
|
||||
|
||||
```
|
||||
Audite la branche release/X.Y.Z en suivant docs/audit/master.md
|
||||
```
|
||||
|
||||
### Lancer un audit unitaire
|
||||
|
||||
```
|
||||
Execute l'audit docs/audit/audits/02-ddd.md sur la branche courante
|
||||
```
|
||||
|
||||
### Re-auditer apres correction
|
||||
|
||||
```
|
||||
Re-audite uniquement les ecarts CRITICAL et MAJOR du rapport docs/audit/reports/release-X.Y.Z/summary.md
|
||||
```
|
||||
0
docs/audit/reports/.gitkeep
Normal file
0
docs/audit/reports/.gitkeep
Normal file
67
docs/audit/reports/release-0.3.1/01-clean-architecture.md
Normal file
67
docs/audit/reports/release-0.3.1/01-clean-architecture.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Rapport d'audit : Clean Architecture
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
**Derniere mise a jour** : 2026-04-10 (re-audit post PR #133)
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 13 / 13 |
|
||||
| Score | 100 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts resolus (PR #133 — fix/clean-architecture-audit)
|
||||
|
||||
### [CRIT — RESOLU] Services importent directement les modules persistence (concretions)
|
||||
|
||||
- **Localisation** : `services/analysis_service.py`, `services/document_service.py`
|
||||
- **Resolution** : `AnalysisService` et `DocumentService` recoivent `analysis_repo` et `document_repo` par injection dans leur constructeur. Plus aucun import direct de `persistence.*` au top-level des services.
|
||||
|
||||
### [CRIT — RESOLU] Services importent directement `infra.settings`
|
||||
|
||||
- **Localisation** : `services/analysis_service.py`, `services/document_service.py`
|
||||
- **Resolution** : Les valeurs de configuration sont encapsulees dans des dataclasses `AnalysisConfig` et `DocumentConfig` injectees dans les constructeurs. Plus aucun import direct de `infra.settings` dans les services.
|
||||
|
||||
### [CRIT — RESOLU] Pas de protocol pour les repositories dans `domain/ports.py`
|
||||
|
||||
- **Localisation** : `domain/ports.py`
|
||||
- **Resolution** : `DocumentRepository` et `AnalysisRepository` ajoutes comme `Protocol` dans `domain/ports.py`. Les services dependent maintenant de ces abstractions.
|
||||
|
||||
### [MAJ — RESOLU] `document_service` est un module procedural, non une classe injectable
|
||||
|
||||
- **Resolution** : `document_service` transforme en classe `DocumentService` avec injection du repository et de la config.
|
||||
|
||||
### [MAJ — RESOLU] Logique metier dans le service (`_classify_error`, `_merge_results`, validation)
|
||||
|
||||
- **Resolution** : `_merge_results` et `_classify_error` deplaces dans `domain/`. Validation de fichier encapsulee.
|
||||
|
||||
### [MIN — RESOLU] `api/documents.py` importe `infra.settings`
|
||||
|
||||
- **Resolution** : La valeur `max_file_size_mb` obtenue via le service, plus d'import direct dans la couche API.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Domain pur : `domain/models.py`, `domain/value_objects.py` et `domain/ports.py` n'importent aucune librairie externe. Les modeles sont des dataclasses pures avec des methodes de transition d'etat.
|
||||
- Ports complets : `DocumentConverter`, `DocumentChunker`, `DocumentRepository` et `AnalysisRepository` couvrent toutes les interactions externes.
|
||||
- Injection de dependances complete : services, repositories et config injectes via constructeur + `Depends` FastAPI.
|
||||
- Pydantic confine a la couche API : Tous les schemas Pydantic sont dans `api/schemas.py`. Le domaine n'utilise que des dataclasses.
|
||||
- Routes delegent aux services : Les endpoints se contentent de mapper les requetes/reponses et de deleguer.
|
||||
- Configuration centralisee dans `infra/settings.py` et propagee par injection.
|
||||
|
||||
---
|
||||
|
||||
## Verdict : GO
|
||||
|
||||
Score 100/100 — 0 ecart critique. Toutes les non-conformites precedentes resolues via PR #133.
|
||||
57
docs/audit/reports/release-0.3.1/02-ddd.md
Normal file
57
docs/audit/reports/release-0.3.1/02-ddd.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Rapport d'audit : Domain-Driven Design (DDD)
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
**Derniere mise a jour** : 2026-04-10 (re-audit post PR #135)
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 16 / 16 |
|
||||
| Score | 100 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts resolus (PR #135 — fix/ddd-audit)
|
||||
|
||||
### [CRIT — RESOLU] Invariants metier non proteges dans la state machine
|
||||
|
||||
- **Localisation** : `domain/models.py` (methodes `mark_running`, `mark_completed`, `update_progress`, `mark_failed`)
|
||||
- **Resolution** : Guard clauses ajoutees dans les 4 methodes de transition. `mark_running` leve `ValueError` si status != PENDING. `mark_completed` leve si status != RUNNING. `update_progress` leve si status != RUNNING. `mark_failed` accepte PENDING ou RUNNING uniquement. 11 tests couvrent les transitions valides et invalides dans `TestAnalysisJobGuardClauses`.
|
||||
|
||||
### [MAJ — RESOLU] Value objects non immutables
|
||||
|
||||
- **Localisation** : `domain/value_objects.py`
|
||||
- **Resolution** : `frozen=True` ajoute sur les 7 dataclasses : `PageElement`, `PageDetail`, `ConversionOptions`, `ConversionResult`, `ChunkingOptions`, `ChunkBbox`, `ChunkResult`. Les instances sont desormais immutables et hashables.
|
||||
|
||||
### [MAJ — RESOLU] Vocabulaire inconsistant "analysis" vs "job"
|
||||
|
||||
- **Resolution** : Le terme `analysis` unifie dans les couches exposees (API, frontend, store). `AnalysisJob` conserve en domaine interne pour sa semantique de job long-running, les interfaces publiques utilisent `analysis_id`.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Bounded contexts clairement identifies et isoles (Document, Analysis/Chunking) avec des modeles, services et repos separes
|
||||
- `domain/models.py` compact avec deux entites bien definies, pas de "god object"
|
||||
- `AnalysisJob` porte du comportement metier (state machine, progress tracking) avec invariants proteges
|
||||
- State machine exhaustivement testee (11 tests de guard clauses)
|
||||
- Value objects immutables et hashables (`frozen=True`)
|
||||
- Les repositories retournent des entites du domaine, pas des dicts ou Row objects
|
||||
- La couche anti-corruption (schemas Pydantic) transforme correctement les donnees HTTP en objets du domaine
|
||||
- Les adaptateurs infra ne leakent pas les types Docling vers les services
|
||||
- Le frontend respecte les memes bounded contexts (features = contextes)
|
||||
|
||||
---
|
||||
|
||||
## Verdict : GO
|
||||
|
||||
Score 100/100 — 0 ecart critique. Toutes les non-conformites precedentes resolues via PR #135.
|
||||
74
docs/audit/reports/release-0.3.1/03-clean-code.md
Normal file
74
docs/audit/reports/release-0.3.1/03-clean-code.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Rapport d'audit : Clean Code
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
**Derniere mise a jour** : 2026-04-10 (re-audit post PR #139)
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 12 / 14 |
|
||||
| Score | 93 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 2 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts resolus (PR #139 — fix/clean-code-audit)
|
||||
|
||||
### [MAJ — RESOLU] Code non entierement en anglais — mode strings en francais
|
||||
|
||||
- **Localisation** : `frontend/src/pages/StudioPage.vue`, `frontend/src/features/history/navigation.test.ts`
|
||||
- **Resolution** : `configurer` → `configure`, `verifier` → `verify`, `preparer` → `prepare`. Toutes les valeurs d'etat internes sont en anglais.
|
||||
|
||||
### [MAJ — RESOLU] `_run_analysis_inner` viole le Single Responsibility
|
||||
|
||||
- **Localisation** : `services/analysis_service.py`
|
||||
- **Resolution** : 3 sous-fonctions extraites : `_build_conversion_options()` (construit `ConversionOptions` avec table_mode par defaut), `_run_conversion()` (orchestre batched vs single), `_finalize_analysis()` (serialise, chunke, marque completed). `_run_analysis_inner` reduite a 20 lignes d'orchestration.
|
||||
|
||||
### [MAJ — RESOLU] `_get_default_converter()` modifie un etat global
|
||||
|
||||
- **Localisation** : `infra/local_converter.py`
|
||||
- **Resolution** : Renomme en `_ensure_default_converter()`. Tous les call sites mis a jour. Les 9 patches de test mis a jour.
|
||||
|
||||
---
|
||||
|
||||
## Ecarts residuels
|
||||
|
||||
### [MIN] Fonctions depassant 30 lignes
|
||||
|
||||
- **Localisation** : `infra/local_converter.py` (~50 et ~48 lignes), `infra/local_chunker.py` (~48 lignes)
|
||||
- **Constat** : 3-4 fonctions restent au-dessus de 30 lignes apres les extractions (les fonctions de construction de pipeline Docling sont difficiles a decomposer sans perte de lisibilite).
|
||||
- **Regle violee** : 3.2.2 — Aucune fonction ne depasse 30 lignes
|
||||
|
||||
### [MIN] Fichiers source depassant 300 lignes
|
||||
|
||||
- **Localisation** : `StudioPage.vue` (~1200 lignes dont ~700 de CSS), `ResultTabs.vue` (~690 lignes), `ChunkPanel.vue` (~483 lignes)
|
||||
- **Constat** : Les fichiers Vue restent volumineux. Decomposition en sous-composants reportee (hors perimetre de cette PR).
|
||||
- **Regle violee** : 3.3.1 — Aucun fichier source ne depasse 300 lignes
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Nommage excellent : verbes d'action, variables expressives, conventions respectees
|
||||
- Pas de flag arguments booleen
|
||||
- Un concept par fichier, architecture bien organisee
|
||||
- Imports ordonnes (isort/Ruff)
|
||||
- Commentaires pertinents expliquant le "pourquoi"
|
||||
- Pas de code commente/dead code
|
||||
- Pas d'abbreviations ambigues
|
||||
- SRP respecte dans `_run_analysis_inner` apres extraction des 3 sous-fonctions
|
||||
- Nommage descriptif : `_ensure_default_converter` communique le side-effect intentionnel
|
||||
|
||||
---
|
||||
|
||||
## Verdict : GO
|
||||
|
||||
Score 93/100 — 0 ecart CRITICAL, 0 ecart MAJOR. 2 ecarts MINOR residuels (longueur de fonctions/fichiers) planifies pour le prochain cycle. Seuil GO atteint.
|
||||
43
docs/audit/reports/release-0.3.1/04-kiss.md
Normal file
43
docs/audit/reports/release-0.3.1/04-kiss.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Rapport d'audit : KISS (Keep It Simple, Stupid)
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 8 / 8 |
|
||||
| Score | 100 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
Aucun ecart constate.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Aucune classe Factory, Strategy, Observer, Builder ni Singleton detectee
|
||||
- Le pattern Ports & Adapters est justifie (deux implementations reelles) avec un wiring minimal (`if/else` dans `main.py`)
|
||||
- Les Protocols sont la forme la plus legere possible d'interfaces (duck typing Python)
|
||||
- Les features implementees correspondent a des cas d'usage reels, pas de genericite prematuree
|
||||
- Le systeme i18n est un dictionnaire statique simple (~80 cles), pas de lib lourde
|
||||
- Le feature flag system est minimal (2 flags, un registre de 2 entrees)
|
||||
- Configuration via un simple dataclass + env vars, pas de framework de config
|
||||
- Aucune meta-programmation, metaclass, ou magie detectee
|
||||
- Structures de donnees simples (dataclasses plates, listes, schema SQLite a 2 tables)
|
||||
- Chemin d'execution d'une requete : 4 couches justifiees (HTTP -> Service -> Persistence + Infra)
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
44
docs/audit/reports/release-0.3.1/05-dry.md
Normal file
44
docs/audit/reports/release-0.3.1/05-dry.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Rapport d'audit : DRY (Don't Repeat Yourself)
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 6 / 7 |
|
||||
| Score | 83 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 1 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [MAJ] Magic numbers 612.0 / 792.0 dupliques dans `serve_converter.py`
|
||||
|
||||
- **Localisation** : `infra/serve_converter.py:195,196,223,224`
|
||||
- **Constat** : Les dimensions US Letter (612.0, 792.0) sont utilisees comme litteraux bruts 4 fois, alors que `local_converter.py` definit correctement les constantes nommees `_DEFAULT_PAGE_WIDTH` et `_DEFAULT_PAGE_HEIGHT`.
|
||||
- **Regle violee** : 5.3 — Pas de magic numbers eparpilles
|
||||
- **Remediation** : Extraire ces constantes dans un module partage ou les importer depuis `local_converter.py`.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Aucun bloc de code identique n'apparait 3+ fois sans factorisation
|
||||
- Types partages centralises dans `shared/types.ts` (frontend) et `domain/models.py` + `domain/value_objects.py` (backend)
|
||||
- Logique reactive partagee dans `shared/composables/usePagination.ts`
|
||||
- Appels API centralises via `apiFetch` dans `shared/api/http.ts` — zero fuite de `fetch()` brut
|
||||
- Schemas Pydantic transforment les modeles domaine, ne les redefinissent pas
|
||||
- Regles de validation definies en un seul endroit (backend = source de verite, frontend = UX optimization)
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
38
docs/audit/reports/release-0.3.1/06-solid.md
Normal file
38
docs/audit/reports/release-0.3.1/06-solid.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Rapport d'audit : SOLID
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 15 / 15 |
|
||||
| Score | 100 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
Aucun ecart constate.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- **S (SRP)** : Chaque service, store Pinia et router a une responsabilite unique bien definie
|
||||
- **O (OCP)** : Les ports permettent d'ajouter de nouveaux adaptateurs sans modifier le code existant. Le wiring local/remote est extensible via `_build_converter()`
|
||||
- **L (LSP)** : `LocalConverter` et `ServeConverter` sont pleinement interchangeables. Zero `isinstance` dans les services pour differencier les implementations
|
||||
- **I (ISP)** : `DocumentConverter` et `DocumentChunker` sont des ports separes avec une seule methode chacun
|
||||
- **D (DIP)** : Les services dependent des protocols abstraits. L'injection se fait dans `main.py` (composition root). Zero instanciation directe d'adaptateurs dans les services
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
73
docs/audit/reports/release-0.3.1/07-decoupling.md
Normal file
73
docs/audit/reports/release-0.3.1/07-decoupling.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# Rapport d'audit : Decouplage
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
**Derniere mise a jour** : 2026-04-10 (re-audit post PR #144)
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 16 / 16 |
|
||||
| Score | 100 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts resolus (PR #144 — fix/decoupling-audit)
|
||||
|
||||
### [CRIT — RESOLU] Imports croises entre features frontend
|
||||
|
||||
- **Localisation** : `features/history/store.ts`, `features/chunking/`, `features/document/store.ts`, `shared/i18n.ts`
|
||||
- **Resolution** :
|
||||
- `shared/appConfig.ts` cree comme pont reactif neutre (`appLocale`, `appMaxFileSizeMb`, `appMaxPageCount`).
|
||||
- `shared/i18n.ts` lit `appLocale` depuis `shared/appConfig` — plus d'import depuis `features/`.
|
||||
- `features/document/store.ts` lit `appMaxFileSizeMb` depuis `shared/appConfig` — plus d'import de `useFeatureFlagStore`.
|
||||
- `features/feature-flags/store.ts` ecrit dans `appConfig` lors du chargement.
|
||||
- `features/settings/store.ts` ecrit `appLocale` lors du changement de langue.
|
||||
|
||||
### [MAJ — RESOLU] Features `chunking` et `history` sans store/API propres
|
||||
|
||||
- **Resolution** :
|
||||
- `features/chunking/api.ts` cree avec `rechunkAnalysis()`.
|
||||
- `features/chunking/store.ts` cree avec `useChunkingStore` (state: `rechunking`, `error`; action: `rechunk()`).
|
||||
- `features/history/api.ts` cree avec `fetchHistory()` et `deleteHistoryEntry()`.
|
||||
- `features/history/store.ts` reecrit comme store Pinia distinct (state: `analyses`, `error`; actions: `load()`, `remove()`).
|
||||
|
||||
### [MAJ — RESOLU] Collapse d'identite store history/analysis
|
||||
|
||||
- **Resolution** : `useHistoryStore` est desormais un store Pinia independant avec son propre state et ses propres appels API. Plus de re-export vers `useAnalysisStore`.
|
||||
|
||||
### [MAJ — RESOLU] Health endpoint sans schema Pydantic
|
||||
|
||||
- **Resolution** : `HealthResponse` schema Pydantic cree dans `api/schemas.py`. Le endpoint `/api/health` retourne `HealthResponse` avec `response_model=HealthResponse`.
|
||||
|
||||
### [MIN — RESOLU] Pas de format de reponse API coherent
|
||||
|
||||
- **Resolution** : Le schema `HealthResponse` etablit le pattern type pour les endpoints systeme. Les erreurs fonctionnelles utilisent le format standard FastAPI `HTTPException` de facon coherente.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Decouplage frontend/backend exemplaire via API REST, nginx proxy, et services Docker separes
|
||||
- Contrat API stable : types TypeScript alignes sur les schemas Pydantic avec serialisation camelCase
|
||||
- Backend pleinement testable sans frontend (TestClient)
|
||||
- Repos retournent des objets domaine, pas de dicts ou Row SQLite
|
||||
- Les adaptateurs infra ne leakent pas les types Docling vers les services
|
||||
- Changement de DB ne necessiterait de modifier que `persistence/`
|
||||
- Ports avec signatures claires utilisant des types du domaine
|
||||
- Features frontend isolees : chaque feature possede son store, son API client et ses composants UI
|
||||
- `shared/appConfig.ts` pattern : pont reactif sans couplage de feature a feature
|
||||
|
||||
---
|
||||
|
||||
## Verdict : GO
|
||||
|
||||
Score 100/100 — 0 ecart critique. Toutes les non-conformites precedentes resolues via PR #144.
|
||||
57
docs/audit/reports/release-0.3.1/08-security.md
Normal file
57
docs/audit/reports/release-0.3.1/08-security.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Rapport d'audit : Securite
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 13 / 14 |
|
||||
| Score | 97 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 1 |
|
||||
| Ecarts INFO | 1 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [MIN] `python-multipart>=0.0.12` sans borne superieure
|
||||
|
||||
- **Localisation** : `document-parser/requirements.txt`
|
||||
- **Constat** : `python-multipart>=0.0.12` n'a pas de borne superieure, contrairement aux autres dependances.
|
||||
- **Regle violee** : 8.5.2 — Les versions des dependances sont epinglees
|
||||
- **Remediation** : Ajouter `<1.0.0` pour la coherence.
|
||||
|
||||
### [INFO] Mismatch nginx `client_max_body_size 5M` vs `MAX_FILE_SIZE_MB=50`
|
||||
|
||||
- **Localisation** : `nginx.conf`, `frontend/nginx.conf`, `infra/settings.py`
|
||||
- **Constat** : Nginx rejette les uploads > 5MB avant que le backend (configure a 50MB par defaut) ne les voie. Pas un probleme de securite (plus restrictif), mais un probleme de coherence fonctionnelle.
|
||||
- **Remediation** : Aligner nginx `client_max_body_size` avec `MAX_FILE_SIZE_MB` ou rendre configurable.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Zero secret hardcode dans le code source — tout via env vars
|
||||
- `.env` dans `.gitignore` (+ `.env.local`, `.env.production`)
|
||||
- Secrets Docker passes via `environment:`, pas `build: args:`
|
||||
- Toutes les entrees validees par schemas Pydantic avec validators
|
||||
- `MAX_FILE_SIZE_MB` enforce en double couche (eager check + streaming check)
|
||||
- Validation de contenu PDF par magic bytes, pas seulement par extension
|
||||
- SQL parametrise partout (`?` placeholders), zero f-string SQL
|
||||
- Zero `eval()`, `exec()`, `os.system()` dans le code
|
||||
- DOMPurify utilise sur l'unique `v-html` (MarkdownViewer)
|
||||
- CORS explicitement configure, pas de wildcard `*`
|
||||
- Rate limiter actif sur tous les endpoints sauf `/api/health`
|
||||
- Nginx sans `autoindex`, avec headers de securite
|
||||
- Dependances recentes sans CVE critiques connues
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
65
docs/audit/reports/release-0.3.1/09-tests.md
Normal file
65
docs/audit/reports/release-0.3.1/09-tests.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Rapport d'audit : Tests
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 11 / 14 |
|
||||
| Score | 100 / 100 (*) |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 3 |
|
||||
|
||||
(*) Score calcule sur les 11 items verifiables. Les 3 items d'execution (9.1.x) sont marques [INFO] car non executables dans le contexte d'audit.
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [INFO] Execution des tests backend non verifiable
|
||||
|
||||
- **Localisation** : `document-parser/tests/`
|
||||
- **Constat** : 14 fichiers de tests backend bien structures. Execution non possible dans le contexte d'audit.
|
||||
- **Regle violee** : 9.1.1 — Tous les tests backend passent
|
||||
- **Remediation** : Verifier via CI (GitHub Actions).
|
||||
|
||||
### [INFO] Execution des tests frontend non verifiable
|
||||
|
||||
- **Localisation** : `frontend/src/**/*.test.*`
|
||||
- **Constat** : 15 fichiers de tests frontend bien structures. Execution non possible dans le contexte d'audit.
|
||||
- **Regle violee** : 9.1.2 — Tous les tests frontend passent
|
||||
- **Remediation** : Verifier via CI.
|
||||
|
||||
### [INFO] Execution des tests e2e Karate UI non verifiable
|
||||
|
||||
- **Localisation** : `e2e/`
|
||||
- **Constat** : Suite e2e comprehensive (10+ features UI, 13+ features API). Execution non possible dans le contexte d'audit.
|
||||
- **Regle violee** : 9.1.3 — Les tests e2e Karate UI passent
|
||||
- **Remediation** : Verifier via CI (release-gate).
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Couverture complete : tous les 11 endpoints API ont des tests happy-path
|
||||
- Cas d'erreur testes (400, 404, 413, 422, 429) avec verification des messages et headers
|
||||
- Tests de services complets : concurrence, batch, cancellation, regression
|
||||
- Domain teste en profondeur (bbox : 19 tests, models, schemas, value objects)
|
||||
- Tous les stores et composables Vue sont testes (15 fichiers, 100+ tests)
|
||||
- Zero `.only`, `fdescribe`, ou `fit` laisse par accident
|
||||
- Tous les `@pytest.mark.skip` sont justifies (dependance `docling` optionnelle)
|
||||
- Tests deterministes : `vi.useFakeTimers()`, `patch("time.monotonic")`, fresh Pinia instances
|
||||
- Tests d'integration sur flux reel (SQLite reel, TestClient, async tasks)
|
||||
- Assertions specifiques partout (zero `is not None` ou `toBeTruthy()` isolees)
|
||||
- Noms de tests descriptifs et explicites
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
55
docs/audit/reports/release-0.3.1/10-ci-build.md
Normal file
55
docs/audit/reports/release-0.3.1/10-ci-build.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Rapport d'audit : CI / Build
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 9 / 11 |
|
||||
| Score | 90 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 2 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [MIN] ESLint n'enforce pas zero warnings
|
||||
|
||||
- **Localisation** : `.github/workflows/ci.yml:69`, `.github/workflows/release-gate.yml:53`
|
||||
- **Constat** : `npx eslint src/` est invoque sans `--max-warnings 0`. Les warnings passent silencieusement.
|
||||
- **Regle violee** : 10.1.2 — Les warnings ESLint sont resolus (0 warning)
|
||||
- **Remediation** : Ajouter `--max-warnings 0` a la commande ESLint dans les deux workflows.
|
||||
|
||||
### [MIN] Checks de formatting absents du CI
|
||||
|
||||
- **Localisation** : `.github/workflows/` (tous les workflows)
|
||||
- **Constat** : Ni `ruff format --check` ni `prettier --check` ne sont executes dans les workflows CI.
|
||||
- **Regle violee** : 10.1.5 — Le formatting est conforme
|
||||
- **Remediation** : Ajouter les steps `ruff format --check .` et `npx prettier --check src/` aux jobs lint.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Pipeline CI comprehensive : `ci.yml` (push/PR), `release-gate.yml` (4 phases), `release.yml` (multi-arch), `docling-compat.yml` (cron daily)
|
||||
- Ruff check enforce (zero tolerance par defaut)
|
||||
- Type-check frontend via `vue-tsc --noEmit` dans CI
|
||||
- Docker build des deux variantes (local/remote) via matrix strategy
|
||||
- Smoke test automatise : demarrage container + validation `/api/health` (status, engine)
|
||||
- Trivy security scan + check taille image
|
||||
- `.dockerignore` complet (git, tests, docs, dev artifacts exclus)
|
||||
- Nginx route correctement `/api/*` -> backend, `/` -> frontend
|
||||
- Variables d'environnement documentees dans `.env.example` avec defaults coherents
|
||||
- Multi-stage Dockerfile optimise (node build, python runtime, non-root user)
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
49
docs/audit/reports/release-0.3.1/11-documentation.md
Normal file
49
docs/audit/reports/release-0.3.1/11-documentation.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Rapport d'audit : Documentation & Changelog
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 8 / 9 |
|
||||
| Score | 89 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 1 |
|
||||
| Ecarts MINOR | 0 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [MAJ] Changelog 0.3.1 incomplet
|
||||
|
||||
- **Localisation** : `CHANGELOG.md`, section `[0.3.1]`
|
||||
- **Constat** : Plusieurs modifications significatives manquent dans le changelog :
|
||||
- `feat: make document max size configurable via MAX_FILE_SIZE_MB env var` (nouvelle feature operateur)
|
||||
- `fix: forward RATE_LIMIT_RPM and MAX_FILE_SIZE_MB to backend container` (config deployment)
|
||||
- `feat: add Karate UI e2e tests with data-e2e selectors` (nouvelle infra de test)
|
||||
- **Regle violee** : 11.1.2 — Toutes les modifications significatives sont listees
|
||||
- **Remediation** : Ajouter les entrees manquantes user/operator-facing avant le tag release.
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Section `[Unreleased]` correctement renommee en `[0.3.1] - 2026-04-09`
|
||||
- Pas de breaking changes (coherent avec un patch release)
|
||||
- Format Keep a Changelog respecte
|
||||
- `frontend/package.json` contient la bonne version `"0.3.1"`
|
||||
- Version suit le Semantic Versioning
|
||||
- Zero TODO/FIXME/HACK/XXX dans le code source (backend et frontend)
|
||||
- Zero `console.log` de debug dans le frontend (seuls `console.warn` et `console.error` legitimes)
|
||||
- Zero `print()` de debug dans le backend
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
63
docs/audit/reports/release-0.3.1/12-performance.md
Normal file
63
docs/audit/reports/release-0.3.1/12-performance.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Rapport d'audit : Performance & Ressources
|
||||
|
||||
**Release** : 0.3.1
|
||||
**Date** : 2026-04-10
|
||||
**Auditeur** : claude-code
|
||||
|
||||
---
|
||||
|
||||
## Score de compliance
|
||||
|
||||
| Metrique | Valeur |
|
||||
|----------|--------|
|
||||
| Items conformes | 10 / 13 |
|
||||
| Score | 86 / 100 |
|
||||
| Ecarts CRITICAL | 0 |
|
||||
| Ecarts MAJOR | 0 |
|
||||
| Ecarts MINOR | 3 |
|
||||
| Ecarts INFO | 0 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts constates
|
||||
|
||||
### [MIN] Pas de mecanisme d'annulation/debounce sur les requetes API frontend
|
||||
|
||||
- **Localisation** : `frontend/src/shared/api/http.ts`, `frontend/src/features/analysis/store.ts`
|
||||
- **Constat** : `apiFetch` utilise `fetch()` brut sans support `AbortController`. Les requetes de polling peuvent se chevaucher.
|
||||
- **Regle violee** : 12.2.3 — Les requetes API ont un mecanisme d'annulation ou de debounce
|
||||
- **Remediation** : Ajouter le support `AbortController` dans `apiFetch`.
|
||||
|
||||
### [MIN] Logo de 879 KB non optimise
|
||||
|
||||
- **Localisation** : `frontend/src/assets/logo.png`
|
||||
- **Constat** : Le logo fait 879 KB, excessif pour une image de logo (devrait etre < 50 KB).
|
||||
- **Regle violee** : 12.2.5 — Les assets lourds sont optimises
|
||||
- **Remediation** : Convertir en SVG ou WebP, ou compresser significativement.
|
||||
|
||||
### [MIN] Nginx sans configuration de cache pour les fichiers statiques
|
||||
|
||||
- **Localisation** : `nginx.conf`, `frontend/nginx.conf`
|
||||
- **Constat** : Aucune directive `expires`, `Cache-Control` ou `add_header Cache-Control` pour les assets statiques. Vite produit des noms hashes qui sont safe a cacher agressivement.
|
||||
- **Regle violee** : 12.3.1 — Nginx a une configuration de cache pour les fichiers statiques
|
||||
- **Remediation** : Ajouter `location ~* \.(js|css|png|svg|ico|woff2?)$ { expires 1y; add_header Cache-Control "public, immutable"; }`
|
||||
|
||||
---
|
||||
|
||||
## Points positifs
|
||||
|
||||
- Zero requete N+1 : queries optimisees avec JOIN, LIMIT/OFFSET
|
||||
- Fichiers uploades correctement geres (persistants, nettoyes a la suppression avec protection path-traversal)
|
||||
- `MAX_CONCURRENT_ANALYSES` configure et respecte via semaphore asyncio
|
||||
- Conversion Docling correctement deplacee hors event loop via `asyncio.to_thread()`
|
||||
- Upload en streaming (chunks de 64 KB)
|
||||
- Watchers Vue automatiquement nettoyes par le lifecycle des composants
|
||||
- Event listeners supprimes dans `onBeforeUnmount` (mousemove, mouseup, ResizeObserver)
|
||||
- Polling avec `stopPolling()` qui clear interval et timeout
|
||||
- `computed` utilises correctement plutot que des fonctions dans les templates
|
||||
- Reponses API de taille raisonnable (`has_document_json: bool` au lieu du blob complet)
|
||||
- Health check leger (`SELECT 1`)
|
||||
|
||||
---
|
||||
|
||||
## Verdict partiel : GO
|
||||
80
docs/audit/reports/release-0.3.1/summary.md
Normal file
80
docs/audit/reports/release-0.3.1/summary.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Synthese d'audit — Release 0.3.1
|
||||
|
||||
**Date** : 2026-04-10
|
||||
**Branche** : release/0.3.1
|
||||
**Derniere mise a jour** : 2026-04-10 (re-audit post remediations PR #131, #133, #135, #139, #144)
|
||||
|
||||
---
|
||||
|
||||
## Tableau de bord
|
||||
|
||||
| # | Audit | Score initial | Score actuel | CRIT | MAJ | MIN | INFO | Verdict |
|
||||
|---|-------|--------------|--------------|------|-----|-----|------|---------|
|
||||
| 01 | Clean Architecture | 75 | **100** | 0 | 0 | 0 | 0 | **GO** |
|
||||
| 02 | DDD | 81 | **100** | 0 | 0 | 0 | 0 | **GO** |
|
||||
| 03 | Clean Code | 56 | **93** | 0 | 0 | 2 | 0 | **GO** |
|
||||
| 04 | KISS | 100 | 100 | 0 | 0 | 0 | 0 | GO |
|
||||
| 05 | DRY | 83 | 83 | 0 | 1 | 0 | 0 | GO |
|
||||
| 06 | SOLID | 100 | 100 | 0 | 0 | 0 | 0 | GO |
|
||||
| 07 | Decouplage | 76 | **100** | 0 | 0 | 0 | 0 | **GO** |
|
||||
| 08 | Securite | 97 | 97 | 0 | 0 | 1 | 1 | GO |
|
||||
| 09 | Tests | 100 | 100 | 0 | 0 | 0 | 3 | GO |
|
||||
| 10 | CI / Build | 90 | 90 | 0 | 0 | 2 | 0 | GO |
|
||||
| 11 | Documentation | 89 | 89 | 0 | 1 | 0 | 0 | GO |
|
||||
| 12 | Performance | 86 | 86 | 0 | 0 | 3 | 0 | GO |
|
||||
|
||||
**Score global** : 95 / 100 (moyenne ponderee)
|
||||
**Ecarts CRITICAL totaux** : 0 (etaient 5)
|
||||
**Ecarts MAJOR totaux** : 2 (etaient 12)
|
||||
|
||||
---
|
||||
|
||||
## PRs de remediation mergees
|
||||
|
||||
| PR | Branche | Sujet | Ecarts corriges |
|
||||
|----|---------|-------|-----------------|
|
||||
| #131 | fix/clean-architecture-audit (base) | Clean Architecture | C1, C2, C3, M1, M2, MIN-1 |
|
||||
| #133 | fix/clean-architecture-audit | Clean Architecture | (complement PR #131) |
|
||||
| #135 | fix/ddd-audit | DDD | C4, M3, M4 |
|
||||
| #139 | fix/clean-code-audit | Clean Code | M5, M6, M7 |
|
||||
| #144 | fix/decoupling-audit | Decouplage | C5, M9, M10, M11, MIN-7 |
|
||||
|
||||
---
|
||||
|
||||
## Ecarts residuels
|
||||
|
||||
### MAJOR restants
|
||||
|
||||
1. **[05]** Magic numbers 612.0/792.0 dupliques — `infra/serve_converter.py:195,196,223,224`
|
||||
2. **[11]** Changelog 0.3.1 incomplet — `CHANGELOG.md`
|
||||
|
||||
### MINOR restants (non bloquants)
|
||||
|
||||
1. **[03]** Fonctions depassant 30 lignes — `infra/local_converter.py`, `infra/local_chunker.py` (pipeline Docling)
|
||||
2. **[03]** Fichiers source depassant 300 lignes — `StudioPage.vue` (~1200 lignes), `ResultTabs.vue` (~690 lignes)
|
||||
3. **[08]** Securite — ecart MINOR residuel
|
||||
4. **[09]** Tests — 3 ecarts INFO
|
||||
5. **[10]** CI / Build — 2 ecarts MINOR
|
||||
6. **[12]** Performance — 3 ecarts MINOR
|
||||
|
||||
---
|
||||
|
||||
## Verdict final : GO
|
||||
|
||||
**0 ecart CRITICAL** — tous les bloqueurs de release resolus.
|
||||
|
||||
**Score global 95/100** — toutes les categorues au-dessus du seuil GO.
|
||||
|
||||
**Points forts du projet :**
|
||||
- Clean Architecture complete (100/100) : injection de dependances, ports/adapters, domain pur
|
||||
- DDD exemplaire (100/100) : invariants proteges, value objects immutables, bounded contexts
|
||||
- Architecture SOLID exemplaire (100/100)
|
||||
- Simplicite KISS (100/100), aucune sur-ingenierie
|
||||
- Suite de tests exhaustive (100/100) couvrant tous les endpoints, services et composants
|
||||
- Decouplage frontend complet (100/100) : features isolees, pont reactif `appConfig`
|
||||
- Securite solide (97/100), aucune vulnerabilite detectee
|
||||
- CI/Build robuste (90/100) avec pipeline multi-phase et smoke tests
|
||||
|
||||
**Ecarts MAJOR residuels a planifier (prochain cycle) :**
|
||||
- Extraire les magic numbers de `serve_converter.py` (S)
|
||||
- Completer le changelog 0.3.1 (S)
|
||||
|
|
@ -66,7 +66,7 @@ git checkout main && git pull upstream main
|
|||
git checkout -b feature/my-change # or fix/my-fix
|
||||
```
|
||||
|
||||
Follow the [branching strategy](../../CONTRIBUTING.md#branching-strategy).
|
||||
Follow the [branching strategy](https://github.com/scub-france/Docling-Studio/blob/main/CONTRIBUTING.md#branching-strategy).
|
||||
|
||||
## Step 6 — Code
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ git push origin feature/my-change
|
|||
## Step 9 — Open a PR
|
||||
|
||||
- Target: `main` (or `release/*` for pre-release fixes)
|
||||
- Fill in the [PR template](../../.github/PULL_REQUEST_TEMPLATE.md)
|
||||
- Fill in the [PR template](https://github.com/scub-france/Docling-Studio/blob/main/.github/PULL_REQUEST_TEMPLATE.md)
|
||||
- Add a line in `CHANGELOG.md` under `[Unreleased]`
|
||||
- Wait for CI to pass, then request a review
|
||||
|
||||
|
|
@ -117,4 +117,4 @@ git push origin feature/my-change
|
|||
|
||||
- Open a [Discussion](https://github.com/scub-france/Docling-Studio/discussions) on GitHub
|
||||
- Check existing issues for similar questions
|
||||
- Read the [CONTRIBUTING guide](../../CONTRIBUTING.md) for detailed rules
|
||||
- Read the [CONTRIBUTING guide](https://github.com/scub-france/Docling-Studio/blob/main/CONTRIBUTING.md) for detailed rules
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Use this checklist when reviewing a Pull Request. Not every item applies to ever
|
|||
- [ ] New behavior has corresponding tests
|
||||
- [ ] Tests are deterministic (no `sleep`, no random, no network)
|
||||
- [ ] Test names describe the scenario, not the implementation
|
||||
- [ ] E2E tests use `data-e2e` attributes, not CSS classes (see [e2e/CONVENTIONS.md](../../e2e/CONVENTIONS.md))
|
||||
- [ ] E2E tests use `data-e2e` attributes, not CSS classes (see [e2e/CONVENTIONS.md](https://github.com/scub-france/Docling-Studio/blob/main/e2e/CONVENTIONS.md))
|
||||
|
||||
## Code Quality
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Security Vulnerability Response
|
||||
|
||||
Process for handling reported security vulnerabilities. See also [SECURITY.md](../../SECURITY.md) for the public-facing policy.
|
||||
Process for handling reported security vulnerabilities. See also [SECURITY.md](https://github.com/scub-france/Docling-Studio/blob/main/SECURITY.md) for the public-facing policy.
|
||||
|
||||
## Response Timeline
|
||||
|
||||
|
|
|
|||
41
mkdocs.yml
41
mkdocs.yml
|
|
@ -35,6 +35,47 @@ nav:
|
|||
- Architecture: architecture.md
|
||||
- Bbox Pipeline: bbox-pipeline.md
|
||||
- Contributing: contributing.md
|
||||
- Processes: PROCESSES.md
|
||||
- Development:
|
||||
- Coding Standards: architecture/coding-standards.md
|
||||
- Commit Conventions: git-workflow/commit-conventions.md
|
||||
- Code Review Checklist: git-workflow/code-review-checklist.md
|
||||
- Merge Policy: git-workflow/merge-policy.md
|
||||
- ADR Guide: architecture/adr-guide.md
|
||||
- ADR Template: architecture/adr-template.md
|
||||
- Release:
|
||||
- Deployment Checklist: release/deployment-checklist.md
|
||||
- Rollback Playbook: release/rollback-playbook.md
|
||||
- Operations:
|
||||
- Incident Response: operations/incident-response.md
|
||||
- Security Response: operations/security-response.md
|
||||
- Monitoring Checklist: operations/monitoring-checklist.md
|
||||
- Community:
|
||||
- Onboarding Guide: community/onboarding-guide.md
|
||||
- Issue Triage: community/issue-triage-process.md
|
||||
- Roadmap Template: community/roadmap-template.md
|
||||
- Audit:
|
||||
- Audit Master: audit/master.md
|
||||
- Audits:
|
||||
- Clean Architecture: audit/audits/01-clean-architecture.md
|
||||
- DDD: audit/audits/02-ddd.md
|
||||
- Clean Code: audit/audits/03-clean-code.md
|
||||
- KISS: audit/audits/04-kiss.md
|
||||
- DRY: audit/audits/05-dry.md
|
||||
- SOLID: audit/audits/06-solid.md
|
||||
- Decoupling: audit/audits/07-decoupling.md
|
||||
- Security: audit/audits/08-security.md
|
||||
- Tests: audit/audits/09-tests.md
|
||||
- CI & Build: audit/audits/10-ci-build.md
|
||||
- Documentation: audit/audits/11-documentation.md
|
||||
- Performance: audit/audits/12-performance.md
|
||||
|
||||
validation:
|
||||
nav:
|
||||
omitted_files: info
|
||||
absolute_links: info
|
||||
links:
|
||||
absolute_links: info
|
||||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
|
|
|
|||
Loading…
Reference in a new issue