ADR-018 — Patrón base↔satélite: separación entre librería y productos consumidores¶
Fecha: 2026-05-07 Estado: Aceptado — patrón vigente (primer ejemplo retirado, ver nota abajo)
Contexto¶
Durante la sesión 2026-05-07 emergió la pregunta concreta: dónde vive un dashboard Streamlit que opera sobre datos de calidad del aire. Dos modelos posibles:
- Todo dentro del repo base — incluir un módulo
dashboard/oapp/con la app Streamlit, sus configs de deploy y posiblemente datos crudos. - Repo satélite separado — la app vive en su propio repositorio y consume
estadistica-ambientalcomo dependencia desde PyPI.
Sin una decisión explícita, la primera opción es tentadora (todo en un solo
sitio) pero diluye la promesa del repo: ser una base de conocimiento +
librería estable, citable, reutilizable, instalable con pip install
estadistica-ambiental desde cualquier proyecto.
Decisión¶
Adoptar el patrón base↔satélite:
-
Estadistica_Ambiental(este repo) — librería + plantillas + fichas de dominio. Se publica en PyPI comoestadistica-ambiental. Tiene su propio versionado SemVer y su propio CI. No contiene apps de cliente, dashboards específicos, pipelines ETL nocturnos, datos crudos ni configuraciones de deploy productivo. -
Satélites — repos separados que importan
estadistica-ambientalcomo dependencia. Ejemplos materializados o previstos: Estadistica_Ambiental_Dashboard(Streamlit, calidad del aire genérico) — ❌ retirado 2026-07-24 (repo eliminado; el patrón sigue vigente para futuros satélites).calidad-aire-CAR(dashboard CAR-específico) — previsto.paramos-rabanal,pomca-magdalena, etc. — previstos.
Cada satélite tiene su propio versionado, deploy y CI. Pinea la versión
exacta de la base en su requirements.txt (ej. estadistica-ambiental==1.3.2).
Reglas operativas¶
Lo que SÍ va en el repo base:
- Módulos en
src/(estadística, validación, conectores genéricos, reportes HTML reutilizables). - Conectores oficiales a fuentes ambientales colombianas (OpenAQ, SISAIRE, RMCAB, IDEAM DHIME, SMByC).
- Notebooks plantilla por línea temática en
notebooks/lineas_tematicas/. - Fichas de dominio en
docs/fuentes/<linea>.md. - ADRs en
docs/decisiones.mdydocs/adr/. - Tests genéricos.
- Empaquetado para PyPI / install-from-git.
Lo que NO va en el repo base:
- Apps Streamlit, Dash, Shiny, etc.
- Dashboards específicos de un cliente o entidad (CAR, Corpoboyacá, etc.).
- Pipelines ETL nocturnos / cron jobs operativos.
- Configuraciones de deploy productivo (Docker compose para producción, Helm charts, configuraciones de Streamlit Cloud específicas).
- Datos crudos del cliente (ya cubierto por
.gitignore).
Coupling y versionado¶
- Los satélites pinean la versión exacta de la base
(
estadistica-ambiental==X.Y.Z), no rangos abiertos. Razón: garantiza reproducibilidad y aísla a cada satélite de releases breaking de la base. - Cuando el satélite necesita una función no expuesta en la base, se evalúa:
- ¿Es genérica y útil para múltiples satélites? → PR a la base, release nueva, satélite bumpea pin.
- ¿Es específica del satélite? → vive en el satélite, no contamina la base.
- La base nunca depende de un satélite. La dirección del coupling es unidireccional: satélite → base.
Scaffolding del primer satélite (referencia histórica, repo retirado)¶
Estadistica_Ambiental_Dashboard estableció el patrón replicable antes de su retiro el 2026-07-24.
La estructura se conserva aquí como referencia para el próximo satélite que se instancie:
Estadistica_Ambiental_Dashboard/
├── app.py # Streamlit entrypoint
├── src/dashboard/
│ ├── data.py # Carga datos (demo o real)
│ ├── plots.py # Wrappers Plotly específicos del producto
│ ├── pages.py # Una función por tab
│ └── __init__.py
├── requirements.txt # estadistica-ambiental==X.Y.Z + streamlit
├── pyproject.toml # ruff, version, etc.
├── .streamlit/config.toml # Tema, page config
├── .github/workflows/deploy.yml # smoke headless + ruff
├── .gitignore
└── README.md
Para un nuevo satélite, copiar esta estructura y reemplazar la lógica de páginas. La base permanece intacta.
Consecuencias¶
- Trazabilidad clara de qué es metodología (base) vs. producto (satélite).
- Reutilización — agregar una segunda corporación regional no requiere fork ni mantenimiento del repo base; se crea un satélite nuevo.
- Versionado limpio — la base versiona su API; los satélites versionan su producto. Sin acoplamiento de release schedules.
- Memoria de Claude Code ya refleja esta regla
(
feedback_repo_es_base_de_conocimiento.md): cuando emerge una idea de "agregar un dashboard al repo", redirigir a un satélite nuevo. - Reevaluar si en algún momento el repo base requiere una app de
referencia mínima para demostrar uso (ej. un quickstart Streamlit). En ese
caso, vivir en
examples/con una nota explícita "este es ejemplo, no producto" — y no ensrc/.
Referencias¶
- Primer satélite (retirado 2026-07-24):
Estadistica_Ambiental_Dashboard— repo eliminado, sin URL activa. - Memoria correlacionada:
feedback_repo_es_base_de_conocimiento.md. - Plan §13 entry "2026-05-07 — Release v1.3.2 + JupyterLite + Fase 10 + primer satélite".
- Commit: scaffolding del satélite (repo aparte), referencia desde la base.