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