Phase 1 : socle Python, schéma SQLite + FTS5, modèles pydantic
- pyproject/uv sur Python 3.12, dépendances épinglées - migrations versionnées (PRAGMA user_version) ; 001_initial pose textes, sources, evenements, decisions_cc, insights, veille_log, veille_changements - index FTS5 à contenu externe, tokenizer unicode61 remove_diacritics 2 : « chlordecone » retrouve « chlordécone », highlight() disponible - vue v_textes : devant_cc combine le statut et les affaires CC en instance, ce qui réconcilie le §7 (Riposte reste adoptee_non_promulguee) et le §8.7 (la facette saisie_cc doit remonter ≥ 7 textes) - modèles pydantic refusant les incohérences de statut : promulguée sans numéro, navette avec numéro officiel, slug malformé - Makefile, .env.example, journalisation structlog Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3ce7d17db9
commit
31d3935bce
@@ -0,0 +1,66 @@
|
||||
"""Localisation des fichiers du projet.
|
||||
|
||||
Un unique point de vérité pour les chemins, afin que les parseurs, les tests et
|
||||
les collecteurs ne fassent jamais d'hypothèse sur le répertoire courant.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# pipeline/chemins.py → pipeline/ → racine du dépôt
|
||||
RACINE = Path(__file__).resolve().parent.parent
|
||||
|
||||
load_dotenv(RACINE / ".env")
|
||||
|
||||
# ── Corpus d'entrée — LECTURE SEULE ──────────────────────────────────────────
|
||||
ENTREE = RACINE / "data" / "input"
|
||||
RECHERCHE = ENTREE / "research"
|
||||
|
||||
RAPPORT_FINAL = ENTREE / "lois-france-2026-guadeloupe.agent.final.md"
|
||||
RAPPORT_OUTLINE = ENTREE / "lois-france-2026-guadeloupe.agent.outline.md"
|
||||
BIBLIOGRAPHIE = ENTREE / "lois-france-2026-guadeloupe_ref.md"
|
||||
|
||||
CROSS_VERIFICATION = RECHERCHE / "lois-2026_cross_verification.md"
|
||||
INSIGHTS = RECHERCHE / "lois-2026_insight.md"
|
||||
PHASE5_VALIDATION = RECHERCHE / "lois-2026_phase5_validation.md"
|
||||
|
||||
|
||||
def chapitre(numero: int) -> Path:
|
||||
"""Chemin d'un chapitre du rapport : `chapitre(10)` → `…_sec10.md`."""
|
||||
return ENTREE / f"lois-france-2026-guadeloupe_sec{numero:02d}.md"
|
||||
|
||||
|
||||
def dimension(numero: int) -> Path:
|
||||
"""Chemin d'un rapport de dimension : `dimension(7)` → `lois-2026_dim07.md`."""
|
||||
return RECHERCHE / f"lois-2026_dim{numero:02d}.md"
|
||||
|
||||
|
||||
CHAPITRES = [chapitre(n) for n in range(11)]
|
||||
DIMENSIONS = [dimension(n) for n in range(1, 13)]
|
||||
|
||||
# ── Sorties ──────────────────────────────────────────────────────────────────
|
||||
DONNEES = RACINE / "data"
|
||||
BASE_SQLITE = RACINE / os.environ.get("VEILLE_DB", "data/veille.db")
|
||||
DUMP_JSON = DONNEES / "textes.json"
|
||||
CACHE_HTTP = RACINE / os.environ.get("VEILLE_CACHE", "data/cache_http")
|
||||
|
||||
MIGRATIONS = Path(__file__).resolve().parent / "migrations"
|
||||
CONFIG = Path(__file__).resolve().parent / "config.yaml"
|
||||
|
||||
|
||||
def verifier_corpus() -> list[str]:
|
||||
"""Retourne la liste des fichiers d'entrée attendus mais absents."""
|
||||
attendus = [
|
||||
RAPPORT_FINAL,
|
||||
BIBLIOGRAPHIE,
|
||||
CROSS_VERIFICATION,
|
||||
INSIGHTS,
|
||||
PHASE5_VALIDATION,
|
||||
*CHAPITRES,
|
||||
*DIMENSIONS,
|
||||
]
|
||||
return [str(p.relative_to(RACINE)) for p in attendus if not p.exists()]
|
||||
Reference in New Issue
Block a user