feat(metabase): expansion cards y documents — export, model, ProseMirror validation, copy nativo

Cards: export_card (CSV/XLSX/JSON), create_model (type=model para fuentes MBQL).
Documents: prosemirror_card_embed helper (resizeNode envolviendo cardEmbed),
validacion automatica contra whitelist TipTap antes de enviar, copy_document
refactorizado al endpoint nativo POST /api/document/:id/copy.
Docs: dataset_query legacy vs MBQL5, template-tags, whitelist de nodos.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-14 19:03:19 +02:00
parent 4299482b75
commit 58539f45c9
9 changed files with 516 additions and 71 deletions
@@ -3,12 +3,12 @@ name: metabase_update_document
kind: function
lang: py
domain: infra
version: "1.0.0"
version: "1.1.0"
purity: impure
signature: "def metabase_update_document(client: MetabaseClient, document_id: int, **fields) -> dict"
description: "Actualiza un document. Solo envia los campos pasados. Endpoint: PUT /api/document/:id."
signature: "def metabase_update_document(client: MetabaseClient, document_id: int, *, validate: bool = True, **fields) -> dict"
description: "Actualiza un document. Solo envia los campos pasados. Si se pasa 'document', valida el ProseMirror antes de enviar (evita documentos vacíos por nodos no soportados)."
tags: [metabase, document, update, api, python]
uses_functions: []
uses_functions: [metabase_validate_document_payload_py_infra]
uses_types: []
returns: []
returns_optional: false
@@ -19,6 +19,8 @@ params:
desc: "instancia autenticada de MetabaseClient"
- name: document_id
desc: "ID del document a actualizar"
- name: validate
desc: "si True (default), valida el ProseMirror antes de enviar cuando se pasa 'document'"
- name: fields
desc: "kwargs con campos a modificar: name, document (arbol ProseMirror), collection_id, archived"
output: "dict: document actualizado"
@@ -31,15 +33,27 @@ file_path: "python/functions/metabase/documents.py"
## Ejemplo
```python
from metabase.documents import prosemirror_card_embed
# Renombrar
metabase_update_document(client, 1, name="Nuevo titulo")
# Reemplazar contenido completo
# Reemplazar contenido con card embebida
metabase_update_document(client, 1, document={
"type": "doc",
"content": [{"type": "paragraph", "content": [{"type": "text", "text": "Nuevo"}]}]
"content": [
{"type": "heading", "attrs": {"level": 1},
"content": [{"type": "text", "text": "Resumen"}]},
prosemirror_card_embed(42, height=450),
]
})
# Mover a coleccion
metabase_update_document(client, 1, collection_id=5)
```
## Notas
- La validación es automática cuando se pasa `document=...`. Si contiene nodos que el frontend no renderiza (callout, taskList, etc.), lanza `ValueError` antes de enviar.
- Usar `blockquote` en vez de `callout` para destacar texto.
- Usar `prosemirror_card_embed(card_id)` en vez de `cardEmbed` desnudo.