Skip to content

Provider API - Especificacao para Backend

Contexto

O modulo provider foi refatorado de uma navegacao com sidebar para uma pagina unica com abas. O provider agora tem uma pagina principal (/my-contract) com 5 abas:

  1. Contrato - Detalhe do contrato ativo
  2. Registro de Horas - Lancamento e historico de horas
  3. Compliance - Envio mensal de documentos obrigatorios
  4. Documentos - Documentos do contrato
  5. Historico - Contratos inativos/encerrados com visualizacao de PDF

Endpoints Novos

GET /provider/active-contract/summary

Retorna informacoes publicas do borrower e status do contrato ativo para o header da pagina do provider. Este endpoint deve ser leve (sem documentos, sem detalhes completos do contrato).

Auth: Bearer token, role provider

Response 200:

json
{
  "contractId": "uuid-do-contrato-ativo",
  "contractStatus": "signed",
  "borrowerName": "TechCorp Solutions Ltda",
  "fantasyName": "TechCorp",
  "avatar": "https://storage.example.com/logos/techcorp.png",
  "email": "[email protected]",
  "phone": "(11) 3456-7890",
  "cnpj": "12345678000190"
}

Campos:

CampoTipoObrigatorioDescricao
contractIdstring (UUID)SimID do contrato ativo
contractStatusContractStatusSimStatus do contrato (draft, signed, completed, cancelled)
borrowerNamestringSimRazao social do borrower
fantasyNamestringNaoNome fantasia do borrower
avatarstring (URL)NaoURL do logo/avatar da empresa borrower
emailstringNaoE-mail de contato do borrower
phonestringNaoTelefone de contato do borrower
cnpjstringSimCNPJ do borrower (apenas numeros, sem formatacao)

Response 404: Provider nao possui contrato ativo

Notas:

  • Os dados do borrower vem da empresa contratante (borrower company)
  • avatar pode ser null se a empresa nao tem logo cadastrado
  • fantasyName pode ser null
  • O frontend formata o CNPJ com mascara (XX.XXX.XXX/XXXX-XX)

GET /contracts/:id/documents

Retorna a lista de documentos associados a um contrato especifico.

Auth: Bearer token, role provider

Path Params:

ParamTipoDescricao
idstring (UUID)ID do contrato

Response 200:

json
{
  "data": [
    {
      "id": "uuid-do-documento",
      "name": "Contrato de Prestacao de Servicos",
      "fileName": "contrato_prestacao_servicos.pdf",
      "fileUrl": "https://storage.example.com/documents/contrato.pdf",
      "fileSize": 245760,
      "status": "approved",
      "uploadedAt": "2025-09-01T00:00:00.000Z"
    }
  ]
}

Campos de cada documento:

CampoTipoDescricao
idstring (UUID)ID do documento
namestringNome descritivo do documento
fileNamestringNome do arquivo
fileUrlstring (URL)URL para download do arquivo
fileSizenumberTamanho do arquivo em bytes
status"pending" | "approved" | "rejected"Status de revisao
uploadedAtstring (ISO 8601)Data de upload

Response 404: Contrato nao encontrado


Endpoints Existentes (Referencia)

Estes endpoints ja existem e continuam sendo usados nas abas do provider.

Aba: Contrato

MetodoEndpointDescricao
GET/contracts/:id/provider/detailDetalhe completo do contrato com documentos

Response: ProviderContractDetail (ProviderContract + documents[])


Aba: Registro de Horas

MetodoEndpointDescricao
GET/hoursLista resumos mensais de horas (paginado, filtros: year, search)
GET/hours/currentResumo do mes atual
GET/hours/:idDetalhe de um periodo especifico
POST/monitoring/entriesCria lancamento de horas (com geolocalizacao obrigatoria do mobile)
POST/monitoring/retroactive-requestsCria solicitacao retroativa (com geolocalizacao obrigatoria do mobile)

Payload de POST /monitoring/entries (mobile):

json
{
  "providerId": "uuid-do-provider",
  "date": "2026-05-02",
  "reason": "opcional",
  "tasks": [
    { "description": "Tarefa A", "durationMinutes": 60 }
  ],
  "capturedAt": "2026-05-02T13:42:00.000Z",
  "latitude": -23.5505,
  "longitude": -46.6333,
  "locationAccuracy": 12.5
}

Campos obrigatorios de geolocalizacao (mobile):

CampoTipoObrigatorioDescricao
capturedAtstring (ISO 8601 UTC)Sim (mobile)Instante da captura no dispositivo
latitudenumberSim (mobile)Latitude no momento do submit
longitudenumberSim (mobile)Longitude no momento do submit
locationAccuracynumberNaoPrecisao em metros (quando disponivel)

Status backend: implementacao pendente. O frontend RN ja envia esses campos; o backend deve validar e persistir as colunas correspondentes em WorkEntry (e em RetroactiveHourRequest para a rota de retroativos).

Query Params de /hours:

ParamTipoDescricao
yearnumberFiltrar por ano
searchstringBusca textual

Aba: Compliance

Os compliances do prestador sao derivados dos fluxos de compliance anexados pelo tomador. Cada compliance representa a execucao de um fluxo para um periodo (mes/ano), com rastreamento por step.

IMPORTANTE: Os endpoints do prestador usam o prefixo /provider-compliances (diferente de /compliances que e a API do tomador com visao de todos os providers). O /provider-compliances retorna apenas os compliances do prestador autenticado, com steps detalhados.

COMPORTAMENTO DO FRONTEND: A tela do prestador exibe o step ativo (determinado pelo schedule dayStart/dayEnd vs dia atual) e seus sub-itens na tabela abaixo do card de resumo. Para steps do tipo documents, a tabela mostra os requiredDocuments com status de upload cruzando com documents[] via documentRequirementId. Para steps do tipo platformData, a tabela mostra os platformDataTypes. Por isso, e essencial que:

  • requiredDocuments esteja sempre populado em cada step (define o que o prestador precisa enviar)
  • documents[] inclua documentRequirementId para cruzamento com requiredDocuments
  • isSubmissionOpen seja calculado pelo backend baseado no schedule e status do step
MetodoEndpointDescricao
GET/provider-compliancesLista compliances do prestador (filtros: year, month, status, search)
GET/provider-compliances/currentCompliances do mes atual (pode retornar multiplos, um por fluxo)
GET/provider-compliances/:idDetalhe de um compliance com steps
POST/provider-compliances/:complianceId/steps/:stepId/documentsUpload de documento para um step (multipart/form-data)
POST/provider-compliances/:complianceId/steps/:stepId/submitSubmeter um step para revisao

GET /provider-compliances

Lista os compliances do prestador autenticado. O backend deve filtrar automaticamente pelo provider do token JWT.

Auth: Bearer token, role provider

Query Params:

ParamTipoObrigatorioDescricao
yearnumberNaoFiltrar por ano
monthnumberNaoFiltrar por mes (1-12)
status"pending" | "sent" | "approved" | "rejected" | "all"NaoFiltrar por status
searchstringNaoBusca textual (por nome do fluxo)

Exemplo de request:

GET /provider-compliances?year=2026&month=3
Authorization: Bearer <token>
x-company-id: <company-uuid>

Response 200:

json
{
  "data": [
    {
      "id": "uuid-do-compliance",
      "providerId": "uuid-do-provider",
      "providerComplianceFlowId": "uuid-do-vinculo-provider-flow",
      "complianceFlowId": "uuid-do-fluxo-original",
      "complianceFlowName": "Documento de comprobidade",
      "month": 3,
      "year": 2026,
      "status": "pending",
      "steps": [
        {
          "id": "uuid-do-step-compliance",
          "complianceStepId": "uuid-do-step-original",
          "title": "Certificados de regularidade",
          "order": 1,
          "stepType": "documents",
          "status": "submitted",
          "schedule": {
            "frequency": "monthly",
            "dayStart": 20,
            "dayEnd": 25
          },
          "documents": [
            {
              "id": "uuid-doc-1",
              "stepComplianceId": "uuid-do-step-compliance",
              "documentRequirementId": "uuid-req-estadual",
              "documentRequirementName": "Certificado de regularidade estadual",
              "fileName": "cert_estadual_marco_2026.pdf",
              "fileUrl": "https://storage.example.com/compliance/cert_estadual.pdf",
              "status": "pending",
              "sentAt": "2026-03-05T10:00:00.000Z",
              "reviewedAt": null
            }
          ],
          "requiredDocuments": [
            {
              "id": "uuid-req-estadual",
              "name": "Certificado de regularidade estadual",
              "required": true,
              "formats": [".pdf"]
            },
            {
              "id": "uuid-req-federal",
              "name": "Certificado de regularidade federal",
              "required": true,
              "formats": [".pdf"]
            },
            {
              "id": "uuid-req-municipal",
              "name": "Certificado de regularidade municipal",
              "required": true,
              "formats": [".pdf"]
            },
            {
              "id": "uuid-req-fgts",
              "name": "Certificado de regularidade FGTS",
              "required": true,
              "formats": [".pdf"]
            }
          ],
          "platformDataTypes": [],
          "validators": [
            {
              "id": "uuid-do-validator",
              "userId": "uuid-do-user",
              "name": "Ana Silva",
              "avatar": null
            }
          ],
          "dependsOnPrevious": false,
          "submissionDeadline": "2026-03-21T00:00:00.000Z",
          "isSubmissionOpen": false,
          "submittedAt": "2026-03-05T10:00:00.000Z",
          "reviewedAt": null
        },
        {
          "id": "uuid-step-2",
          "complianceStepId": "uuid-step-original-2",
          "title": "Envio de nota e boleto",
          "order": 2,
          "stepType": "documents",
          "status": "pending",
          "schedule": {
            "frequency": "monthly",
            "dayStart": 20,
            "dayEnd": 25
          },
          "documents": [],
          "requiredDocuments": [
            {
              "id": "uuid-req-nota",
              "name": "Nota fiscal",
              "required": true,
              "formats": [".pdf"]
            },
            {
              "id": "uuid-req-boleto",
              "name": "Boleto de pagamento",
              "required": true,
              "formats": [".pdf"]
            }
          ],
          "platformDataTypes": [],
          "validators": [
            {
              "id": "uuid-do-validator",
              "userId": "uuid-do-user",
              "name": "Ana Silva",
              "avatar": null
            }
          ],
          "dependsOnPrevious": true,
          "submissionDeadline": "2026-03-21T00:00:00.000Z",
          "isSubmissionOpen": false,
          "submittedAt": null,
          "reviewedAt": null
        }
      ],
      "submittedAt": null,
      "reviewedAt": null
    }
  ],
  "total": 1
}

Diferenca entre /provider-compliances e /compliances (tomador):

Aspecto/provider-compliances (prestador)/compliances (tomador)
Auth roleproviderborrower
EscopoApenas compliances do provider logadoCompliances de TODOS os providers
DadosCompleto (steps, documents, validators)Resumido (id, providerId, providerName, month, year, status)
Filtrosyear, month, status, searchyear, month, status, search
UsoTela do prestador (/contract-provider/compliance)Tela do tomador (gestao de providers)

GET /provider-compliances/current

Retorna os compliances do mes/ano atual. Atalho para GET /provider-compliances?year=<atual>&month=<atual>.

Auth: Bearer token, role provider

Response 200: Mesmo formato de GET /provider-compliances


GET /provider-compliances/:id

Retorna detalhes completos de um compliance especifico.

Auth: Bearer token, role provider

Path Params:

ParamTipoDescricao
idstring (UUID)ID do compliance

Response 200:

json
{
  "data": ProviderCompliance
}

Response 404: Compliance nao encontrado ou nao pertence ao provider autenticado


POST /provider-compliances/:complianceId/steps/:stepId/documents

Upload de documento para um step de compliance.

Auth: Bearer token, role provider

Path Params:

ParamTipoDescricao
complianceIdstring (UUID)ID do compliance
stepIdstring (UUID)ID do step compliance

Body:

Content-Type: multipart/form-data

documentRequirementId: string (UUID)    // ID do requisito de documento no fluxo
file: File

Response 201:

json
{
  "data": {
    "id": "doc-uuid",
    "stepComplianceId": "step-comp-uuid",
    "documentRequirementId": "req-uuid",
    "documentRequirementName": "Nota Fiscal",
    "fileName": "nf_fevereiro_2026.pdf",
    "fileUrl": "https://storage.example.com/compliance/nf.pdf",
    "status": "pending",
    "sentAt": "2026-02-08T10:00:00.000Z",
    "reviewedAt": null
  }
}

Regras de upload:

  • O step deve ter status pending ou in_progress (nao aceita upload em steps blocked, submitted, approved)
  • O documentRequirementId deve corresponder a um documento requerido do step
  • Ao fazer o primeiro upload, o status do step muda de pending para in_progress
  • Formatos aceitos sao validados conforme formats do ComplianceDocumentRequirement

POST /provider-compliances/:complianceId/steps/:stepId/submit

Submete um step para revisao do tomador.

Auth: Bearer token, role provider

Path Params:

ParamTipoDescricao
complianceIdstring (UUID)ID do compliance
stepIdstring (UUID)ID do step compliance

Body:

json
{}

Response 200:

json
{
  "data": StepCompliance
}

Regras de submissao:

  • Todos os documentos required: true do step devem ter sido enviados
  • O status do step muda para submitted
  • Se todos os steps do compliance estiverem submitted ou approved, o status geral muda para sent

Aba: Historico

MetodoEndpointDescricao
GET/contractsLista todos os contratos do provider

O frontend filtra localmente os contratos com isActive === false para mostrar apenas os inativos/encerrados. O campo signedDocument do contrato e usado para mostrar o PDF assinado em um modal.


Outros

MetodoEndpointDescricao
GET/summaryDashboard summary do provider

Tipos TypeScript (Referencia)

typescript
type ContractStatus = 'draft' | 'signed' | 'completed' | 'cancelled'

type BorrowerSummary = {
  contractId: string
  contractStatus: ContractStatus
  borrowerName: string
  fantasyName?: string
  avatar?: string
  email?: string
  phone?: string
  cnpj: string
}

type ProviderDetailDocument = {
  id: string
  name: string
  fileName: string
  fileUrl: string
  fileSize: number
  status: 'pending' | 'approved' | 'rejected'
  uploadedAt: Date
}

type ProviderContract = Contract & {
  isActive: boolean
  borrowerName: string
  borrowerCnpj: string
  monthlyHours?: number
  hourlyRate?: number
}

type ProviderContractDetail = ProviderContract & {
  documents: ProviderDetailDocument[]
}

// Tipos de Compliance: mesmos tipos usados em team-api.md

type ComplianceStatus = 'pending' | 'sent' | 'approved' | 'rejected'

type StepComplianceStatus =
  | 'pending'
  | 'in_progress'
  | 'submitted'
  | 'approved'
  | 'rejected'
  | 'blocked'

type StepComplianceDocumentStatus = 'pending' | 'approved' | 'rejected'

type ProviderCompliance = {
  id: string
  providerId: string
  providerComplianceFlowId: string
  complianceFlowId: string
  complianceFlowName: string
  month: number
  year: number
  status: ComplianceStatus
  steps: StepCompliance[]
  submittedAt: Date | null
  reviewedAt: Date | null
}

type StepCompliance = {
  id: string
  complianceStepId: string
  title: string
  order: number
  stepType: 'documents' | 'platformData'
  status: StepComplianceStatus
  schedule: StepSchedule
  documents: StepComplianceDocument[]
  requiredDocuments: ComplianceDocumentRequirement[]
  platformDataTypes: ('hours' | 'activeContracts')[]
  validators: ComplianceValidator[]
  dependsOnPrevious: boolean
  submissionDeadline: Date
  isSubmissionOpen: boolean
  submittedAt: Date | null
  reviewedAt: Date | null
}

type StepComplianceDocument = {
  id: string
  stepComplianceId: string
  documentRequirementId: string
  documentRequirementName: string
  fileName: string
  fileUrl: string
  status: StepComplianceDocumentStatus
  sentAt: Date
  reviewedAt: Date | null
}