{"id":"docs/export-data/spec","source":"docs","sourceLabel":"docs/","sourcePath":"docs/export-data/SPEC.md","routePath":"/fastapp/public-docs/page/docs/export-data/spec","rawPath":"/fastapp/public-docs/raw/docs/export-data/spec","slug":["docs","export-data","spec"],"slugPath":"docs/export-data/spec","title":"Exportacao de Dados Spec Final","description":"Status: Sprint implementada na branch feat/export data.","headings":["Exportacao de Dados Spec Final","1. Evidencias Lidas no Repositorio","2. Como Esta Feature Deve Seguir o Modelo FastApp","3. Objetivo","4. Fora de Escopo Inicial","5. Estado Atual","6. UX Proposta","7. Contrato de API Proposto","8. Modelagem em App JSON","9. Permissionamento e Seguranca","10. Sprint feat/export data","Task 1 Contexto e planejamento SDD Concluida","Task 2 Contrato server side de exportacao Concluida","Task 3 Serializadores CSV/XLSX/PDF/JSON Concluida","Task 4 UI universal no CoreDynamicCRUD Concluida","Task 5 Escopos de exportacao Concluida","Task 6 Cobertura em CMS e views especiais Concluida","Task 7 Testes e regressao Concluida","Task 8 Documentacao final e handoff Concluida apos commit desta task","11. Decisoes Fechadas e Riscos Restantes","12. Handoff"],"wordCount":1117,"markdown":"# Exportacao de Dados - Spec Final\r\n\r\n> Status: Sprint implementada na branch `feat/export-data`.\r\n\r\n---\r\n\r\n## 1. Evidencias Lidas no Repositorio\r\n\r\n- Stack e arquitetura: `package.json`, `ARCHITECTURE.md`, `app/types/schema.ts`,\r\n  `app/fastapp/manifest.ts`.\r\n- Runtime dinamico: `app/pages/[app]/[module]/[object]/index.vue`,\r\n  `app/components/core/DynamicCRUD.vue`, `DynamicTable.vue`,\r\n  `DynamicList.vue`, `DynamicKanban.vue`, `DynamicIntegratedList.vue`.\r\n- API dinamica: `server/api/v1/data/[app]/[object]/index.get.ts`,\r\n  `server/utils/query-parser.ts`, `server/utils/dynamic-db.ts`,\r\n  `server/utils/data-source-resolver.ts`, `server/utils/legacy-list-contract.ts`,\r\n  `server/utils/api-parser.ts`.\r\n- Bulk e selecao: `server/api/v1/data/[app]/[object]/bulk.patch.ts`,\r\n  `bulk.delete.ts`, `server/utils/bulk-data.ts`.\r\n- RBAC e app scope: `server/middleware/rbac-data-scope.ts`,\r\n  `server/utils/rbac-data-scope.ts`, `server/utils/user-membership-scope.ts`.\r\n- Task Board: `task-board-app.json`, `scripts/seed-task-board.mjs`,\r\n  objeto `task_item` com `ui_mode: \"kanban\"`.\r\n- SDD interno: `docs/ura-ai/SPEC.md`, `docs/ura-ai/CONTEXT.md`,\r\n  `app/types/draft-app.ts`, `server/api/apps/wizard-commit.post.ts`.\r\n- Estado existente de parsers: `docs/api-parsers.md`,\r\n  `server/utils/api-parser.ts`.\r\n\r\n---\r\n\r\n## 2. Como Esta Feature Deve Seguir o Modelo FastApp\r\n\r\nO sistema e um construtor de apps orientado por objetos no JSON do `app`. A\r\nexportacao deve ser uma capacidade transversal do runtime dinamico, nao uma tela\r\nhardcoded por cliente.\r\n\r\nRegras de arquitetura:\r\n\r\n- O ponto universal de entrada deve ficar no `CoreDynamicCRUD`, porque ele\r\n  orquestra tabela, lista, kanban, agenda, mapa e views hibridas.\r\n- As views filhas (`DynamicTable`, `DynamicList`, `DynamicKanban`,\r\n  `DynamicIntegratedList`, CMS object views) nao devem duplicar logica de\r\n  exportacao; elas devem expor dados/estado ao CRUD ou reaproveitar helper\r\n  comum.\r\n- A exportacao precisa respeitar o mesmo contrato de filtros, sort, app hint,\r\n  RBAC e data source usado por `/api/v1/data/:app/:object`.\r\n- O schema do objeto deve poder configurar a capacidade por metadado, com\r\n  default seguro. Proposta inicial:\r\n  `schema.ui_config.export.enabled !== false`,\r\n  `schema.ui_config.export.formats`, `schema.ui_config.export.max_rows`,\r\n  `schema.ui_config.export.filename_template`,\r\n  `schema.ui_config.export.include_hidden_fields`.\r\n- O comportamento padrao deve funcionar mesmo sem metadado novo: todo objeto de\r\n  dados que aparece em CRUD/listagem pode exportar CSV e, apos implementacao,\r\n  XLSX e PDF.\r\n\r\nResultado da sprint: a exportacao virou capacidade transversal do runtime,\r\ncom backend dedicado, UI reutilizavel, cobertura em CMS e testes de regressao.\r\n\r\n---\r\n\r\n## 3. Objetivo\r\n\r\nAdicionar uma acao padrao de download/exportacao em todas as abas e views que\r\nmostram dados de objetos do FastApp, permitindo baixar os registros visiveis ou a\r\nconsulta filtrada em formatos comuns de sistemas administrativos.\r\n\r\nFormatos alvo da sprint:\r\n\r\n- CSV: aproveitar e endurecer parser existente.\r\n- XLSX: planilha Excel real.\r\n- PDF: relatorio tabular basico com cabecalho, filtros e colunas.\r\n- JSON: opcional no menu para diagnostico/uso tecnico.\r\n\r\n---\r\n\r\n## 4. Fora de Escopo Inicial\r\n\r\n- Exportar anexos/binarios de `CoreAssetUpload`.\r\n- Criar designer visual de relatorios PDF.\r\n- Exportar dashboards graficos como imagem.\r\n- Criar agendamento/envio por email.\r\n- Exportar milhoes de linhas em processamento assincrono.\r\n- Implementar permissao nova sem antes entender o modelo atual de RBAC; a\r\n  Sprint 1 deve reutilizar read permission/app scope existente.\r\n\r\n---\r\n\r\n## 5. Estado Atual\r\n\r\nJa existe suporte parcial a parsers na API dinamica:\r\n\r\n- `$parser=csv`, `$format=csv`: retorna CSV via `server/utils/api-parser.ts`.\r\n- `$parser=yaml`, `$parser=markdown`: existem para usos tecnicos.\r\n\r\nLimites do estado atual:\r\n\r\n- `CoreDynamicCRUD` usa `CoreExportDataButton` no action bar.\r\n- CSV de export usa schema para labels, ordem, visibilidade e `exportable`.\r\n- XLSX/PDF foram adicionados com `exceljs` e `pdfkit`.\r\n- O endpoint dedicado decide entre consulta filtrada, pagina atual e\r\n  selecionados.\r\n- Headers de download e filename estao formalizados no helper server-side.\r\n\r\n---\r\n\r\n## 6. UX Proposta\r\n\r\nNo action bar do `CoreDynamicCRUD` e nas views CMS de objeto, ha botao com\r\nicone `pi pi-download` e tooltip \"Exportar\". Ao clicar, abre menu compacto com:\r\n\r\n- \"CSV\"\r\n- \"Excel\"\r\n- \"PDF\"\r\n- \"JSON\"\r\n\r\nEscopos de exportacao:\r\n\r\n- Consulta filtrada: refaz request com filtros/sort atuais e limite de export.\r\n- Pagina atual: envia `$limit` e `$skip` atuais.\r\n- Selecionados: envia `ids=...` quando houver selecao ativa.\r\n\r\nO default da UI e \"Consulta filtrada\" com limite seguro e feedback de loading,\r\nsucesso e erro.\r\n\r\n---\r\n\r\n## 7. Contrato de API Proposto\r\n\r\nManter compatibilidade com parsers existentes e adicionar endpoint dedicado para\r\nformatos que precisam de headers/arquivo:\r\n\r\n- `GET /api/v1/data/:app/:object/export?format=csv|xlsx|pdf|json`\r\n- Query normal de filtros/sort: mesmos parametros de `index.get.ts`.\r\n- `scope=current_query|current_page|selected`\r\n- `ids=...` quando `scope=selected`.\r\n- `fields=campo1,campo2` opcional.\r\n- `include_hidden=0|1`\r\n\r\nReaproveitamento:\r\n\r\n- Usar `resolveObjectDataSource`, `resolveObjectSchema`, `parseQueryParams`,\r\n  `mergeRbacWhereConstraint`, enriquecimento de relacoes/computed e fallback\r\n  interno/externo do endpoint de listagem.\r\n- Serializacao centralizada em `server/utils/export-data.ts`.\r\n\r\nHeaders:\r\n\r\n- `Content-Type` correto por formato.\r\n- `Content-Disposition: attachment; filename=\"<app>-<object>-<date>.<ext>\"`.\r\n- BOM UTF-8 para CSV quando necessario para Excel.\r\n\r\n---\r\n\r\n## 8. Modelagem em App JSON\r\n\r\nAdicionar suporte a metadado opcional por objeto:\r\n\r\n```json\r\n{\r\n  \"ui_config\": {\r\n    \"export\": {\r\n      \"enabled\": true,\r\n      \"formats\": [\"csv\", \"xlsx\", \"pdf\", \"json\"],\r\n      \"scopes\": [\"current_query\", \"current_page\", \"selected\"],\r\n      \"max_rows\": 5000,\r\n      \"include_hidden_fields\": false,\r\n      \"filename_template\": \"{app}-{object}-{date}\",\r\n      \"fields\": [\"id\", \"nome\", \"status\", \"created_at\"]\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nDefaults quando ausente:\r\n\r\n- `enabled: true` para objetos de dados com CRUD/lista.\r\n- `formats: [\"csv\", \"xlsx\", \"pdf\", \"json\"]`.\r\n- `scopes: [\"current_query\", \"current_page\", \"selected\"]`.\r\n- `max_rows: 5000`.\r\n- Campos exportados: `show_in_list !== false`, mais `id`, respeitando ordem do\r\n  schema; campos `object/json/array/inner_collection` devem ser serializados de\r\n  forma segura ou excluidos no PDF.\r\n\r\n---\r\n\r\n## 9. Permissionamento e Seguranca\r\n\r\n- Exportacao deve passar pelos mesmos middlewares e constraints de leitura.\r\n- Nao deve permitir burlar filtros de app/membership via query.\r\n- `include_hidden_fields` so pode ser respeitado se o usuario tiver permissao\r\n  administrativa ou se o schema permitir explicitamente.\r\n- Exports de objetos externos devem encaminhar query sanitizada, como a listagem.\r\n- Limites de linhas e tamanho de arquivo devem ser aplicados no servidor.\r\n- Campos sensiveis podem ser bloqueados por metadado futuro:\r\n  `exportable: false` em `PropSchema`.\r\n\r\n---\r\n\r\n## 10. Sprint `feat/export-data`\r\n\r\n### Task 1 - Contexto e planejamento SDD - Concluida\r\n\r\nAceite:\r\n\r\n- Branch `feat/export-data` criada a partir da `main`.\r\n- `docs/export-data/SPEC.md` e `CONTEXT.md` criados.\r\n- Cards da sprint criados no Task Board.\r\n- Nenhum feature code implementado antes da aprovacao.\r\n\r\n### Task 2 - Contrato server-side de exportacao - Concluida\r\n\r\nAceite:\r\n\r\n- Endpoint ou parser dedicado de export definido e coberto por testes.\r\n- CSV existente preservado sem quebrar `docs/api-parsers.md`.\r\n- Headers de download e filename implementados.\r\n- Filtros, sort, app hint e RBAC continuam aplicados.\r\n\r\n### Task 3 - Serializadores CSV/XLSX/PDF/JSON - Concluida\r\n\r\nAceite:\r\n\r\n- CSV usa labels/ordem do schema e lida com valores especiais.\r\n- XLSX gera arquivo abrivel no Excel/Sheets.\r\n- PDF gera relatorio tabular basico com cabecalho, data e colunas visiveis.\r\n- JSON baixa envelope ou linhas de forma documentada.\r\n- Dependencias novas justificadas e minimizadas.\r\n\r\n### Task 4 - UI universal no CoreDynamicCRUD - Concluida\r\n\r\nAceite:\r\n\r\n- Botao de export aparece em views de dados sem duplicacao por view.\r\n- Menu de formatos respeita `schema.ui_config.export`.\r\n- Estado de loading/toast para sucesso/erro.\r\n- Funciona em tabela, lista, kanban e pagina dinamica padrao.\r\n\r\n### Task 5 - Escopos de exportacao - Concluida\r\n\r\nAceite:\r\n\r\n- Exportar consulta filtrada com sort atual.\r\n- Exportar pagina atual quando configurado.\r\n- Exportar selecionados quando houver selecao.\r\n- Limites e mensagens claras quando exceder max rows.\r\n\r\n### Task 6 - Cobertura em CMS e views especiais - Concluida\r\n\r\nAceite:\r\n\r\n- `object_table`, `object_list_simple`, `object_kanban` no CMS nao perdem\r\n  comportamento.\r\n- Dashboards/listagens customizadas sao avaliadas e documentadas.\r\n- Onde export nao for aplicavel, a UI nao mostra acao quebrada.\r\n\r\n### Task 7 - Testes e regressao - Concluida\r\n\r\nAceite:\r\n\r\n- Testes API para formatos, filtros, sort, selected ids, RBAC e limite.\r\n- Teste de componente ou E2E minimo para menu/botao.\r\n- `npm run test:api` passa.\r\n\r\n### Task 8 - Documentacao final e handoff - Concluida apos commit desta task\r\n\r\nAceite:\r\n\r\n- `docs/api-parsers.md` atualizado.\r\n- `docs/export-data/CONTEXT.md` atualizado com o que foi feito.\r\n- Cards movidos para `CONCLUIDA` ao concluir cada task.\r\n- Commits pequenos por task com mensagens claras.\r\n\r\n---\r\n\r\n## 11. Decisoes Fechadas e Riscos Restantes\r\n\r\n1. XLSX/PDF sao gerados no servidor para preservar RBAC, filtros e exportacao\r\n   da consulta sem depender de cache local.\r\n2. Dependencias escolhidas: `exceljs` para XLSX e `pdfkit` para PDF.\r\n3. Limite inicial default: `max_rows=5000`, configuravel por objeto.\r\n4. A Sprint 1 reutiliza permissao/escopo de leitura; permissao `export`\r\n   dedicada fica como evolucao futura.\r\n5. Campos computed e relacionamentos sao enriquecidos antes da serializacao.\r\n6. Campos exportados seguem `show_in_list !== false`, `fields`,\r\n   `include_hidden_fields` e `exportable: false`.\r\n7. `npm run build` nao concluiu dentro de 300s durante a sprint; `npm run\r\n   test:api` passou com 16 testes.\r\n\r\n---\r\n\r\n## 12. Handoff\r\n\r\n- Endpoint principal: `server/api/v1/data/[app]/[object]/export.get.ts`.\r\n- Helpers server-side: `server/utils/export-data.ts`.\r\n- Botao reutilizavel: `app/components/core/ExportDataButton.vue`.\r\n- Helpers client-side testaveis: `app/utils/export-client.ts`.\r\n- Cobertura UI dinamica: `app/components/core/DynamicCRUD.vue`.\r\n- Cobertura CMS: `app/components/core/cms/CoreCmsElementProxy.vue`,\r\n  `CoreCmsSectionObjectTable.vue`, `CoreCmsSectionObjectList.vue`.\r\n- Testes: `tests/api/export-data.spec.ts`.\r\n- Documentacao operacional: `docs/api-parsers.md`.\r\n\r\nPara validar manualmente, abrir qualquer tela de objeto, clicar no icone de\r\ndownload e testar CSV, Excel, PDF e JSON nos escopos Consulta, Pagina e\r\nSelecionados quando houver selecao.\r\n"}