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.
-
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.
-
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:
- 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.
- 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.
-
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
filecom 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_idna 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
-
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}/ ...
]
}
- 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:
- O status do processamento será atualizado para "P"(Em processamento) imediatamente
- O arquivo solicitado será recuperado do Storage(S3) e enviado à DocumentAI para extração dos dados
- 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
- 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.