ISNAD Scientific Platform

Documentation Center
V1 · Référence officielle

Architecture

ISNAD — Architecture cible du repository (E11-T2)

13 min de lectureMis à jour le 29 أكتوبر 2026
Sur cette page

Statut : proposition officielle soumise à validation du Project Lead. Ce document ne déplace, ne renomme et ne modifie aucun fichier. Il définit où chaque type de fichier doit vivre, et pourquoi, à partir de l'inventaire réel produit en E11-T1.

Principe directeur : la plus petite architecture capable de soutenir ISNAD durablement (§27 de la mission) — pas d'usine à gaz, pas de couche créée « pour faire joli ». Chaque décision ci-dessous part des fichiers réels, pas d'une préférence esthétique.

ACTUAL REPOSITORY
      ↓
ARCHITECTURAL DECISIONS   (ce document, §2-§13)
      ↓
TARGET STRUCTURE          (ce document, §14-§18)
      ↓
FILE PLACEMENT MATRIX     (planning/audits/e11-target-file-placement.md)
      ↓
VALIDATED MIGRATION PLAN  (§21 ci-dessous, à valider avant exécution)

1. Principes#

  1. Le domaine (domain/) doit rester du TypeScript pur. Vérifié sur l'existant : aucun fichier sous src/domain/ n'importe React, Next.js, @supabase/supabase-js ou pg (grep exhaustif, 0 résultat). C'est la propriété la plus précieuse du repository actuel — la cible doit la préserver, jamais la régresser.
  2. Une responsabilité, un dossier. Si deux dossiers font la même chose pour des raisons historiques, on documente la distinction réelle plutôt que de forcer une fusion mécanique qui casserait ce qui fonctionne déjà.
  3. On ne construit pas une couche qui n'a pas encore de justification. application/ n'est pas créé maintenant — voir D3.
  4. La convention existante gagne quand elle est déjà cohérente. planning/{epic-prefix}-sujet.md est déjà appliquée à 33 des 53 fichiers de planning/ — la cible formalise cette convention plutôt que d'en inventer une autre.
  5. Aucun fichier ne doit être sans destination. Voir la matrice pour le traitement exhaustif de chaque fichier racine et de chaque grande famille.

2. Décisions architecturales#

D1 — src/infrastructure/ : CONSERVÉ comme couche officielle#

Analyse des 92 fichiers réels (voir T1 §4-5, approfondi ici) :

Sous-dossierFichiersNature réelle
knowledge-acquisition/73Adapters par source (rijal/ 10, commentary/ 8, terminology/ 7, quran/ 7, muslim-openiti/ 4, bukhari/ 3) + writers Postgres (Postgres*Ledger, PostgresDatasetBindingResolver, …) + moteurs d'orchestration d'acquisition (DefaultKnowledgeAcquisitionEngine, ContextualAcquisitionEngine, ObservedAcquisitionRunner) + __fixtures__/ (11, fixtures de test colocalisées)
provenance/11Postgres*ProvenanceResolver (Commentary/Quran/Rijal/Terminology) + services par défaut (DefaultCitationService, DefaultAssertionEvidenceIntegrityService)
repositories/4Preuve du pattern hexagonal : SupabaseHadithAggregateWriter.ts (implémentation réelle) + FakeHadithAggregateWriter.ts (double de test) — les deux implémentent l'interface HadithAggregateWriter définie dans src/domain/repositories/
project-planning/3parser.ts/reader.ts/types.ts — lecture de fichiers Markdown de planning depuis le filesystem (alimente le tableau de bord project/planning)

Verdict : src/infrastructure/ est un véritable étage ports-and-adapters — chaque port est défini dans src/domain/repositories/*.ts (HadithAggregateWriter, NarratorRepository, RijalKnowledgeWriter, CommentaryKnowledgeWriter, QuranTextWriter, TerminologyWriter, KnowledgeRepository), et src/infrastructure/ fournit les implémentations concrètes (Postgres réel + doubles de test). C'est exactement la séparation que la cible §22 de la mission cherchait à obtenir avec domain/ + server/ — sauf qu'elle existe déjà, sous un autre nom, et fonctionne (E2/E3/E4 entièrement construits dessus, tests colocalisés). La supprimer ou la fusionner arbitrairement romprait ce contrat.

Sous-arborescence proposée (uniquement si l'inventaire post-T1 confirme qu'elle apporte une clarté réelle — proposition légère, voir §7 pour le détail et la justification fichier-par-fichier) :

infrastructure/
├── knowledge-acquisition/    (inchangé — déjà bien organisé par source)
├── repositories/              (implémentations des ports domain/repositories)
├── provenance/                 (resolvers Postgres + services de citation)
└── project-planning/           (lecture filesystem des documents de planning)

Aucun renommage interne recommandé : la sous-structure actuelle par source (rijal/, commentary/, quran/, terminology/, bukhari/, muslim-openiti/) est déjà la bonne granularité.

D2 — src/server/ : CONSERVÉ, rôle distinct clarifié (pas de fusion avec infrastructure/)#

Vérification factuelle : src/server/ (59 fichiers) n'utilise aucune API Next.js spécifique (NextResponse/NextRequest : 0 occurrence — celles-ci vivent dans src/app/api/*/route.ts, pas dans src/server/) et seulement 2 fichiers y importent pg directement.

Rôle réel distinct de infrastructure/ :

  • infrastructure/ = implémentations de ports formels définis dans domain/repositories/ — discipline « on définit l'interface avant l'implémentation ».
  • server/ = modules de lecture directement consommés par les Server Components et routes API (openiti/ 28, live-agent/ 24, database-explorer/ 6, commentary/ 1) pour des fonctionnalités qui n'ont pas encore de port domain/ formel — lecture pragmatique, introduite au fil des missions BETA-DESIGN récentes.

Ce ne sont pas deux dossiers avec le même rôle par accident : ce sont deux maturités différentes de la même préoccupation (accès aux données). Fusionner server/ dans infrastructure/ maintenant forcerait soit la création de ports domain/ prématurés pour OpenITI/commentary/ live-agent (sur-ingénierie), soit un dossier infrastructure/ qui perd sa cohérence de contrat.

Règle cible : quand une fonctionnalité aujourd'hui servie par src/server/<feature>/ acquiert un vrai port domain/repositories/, son implémentation concrète migre vers infrastructure/<feature>/ à ce moment-là — pas avant. server/ reste le point d'entrée « lecture Next.js‑server » tant qu'aucun contrat domain ne le justifie.

Gap identifié (à traiter hors E11) : src/server/commentary/commentary-read.ts est le seul module de server/ sans test dédié — la même remarque que T1 §19.5, non résolue ici (T2 ne modifie pas le code).

D3 — src/application/ : NON CRÉÉ pour l'instant#

Les candidats d'usage cités par la mission (BuildScientificDossier, ResolveNarratorIdentity, FindTraditionCandidates) n'existent pas encore comme orchestrations concrètes traversant plusieurs domaines. L'équivalent le plus proche aujourd'hui est src/domain/services/ (AnalysisService.ts, HadithService.ts, NarratorService.ts) — des services d'orchestration qui restent purs car ils ne dépendent que d'interfaces domain/repositories/ injectées, jamais d'une implémentation concrète. Ce pattern suffit à l'échelle actuelle.

Décision : ne pas créer src/application/ en E11. Réserver le nom pour E8 (Reasoning) / E9 (Scientific Dossier), quand une orchestration authentique combinant narrator + hadith + commentary + tradition sur plusieurs frontières transactionnelles apparaîtra réellement. Créer la coquille maintenant, sans contenu réel, serait de la sur-architecture (§27).

D4 — src/domain/ : rôle confirmé, règle formalisée#

domain/ = logique scientifique / métier pure, testable en TypeScript pur

Interdits (vérifiés déjà respectés à 100 % sur l'existant, à faire respecter pour tout futur ajout) :

  • aucun import React / JSX
  • aucun import next/*
  • aucun import @supabase/supabase-js ou pg
  • aucun fetch, aucune API navigateur

Seules dépendances autorisées : TypeScript standard, autres modules domain/, et — pour les services d'orchestration — des interfaces domain/repositories/* (jamais leur implémentation concrète).

src/domain/tradition-variant/ (5 fichiers, groundwork E5) reste en place tel quel : c'est déjà la bonne destination architecturale pour ce code, même si E5 est gelé. Aucune action requise — voir le risque de gouvernance déjà noté en T1 (ne pas y toucher pendant le gel, pas un problème de placement).

D5 — src/features/ : introduit progressivement, pas de big-bang#

features/ = capacités fonctionnelles visibles du produit

Candidats confirmés par l'inventaire réel (chacun a déjà un embryon cohérent de UI + logique + tests, dispersé aujourd'hui entre components/, lib/, server/) :

FeatureUI existanteLogique existanteTests existants
librarycomponents/library/* (5)lib/library-catalog.tslib/library-catalog.test.ts
readingcomponents/reading/* (3)lib/reading-preferences.ts, lib/book-navigation.ts, lib/reading/use-scroll-spy.tslib/book-navigation.test.ts
openiticomponents/openiti/* (2)lib/openiti/*test:openiti-reading, test:book-workspace
commentarycomponents/commentary/* (1)server/commentary/commentary-read.tsaucun (gap)
hadithpages corpus/*, atelier de lecturedomain/knowledge-acquisition/HadithCorpusProjectornombreux
narratorNarratorProfile.tsx, NarratorHadiths.tsxdomain/narrator-identity/* (32)nombreux
tradition— (E5 gelé)domain/tradition-variant/*1
provenance— (transverse)domain/provenance/*colocalisés
sourcesSourcesCatalogue.tsxdata/bibliographic-sources.ts—
searchpage /search——
statisticspages /stats, /statistics——
adminapp/[locale]/(site)/admin/*server/database-explorer/*colocalisés
labscomponents/labs/* (28)dispersévariable

Règle : une feature ne migre vers src/features/<nom>/ que lorsqu'elle a réellement au moins deux des sous-dossiers components/, services/, types/, tests/ à regrouper — pas de structure vide créée par anticipation. labs/ (28 fichiers, expérimentations très hétérogènes) reste probablement une zone à part (« sandbox produit »), pas une feature unique — à trancher lot par lot, pas en bloc.

D6 — src/shared/ : règle stricte, contenu limité#

shared/ = utilisé par ≥ 2 features ET sans appartenance fonctionnelle claire

Admissible : composants génériques de layout/UI sans logique métier (NavBar.tsx, Footer.tsx, Logo.tsx, ThemeToggle.tsx — 4 des 25 fichiers isolés actuels de src/components/ correspondent déjà à ce profil).

Non admissible (exemples réels du repo à ne pas faire migrer vers shared/) : ChainAnalyzer.tsx, DataModelExplorer.tsx, HadithCommentaries.tsx, NarratorProfile.tsx, FathAlBariWorkspace.tsx — chacun appartient à une seule feature (hadith/narrator/ commentary), même s'il est aujourd'hui rangé au même niveau plat que les composants génériques.

D7 — src/core/ : rôle limité, pas de fourre-tout#

core/ = configuration, environnement, feature flags, providers globaux, i18n, thème

Exécuté (E11-T7, LOT A) : src/config/ (7 fichiers) → src/core/config/ ; src/lib/i18n.tsx, src/lib/i18n-data.ts, src/lib/theme.tsx, src/lib/theme-script.ts, src/lib/fonts.ts, src/lib/supabaseClient.ts → src/core/ (providers globaux transverses, pas des primitives génériques au sens de D8).

Limite explicite : core/ ne reçoit que ce qui est transverse à toute l'application (config, thème, langue, providers). Toute logique spécifique à une feature reste dans features/<nom>/, même si elle « semble » générique.

D8 — src/lib/ : réduit aux primitives techniques génériques#

Règle stricte confirmée nécessaire par l'inventaire (44 fichiers actuels, le fourre-tout le plus net du repo — T1 §5) :

lib/ = primitives techniques génériques uniquement

Admissible : normalisation de chaînes, dates, identifiants, validation générique, helpers HTTP/erreurs génériques.

Doit sortir de lib/ vers leur domaine propre (mouvement documenté dans la matrice, non exécuté en T2) :

  • tabaqa.ts, isnadMatching.ts, entityResolution.ts, matchTier.ts, nominalTransliteration.ts, narrator-identity.ts, narrator-hadiths.ts, narrator-display.ts, grade-tiers.ts, grade-display.ts, displayResolver.ts, reliability.ts, searchResultMerge.ts → logique métier narrator/hadith, candidats pour domain/narrator-identity/ ou une nouvelle zone features/narrator/services/.
  • openiti/ (déjà un sous-dossier cohérent) → features/openiti/.
  • library-catalog.ts → features/library/.
  • reading-preferences.ts, book-navigation.ts, reading/ → features/reading/.
  • hadithrank/ → features/hadithrank/ (ou sous labs/ selon décision produit — HadithRank vit aujourd'hui sous labs/).
  • live-agent/ → features/live-agent/ (déjà cohérent en sous-dossier).

Reste légitimement dans lib/ (ou migre vers core/ selon D7) : report-load-error.ts, supabaseClient.ts (client générique, pas de logique métier), documentation.ts (générique au rendu Markdown).


3. Structure cible évaluée#

La structure proposée par la mission est confirmée avec une correction majeure : infrastructure/ est réintégré explicitement (elle existe déjà et fonctionne), et application/ est différé (D3).

src/
├── app/              (Next.js App Router — inchangé)
├── features/         (nouveau — capacités produit, introduites progressivement, D5)
├── domain/           (inchangé dans son contenu — règle de pureté formalisée, D4)
├── infrastructure/    (conservé — adapters des ports domain/repositories, D1)
├── server/            (conservé — lecture Next.js-server pour features sans port domain, D2)
├── shared/            (nouveau, restreint — composants génériques cross-feature, D6)
├── core/              (nouveau — config, i18n, thème, providers globaux, D7)
├── lib/               (conservé mais réduit — primitives techniques génériques seulement, D8)
└── types/             (inchangé — types partagés, aucun problème identifié)

(src/application/ n'existe pas encore — réservé, voir D3)
(src/hooks/ n'est pas recréé comme dossier séparé — les hooks vivent dans
  features/<nom>/ ou core/ selon leur portée, pas de dossier hooks/ générique)
(src/tests/ n'est pas créé — les tests unitaires restent colocalisés, voir §20)

4. Responsabilité de chaque couche#

CoucheResponsabilitéNe doit JAMAIS contenir
app/Routage Next.js, layouts, orchestration de rendu serveur/clientlogique métier scientifique, requêtes SQL directes complexes
features/Assemblage produit d'une capacité visible (UI + services + types + tests de la feature)logique réutilisable par ≥ 2 features (→ shared/core/lib)
domain/Règles scientifiques et métier puresReact, Next.js, Supabase, pg, fetch
infrastructure/Implémentations concrètes des ports domain/repositories/logique de décision métier (doit rester dans domain/)
server/Lecture de données server-only consommée par app/ pour des features sans port domain formelcode exécuté côté navigateur
shared/Composants UI génériques cross-feature, sans logique métiertout composant propre à une seule feature
core/Configuration, environnement, feature flags, i18n, thème, providers globauxlogique spécifique à une feature
lib/Primitives techniques génériques (chaînes, dates, ids, validation générique)logique métier scientifique
types/Types TypeScript partagés entre couchesimplémentations

5. Dépendances autorisées / interdites#

Voir dependency-rules.md pour le détail complet et le graphe annoté.

Résumé :

Autorisé

app          → features, domain, server, shared, core, lib, types
features     → domain, server (temporairement, voir D2), shared, core, lib, types
infrastructure → domain (implémente ses ports), core, lib, types
server        → domain (lecture de types), core, lib, types
domain        → domain, types  (rien d'autre)
shared/core/lib → types  (entre eux : lib → core interdit, core → lib interdit — pas de dépendance croisée entre primitives transverses)

Interdit explicitement

domain      → features, app, React, Next.js, Supabase, pg, fetch
shared      → une feature spécifique
infrastructure → app, features, React
server       → React, JSX (server/ produit des données, jamais du JSX)
lib          → domain (sens interdit : lib est en-dessous de domain, jamais l'inverse)
core         → features (core ne connaît aucune feature)

6. Modèle features/#

Chaque feature peut posséder, seulement si nécessaire :

features/<nom>/
├── components/    (si l'UI est propre à la feature)
├── services/      (logique de projection/agrégation propre à la feature)
├── types/         (si les types ne sont pas déjà dans src/types/)
└── tests/ (ou colocalisés *.test.ts, au choix de la feature — pas de règle unique imposée, voir §20)

Pas de sous-dossier vide créé par anticipation. Une feature avec 3 fichiers (ex. commentary aujourd'hui) peut rester plate.


7. Modèle domain/#

Inchangé dans le fond — déjà conforme. Rappel de la structure actuelle (à conserver) :

domain/
├── narrator-identity/    (32 — sous-domaine le plus riche, E4)
├── knowledge-acquisition/ (13 — contrats génériques)
├── repositories/          (9 — ports/interfaces)
├── entities/              (9)
├── provenance/            (8)
├── tradition-variant/     (5 — E5, gelé, ne pas toucher)
├── types/                 (4)
├── services/              (4 — orchestration pure via ports injectés)
└── openiti/                (2)

8. Décision infrastructure/#

Voir D1. Sous-arborescence actuelle confirmée adéquate, aucun renommage interne recommandé.

9. Décision server/#

Voir D2.

10. Décision application/#

Voir D3 — non créé.

11. Décision shared/#

Voir D6 — restreint à NavBar.tsx, Footer.tsx, Logo.tsx, ThemeToggle.tsx et tout futur composant réellement générique cross-feature (ex. un futur Pagination, EmptyState, Modal générique s'ils apparaissent — aucun composant modal générique n'existe encore séparément de CollectionLibraryModal.tsx, qui lui est spécifique à library).

12. Décision core/#

Voir D7 — exécuté en E11-T7 LOT A : src/core/config/*, src/core/i18n.tsx, src/core/i18n-data.ts, src/core/theme.tsx, src/core/theme-script.ts, src/core/fonts.ts, src/core/supabaseClient.ts.

13. Décision lib/#

Voir D8.

14. Stratégie tests#

Voir e11-target-file-placement.md §19 et la synthèse ci-dessous :

Type de testEmplacement cibleEmplacement actuelChangement ?
Unitaire (domain, lib, infra)colocalisé *.test.ts à côté du codedéjà colocalisé (51 fichiers)aucun — confirmé comme la bonne convention
Intégration / scientifique (scripts)scripts/test-*.mjs, référencés individuellement dans package.jsondéjà le cas (66 fichiers)aucun structurel — un futur tri par sous-dossier scripts/validation/ reste possible (E11-T3+), pas dans ce document
SQL / DBsupabase/tests/*.sqldéjà le cas (37 fichiers)aucun
Audit scientifique manuelscripts/audit-*.mjs + rapport dans planning/audits/déjà largement le casclarifier la frontière : un audit-*.mjs ne doit jamais être confondu avec un test automatisé exécuté en CI — voir §16
End-to-end / browsern'existe pas aujourd'hui—non traité en E11-T2 (décision produit distincte : introduire ou non Playwright)

Principe : ne pas mélanger test automatisé reproductible et audit scientifique manuel dans le même espace de nommage. Un test-*.mjs doit pouvoir tourner sans supervision humaine ; un audit-*.mjs produit un rapport à lire par un humain. Les deux préfixes existent déjà et sont globalement bien respectés (voir T1 §8) — la cible formalise cette distinction plutôt que de la réinventer.

15. Stratégie scripts#

scripts/
├── audit/         (audit-*.mjs — rapports scientifiques manuels)
├── import/         (scripts d'ingestion/import de données)
├── validation/      (test-*.mjs référencés par npm run test:*)
├── maintenance/      (db-cold-rebuild.mjs, verify-extension-relocation.mjs, etc.)
├── migration/        (build-*-migration.mjs, generate-*-seed-sql.mjs)
├── quality-engine/   (inchangé — déjà un module cohérent)
├── lib/               (inchangé — modules internes partagés entre scripts)
└── translations/       (inchangé — déjà son propre __tests__/)

182 scripts actuellement à plat, classifiables par préfixe (voir T1 §8). Aucun script n'est déplacé en T2 — cette arborescence est la cible pour une migration ultérieure validée.

16. Stratégie docs / planning#

docs/
├── architecture/    (ce document + dependency-rules.md — nouveau, créé en T2)
├── adr/              (inchangé — déjà correct, 3 fichiers)
├── scientific/        (ISNAD_SCIENTIFIC_PRINCIPLES.md, KNOWLEDGE_MODEL_V1.md, DOMAIN_LAYER_V1.md, etc.)
├── product/            (contenu produit/roadmap si distinct du scientifique)
└── development/         (translations/, standards techniques de dev)

planning/
├── epics/    (les 33 fichiers plats actuels b0-*/e2-*/e3-*/e4-*/e5-*/stab-01-*, déjà nommés par epic)
├── audits/    (inchangé — déjà correct, 20 fichiers)
├── reports/    (rapports ponctuels type HANDOVER, LIVE_AGENT_*, RIJAL_CANONICAL_REFERENCE_*)
└── archive/     (contenu clos sans valeur de référence continue)

docs/ = documentation durable (principes scientifiques, ADR, modèle de domaine). planning/ = gestion de projet (specs d'epic, audits, rapports). Aucune donnée brute (JSON d'audit, manifestes) ne devrait rester dans docs/ — direction cible : planning/audits/ ou un futur docs/data/ si le volume le justifie (non tranché ici, voir la matrice pour les cas concrets).

specs/ (Spec Kit) : voir §17. .specify/ : voir §17.

17. .specify/, specs/, scratch/ — décisions explicites#

.specify/ → KEEP à la racine#

  • À quoi sert-il : état local + configuration du workflow GitHub Spec Kit, intégré à Claude Code (.specify/integration.json déclare "integration": "claude").
  • Actif : oui — 10 skills speckit-* sont committées sous .claude/skills/ et listées comme disponibles dans les sessions Claude Code actuelles.
  • Généré : partiellement (.specify/.gitignore exclut déjà les pointeurs locaux comme feature.json).
  • Doit rester à la racine : oui, contrainte de l'outil (Spec Kit s'attend à trouver .specify/ au niveau racine du repo, au même titre que .next/ ou tsconfig.json).
  • Décision : KEEP. Aucune action.

specs/ → KEEP comme emplacement structurel, contenu marqué HISTORICAL#

  • Usage réel : sortie du workflow Spec Kit (spec.md/plan.md/tasks.md/ data-model.md/...). C'est la convention imposée par l'outil — toute future exécution de /speckit-specify y écrira à nouveau sous specs/NNN-nom-feature/.
  • Relation avec planning/ : les epics E2 à E10 ont utilisé planning/e{N}-*.md à la place, sans repasser par Spec Kit — donc specs/001-hadith-canonical-projection/ est resté seul.
  • Duplication : aucune duplication active de vérité aujourd'hui (E1 est clos, son contenu ne contredit rien de vivant).
  • Décision : KEEP le dossier specs/ comme emplacement structurel réservé au workflow Spec Kit (ne pas le supprimer ni le renommer — l'outil continuerait autrement à recréer un dossier specs/ à la prochaine invocation). Marquer specs/001-hadith-canonical-projection/ spécifiquement comme HISTORICAL dans la matrice (E1, clos, conservé pour traçabilité de la toute première exécution du workflow).

scratch/ (tracké) → ARCHIVE-CANDIDATE, règle de non-reproduction établie#

  • 15 fichiers, tous datés du 2026-08-25 (même campagne que AUDIT-REPORT.md/HUMAN_REVIEW_NARRATORS.json à la racine), non référencés depuis src/ ni scripts/ (vérifié par grep).
  • Décision : ARCHIVE-CANDIDATE — à déplacer vers planning/archive/2026-08-e4-night-shift-scratch/ (ou équivalent) lors d'une future micro-tâche de migration, jamais supprimé sans confirmation que la campagne E4 correspondante est bien close (elle l'est d'après T1/mémoires de session, mais la confirmation finale reste au Project Lead).
  • Règle établie pour l'avenir : scratch/ (tracké) ne doit plus recevoir de nouveaux fichiers de travail ponctuel — cet usage est remplacé par le dossier local .scratch/ (non tracké, déjà dans .gitignore de facto par convention de nom, à formaliser explicitement dans .gitignore lors d'une future migration) pour tout travail véritablement jetable. Un script qui mérite de survivre va dans scripts/ avec un préfixe clair (audit-, test-, etc.), jamais dans scratch/.

18. Politique fichiers racine#

Voir la matrice complète (e11-target-file-placement.md) pour le traitement fichier par fichier. Règle générale :

La racine ne doit contenir que ce que l'outillage (npm, Next.js, TypeScript, Git, Vercel) exige explicitement à cet emplacement, plus README.md comme point d'entrée développeur. Tout le reste (rapports d'audit ponctuels, exports de données, scripts d'export historiques) migre vers planning/, docs/ ou scripts/ selon sa nature.

19. Implications de nommage#

  • SCREAMING_SNAKE_CASE.md vs kebab-case.md : la cible retient kebab-case comme convention (déjà dominante dans planning/ — 33/37 fichiers epic-prefixés). Les fichiers SCREAMING_SNAKE_CASE existants (RIJAL_CANONICAL_REFERENCE_*, LIVE_AGENT_*, SCIENTIFIC_KNOWLEDGE_LAYER_ROADMAP.md, ISNAD_SCIENTIFIC_PRINCIPLES.md, etc.) ne sont pas renommés en E11-T2 — seule la convention future est fixée ici. Un renommage de masse est un choix distinct, à valider séparément (impact sur les liens existants).
  • scratch/ vs .scratch/ : voir §17 — règle établie, pas de renommage immédiat des fichiers existants dans scratch/.

20. Principes de migration#

  1. Ne jamais déplacer une migration Supabase déjà appliquée.
  2. Ne jamais déplacer un fichier sans avoir confirmé toutes ses références (imports, scripts npm, liens de documentation).
  3. Toute migration se fait par lot homogène (une feature à la fois), jamais en un seul gros commit.
  4. Chaque lot de migration doit repasser tsc --noEmit + npm run build + les suites de tests concernées avant validation.
  5. Les fichiers E4 locaux non commités restent strictement hors périmètre de toute migration tant qu'ils n'ont pas été explicitement traités par leur propriétaire.
  6. Aucune migration ne commence sans validation explicite du Project Lead sur CE document.

21. Séquence de migration recommandée (future, non exécutée)#

M1  Nettoyage racine générés (tsconfig.tsbuildinfo → gitignore + untrack)
M2  Racine : relocalisation des rapports/exports isolés (AUDIT-REPORT.md,
    audit-candidates.json, HUMAN_REVIEW_NARRATORS.json, data-export/)
M3  docs/ + planning/ (introduction des sous-dossiers architecture/adr/
    scientific/product/development et epics/reports/archive)
M4  scripts/ (introduction des sous-dossiers audit/import/validation/
    maintenance/migration, déplacement par lot)
M5  src/core/ (extraction de src/config/ + i18n/theme/fonts depuis lib/) — ✅ FAIT (E11-T7 LOT A)
M6  src/shared/ (extraction des 4 composants génériques confirmés) — ✅ FAIT (E11-T7 LOT A)
M7  src/features/reading/ + src/features/library/ (les plus petites,
    déjà bien isolées)
M8  src/features/openiti/ + src/features/commentary/
M9  src/features/hadith/ + src/features/narrator/ (les plus gros, les
    plus risqués — dernier lot applicatif)
M10 src/lib/ résiduel (vérification qu'il ne reste que des primitives)
M11 scratch/ → planning/archive/
M12 Nettoyage final (branches mergées, worktrees clos) — décision Project
    Lead distincte, hors périmètre technique de cette séquence

Chaque étape M1-M12 correspond à une micro-tâche E11 future distincte, pas à une action de cette mission T2.


Document produit par E11-T2. Ne remplace pas le jugement du Project Lead — sert de base de décision.