Pular para o conteúdo principal

Envios de Documentos e Formulários (App Mobile)

Pilar: 02 — Funcionalidades Core / App Mobile
Status: 🟢 Implementado
Última Revisão Técnica: 2026-08-09
Módulos Conectados: gatein-server (app/api/mobile/submissions.py, app/models.py), gatein-app (src/screens/Submissions/)


1. Visão Geral e Arquitetura do Módulo

O módulo de Envios Mobile permite que motoristas autenticados transmitam dados estruturados (formulários dinâmicos) e arquivos binários (imagens e PDFs) para empresas (Terminais ou Transportadoras).

Para evitar gargalos de I/O no servidor principal da API, o upload de anexos utiliza a arquitetura de Presigned URLs com upload direto do cliente para o Cloudflare R2 (armazenamento compatível com S3). O servidor FastAPI apenas autoriza a assinatura presigned e recebe as URLs finais no banco de dados.

1.1 Diagrama de Sequência — Upload Presigned R2 e Criação do Envio

sequenceDiagram
autonumber
actor M as App Mobile (Motorista)
participant S as Gatein Server (FastAPI)
participant R2 as Cloudflare R2 Storage
participant DB as PostgreSQL

M->>S: GET /api/mobile/submissions/types/{company_id}
S->>DB: Query SubmissionType (company_id, is_active=True)
S-->>M: Retorna tipos configurados + tipo default fallback

opt Envio contém anexo (Foto/PDF)
M->>S: GET /api/mobile/submissions/presign-attachment?content_type=image/jpeg
S->>S: Gera presigned PUT URL no R2 (TTL 3600s, bucket submissions/)
S-->>M: Retorna upload_url e public_url
M->>R2: HTTP PUT <upload_url> (Payload Binário do Arquivo)
R2-->>M: HTTP 200 OK
end

M->>S: POST /api/mobile/submissions (company_id, submission_type_id, field_data, attachments)
S->>S: Decodifica Sqids de IDs e valida regras (campos e anexos obrigatórios)
S->>DB: Insert Submission (status='SENT', user_tax_id=current_user.tax_id)
S-->>M: Retorna HTTP 200 { success: true, data: { id, status } }

2. Ciclo de Vida do Envio e Gerenciamento Delta de Anexos

Os envios possuem três estados possíveis na coluna status:

  • SENT: Envio criado originalmente.
  • EDITED: Envio atualizado pelo motorista (caso o SubmissionType.allow_edit seja True).
  • CANCELLED: Envio cancelado pelo motorista (marca is_active = False).

2.1 Diagrama de Limpeza Delta em Atualização/Cancelamento

flowchart TD
A[Motorista Solicita Edição ou Cancelamento] --> B{Ação?}

B -- PUT /submissions/:id --> C[Compara URLs de Anexos Antigos vs Novos]
C --> D[Identifica URLs Removidas]
D --> E[Executa delete_r2_image via boto3 para cada URL removida]
E --> F[Atualiza field_data e attachments no PostgreSQL]
F --> G[Define status = 'EDITED' e edited_at = now]

B -- PATCH /submissions/:id/cancel --> H[Obtém todos os anexos do envio]
H --> I[Executa delete_r2_image via boto3 para cada anexo]
I --> J[Define status = 'CANCELLED' e is_active = False]

3. Schemas de Dados e Endpoints da API Mobile

3.1 Endpoints Mobile (/api/mobile/submissions)

MétodoEndpointAutenticaçãoDescrição / Objetivo
GET/submissions/presign-attachmentBearer JWT (Driver)Gera URL pré-assinada para upload direto de anexo no Cloudflare R2
GET/submissionsBearer JWT (Driver)Lista o histórico de envios do motorista logado (user_tax_id)
GET/submissions/types/{company_id}Bearer JWT (Driver)Obtém os tipos de envio configurados para a empresa selecionada
POST/submissionsBearer JWT (Driver)Cria um novo envio de formulário/anexos
PUT/submissions/{submission_id}Bearer JWT (Driver)Edita um envio existente (se permitido pelo tipo)
PATCH/submissions/{submission_id}/cancelBearer JWT (Driver)Cancela o envio e exclui os anexos do R2

3.2 Payload de Criação (SubmissionCreateSchema)

{
"company_id": "p4k2n8m9",
"submission_type_id": "w8x9k2m1",
"type_title": "Comprovante de Carga",
"field_data": {
"numero_dacte": "123456789",
"observacoes": "Carga entregue sem avarias na doca 3"
},
"attachments": [
{
"url": "https://pub-r2.gatein.app/submissions/a1b2c3d4.jpg",
"type": "image",
"name": "foto_doca.jpg"
},
{
"url": "https://pub-r2.gatein.app/submissions/e5f6g7h8.pdf",
"type": "pdf",
"name": "dacte_assinado.pdf"
}
]
}

4. Regras de Negócio e Validações Nativas (RN-SUB-MOB)

  • RN-SUB-MOB-001 (Formatos de Anexo Autorizados): Somente image/* (JPEG, PNG, WEBP) e application/pdf são permitidos no endpoint de presign.
  • RN-SUB-MOB-002 (Validação de Campos Obrigatórios): Se um SubmissionType possuir campos com "required": true, o servidor valida a presença de valores não vazios no dicionário field_data.
  • RN-SUB-MOB-003 (Exigência de Anexo): Se SubmissionType.attachment_required for true, a lista attachments deve conter ao menos 1 item.
  • RN-SUB-MOB-004 (Opcionalidade em Tipo Default): Quando a empresa não possui tipos personalizados configurados, a API fornece o tipo Outros envios (ref: default), onde anexos e campos são opcionais.
  • RN-SUB-MOB-005 (Sqid Identification): Todos os IDs de Submission e SubmissionType trafegados para o aplicativo móvel usam codificação Sqids para ocultar os IDs sequenciais de banco de dados.