--- name: metabase_registry lang: py domain: analytics description: "Setup y dashboards automaticos de Metabase para visualizar metricas del fn-registry y operations.db de cada app." tags: [metabase, dashboard, analytics, visualization, operations] uses_functions: - metabase_auth_py_infra - metabase_create_card_py_infra - metabase_create_dashboard_py_infra - metabase_update_dashboard_py_infra - metabase_list_databases_py_infra - metabase_add_database_py_infra - metabase_list_dashboards_py_infra - metabase_delete_dashboard_py_infra - metabase_create_user_py_infra uses_types: [] framework: httpx entry_point: "main.py" dir_path: "apps/metabase_registry" --- ## Arquitectura Metabase corre en Docker (`fn_registry-metabase`) con Postgres como backend interno. Las bases de datos SQLite del proyecto se montan como bind mounts RW en `/data/`: | Database | Mount en container | Contenido | |----------|-------------------|-----------| | registry.db | `/data/registry/registry.db` | functions, types, proposals, apps | | ops-docker-tui | `/data/ops-docker-tui/operations.db` | entities, relations, executions | | ops-metabase-registry | `/data/ops-metabase-registry/operations.db` | entities, relations, executions | | ops-pipeline-launcher | `/data/ops-pipeline-launcher/operations.db` | entities, relations, executions | ## Dashboards | Dashboard | Contenido | |-----------|-----------| | fn-registry Overview | KPIs, distribucion y analisis del registry | | fn-registry Apps | Apps por lenguaje, dominio, dependencias | | ops: \ | Dashboard operativo por app (entities, relations, executions, assertions) | ## Permisos SQLite en Docker Metabase corre Java como UID 2000 (usuario `metabase`). SQLite necesita crear journal/WAL files en el mismo directorio que la BD. Reglas: - **NUNCA** hacer `chown` dentro del container: se propaga al host via bind mount y rompe permisos locales. - **Usar `chmod`**: `chmod 777` en directorios, `chmod 666` en archivos `.db`. - **Pipeline automatico**: `./fn run metabase_fix_permissions` arregla todos los permisos. - **Ejecutar despues de**: recrear container, aƱadir nueva database, o ver error `SQLITE_READONLY_DIRECTORY`. ## Flujo para app nueva ```bash # 1. Crear operations.db ./fn ops init apps/nueva_app # 2. Recrear container con el nuevo mount docker stop fn_registry-metabase && docker rm fn_registry-metabase docker run -d \ --name fn_registry-metabase \ --network fn_registry-net \ -p 3000:3000 \ -e MB_DB_TYPE=postgres -e MB_DB_DBNAME=metabase \ -e MB_DB_PORT=5432 -e MB_DB_USER=metabase \ -e MB_DB_PASS=metabase -e MB_DB_HOST=fn_registry-postgres \ -v /home/lucas/fn_registry:/registry:ro \ -v /home/lucas/fn_registry/registry.db:/data/registry/registry.db \ -v /home/lucas/fn_registry/apps/docker_tui:/data/ops-docker-tui \ -v /home/lucas/fn_registry/apps/metabase_registry:/data/ops-metabase-registry \ -v /home/lucas/fn_registry/apps/pipeline_launcher:/data/ops-pipeline-launcher \ -v /home/lucas/fn_registry/apps/nueva_app:/data/ops-nueva-app \ metabase/metabase:latest # 3. Fix permisos ./fn run metabase_fix_permissions # 4. Registrar database en Metabase ./fn run metabase_add_ops_db nueva_app # 5. Crear dashboard operativo ./fn run metabase_create_ops_dashboard nueva_app ``` ## Scripts | Script | Funcion | |--------|---------| | `main.py` | Setup inicial: datasource + cards basicas + dashboard Overview | | `create_registry_dashboard.py` | Dashboard fn-registry Overview (18 cards) | | `create_apps_dashboard.py` | Dashboard fn-registry Apps (10 cards) | ## Pipelines relacionados | Pipeline | ID | Funcion | |----------|-----|---------| | `metabase_add_ops_db` | `metabase_add_ops_db_py_pipelines` | Registra operations.db de una app | | `metabase_create_ops_dashboard` | `metabase_create_ops_dashboard_py_pipelines` | Crea dashboard operativo para una app | | `metabase_fix_permissions` | `metabase_fix_permissions_py_pipelines` | Arregla SQLITE_READONLY_DIRECTORY | ## Credenciales En `.env` local (NO commitear).