Appearance
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/MMaté o último dia do mês).periodClosingDay: 25, referência10/09/2026→ janela25/08/2026a24/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
| Campo | Tipo | Descrição |
|---|---|---|
timesheetUserId | Number | Profissional do período. |
startsOn / endsOn | Date | Janela de apuração (YYYY-MM-DD). |
status | String | open, submitted, approved, rejected ou closed. |
expectedMinutes | Number | Total esperado na janela. |
workedMinutes | Number | Total trabalhado na janela. |
breakMinutes | Number | Total de intervalos. |
overtimeMinutes | Number | Horas extras (soma dos saldos positivos por dia). |
deficitMinutes | Number | Horas devidas (soma dos saldos negativos por dia). |
absenceMinutes | Number | Minutos esperados cobertos por ausências aprovadas. |
totalCost | Number | Custo total dos apontamentos da janela. |
totalBillable | Number | Total faturável da janela. |
currency | String | Moeda (da instância). |
submittedAt / approvedAt / closedAt | DateTime | Marcos do fluxo. |
approvedByTimesheetUserId | Number | Gestor 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 paraopenerejected.approve/reject/close: somente gestores.closetrava 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/closeGET /me/periods: os períodos do próprio profissional (filtrosstatus,startsOn/endsOn).GET /periods: todos os períodos da instância (somente gestor), com filtro adicionaltimesheetUserId.GET /periods/:id: retorna o período com o profissional (timesheetUser) e o aprovador (approvedBy) embutidos. Profissionais só enxergam os próprios períodos (404para 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/generatePayload (Body)
| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timesheetUserId | number | Sim | Profissional existente na instância. |
referenceDate | date | Sim | Qualquer 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| Flag | Padrão | Descrição |
|---|---|---|
--days | 7 | Dias 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.