Projeto técnico: Extração automatizada de dados de documentos automatizada - GrupoBRA/SocialAPI-v2-Doc GitHub Wiki

Objetivo

Especificação dos itens necessários para a implementação de um serviço para extração de dados usando Google DocumentAI e preenchimento automatizado dos campos relevantes.

Especificações

O usuário terá duas interfaces principais de interação com a nova funcionalidade, sendo uma delas no upload de um novo documento e a outra diretamente na tela/formulário do respectivo documento que já foi enviado anteriormente.

  1. No upload: será possível marcar um checkbox informando que logo após a conclusão do envio deste documento, o processo de extração deve ser iniciado e o seu status poderá ser acompanhado pelo usuário posteriormente na tela do respectivo documento.

  2. Na tela/formulário documento já enviado: o usuário poderá clicar em um ícone para iniciar o processo a partir do documento já enviado.

Após o upload do arquivo com a opção de extração de texto ativo ou solicitação avulsa direto na tela/formulário do documento, um ícone para a consulta do status do processamento será exibido sob o thumbnail do documento, ao clicar nesse ícone o usuário terá acesso à informação de status, que pode ser:

  • Aguardando
  • Em processamento
  • Erro
  • Concluído

Em caso de erro, o usuário terá a opção de solicitar o processamento novamente. Em caso de status concluído, o usuário terá acesso à pop-up para fornecer feedback sobre a precisão das informações extraídas no processamento.

Infra

Banco de dados

Criar as seguintes tabelas no banco de dados da Social para registros dos processamentos realizados, resultados obtidos e identificação do arquivo relacionado.

Processamento(processamento)

Column Type Constraints
id BIGINT(11) PRIMARY KEY
paginas TINYINT(3) NOT NULL
id_arquivo VARCHAR(35) NOT NULL, INDEX
tipo_arquivo VARCHAR(50) NOT NULL, INDEX
checksum VARCHAR(100) NOT NULL, INDEX
status ENUM('A','P','E','C') NOT NULL
oid VARCHAR(35) NOT NULL, INDEX
oeid VARCHAR(35) NOT NULL, INDEX
uupfid VARCHAR(35) NOT NULL

ResultadoProcessamento(resultado_processamento)

Column Type Constraints
id BIGINT(11) PRIMARY KEY
campo VARCHAR(100) NOT NULL, INDEX
valor VARCHAR(255) NOT NULL
precisao FLOAT(10,2) NOT NULL
posicao_texto_bruto VARCHAR(10) NOT NULL
coordenadas_pagina JSON NOT NULL
processamento_id BIGINT(11) NOT NULL, FOREIGN KEY

FeedBackProcessamento(feedback_processamento)

Column Type Constraints
id BIGINT(11) PRIMARY KEY
feedback TINYINT(1) NOT NULL, INDEX
comentario TEXT NULL
processamento_id FK(processamento) NOT NULL
resultado_processamento_id FK(resultado_processamento) NULL

OrgaoParticipante(orgao_participante)

Column Type Constraints
id BIGINT(11) PRIMARY KEY
oeid VARCHAR(35) NOT NULL, INDEX
documentos_liberados SMALLINT(6) NULL
documentos_ciclo SMALLINT(6) NULL

Endpoints

Para dar suporte às interfaces a serem utilizadas pelos usuários, serão criados os seguintes endpoints:

  1. Retorna as informações de status do serviço: conexão com a API do DocumentAI, disponibilidade de acesso para o usuário/órgão selecionados de acordo com a tabela OrgaoParticipante.

GET /v2/document/

Utilizando os dados do token do usuário, listas as informações de status deste usuário/entidade para utilização da feature de extração de dados de documentos automatizada. Resposta:

{
  "orgao": "Grupo BRA, PE",
  "document_ai_status": "healthy",
  "usuario_status": null // Número de documentos liberados. Ilimitado, se null
}

Status:

200 | 404

Caso a Entidade do usuário não esteja liberada, a resposta deve ser 404.

  1. Lista os dados de todos os processamentos de documentos já realizados para este pf_id

GET /v2/document/{pf_id}/

Lista as informações de todos processamentos solicitados para os documentos deste pf_id no Órgão(oid). Resposta:

{
  "total": 10,
  "processamentos": [
    {
      "id": 999,
      "file_id": "071cc69d4f9753d05469b3de230d33.jpg",
      "type": "dhar00",
      "classificacao": "identidade",
      "status": "C",
      "texto_bruto": "...94910159-1...",
      "uupfid": "5403600818138761067",
      "data_hora": "2025-01-01 00:00:01",
      "resultados": [
        {
          "id": 1999,
          "campo": "registro_geral",
          "valor": "94910159-1",
          "precisao": 0.9994201,
          "posicao_texto_bruto": [
            365,
            375
          ],
          "coordenadas_pagina": [
            {
              "x": 0.8527778,
              "y": 0.37109375
            },
            {
              "x": 0.89444447,
              "y": 0.37109375
            },
            {
              "x": 0.89444447,
              "y": 0.38046876
            },
            {
              "x": 0.8527778,
              "y": 0.38046876
            }
          ]
        }
      ],
    }
  ]
}

Status-codes:

200 | 404

Caso a Entidade do usuário não esteja liberada, a resposta deve ser 404.

  1. POST /v2/document/processamento/

Adiciona um documento à fila de processamento para extração das informações e posterior preenchimento dos campos associados. O processo se dará da seguinte forma:

  • Verificar se o file_id informado existe na tabela file com o OID do token da requisição ou retornar 404.
  • Verificar se o Órgão relacionado ao OID do token possui documentos liberados no ciclo atual ou retornar status 402.
  • Caso esse file_id já esteja na tabela processamento para este OID, retornar status 409 com os dados do processamento, conforme exemplo abaixo.
  • Adicionar um registro na tabela processamento com status "A" para rastrear o processamento.
  • Adicionar o file_id na fila de processamento de arquivos com OCR e preenchimento Request payload:
{
  "pf_id": "...",
  "file_id": "071cc69d4f9753d05469b3de230d33.jpg",
  "file_type": "zmspog"
}

Resposta(Sucesso):

{
  "id": 999,
  "status": "A",
  "uupfid": "5403600818138761067",
  "data_hora": "2025-01-01 00:00:01"
}

Resposta(Duplicado):

{
  "id": 999,
  "file_id": "071cc69d4f9753d05469b3de230d33.jpg",
  "type": "dhar00",
  "classificacao": "identidade",
  "status": "C",
  "texto_bruto": "...94910159-1...",
  "uupfid": "5403600818138761067",
  "data_hora": "2025-01-01 00:00:01",
  "resultados": [
    // Conforme o exemplo no endpoint GET /v2/document/{pf_id}/ ...
  ]
}

Status-codes:

201 | 402 | 404 | 409

  1. GET /v2/document/processamento/<processamento_id>/status/

Lista o status de um processamento submetido à fila Resposta:

{
  "id": 999,
  "file_id": "071cc69d4f9753d05469b3de230d33.jpg",
  "type": "dhar00",
  "classificacao": "identidade",
  "status": "C",
  "texto_bruto": "...94910159-1...",
  "uupfid": "5403600818138761067",
  "data_hora": "2025-01-01 00:00:01",
  "resultados": [
    // Conforme o exemplo no endpoint GET /v2/document/{pf_id}/ ...
  ]
}
  1. POST /v2/document/processamento/<processamento_id>/feedback/ Registro o feedback do usuário acerca de um processamento já concluído. Request payload:
{
  "feedback": 1 | 0,
  "comentario": "...",
  "resultado_processamento_id": 9999 // Caso o feedback esteja vinculado a um campo específico.
}

Queue

Para processamento assíncrono será utilizada uma fila específica no Redis da Social com Dead-Letter Queue pra registrar eventuais falhas de processamento.

O processamento na fila seguirá os seguintes passos:

  1. O status do processamento será atualizado para "P"(Em processamento) imediatamente
  2. O arquivo solicitado será recuperado do Storage(S3) e enviado à DocumentAI para extração dos dados
  3. Os dados extraídos serão validados e caso o mínimo necessário esteja presente para preenchimento, de acordo com o tipo de documento, os dados serão salvos nas respectivas tabelas
  4. O status será atualizado para "C"(Concluído)
  • Em caso de erros inesperados, o processo será tentado outras 3 vezes, com intervalo exponencialmente maior a cada falha
  • Caso o limite de tentativas seja exaurido sem que o arquivo seja processado com sucesso, então o processamento será marcado com status "E"(Erro) e a mensagem será movida para a Dead-Letter Queue para investigação posterior e/ou reprocessamento.