# Projets : code anonymisé

Sept projets développés en alternance chez un opérateur d'infrastructures télécoms, avec leur code réel anonymisé. Chacun a un `README-PORTFOLIO.md` qui dit ce que fait le projet, ce qui vaut d'être regardé et pourquoi.

Les fiches de méthode correspondantes sont dans `../docs/`. Ici c'est le code ; là-bas c'est le raisonnement transposable.

---

## Les sept projets

| Projet | Ce que c'est | Tests | Fiche de méthode |
|---|---|---|---|
| [catalogue-donnees](catalogue-donnees/README-PORTFOLIO.md) | catalogue de données d'entreprise, connecteurs développés, lineage de bout en bout | 478 | `docs/09` |
| [generateur-ddl](generateur-ddl/README-PORTFOLIO.md) | génération de DDL depuis l'introspection, 3 interfaces sur un noyau unique | 203 | `docs/04` |
| [exporteur-metriques-bi](exporteur-metriques-bi/README-PORTFOLIO.md) | supervision d'une plateforme BI, mise en production complète | 60 | `docs/14` |
| [lineage-postgres](lineage-postgres/README-PORTFOLIO.md) | lineage par analyse statique du catalogue système, mesure d'usage | 112 | `docs/09`, `docs/10` |
| [agent-autonome](agent-autonome/README-PORTFOLIO.md) | agent sans supervision, deux barrières, vérification par un juge | 103* | `docs/16` |
| [outillage-cli](outillage-cli/README-PORTFOLIO.md) | outils d'intégration aux systèmes d'entreprise, multi-plateforme | 96 | `docs/06` |
| [config-assistant](config-assistant/README-PORTFOLIO.md) | configuration d'assistant de code partageable en équipe | 33 | `docs/15` |

**982 tests collectés par `pytest`**, plus **103 assertions** dans des scripts autonomes.

\* L'agent autonome a ses tests écrits comme scripts exécutables (`python3 tests/test_x.py`), pas
comme fonctions `pytest` : ils affichent leur propre décompte (50, 47 et 7 assertions, toutes
passantes) et sont rejoués en intégration continue. Un `pytest` lancé sur ce projet collecte donc
zéro test, ce qui est normal et non un défaut de couverture.

---

## Par où commencer

| Si vous voulez | Regardez |
|---|---|
| Juger le niveau technique sur du code métier | `generateur-ddl/product/src/ddl.py` et ses tests |
| Voir une mise en production complète | `exporteur-metriques-bi/` : coffre-fort, conteneur durci, pipeline |
| Voir de l'intégration à un écosystème hétérogène | `catalogue-donnees/src/product/openmetadata-ingestion/connectors/` |
| Voir de l'algorithmique appliquée | `lineage-postgres/lineage-explorer/lineage/` |
| Voir des garde-fous de sécurité conçus et testés | `agent-autonome/guard-hook.py`, `config-assistant/hooks/block_sensitive.py` |
| Voir de la robustesse d'appel d'API | `exporteur-metriques-bi/product/pbi_exporter/clients/base.py` |

---

## Trois fichiers qui résument le mieux la façon de travailler

**`generateur-ddl/product/src/ddl.py`** : génération de SQL par fonctions pures, avec une distinction stricte entre échappement d'identifiant et échappement de littéral. Confondre les deux ouvre une injection ; un test vérifie qu'aucune apostrophe ne reste non doublée.

**`agent-autonome/guard-hook.py`** : un garde-fou qui se ferme par défaut, où entrée invalide, configuration absente ou exception interne conduisent au refus. Avec sa suite de tests, parce qu'un composant qui décide d'autoriser ou refuser mérite le même traitement que du code de production.

**`catalogue-donnees/src/product/openmetadata-ingestion/connectors/powerbi/PATCH_NOTES.md`** : douze patches sur un projet open source, chacun avec son problème, sa cause racine et son statut, y compris ceux retirés ou jamais implémentés. Neuf sont contribuables en amont (voir `../docs/25`).

---

## Ce qui a été retiré de tous les projets

| Retiré | Raison |
|---|---|
| Historique de contrôle de version | contient tout ce qui a été supprimé, y compris d'anciens secrets |
| Fichiers d'environnement réels | secrets |
| Exports de données, dumps, tableurs, notebooks | données de production |
| Journaux d'exécution | chemins, noms, contenus de travail |
| Dépendances tierces, environnements virtuels, caches | volume, non pertinent |
| Sorties générées (graphes de connaissance, exports pour assistant) | régénérable |
| Artefacts de construction et de couverture | régénérable |

Volume écarté le plus important : environ 14 Go sur le projet de catalogue (dumps de base, dépôts de jobs clonés, exports).

---

## Méthode d'anonymisation

Substitution **cohérente** : un même élément réel donne toujours le même remplacement dans tout un projet, pour que le code reste lisible et que les tests continuent de passer.

| Type | Traitement |
|---|---|
| Entreprise, personnes | `<COMPANY>`, `<USER>`, `<COLLEAGUE>` |
| Hôtes, domaines, URLs internes | marqueurs, ou adresses de documentation quand des valeurs distinctes sont nécessaires |
| Secrets, jetons, identifiants de compte | `<API_KEY>`, `<CLIENT_ID>`, `<TENANT_ID>` |
| Bases et schémas métier | noms génériques parlants : `warehouse_prod`, `tickets_tra`, `billing_bi` |
| Rôles applicatifs | `appuser_ops`, `appuser_reporting` |
| Projets et partenaires internes | `<PROJECT_A>`, `<PARTNER_A>` |
| Références de demandes | `<TICKET>` |

### La leçon apprise en le faisant

**Une anonymisation qui collapse plusieurs valeurs distinctes en un seul marqueur casse tout code qui les compare.**

Cas rencontré sur le projet de catalogue : 28 hôtes différents remplacés par un unique `<HOST>` faisaient échouer 13 tests qui vérifiaient précisément que ces hôtes diffèrent. Correction : 28 adresses de documentation distinctes.

Trois autres pièges du même ordre, tous rencontrés :

| Piège | Effet |
|---|---|
| Substituer l'attendu d'un test mais pas son entrée (ou l'inverse) | test rouge, sur une valeur pourtant équivalente |
| Ignorer les variantes de casse et de séparateur | le code normalise `DWH-PROD` en `dwh_prod` : les deux formes doivent être traitées |
| Utiliser un marqueur à chevrons là où la valeur sert d'identifiant technique | la normalisation le met en minuscules ou le mutile, l'identifiant produit diverge |

D'où la règle de vérification appliquée : **comparer la liste des tests en échec avant et après anonymisation.** Sur le projet de catalogue, la liste finale est strictement identique à celle du dépôt d'origine, ce qui prouve zéro régression introduite.

---

## Vérification

Audit automatisé sur les 588 fichiers du portfolio :

| Contrôle | Résultat |
|---|---|
| Nom d'entreprise, toutes casses et formes composées | aucun |
| Noms de personnes | aucun |
| Adresses IP privées | aucune |
| Domaines et URLs internes | aucun |
| Adresses de courriel | aucune |
| Références de demandes internes | aucune |
| Jetons, clés, chaînes d'authentification | aucun |
| Chemins de poste | aucun |
| Fichiers interdits (secrets, données, dépôts) | aucun |

Les tirets longs présents dans le code d'origine sont conservés tels quels : le code n'est pas réécrit, seulement anonymisé.
