feat(datasets): catálogo curado de datasets para Widget Builder simple
Nueva capa abstraida sobre data_sources que oculta tablas/columnas técnicas detrás de "datasets" con nombres legibles y campos clasificados (metric/dimension/filter). El SQL builder es dialect-aware (ClickHouse + PostgreSQL) y valida constraints por tipo de visual.
Componentes:
- Migración 20260512_create_dataset_catalog.sql (dataset_catalog + dataset_fields con FKs a data_sources y areas)
- Modelos SQLAlchemy DatasetCatalog y DatasetField (cascade delete)
- Router /api/datasets, /api/datasets/{slug}, /api/widgets/from-dataset
- Auth por área (403 si el dataset es de área que no controlas)
- SQL injection prevenido con escape ANSI de comillas y validación estricta de field IDs contra el dataset
- Constraints viz: KPI sin dims, Line solo dims temporales, etc.
- Persiste en custom_widgets (mismo path que el builder legacy — los widgets existentes no se ven afectados)
- Seed 20260512_seed_dataset_trato.sql ("Contratos Trato" con 1 métrica, 4 dimensiones y 3 filtros). Idempotente y resuelve source_id por nombre (no hardcoded).
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com