# Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca """Central configuration: paths, snapshot identity, sample window, conventions.""" from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[2] DATA = ROOT / "data" RAW = DATA / "raw" EXTERNAL = DATA / "external" INTERIM = DATA / "interim" PROCESSED = DATA / "processed" RESULTS = ROOT / "results" FIGURES = ROOT / "figures" DOCS = ROOT / "docs" CONFIGS = ROOT / "configs" LOGS = ROOT / "logs" # --- Immutable extraction snapshot (Phase 1) ------------------------------- # `sqlite3 .backup` of M3U96a:~/apps/vrai-prix/data/vraiprix.db taken # 2026-10-21 00:30 (America/Toronto) into ~/wp22-snapshot/, copied to RAW. SNAPSHOT_DB = RAW / "vraiprix-20261021.db" SNAPSHOT_SHA256 = "2816d8ddbee66faf7f8961fabf0460583249e911dab52014e633be14b9d34461" SNAPSHOT_TAKEN = "2026-10-21T00:30:00-04:00" SNAPSHOT_SOURCE = "M3U96a:~/apps/vrai-prix/data/vraiprix.db (production, read via .backup)" # Earlier vintages of the same transaction table (ids + dates only), used to # measure registration/publication lags. See docs/provenance_report.md. VINTAGES = { "2026-08-06": RAW / "vintages" / "vintage_qwhpi_csv.parquet", "2026-08-09": RAW / "vintages" / "vintage_wp10_parquet.parquet", "2026-10-10": RAW / "vintages" / "vintage_20261010.csv.gz", "2026-10-17": RAW / "vintages" / "vintage_toveli_20261017.parquet", } # --- External reference data ---------------------------------------------- SDA_GPKG = EXTERNAL / "SDA.gpkg" # MRNF administrative boundaries V2026-07 MAMH_MUN_CSV = EXTERNAL / "MUN.csv" # MAMH répertoire des municipalités MAMH_MRC_CSV = EXTERNAL / "MRC.csv" # --- Sample window and index conventions ---------------------------------- SAMPLE_START = "2021-01-01" SAMPLE_END = "2026-10-07" # last transaction date in snapshot BASE_YEAR = 2021 # primary normalisation: 2021 avg = 100 BASE_MONTH = "2021-01" # secondary normalisation PROPERTY_TYPES = ("house", "condo", "plex") SEED = 20261021 MODEL_VERSION = "0.1.0" CRS_METRIC = "EPSG:32198" # NAD83 / Quebec Lambert # --- Parquet layers -------------------------------------------------------- RAW_TX = INTERIM / "raw_transactions.parquet" RAW_UNITS_MATCHED = INTERIM / "raw_units_matched.parquet" RAW_UNITS_STOCK = INTERIM / "raw_units_stock.parquet" RAW_MARKET_INDEX = INTERIM / "raw_market_index.parquet" STD_TX = INTERIM / "std_transactions.parquet" # standardized layer GEO_TX = INTERIM / "geo_transactions.parquet" # + geography CLEAN_TX = PROCESSED / "clean_transactions.parquet" # cleaned (flags, ledger) ANALYTIC_TX = PROCESSED / "analytic_transactions.parquet" # analytic layer def ensure_dirs() -> None: for d in (INTERIM, PROCESSED, RESULTS, FIGURES, DOCS, LOGS): d.mkdir(parents=True, exist_ok=True)