Skip to content

Períodos & Fechamento ​

O período é a janela de apuração (normalmente mensal) por profissional, com os totais materializados e o status do fluxo até o fechamento. É a fonte da folha: depois de gerado, os totais não são recalculados a cada consulta — e depois de fechado, os apontamentos daquela janela ficam bloqueados.

Headers obrigatórios

Todas as requisições devem incluir X-Timesheet-Id e Authorization: Bearer {token}. Gerar, aprovar, rejeitar e fechar períodos exige gestor; o profissional consulta e envia os próprios períodos.


A Janela de Apuração ​

A janela é calculada a partir do periodClosingDay da instância (1 a 28) e de uma data de referência:

  • periodClosingDay: 1 → mês civil (01/MM até o último dia do mês).
  • periodClosingDay: 25, referência 10/09/2026 → janela 25/08/2026 a 24/09/2026. Se a referência já passou do dia de virada (ex.: 26/09), a janela começa no mês corrente.

Estrutura de Dados ​

CampoTipoDescrição
timesheetUserIdNumberProfissional do período.
startsOn / endsOnDateJanela de apuração (YYYY-MM-DD).
statusStringopen, submitted, approved, rejected ou closed.
expectedMinutesNumberTotal esperado na janela.
workedMinutesNumberTotal trabalhado na janela.
breakMinutesNumberTotal de intervalos.
overtimeMinutesNumberHoras extras (soma dos saldos positivos por dia).
deficitMinutesNumberHoras devidas (soma dos saldos negativos por dia).
absenceMinutesNumberMinutos esperados cobertos por ausências aprovadas.
totalCostNumberCusto total dos apontamentos da janela.
totalBillableNumberTotal faturável da janela.
currencyStringMoeda (da instância).
submittedAt / approvedAt / closedAtDateTimeMarcos do fluxo.
approvedByTimesheetUserIdNumberGestor que aprovou.

Fluxo do Período ​

open ──submit──> submitted ──approve──> approved ──close──> closed
  ^                  │
  └─────reject───────┘
  • submit: o próprio profissional (ou um gestor) envia o período — vale para open e rejected.
  • approve / reject / close: somente gestores.
  • close trava todos os dias da janela (status: locked), encerrando qualquer edição.
  • Transição fora da tabela falha com 422 INVALID_STAGE_MOVE.

Depois do fechamento, batidas, lançamentos e correções em datas da janela falham com 422 PERIOD_CLOSED — é a trava definitiva da folha.


Endpoints ​

http
GET   /v1/timesheet/me/periods
GET   /v1/timesheet/periods
POST  /v1/timesheet/periods/generate
GET   /v1/timesheet/periods/:id
PATCH /v1/timesheet/periods/:id/submit
PATCH /v1/timesheet/periods/:id/approve
PATCH /v1/timesheet/periods/:id/reject
PATCH /v1/timesheet/periods/:id/close
  • GET /me/periods: os períodos do próprio profissional (filtros status, startsOn/endsOn).
  • GET /periods: todos os períodos da instância (somente gestor), com filtro adicional timesheetUserId.
  • GET /periods/:id: retorna o período com o profissional (timesheetUser) e o aprovador (approvedBy) embutidos. Profissionais só enxergam os próprios períodos (404 para terceiros).

Exemplo de Resposta (show) ​

json
{
  "id": 1,
  "timesheetId": 4,
  "timesheetUserId": 6,
  "startsOn": "2026-07-01",
  "endsOn": "2026-07-31",
  "status": "open",
  "expectedMinutes": 0,
  "workedMinutes": 0,
  "breakMinutes": 0,
  "overtimeMinutes": 0,
  "deficitMinutes": 0,
  "absenceMinutes": 0,
  "totalCost": "0.00",
  "totalBillable": "0.00",
  "currency": "BRL",
  "submittedAt": null,
  "approvedByTimesheetUserId": null,
  "approvedAt": null,
  "closedAt": null,
  "createdAt": "2026-09-25T12:33:55.976-03:00",
  "updatedAt": "2026-09-25T12:33:55.976-03:00",
  "timesheetUser": {
    "id": 6,
    "firstName": "Ana",
    "lastName": "Souza",
    "email": "ana.souza@example.com"
  },
  "approvedBy": null
}

Campos decimais

totalCost e totalBillable são decimais serializados como string (ex.: "1840.00").

Gerar Período (gestor) ​

Materializa o período de um profissional para a janela calculada a partir da data de referência, somando os dias consolidados, as ausências aprovadas e os valores dos apontamentos. Já existe um período sobreposto para o profissional? 422 PERIOD_OVERLAP.

http
POST /v1/timesheet/periods/generate

Payload (Body) ​

AtributoTipoObrigatórioDescrição
timesheetUserIdnumberSimProfissional existente na instância.
referenceDatedateSimQualquer data dentro da janela desejada (YYYY-MM-DD).

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/timesheet/periods/generate" \
  -H "X-Timesheet-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "timesheetUserId": 2,
    "referenceDate": "2026-09-10"
  }'

Respostas ​

201 Created

Retorna o ID do período gerado (status open, totais já materializados): { "id": 1 }.

422 Unprocessable Entity

Já existe um período sobreposto para este profissional.

json
{
  "message": "Já existe um período sobreposto para este profissional",
  "code": "PERIOD_OVERLAP"
}

Transições ​

As rotas submit, approve, reject e close não recebem payload e respondem 204 No Content. Em close, todos os dias da janela que ainda não estão locked são travados na mesma operação.


Fechamento Automático (comando Ace) ​

O fechamento em massa não é um agendador interno: rode o comando timesheet:close-periods (idealmente em cron) para fechar períodos approved cuja data de fim já passou há mais de N dias.

bash
node ace timesheet:close-periods --days=7
FlagPadrãoDescrição
--days7Dias após o fim do período para considerá-lo pronto para fechamento.

Cada fechamento trava os dias da janela, como no PATCH /periods/:id/close manual.