--- name: metabase_validate_card_payload kind: function lang: py domain: infra version: "1.0.0" purity: pure signature: "def metabase_validate_card_payload(payload: dict) -> list[str]" description: "Valida la estructura de un payload de card de Metabase sin necesidad de red. Recorre todos los checks y acumula todos los issues en vez de abortar al primero. Retorna lista vacia si el payload es valido." tags: [metabase, validation, card, pure, pre-flight, structural] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "" imports: [] params: - name: payload desc: "dict con los campos de la card a validar: name, display, dataset_query, type (opcional), visualization_settings (opcional), parameters (opcional), archived (opcional)" output: "lista de strings describiendo cada issue estructural encontrado; lista vacia indica payload valido listo para enviarse a POST/PUT /api/card" tested: true tests: - "card valido retorna lista vacia" - "card display invalido" - "card display ausente" - "card name ausente" - "card name vacio" - "card dataset query ausente" - "card dataset query sin database" - "card nativa sin sql" - "card nativa mbql5" - "card type invalido" - "card type valido" - "card visualization settings no dict" - "card parameters no list" - "card archived no bool" - "card acumula multiples errores" test_file_path: "python/functions/metabase/validation_test.py" file_path: "python/functions/metabase/validation.py" --- ## Ejemplo ```python issues = metabase_validate_card_payload({ "name": "Revenue by Month", "display": "line", "dataset_query": { "database": 1, "type": "native", "native": {"query": "SELECT date_trunc('month', created_at), SUM(total) FROM orders GROUP BY 1"}, }, }) if issues: print("Payload invalido:", issues) else: metabase_update_card(client, card_id, **payload) ``` ## Notas Displays validos: scalar, table, line, bar, pie, area, row, funnel, smartscalar, gauge, progress, combo, pivot, map, scatter, waterfall, sankey, object. Tipos validos (campo `type`): question, model, metric. Soporta dos formatos de SQL nativo: - Legacy: `dataset_query.native.query` - MBQL5: `dataset_query.stages[0].native` No aborta al primer error — recolecta todos los issues para que el caller pueda mostrarlos todos de una vez.