Objetivo Transformar o ConvertX em um serviço backend interno, sem necessidade de UI, para suportar principalmente: - DOCX -> TXT - DOCX -> texto bruto JSON - PDF -> texto - XLSX -> texto/CSV - ODT -> texto - HTML/MD -> texto - PPT -> TXT - PPTX -> TXT - DOC -> TXT - XLS -> TXT O uso principal será: - n8n baixa arquivo do Nextcloud - n8n envia arquivo ao serviço - serviço devolve texto limpo - n8n indexa no Supabase ──────────────────────────────────────────────────────────────────────────────── Decisão arquitetural Não fazer - scraping da UI do ConvertX - automação de login/session/cookies - usar endpoints web atuais como API informal - expor interface pública para clientes Fazer Criar um fork com API interna dedicada, separada da UI. ### Estratégia recomendada Adicionar uma camada nova de rotas, por exemplo: - POST /api/extract-text - POST /api/convert - GET /healthz Com autenticação simples por token interno. ──────────────────────────────────────────────────────────────────────────────── Estado atual observado Pelo container investigado: - o projeto já tem motores funcionais: - LibreOffice - calibre - pandoc - markitdown - o projeto já faz conversões reais - logs confirmam conversão bem-sucedida de docx -> txt - há código compilado indicando: - src/converters/main - handleConvert(...) - conversores separados por engine - a aplicação atual é UI-first - existem rotas web, mas não uma API limpa/documentada para integração M2M Conclusão: a parte difícil da conversão já existe. O trabalho principal é expor isso de forma limpa, previsível e segura. ──────────────────────────────────────────────────────────────────────────────── Meta funcional do fork MVP Entregar um serviço que aceite upload de arquivo e retorne texto extraído. ### Endpoint principal POST /api/extract-text ### Input Multipart upload: - file: arquivo - opcional: - filename - mimeType - preferredConverter - formatHint ### Output ```json { "ok": true, "filename": "contrato.docx", "detectedInputType": "docx", "converter": "calibre", "text": "texto extraído...", "meta": { "chars": 12345, "warnings": [], "durationMs": 842 } } ``` V2 Adicionar endpoint de conversão genérica: POST /api/convert Input: - arquivo - target=txt|pdf|html|md Output: - binário convertido ou - JSON com downloadUrl temporária V3 Adicionar modos assíncronos para arquivos grandes: - POST /api/jobs - GET /api/jobs/:id - GET /api/jobs/:id/result ──────────────────────────────────────────────────────────────────────────────── Proposta de design técnico 1. Criar modo “service-only” Adicionar variável de ambiente: - SERVICE_MODE=true ### Comportamento Quando SERVICE_MODE=true: - não montar UI - não depender de login visual - subir apenas: - healthcheck - rotas de API - middlewares essenciais ### Benefícios - superfície menor - menos complexidade - mais fácil de operar - menos risco de endpoints web desnecessários ──────────────────────────────────────────────────────────────────────────────── 2. Criar namespace /api Separar totalmente das rotas existentes de UI. ### Rotas sugeridas - GET /healthz - GET /api/healthz - POST /api/extract-text - POST /api/convert - opcional: - GET /api/formats - GET /api/converters ──────────────────────────────────────────────────────────────────────────────── 3. Criar camada de autenticação interna Como é serviço de infraestrutura, não precisa auth de usuário final. ### Recomendado Auth por header estático: - Authorization: Bearer ou - X-API-Key: ### Variável - SERVICE_TOKEN=... ### Regra - se SERVICE_MODE=true, bloquear todas as rotas /api/* sem token válido - exceção: - /healthz ### Se rodar só em rede interna Pode até começar sem auth em ambiente fechado, mas eu recomendo token desde o início. ──────────────────────────────────────────────────────────────────────────────── Arquivos/áreas prováveis para alterar no fork Baseado no que encontrei no container: Áreas principais - src/index.tsx - src/converters/main.ts - src/converters/*.ts - src/helpers/* - páginas/rotas web em src/pages/* Novo código a criar ### Novo diretório sugerido - src/api/ ### Arquivos sugeridos - src/api/auth.ts - src/api/health.ts - src/api/extractText.ts - src/api/convert.ts - src/api/utils/files.ts - src/api/utils/text.ts - src/api/utils/cleanup.ts ──────────────────────────────────────────────────────────────────────────────── Implementação recomendada por etapas Etapa 1 — mapear a entrada do app atual Objetivo: entender o mínimo necessário para chamar a conversão sem UI. ### Tarefa DEV Inspecionar: - como src/pages/upload.tsx salva upload - como src/pages/convert.tsx chama handleConvert - assinatura real de handleConvert(...) - formato esperado de: - upload dir - output dir - converter name - target format ### Entregável Documento curto: - fluxo atual de upload → conversão → output - dependências implícitas do sistema de jobs ──────────────────────────────────────────────────────────────────────────────── Etapa 2 — isolar a lógica reutilizável Objetivo: desacoplar conversão da camada web. ### Se handleConvert estiver muito acoplado Criar função nova, por exemplo: ```ts convertSingleFile({ inputPath, outputDir, target, preferredConverter, options }) ``` Retornando algo como: ```ts { outputPath: string, converterUsed: string, target: string } ``` ### Ideal Essa função deve: - não depender de cookie - não depender de user id - não depender de job id da UI - não depender de db/history ### Entregável Uma função reutilizável de backend puro. ──────────────────────────────────────────────────────────────────────────────── Etapa 3 — implementar POST /api/extract-text Objetivo: MVP útil para n8n. ### Fluxo interno 1. receber multipart com arquivo 2. salvar em diretório temporário 3. detectar tipo: - por extensão - e/ou MIME 4. escolher rota de extração ### Regras sugeridas por tipo - docx - tentar calibre -> txt - fallback libreoffice -> txt - fallback markitdown se fizer sentido - odt - libreoffice - pdf - se houver extrator apropriado, usar - senão deixar fora do MVP - txt, md, csv - leitura direta - html - converter para texto via sanitização ### Pós-processamento de texto Aplicar normalização: - trim - normalizar CRLF/LF - remover excesso de linhas vazias - opcional: - remover caracteres nulos - normalizar unicode - colapsar whitespace sem destruir parágrafos ### Output Sempre JSON: ```json { "ok": true, "text": "...", "converter": "calibre", "detectedInputType": "docx", "meta": { "chars": 1234, "durationMs": 820, "tempFilesCleaned": true } } ``` ### Erros Padrão: ```json { "ok": false, "error": { "code": "UNSUPPORTED_INPUT", "message": "Unsupported input type: xlsm" } } ``` ──────────────────────────────────────────────────────────────────────────────── Etapa 4 — implementar escolha de conversor Objetivo: não depender de um único backend. ### Ordem recomendada para DOCX->TXT 1. calibre 2. libreoffice 3. pandoc ou markitdown se útil ### Por quê Você já viu nos logs que o ConvertX converteu DOCX→TXT usando calibre com sucesso. ### Interface sugerida Criar um resolvedor: ```ts resolveTextExtractor(inputType, preferredConverter?) ``` Retorna: - função de conversão - nome do conversor ### Benefício No futuro, trocar backend sem mexer na API. ──────────────────────────────────────────────────────────────────────────────── Etapa 5 — implementar storage temporário robusto Objetivo: evitar vazamento de arquivos e sujeira em disco. ### Recomendação Estrutura temporária por request: - /tmp/convertx-service//input - /tmp/convertx-service//output ### Regras - gerar requestId UUID - limpar sempre no finally - logar falha de cleanup sem quebrar resposta principal - adicionar TTL cleanup defensivo por cron se quiser ### Importante Nunca confiar no nome do arquivo bruto do usuário para compor path. ──────────────────────────────────────────────────────────────────────────────── Etapa 6 — health e observabilidade ### Endpoint GET /healthz Retorno: ```json { "ok": true, "service": "convertx-service", "serviceMode": true, "converters": { "libreoffice": true, "calibre": true, "pandoc": true } } ``` ### Também recomendado GET /api/formats Retorna: - entradas suportadas para extração - conversores disponíveis ### Logging Log por request: - requestId - filename - detected input type - converter escolhido - duration - sucesso/falha Sem logar conteúdo do documento. ──────────────────────────────────────────────────────────────────────────────── Contrato recomendado para o n8n Chamada HTTP Request POST /api/extract-text ### Headers - Authorization: Bearer ### Body Multipart: - file: binário do Nextcloud ### Resposta esperada no n8n ```json { "ok": true, "text": "..." } ``` ### Integração no workflow Branch DOCX fica: 1. Nextcloud download 2. HTTP Request -> convertx-service /api/extract-text 3. Set data = {{$json.text}} 4. Update Data RAG 5. Move para processados ──────────────────────────────────────────────────────────────────────────────── Segurança Requisitos mínimos - rodar em rede interna - autenticação por token - limite de tamanho de upload - tipos aceitos explicitamente - sanitização de nome de arquivo - limpeza garantida de temporários - timeout por conversão Recomendado - MAX_UPLOAD_MB - REQUEST_TIMEOUT_MS - ALLOWED_INPUT_TYPES=docx,txt,md ,pdf,... Não fazer - expor sem auth na internet - aceitar qualquer formato indiscriminadamente - armazenar documentos convertidos por padrão ──────────────────────────────────────────────────────────────────────────────── Performance e concorrência MVP Processamento síncrono por request está ok. Limites recomendados - 1 request = 1 temp dir - limite de concorrência configurável - timeouts por engine ### Variáveis sugeridas - MAX_CONCURRENT_CONVERSIONS=2 ou 4 - REQUEST_TIMEOUT_MS=60000 Se ficar pesado depois Migrar para fila/job assíncrono. ──────────────────────────────────────────────────────────────────────────────── Plano de entrega para DEV Sprint 1 — API mínima funcional ### Objetivo Subir POST /api/extract-text para DOCX. ### Itens - fork do projeto - SERVICE_MODE=true - GET /healthz - POST /api/extract-text - token auth - temp storage - DOCX -> TXT via calibre/libreoffice - retorno JSON com texto - logs básicos ### Critério de aceite - enviar DOCX e receber texto limpo - n8n consegue consumir - sem UI necessária ──────────────────────────────────────────────────────────────────────────────── Sprint 2 — endurecimento ### Itens - fallback entre conversores - suporte a TXT/MD/HTML direto - timeouts - limites de upload - limpeza robusta - testes automatizados - imagem Docker própria do fork ### Critério de aceite - falha controlada - zero lixo de temp após requests - respostas padronizadas de erro ──────────────────────────────────────────────────────────────────────────────── Sprint 3 — extensões úteis ### Itens - POST /api/convert - GET /api/formats - suporte a PDF/XLSX conforme prioridade - métricas e logs melhores - docs internas para integração com n8n ──────────────────────────────────────────────────────────────────────────────── Testes que DEV precisa cobrir Testes funcionais ### DOCX simples - texto corrido - múltiplos parágrafos - heading + lista ### DOCX médio - tabela - quebra de página - caracteres acentuados - unicode ### Casos de erro - arquivo inválido - ZIP corrompido - extensão falsa - arquivo muito grande - timeout de conversão Testes de contrato - resposta JSON sempre válida - ok=true/false - text presente quando sucesso - error.code presente quando falha Testes de operação - cleanup de temp - concorrência de 2-5 requests - comportamento com conversor ausente ──────────────────────────────────────────────────────────────────────────────── Docker/Deploy do fork Recomendação Imagem própria, por exemplo: - ghcr.io//convertx-service Execução Sem UI e com modo serviço: - SERVICE_MODE=true - SERVICE_TOKEN=... ### Exemplo de compose conceitual ```yaml services: convertx-service: image: ghcr.io//convertx-service:latest restart: unless-stopped ports: - "127.0.0.1:3010:3000" environment: - SERVICE_MODE=true - SERVICE_TOKEN=supersecret - MAX_UPLOAD_MB=50 - REQUEST_TIMEOUT_MS=60000 volumes: - ./data:/app/data ``` ### Observação Se não precisar persistência, pode usar volume temporário. Mas algum diretório de trabalho é útil para debug inicial. ──────────────────────────────────────────────────────────────────────────────── Riscos e mitigação Risco 1 — handleConvert muito acoplado à UI/job/db ### Mitigação Extrair função backend pura de conversão. Risco 2 — output TXT ruim em alguns DOCX ### Mitigação Implementar fallback entre calibre/libreoffice/markitdown. Risco 3 — vazar arquivos temporários ### Mitigação try/finally + cleanup periódico defensivo. Risco 4 — serviço virar gargalo ### Mitigação limite de concorrência + timeout + futura fila assíncrona. Risco 5 — quebra com updates upstream ### Mitigação manter mudanças isoladas em src/api/* e em poucos pontos do bootstrap. ──────────────────────────────────────────────────────────────────────────────── Recomendação de abordagem de código Evitar Modificar agressivamente o fluxo web já existente. Preferir Adicionar uma camada nova, quase orthogonal: - src/api/* - boot condicional no src/index.tsx Assim o fork: - continua próximo do upstream - fica mais fácil de manter - reduz conflito de merge ──────────────────────────────────────────────────────────────────────────────── Definição de pronto O fork estará “pronto” para uso no n8n quando: - POST /api/extract-text aceitar DOCX - devolver texto confiável - exigir token interno - limpar temporários - expor GET /healthz - rodar em container sem UI - ser consumível pelo workflow com um único HTTP Request ──────────────────────────────────────────────────────────────────────────────── Minha recomendação final ao time DEV Build order 1. extrair/consolidar função backend de conversão 2. criar /api/extract-text 3. adicionar auth + cleanup 4. dockerizar modo service-only 5. integrar no n8n 6. só depois pensar em /api/convert genérico Porque o caso de uso real hoje é: DOCX -> texto para RAG e não um conversor universal completo. Se quiser, no próximo passo eu posso transformar isso em um artefato mais operacional para o time, por exemplo: - checklist técnico por tarefa - ADR curta - ou especificação de endpoints com payloads exatos. faça os 3 Perfeito. Vou te entregar os 3 artefatos: 1. checklist técnico por tarefa 2. ADR curta 3. especificação de endpoints com payloads exatos ──────────────────────────────────────────────────────────────────────────────── 1) CHECKLIST TÉCNICO POR TAREFA Projeto: Fork do ConvertX para modo service-only interno Objetivo do MVP Entregar um serviço interno que faça: - DOCX -> texto - consumível por n8n via HTTP - sem UI - sem login humano - com token interno - com cleanup de arquivos temporários ──────────────────────────────────────────────────────────────────────────────── EPIC A — Preparação do fork ### Tarefa A1 — Criar fork e baseline Checklist - Criar fork do repositório C4illin/ConvertX - Definir nome do fork/produto interno - sugestão: convertx-service - Criar branch inicial: - feat/service-mode-api - Documentar hash/tag upstream base usada no fork - Confirmar build local do projeto original - Confirmar que a imagem Docker do fork sobe igual ao upstream Entregável - fork funcional - branch de trabalho criada - README interno inicial ──────────────────────────────────────────────────────────────────────────────── ### Tarefa A2 — Mapear fluxo atual de conversão Checklist - Inspecionar src/index.tsx - Inspecionar src/pages/upload* - Inspecionar src/pages/convert* - Inspecionar src/converters/main* - Localizar assinatura real de handleConvert(...) - Identificar dependências com: - user/session - jobId - sqlite/history - diretórios uploads/output - Mapear onde ocorre a seleção de conversor - Mapear onde o output final é salvo - Mapear tratamento de erro atual Entregável - documento curto: “conversion flow map” - diagrama simples do fluxo atual ──────────────────────────────────────────────────────────────────────────────── EPIC B — Desacoplamento da lógica de conversão ### Tarefa B1 — Extrair função backend pura Objetivo Criar função reutilizável sem dependência da UI. Checklist - Criar módulo novo, ex: - src/service/convertSingleFile.ts - Definir interface de entrada: ```ts type ConvertSingleFileInput = { inputPath: string outputDir: string target: string preferredConverter?: string options?: Record } ``` - Definir interface de saída: ```ts type ConvertSingleFileResult = { outputPath: string converterUsed: string target: string durationMs: number } ``` - Reusar lógica de conversão existente - Remover dependência de: - cookie - user id - job id - páginas web - Garantir que a função lance erro padronizado em falha Entregável - função backend pura testável ──────────────────────────────────────────────────────────────────────────────── ### Tarefa B2 — Extrair estratégia de “texto” Objetivo Criar uma camada que escolha o melhor conversor para extrair texto. Checklist - Criar módulo: - src/service/extractText.ts - Implementar detecção de tipo por: - extensão - MIME opcional - Criar resolver de conversor: ```ts resolveTextExtractor(inputType, preferredConverter?) ``` - Ordem inicial para DOCX: - calibre - libreoffice - markitdown/pandoc se aplicável - Definir retorno: ```ts type ExtractTextResult = { text: string detectedInputType: string converterUsed: string durationMs: number warnings?: string[] } ``` Entregável - função extractTextFromFile(...) ──────────────────────────────────────────────────────────────────────────────── EPIC C — Modo service-only ### Tarefa C1 — Criar flag de execução Checklist - Adicionar env var: - SERVICE_MODE=true|false - No bootstrap (src/index.tsx), separar: - rotas web/UI - rotas de serviço/API - Quando SERVICE_MODE=true: - não montar páginas UI - não montar login/register/history/results - montar apenas health + API - Manter compatibilidade com modo original se necessário Entregável - app sobe em modo só-serviço ──────────────────────────────────────────────────────────────────────────────── ### Tarefa C2 — Criar autenticação por token Checklist - Adicionar env: - SERVICE_TOKEN - Criar middleware: - src/api/auth.ts - Ler header: - Authorization: Bearer - Permitir /healthz sem auth - Bloquear /api/* sem token válido - Padronizar erro 401: ```json { "ok": false, "error": { "code": "UNAUTHORIZED", "message": "Invalid or missing service token" } } ``` Entregável - autenticação M2M funcionando ──────────────────────────────────────────────────────────────────────────────── EPIC D — API de extração ### Tarefa D1 — Healthcheck Checklist - Criar GET /healthz - Criar GET /api/healthz opcional - Retornar: - status do serviço - SERVICE_MODE - disponibilidade de conversores - Verificar presença real de: - libreoffice - calibre - pandoc - markitdown se existir Entregável - health confiável para monitoramento e n8n ──────────────────────────────────────────────────────────────────────────────── ### Tarefa D2 — Endpoint POST /api/extract-text Checklist - Criar rota: - POST /api/extract-text - Aceitar multipart form-data - Campo obrigatório: - file - Campos opcionais: - preferredConverter - filename - mimeType - formatHint - Validar tamanho do upload - Persistir em diretório temporário - Executar extração - Ler arquivo convertido TXT se o backend converter para TXT - Normalizar o texto - Devolver JSON Entregável - endpoint consumível pelo n8n ──────────────────────────────────────────────────────────────────────────────── ### Tarefa D3 — Normalização de texto Checklist - Criar módulo: - src/api/utils/text.ts - Aplicar: - trim - normalização de newline - remoção de NUL bytes - colapso de whitespace horizontal excessivo - preservação de parágrafos - limite opcional de tamanho - Adicionar warnings quando: - texto vier vazio - conversão tiver fallback - arquivo parecer corrompido Entregável - texto mais estável para RAG ──────────────────────────────────────────────────────────────────────────────── EPIC E — Arquivos temporários e robustez ### Tarefa E1 — Temp storage por request Checklist - Criar requestId UUID por request - Estrutura: - /tmp/convertx-service//input - /tmp/convertx-service//output - Sanitizar nome do arquivo - Nunca confiar em path do usuário - Sempre limpar em finally - Logar falha de cleanup sem quebrar a resposta Entregável - zero sujeira estrutural por request ──────────────────────────────────────────────────────────────────────────────── ### Tarefa E2 — Timeouts e limites Checklist - Adicionar env: - MAX_UPLOAD_MB - REQUEST_TIMEOUT_MS - MAX_CONCURRENT_CONVERSIONS - Aplicar timeout por processo de conversão - Aplicar limite de upload - Rejeitar tipos não suportados - Padronizar erro: - PAYLOAD_TOO_LARGE - UNSUPPORTED_INPUT - CONVERSION_TIMEOUT Entregável - serviço operacionalmente previsível ──────────────────────────────────────────────────────────────────────────────── EPIC F — Docker e operação ### Tarefa F1 — Dockerfile / imagem do fork Checklist - Reutilizar imagem base do projeto ou adaptar a atual - Garantir que conversores necessários estejam presentes - Garantir modo service-only no start - Expor porta única - Configurar env defaults seguros Entregável - imagem convertx-service ──────────────────────────────────────────────────────────────────────────────── ### Tarefa F2 — Compose de operação Checklist - Criar compose interno - Bind local de porta - ex: 127.0.0.1:3010:3000 - Definir volume de dados se necessário - Definir restart policy - Definir token por env Entregável - deploy repetível ──────────────────────────────────────────────────────────────────────────────── EPIC G — Integração com n8n ### Tarefa G1 — Contrato n8n Checklist - Documentar chamada HTTP Request no n8n - Exemplo com multipart binário - Exemplo de headers - Exemplo de resposta - Exemplo de mapping: - data = {{$json.text}} Entregável - handoff claro para o time de automação ──────────────────────────────────────────────────────────────────────────────── EPIC H — Testes ### Tarefa H1 — Testes funcionais Checklist - DOCX simples - DOCX com acentos - DOCX com tabela - DOCX com listas - DOCX vazio - arquivo inválido/corrompido - extensão falsa - timeout forçado ### Tarefa H2 — Testes operacionais Checklist - concorrência 2-5 requests - cleanup após sucesso - cleanup após falha - auth inválida - healthcheck sem auth Entregável - suíte mínima de confiança ──────────────────────────────────────────────────────────────────────────────── 2) ADR CURTA ADR-001 — Fork do ConvertX como serviço interno de extração de texto ### Status Proposto ### Contexto O fluxo RAG atual depende de ingestão automática de arquivos do Nextcloud e precisa extrair texto de documentos, especialmente .docx, sem: - autenticação Google - UI humana - automação frágil de browser/login Foi validado que o ConvertX, rodando em container, já converte DOCX -> TXT com sucesso usando sua stack interna (ex.: calibre/LibreOffice). Porém, a aplicação atual é orientada a UI e não expõe uma API simples/documentada para integração máquina-a-máquina. ### Decisão Fazer um fork do ConvertX e adicionar um modo service-only, com rotas internas dedicadas para automação, iniciando com: - GET /healthz - POST /api/extract-text O serviço será protegido por token interno e consumido pelo n8n. ### Racional Essa abordagem: - reutiliza a stack de conversão já validada - evita desenvolver um conversor do zero - evita depender de Google - evita scraping da UI - reduz confusão operacional com clientes - mantém a extração como componente de infraestrutura isolado ### Alternativas consideradas #### 1. Google como backend de conversão Rejeitada por exigir autenticação e gerar complexidade externa indesejada. #### 2. LibreOffice no host, chamado diretamente Viável, mas mais chato de operar, versionar e encapsular do que reaproveitar o container já funcional. #### 3. ConvertX UI com automação/scraping Rejeitada por fragilidade e baixa mantenibilidade. #### 4. Serviço local custom do zero Viável, mas desnecessário dado que o ConvertX já resolve a parte difícil da conversão. ### Consequências positivas - integração limpa com n8n - backend interno sem UI - melhor separação de responsabilidades - facilidade de evolução para outros formatos ### Consequências negativas - custo de manutenção do fork - necessidade de isolar mudanças para facilitar merge com upstream - necessidade de lidar com cleanup, auth e limites operacionais ### Decisão operacional Implementar primeiro um MVP de DOCX -> texto via POST /api/extract-text, depois expandir se necessário. ──────────────────────────────────────────────────────────────────────────────── 3) ESPECIFICAÇÃO DE ENDPOINTS Base URL Interna, por exemplo: - http://convertx-service:3000 ou - http://127.0.0.1:3010 Autenticação Header obrigatório para /api/*: ```http Authorization: Bearer ``` ──────────────────────────────────────────────────────────────────────────────── 3.1 GET /healthz ### Objetivo Sonda simples para monitoramento e readiness. ### Auth Não obrigatória ### Request ```http GET /healthz ``` ### Response 200 ```json { "ok": true, "service": "convertx-service", "serviceMode": true, "version": "0.1.0", "converters": { "libreoffice": true, "calibre": true, "pandoc": true, "markitdown": false } } ``` ──────────────────────────────────────────────────────────────────────────────── 3.2 GET /api/formats ### Objetivo Listar formatos e conversores disponíveis. ### Auth Obrigatória ### Request ```http GET /api/formats Authorization: Bearer ``` ### Response 200 ```json { "ok": true, "extractText": { "inputs": ["docx", "txt", "md", "html", "odt"], "preferredConverters": ["calibre", "libreoffice", "pandoc", "markitdown"] } } ``` ──────────────────────────────────────────────────────────────────────────────── 3.3 POST /api/extract-text ### Objetivo Receber um arquivo e retornar texto extraído. ### Auth Obrigatória ### Content-Type multipart/form-data ### Campos #### Obrigatório - file — binário do arquivo #### Opcionais - preferredConverter — string - exemplos: calibre, libreoffice - filename — string - mimeType — string - formatHint — string - ex.: docx ### Exemplo cURL ```bash curl -X POST http://127.0.0.1:3010/api/extract-text \ -H "Authorization: Bearer SEU_TOKEN" \ -F "file=@contrato.docx" \ -F "preferredConverter=calibre" ``` ### Response 200 ```json { "ok": true, "filename": "contrato.docx", "detectedInputType": "docx", "converter": "calibre", "text": "Conteúdo extraído do documento...", "meta": { "chars": 18432, "durationMs": 913, "warnings": [] } } ``` ### Response 400 — arquivo ausente ```json { "ok": false, "error": { "code": "MISSING_FILE", "message": "Field 'file' is required" } } ``` ### Response 400 — tipo não suportado ```json { "ok": false, "error": { "code": "UNSUPPORTED_INPUT", "message": "Unsupported input type: xlsm" } } ``` ### Response 401 — auth inválida ```json { "ok": false, "error": { "code": "UNAUTHORIZED", "message": "Invalid or missing service token" } } ``` ### Response 413 — arquivo grande ```json { "ok": false, "error": { "code": "PAYLOAD_TOO_LARGE", "message": "File exceeds maximum allowed size" } } ``` ### Response 500 — falha de conversão ```json { "ok": false, "error": { "code": "CONVERSION_FAILED", "message": "Failed to extract text from file" } } ``` ──────────────────────────────────────────────────────────────────────────────── 3.4 POST /api/convert ### Objetivo Conversão genérica de arquivo para formato alvo. ### Status Opcional / pós-MVP ### Auth Obrigatória ### Request Multipart: - file - target - preferredConverter opcional ### Exemplo ```bash curl -X POST http://127.0.0.1:3010/api/convert \ -H "Authorization: Bearer SEU_TOKEN" \ -F "file=@arquivo.docx" \ -F "target=txt" ``` ### Resposta possível #### modo JSON ```json { "ok": true, "filename": "arquivo.txt", "converter": "calibre", "contentBase64": "SGVsbG8uLi4=" } ``` #### ou modo binário retorno direto do arquivo convertido com: - Content-Type - Content-Disposition ### Recomendação Para o caso RAG, não priorizar este endpoint no MVP. Priorizar extract-text. ──────────────────────────────────────────────────────────────────────────────── 3.5 Especificação de integração com n8n ### Chamada No HTTP Request node: - Method: POST - URL: http://convertx-service:3000/api/extract-text - Auth header: ```text Authorization: Bearer {{$env.CONVERTX_SERVICE_TOKEN}} ``` - Send Binary Data: true - Binary Property: data - Content type: multipart/form-data ### Resposta esperada ```json { "ok": true, "text": "..." } ``` ### Mapping seguinte No Set: ```javascript {{ $json.text }} ``` para o campo: - data ──────────────────────────────────────────────────────────────────────────────── Recomendação final de execução Ordem 1. MVP extract-text 2. health + auth + cleanup 3. integração n8n 4. testes DOCX reais 5. só depois: - formats - convert - outros formatos