NFS-e/Repasse: Solicitação de Nota

Endpoints da WebApiAlcance para o domínio solicitacao_nota do módulo NFS-e/Repasse médico. Cobrem a solicitação de emissão de nota pelo tomador/cliente, os médicos vinculados a cada solicitação, as regras de nota programada (emissão recorrente) e os médicos vinculados a essas regras.

O router expõe dois recursos de topo, ambos sob o mesmo base path:

  • Solicitações de nota - / + /{solicitacao_id}, com o sub-recurso aninhado /{solicitacao_id}/medicos.
  • Regras de nota programada - /regras-programadas + /regras-programadas/{regra_id}, com o sub-recurso aninhado /regras-programadas/{regra_id}/medicos.

Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.

Escopo compartilhado nfse-repasse

O primeiro segmento do path - nfse-repasse - é compartilhado por todos os recursos do módulo (solicitações, regras programadas, tomadores, prestadores, documentos de entrada etc.). Por isso o escopo também é compartilhado: uma API Key com nfse_repasse:read / nfse_repasse:write habilita todo o módulo NFS-e/Repasse, não apenas este domínio. Emita a chave com o escopo mínimo e trate nfse_repasse:write como uma permissão ampla.

Base path

/api/v1/nfse-repasse/solicitacoes

Escopos necessários

  • nfse_repasse:read - listagens, buscas e detalhamento (todos os GET).
  • nfse_repasse:write - criação, atualização, remoção e vínculo de médicos (todos os POST, PUT, DELETE).

As operações de escrita (POST / PUT / DELETE) também exigem, na WebApi, o perfil administrador (require_perfil("administrador")). A leitura (GET) está liberada para qualquer usuário autenticado do staff. Ambos os segmentos de escopo (read / write) partilham o prefixo nfse-repasse - ver Callout acima.

Endpoints

POST /nfse-repasse/solicitacoes/

Cria uma nova solicitação de nota. O id_usuario_created não entra no corpo - é forçado pelo service a partir do usuário autenticado.

Parâmetros

Este endpoint não recebe parâmetros de rota ou query - os dados vão no corpo da requisição (SolicitacaoNotaCreate, ver Schema SolicitacaoNota). Mínimo: id_prestador e origem.

Request

{
  "id_prestador": 1,
  "id_tomador": 1,
  "origem": "manual",
  "competencia_referencia": "2026-03",
  "valor_total": "5000.00",
  "descricao_sugerida": "Serviços médicos prestados em março/2026.",
  "status": "pendente_validacao"
}

Response 201 Created

{
  "success": true,
  "message": "Solicitação criada com sucesso!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "origem": "manual",
    "competencia_referencia": "2026-03",
    "valor_total": "5000.00",
    "status": "pendente_validacao",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:write

GET /nfse-repasse/solicitacoes/

Lista solicitações de nota com filtros opcionais e paginação.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
statusstrquerynãoFiltro por status (ex.: pendente_validacao)
id_prestadorintquerynãoFiltro por prestador (prestador_medico.id)
id_tomadorintquerynãoFiltro por tomador (tomador.id)
pageint >= 1querynãoPágina (1-based)
per_pageint 1..500querynãoItens por página

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Solicitações recuperadas com sucesso!",
  "data": [
    {
      "id": 1,
      "id_prestador": 1,
      "id_tomador": 1,
      "origem": "manual",
      "status": "pendente_validacao",
      "valor_total": "5000.00"
    }
  ]
}

Escopo: nfse_repasse:read

POST /nfse-repasse/solicitacoes/regras-programadas

Cria uma regra de nota programada (emissão recorrente). O id_usuario_created é forçado pelo service a partir do usuário autenticado.

Parâmetros

Este endpoint não recebe parâmetros de rota ou query - os dados vão no corpo da requisição (RegraNotaProgramadaCreate, ver Schema RegraNotaProgramada). Mínimo: id_prestador.

Request

{
  "id_prestador": 1,
  "id_tomador": 1,
  "descricao_fixa": "Serviços médicos mensais.",
  "valor_total": "5000.00",
  "data_base_emissao": "2026-03-01",
  "periodicidade": "mensal",
  "status": "ativo"
}

Response 201 Created

{
  "success": true,
  "message": "Regra programada criada com sucesso!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "periodicidade": "mensal",
    "valor_total": "5000.00",
    "status": "ativo",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:write

GET /nfse-repasse/solicitacoes/regras-programadas

Lista regras de nota programada com filtros opcionais e paginação.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
statusstrquerynãoFiltro por status (ativo | inativo)
id_prestadorintquerynãoFiltro por prestador (prestador_medico.id)
id_tomadorintquerynãoFiltro por tomador (tomador.id)
pageint >= 1querynãoPágina (1-based)
per_pageint 1..500querynãoItens por página

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Regras programadas recuperadas com sucesso!",
  "data": [
    {
      "id": 1,
      "id_prestador": 1,
      "id_tomador": 1,
      "periodicidade": "mensal",
      "status": "ativo",
      "valor_total": "5000.00"
    }
  ]
}

Escopo: nfse_repasse:read

GET /nfse-repasse/solicitacoes/regras-programadas/{regra_id}/medicos

Lista os médicos vinculados a uma regra programada.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Médicos recuperados com sucesso!",
  "data": [
    {
      "id": 1,
      "id_regra_nota_programada": 1,
      "id_medico": 1,
      "valor_medico": "1500.00"
    }
  ]
}

Escopo: nfse_repasse:read

POST /nfse-repasse/solicitacoes/regras-programadas/{regra_id}/medicos

Vincula um médico a uma regra programada. O id_regra_nota_programada vem da rota; o id_usuario_created é forçado pelo service.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada

O corpo segue RegraNotaProgramadaMedicoCreate (ver Schema RegraNotaProgramadaMedico). Mínimo: id_medico.

Request

{
  "id_medico": 1,
  "valor_medico": "1500.00"
}

Response 201 Created

{
  "success": true,
  "message": "Médico vinculado com sucesso!",
  "data": {
    "id": 1,
    "id_regra_nota_programada": 1,
    "id_medico": 1,
    "valor_medico": "1500.00",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:write

PUT /nfse-repasse/solicitacoes/regras-programadas/{regra_id}/medicos/{medico_vinculo_id}

Atualiza um médico vinculado a uma regra programada. Body parcial - só o que vier preenchido é alterado.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada
medico_vinculo_idintpathsimID interno do vínculo médico

O corpo segue RegraNotaProgramadaMedicoUpdate - campos opcionais: id_medico, valor_medico.

Request

{
  "valor_medico": "1800.00"
}

Response 200 OK

{
  "success": true,
  "message": "Médico atualizado!",
  "data": {
    "id": 1,
    "id_regra_nota_programada": 1,
    "id_medico": 1,
    "valor_medico": "1800.00",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T13:20:00Z"
  }
}

Escopo: nfse_repasse:write

DELETE /nfse-repasse/solicitacoes/regras-programadas/{regra_id}/medicos/{medico_vinculo_id}

Remove o vínculo de um médico com uma regra programada.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada
medico_vinculo_idintpathsimID interno do vínculo médico

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Médico removido!",
  "data": null
}

Escopo: nfse_repasse:write

GET /nfse-repasse/solicitacoes/regras-programadas/{regra_id}

Busca uma regra programada pelo ID.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Regra programada encontrada!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "periodicidade": "mensal",
    "valor_total": "5000.00",
    "status": "ativo",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:read

PUT /nfse-repasse/solicitacoes/regras-programadas/{regra_id}

Atualiza uma regra programada pelo ID. Body parcial (RegraNotaProgramadaUpdate) - só o que vier preenchido é alterado.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada

Request

{
  "valor_total": "5500.00",
  "status": "inativo"
}

Response 200 OK

{
  "success": true,
  "message": "Regra programada atualizada!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "periodicidade": "mensal",
    "valor_total": "5500.00",
    "status": "inativo",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T13:20:00Z"
  }
}

Escopo: nfse_repasse:write

DELETE /nfse-repasse/solicitacoes/regras-programadas/{regra_id}

Deleta uma regra programada pelo ID.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
regra_idintpathsimID da regra programada

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Regra programada removida!",
  "data": null
}

Escopo: nfse_repasse:write

GET /nfse-repasse/solicitacoes/{solicitacao_id}/medicos

Lista os médicos vinculados a uma solicitação de nota.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Médicos recuperados com sucesso!",
  "data": [
    {
      "id": 1,
      "id_solicitacao_nota": 1,
      "id_medico": 1,
      "valor_medico": "1500.00"
    }
  ]
}

Escopo: nfse_repasse:read

POST /nfse-repasse/solicitacoes/{solicitacao_id}/medicos

Vincula um médico a uma solicitação. O id_solicitacao_nota vem da rota; o id_usuario_created é forçado pelo service.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação

O corpo segue SolicitacaoNotaMedicoCreate (ver Schema SolicitacaoNotaMedico). Mínimo: id_medico.

Request

{
  "id_medico": 1,
  "valor_medico": "1500.00"
}

Response 201 Created

{
  "success": true,
  "message": "Médico vinculado com sucesso!",
  "data": {
    "id": 1,
    "id_solicitacao_nota": 1,
    "id_medico": 1,
    "valor_medico": "1500.00",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:write

PUT /nfse-repasse/solicitacoes/{solicitacao_id}/medicos/{medico_vinculo_id}

Atualiza um médico vinculado a uma solicitação. Body parcial - só o que vier preenchido é alterado.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação
medico_vinculo_idintpathsimID interno do vínculo médico

O corpo segue SolicitacaoNotaMedicoUpdate - campos opcionais: id_medico, valor_medico.

Request

{
  "valor_medico": "1800.00"
}

Response 200 OK

{
  "success": true,
  "message": "Médico atualizado!",
  "data": {
    "id": 1,
    "id_solicitacao_nota": 1,
    "id_medico": 1,
    "valor_medico": "1800.00",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T13:20:00Z"
  }
}

Escopo: nfse_repasse:write

DELETE /nfse-repasse/solicitacoes/{solicitacao_id}/medicos/{medico_vinculo_id}

Remove o vínculo de um médico com uma solicitação.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação
medico_vinculo_idintpathsimID interno do vínculo médico

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Médico removido!",
  "data": null
}

Escopo: nfse_repasse:write

GET /nfse-repasse/solicitacoes/{solicitacao_id}

Busca uma solicitação de nota pelo ID.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Solicitação encontrada!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "origem": "manual",
    "competencia_referencia": "2026-03",
    "valor_total": "5000.00",
    "status": "pendente_validacao",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T12:00:00Z"
  }
}

Escopo: nfse_repasse:read

PUT /nfse-repasse/solicitacoes/{solicitacao_id}

Atualiza uma solicitação pelo ID. Body parcial (SolicitacaoNotaUpdate) - só o que vier preenchido é alterado.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação

Request

{
  "status": "validada",
  "valor_total": "5200.00"
}

Response 200 OK

{
  "success": true,
  "message": "Solicitação atualizada!",
  "data": {
    "id": 1,
    "id_prestador": 1,
    "id_tomador": 1,
    "origem": "manual",
    "competencia_referencia": "2026-03",
    "valor_total": "5200.00",
    "status": "validada",
    "id_usuario_created": 42,
    "created_at": "2026-07-03T12:00:00Z",
    "updated_at": "2026-07-03T13:20:00Z"
  }
}

Escopo: nfse_repasse:write

DELETE /nfse-repasse/solicitacoes/{solicitacao_id}

Deleta uma solicitação pelo ID.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
solicitacao_idintpathsimID da solicitação

Request

Sem corpo de requisição.

Response 200 OK

{
  "success": true,
  "message": "Solicitação removida!",
  "data": null
}

Escopo: nfse_repasse:write

Schemas

Schema SolicitacaoNota

Campos do recurso principal (SolicitacaoNotaCreate / SolicitacaoNotaRead):

  • id_prestador: int - obrigatório. ID do prestador (prestador_medico.id).
  • id_tomador: int | null - ID do tomador (tomador.id).
  • id_documento_entrada: int | null - ID do documento de entrada (documento_entrada.id).
  • origem: str - obrigatório. Um de: email_pdf, relatorio_pdf, programada, manual. (máx. 20 chars)
  • competencia_referencia: str | null - competência (texto livre, ex.: 2026-03). (máx. 50 chars)
  • valor_total: Decimal - valor total da solicitação (default 0).
  • descricao_sugerida: str | null - descrição sugerida para a nota.
  • status: str - default pendente_validacao. Um de: pendente_validacao, validada, rejeitada, pronta_para_emissao. (máx. 30 chars)
  • id_validado_por: int | null - ID do usuário que validou (user.id).
  • validado_at: datetime | null - timestamp da validação.
  • uuid_legado: str | null - só no Create. UUID do registro original no Supabase (rastreabilidade da migração); imutável depois. (máx. 36 chars)

Campos gerenciados (apenas leitura, em SolicitacaoNotaRead): id, id_usuario_created, created_at, updated_at.

No SolicitacaoNotaUpdate todos os campos acima (exceto uuid_legado, id, id_usuario_created, created_at, updated_at, que são imutáveis) são opcionais.

Schema SolicitacaoNotaMedico

Sub-recurso - médico vinculado a uma solicitação (SolicitacaoNotaMedicoCreate / SolicitacaoNotaMedicoRead):

  • id_medico: int - obrigatório. ID do médico (medico.id).
  • valor_medico: Decimal - valor atribuído ao médico (default 0).
  • uuid_legado: str | null - só no Create. UUID de migração (máx. 36 chars).

Campos gerenciados (leitura): id, id_solicitacao_nota, id_usuario_created, created_at, updated_at.

No SolicitacaoNotaMedicoUpdate: id_medico e valor_medico são opcionais.

Schema RegraNotaProgramada

Regra de emissão recorrente (RegraNotaProgramadaCreate / RegraNotaProgramadaRead):

  • id_prestador: int - obrigatório. ID do prestador (prestador_medico.id).
  • id_tomador: int | null - ID do tomador (tomador.id).
  • id_modelo_descricao: int | null - ID do modelo de descrição (modelo_descricao_nota.id).
  • descricao_fixa: str | null - descrição fixa aplicada às notas geradas.
  • valor_total: Decimal - valor total da regra (default 0).
  • data_base_emissao: date | null - data-base para a emissão programada (ex.: 2026-03-01).
  • periodicidade: str - default mensal. Um de: unica, mensal. (máx. 20 chars)
  • status: str - default ativo. Um de: ativo, inativo. (máx. 20 chars)
  • uuid_legado: str | null - só no Create. UUID de migração (máx. 36 chars).

Campos gerenciados (leitura): id, id_usuario_created, created_at, updated_at.

No RegraNotaProgramadaUpdate todos os campos (exceto os imutáveis) são opcionais.

Schema RegraNotaProgramadaMedico

Sub-recurso - médico vinculado a uma regra (RegraNotaProgramadaMedicoCreate / RegraNotaProgramadaMedicoRead):

  • id_medico: int - obrigatório. ID do médico (medico.id).
  • valor_medico: Decimal - valor atribuído ao médico (default 0).
  • uuid_legado: str | null - só no Create. UUID de migração (máx. 36 chars).

Campos gerenciados (leitura): id, id_regra_nota_programada, id_usuario_created, created_at, updated_at.

No RegraNotaProgramadaMedicoUpdate: id_medico e valor_medico são opcionais.

Notas

Valores validados (enums)

Campos com CHECK no Postgres são validados na entrada e retornam 422 quando fora do domínio:

  • origem: email_pdf, relatorio_pdf, programada, manual.
  • status (solicitação): pendente_validacao, validada, rejeitada, pronta_para_emissao.
  • periodicidade (regra): unica, mensal.
  • status (regra): ativo, inativo.

Ordem de rotas no FastAPI

As rotas estáticas /regras-programadas/... são declaradas antes das dinâmicas /{solicitacao_id}, e os sub-recursos de médicos têm um segmento estático extra (/medicos) para não colidir com o parâmetro de ID. Chame os paths exatamente como documentado.

  • Toda resposta segue o envelope { success, message, data } (ou { success: false, message, details } em erro). Códigos: 201 na criação, 200 nas demais operações bem-sucedidas.
  • Erros do service mapeiam para HTTP: "não encontrado" → 404, "já existe" → 409, "acesso negado" → 403, demais validações → 422.
  • id_usuario_created nunca entra nos payloads de Create - é forçado pelo service a partir do usuário autenticado.
  • uuid_legado é metadado de migração (app fonte webapp-nfs-repasse-medico/Supabase): aceito no Create, imutável depois - não aparece em nenhum schema de Update.