Pular para o conteúdo principal

Produção OCR (Vision-MacOS) - Instruções de Engenharia

Última Atualização: 03/01/2026
Status: ✅ OPERACIONAL (Pipeline Layout-Aware testado com sucesso)


🏗️ Arquitetura Híbrida

O sistema utiliza um padrão de Remote Worker para acessar a API proprietária da Apple (Vision Framework) que só roda em MacOS.

┌─────────────────────────────────────────────────────────────────────────────┐
│ FLUXO DE PROCESSAMENTO OCR │
│ │
│ 1. POST /dispatch ──► MacOS Worker API (localhost:9001) │
│ 2. Worker baixa imagens ◄── Google Drive API │
│ 3. Executa OCR ──► ocrmac (Apple Vision Framework) │
│ 4. POST /callback ──► Node.js Backend │
│ 5. Salva em clio_ocr + clio_ocr_segments ──► MariaDB │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

✅ Componentes Implementados

1. Backend Node.js (Orquestrador)

Arquivo: node/backend/routes/workerRoute.js

EndpointMétodoDescrição
/api/workersGETLista workers registrados
/api/workers/jobsPOSTCria novo job na fila
/api/workers/jobs/queueGETLista fila de jobs
/api/workers/jobs/:id/dispatchPOSTDespacha job para worker
/api/workers/jobs/:id/callbackPOSTRecebe resultado do worker

Callback Layout-Aware (TESTADO 03/01/2026):

  • ✅ Conecta a dois databases (arboreolabconn + projeto)
  • ✅ Parseia JSON Layout-Aware do worker
  • ✅ Salva em clio_ocr com engine_version='vision-macos-v1'
  • ✅ Insere blocos em clio_ocr_segments com bounding boxes
  • ✅ Atualiza status_ocr='CONCLUÍDO' em gerenciador_dados

2. MacOS Worker (Electron App)

Localização: /home/arboreolab/Clio/apps-desktop-vue-electron/

Worker Python: estudos/macos_worker/worker_server.py (FastAPI)

EndpointMétodoDescrição
/healthGETStatus do worker
/processPOSTProcessa job de OCR
/jobs/{id}GETStatus de job específico

Formato de Saída (Layout-Aware):

{
"source_file": "KIC000049.jpg",
"metadata": {
"dimensoes": { "largura": 3494, "altura": 2932 },
"checksum_sha256": "abc123...",
"exif_detalhado": { ... }
},
"ocr_data": {
"full_text": "CITY. 1974 AMERICA...",
"word_count": 15,
"blocks": [
{ "text": "CITY.", "conf": 1.0, "x": 0.344, "y": 0.017, "w": 0.048, "h": 0.021 },
{ "text": "1974", "conf": 1.0, "x": 0.263, "y": 0.017, "w": 0.029, "h": 0.012 }
]
}
}

3. Tabelas de Banco de Dados

Database: arboreolabconn

TabelaFunção
worker_registryCadastro de workers (mac-vision-01, etc)
job_queueFila de processamento com status
remote_logLog de conexões SSH

Database: [Projeto]Vector (ex: GeopoliticasVector)

TabelaFunção
clio_ocrOCR processado (engine_version, hash, dimensões)
clio_ocr_segmentsBlocos com bounding boxes (x, y, w, h)
gerenciador_dadosStatus de processamento (status_ocr)

🔒 Segurança do Túnel SSH

┌─────────────────┐     SSH Reverso      ┌─────────────────┐
│ MacOS Worker │◄────────────────────►│ Linux Server │
│ (Electron App) │ porta 9001 │ (srv1) │
│ │ │ │
│ FastAPI :8766 │◄─────────────────────│ Node.js :3000 │
└─────────────────┘ localhost:9001 └─────────────────┘
  • O Mac conecta via SSH reverso no servidor Linux
  • O Node.js acessa o Mac via http://localhost:9001
  • A porta é fixa (9001) e registrada em worker_registry

📊 Métricas Operacionais (03/01/2026)

MétricaValor
Worker registradomac-vision-01
StatusONLINE
Jobs completados6
Jobs falhos0
Registros vision-macos-v12
Segmentos com bounding boxes17

🚀 Fluxo de Processamento

# 1. Criar job
curl -X POST "http://localhost:3000/api/workers/jobs" \
-H "Content-Type: application/json" \
-d '{
"job_type": "ocr-vision",
"worker_id": 1,
"projeto_id": 4,
"payload": {
"file_ids": ["ID_DRIVE"],
"file_names": ["arquivo.jpg"],
"drive_email": "user@gmail.com"
}
}'

# 2. Disparar job
curl -X POST "http://localhost:3000/api/workers/jobs/{id}/dispatch"

# 3. Verificar resultado
SELECT * FROM clio_ocr WHERE engine_version = 'vision-macos-v1';
SELECT * FROM clio_ocr_segments WHERE ocr_id = {id};

📋 Próximos Passos

PrioridadeTarefaStatus
ALTAProcessar lote de arquivos🔄 Pronto para produção
MÉDIACriar ProducaoOCR.vue📋 Pendente
MÉDIAImplementar busca híbrida📋 Pendente
BAIXAComponente Grounding visual📋 Pendente

🔧 Troubleshooting

ProblemaCausaSolução
Callback não salva OCRColunas incorretas no UPDATEUsar JOIN com gerenciamento_googledrive
Worker offlineTúnel SSH desconectadoReconectar via Electron App
Segmentos não inseridosBlocks vazios no JSONVerificar OCR retornou blocos

Autor: Engenheiro de Software Sênior (ArboreoLab)