Appearance
Kanban
O kanban do Timesheet é integrado ao restante do módulo: quadros podem estar ligados a um projeto, e cards podem apontar para uma tarefa apontável (timesheetTaskId). Quadros podem ser públicos (todo o time) ou privados (somente membros convidados).
Headers obrigatórios
Todas as requisições devem incluir X-Timesheet-Id e Authorization: Bearer {token}.
RBAC do Kanban
O kanban tem controle de acesso próprio, por quadro. Gestores (isManager) têm acesso irrestrito a todos os quadros. Para os demais:
| Papel no quadro | Permissões |
|---|---|
owner | Edita o quadro, gerencia membros, colunas, cards, etiquetas; arquiva e remove. |
editor | Cria e move cards, gerencia colunas e comentários; não gerencia membros nem o quadro. |
viewer | Somente leitura. |
| Não-membro | Quadros public: leitura. Quadros private: 403 NOT_BOARD_MEMBER (leitura) ou 404. |
Regras adicionais:
- Todo quadro precisa ter ao menos um
owner— rebaixar ou remover o último proprietário falha com422 LAST_OWNER. - Quem cria o quadro entra automaticamente como
owner(convite já aceito).
Quadros (Boards)
Estrutura de Dados
| Campo | Tipo | Descrição |
|---|---|---|
name | String | Nome (máx. 150 caracteres). |
slug | String | Slug gerado automaticamente (único por instância). |
description | String | Descrição (opcional). |
visibility | String | public ou private (padrão: public). |
color | String | Cor em hexadecimal (#RRGGBB, opcional). |
timesheetProjectId | Number | Projeto vinculado (opcional). |
position | Number | Ordenação do quadro na lista (decimal serializado como string, ex.: "1000.0000000000"). |
archivedAt | DateTime | Quando preenchido, o quadro está arquivado. |
Endpoints
http
GET /v1/timesheet/boards
POST /v1/timesheet/boards
GET /v1/timesheet/boards/:id
PUT /v1/timesheet/boards/:id
DELETE /v1/timesheet/boards/:id
POST /v1/timesheet/boards/:id/archive
POST /v1/timesheet/boards/:id/unarchiveGET /boards: lista os quadros visíveis ao autenticado (gestores veem todos). Filtros:visibility,archived,search, paginação.POST /boards: qualquer profissional pode criar; o autor viraowner. Responde201com{ "id": 1 }.PUT,DELETE,archive,unarchive: somente oownerdo quadro (ou gestor).DELETEé soft delete;archiveapenas marcaarchivedAt.
Payload (criar/atualizar)
| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim (criação) | Nome (1 a 150 caracteres). |
description | string | Não | Descrição. |
visibility | string | Não | public ou private. |
color | string | Não | Cor #RRGGBB. |
timesheetProjectId | number | Não | Projeto existente na instância. |
position | number | Não | Ordenação. |
Membros e Convites
http
GET /v1/timesheet/boards/:id/users
POST /v1/timesheet/boards/:id/users
PATCH /v1/timesheet/boards/:id/users/:userId
DELETE /v1/timesheet/boards/:id/users/:userId
POST /v1/timesheet/boards/:id/acceptGET /users: lista os membros, cada um com o profissional embutido (timesheetUser:id,firstName,lastName,email) — visível a quem tem acesso ao quadro.POST /users(somenteowner): convida um profissional — o membro nasce cominviteTokeneacceptedAt: null. Payload:timesheetUserId(único por quadro) erole(owner/editor/viewer, padrãoeditor). Responde201.PATCH /users/:userId(somenteowner): muda o papel. Rebaixar o últimoownerfalha com422 LAST_OWNER.DELETE /users/:userId(somenteowner): remove o membro — remover o últimoownertambém falha comLAST_OWNER.POST /accept: o convidado aceita o convite (gravaacceptedAt). Sem efeito se já aceito.
Colunas (Board Columns)
As colunas do quadro (A fazer, Fazendo, Feito), com limite de WIP.
Estrutura de Dados
| Campo | Tipo | Descrição |
|---|---|---|
name | String | Nome (1 a 150 caracteres). |
position | Number | Ordenação (padrão inicial: 1000). |
wipLimit | Number | Limite de cards ativos na coluna (inteiro, mín. 1, null = ilimitado). |
isDoneColumn | Boolean | Marca a coluna de concluído. |
Endpoints
http
GET /v1/timesheet/boards/:id/columns
POST /v1/timesheet/boards/:id/columns
PUT /v1/timesheet/boards/:id/columns/:columnId
DELETE /v1/timesheet/boards/:id/columns/:columnId
PUT /v1/timesheet/boards/:id/columns/reorder- Escrita exige
owneroueditor(ou gestor). DELETEfalha com422 COLUMN_HAS_CARDSse a coluna tiver cards não arquivados.PUT /reorderrecebe{ "columns": [{ "id": 1, "position": 1000 }, ...] }e atualiza a ordenação em lote (204).
Cards
Os cartões do quadro. A position é fracionária: arrastar um card custa um único UPDATE, sem renumerar a coluna inteira. O timesheetTaskId opcional é a ponte entre o visual e o apontável.
Estrutura de Dados
| Campo | Tipo | Descrição |
|---|---|---|
timesheetBoardColumnId | Number | Coluna atual. |
timesheetTaskId | Number | Tarefa vinculada (opcional). |
title | String | Título (máx. 250 caracteres). |
description | String | Descrição (opcional). |
position | Number | Posição fracionária na coluna (decimal serializado como string, ex.: "1000.0000000000"). |
assigneeTimesheetUserId | Number | Responsável (opcional). |
estimateMinutes | Number | Estimativa em minutos (inteiro, opcional). |
dueAt | DateTime | Prazo (ISO 8601, opcional). |
coverUrl | String | Imagem de capa (máx. 255 caracteres, opcional). |
archivedAt | DateTime | Quando preenchido, o card está arquivado. |
Endpoints
http
GET /v1/timesheet/boards/:boardId/cards
POST /v1/timesheet/cards
GET /v1/timesheet/cards/:id
PUT /v1/timesheet/cards/:id
DELETE /v1/timesheet/cards/:id
POST /v1/timesheet/cards/:id/move
POST /v1/timesheet/cards/:id/archive
POST /v1/timesheet/cards/:id/unarchiveGET /boards/:boardId/cards: filtrostimesheetBoardColumnId,assigneeTimesheetUserId,archivede paginação.GET /cards/:id: retorna o card com suaslabels.- Escrita exige
owneroueditor(ou gestor);viewerrecebe403 FORBIDDEN.
Criar Card
| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timesheetBoardId | number | Sim | Quadro existente na instância. |
timesheetBoardColumnId | number | Sim | Coluna do quadro. |
title | string | Sim | Título (máx. 250 caracteres). |
description | string | Não | Descrição. |
timesheetTaskId | number | Não | Tarefa vinculada. |
assigneeTimesheetUserId | number | Não | Responsável. |
estimateMinutes | number | Não | Estimativa em minutos. |
dueAt | datetime | Não | Prazo (ISO 8601). |
coverUrl | string | Não | Imagem de capa. |
position | number | Não | Posição inicial (padrão: fim da coluna). |
Sem position, o card entra no fim da coluna (maior position + 1000). Coluna no limite de WIP falha com 422 WIP_LIMIT_REACHED.
Mover Card
http
POST /v1/timesheet/cards/:id/move| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timesheetBoardColumnId | number | Sim | Coluna de destino. |
beforeCardId | number | Não | Card de referência — o movido entra antes dele. |
afterCardId | number | Não | Card de referência — o movido entra depois dele. |
A nova posição é a média entre os vizinhos (ou ±1000 nas pontas) — daí a posição fracionária. Sem referências, o card vai para o fim da coluna. Mudança para coluna no limite de WIP falha com 422 WIP_LIMIT_REACHED; referência fora da coluna de destino falha com 422 INVALID_POSITION.
Etiquetas (Labels)
Etiquetas coloridas do quadro (ou globais da instância, quando sem timesheetBoardId).
http
GET /v1/timesheet/boards/:boardId/labels
POST /v1/timesheet/labels
PUT /v1/timesheet/labels/:id
DELETE /v1/timesheet/labels/:idPayload (criar/atualizar)
| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timesheetBoardId | number | Não | Quadro da etiqueta (omitir = etiqueta global). |
name | string | Sim (criação) | Nome (máx. 100 caracteres). |
color | string | Não | Cor #RRGGBB. |
Etiquetas de quadro podem ser gerenciadas por owner/editor do quadro; etiquetas globais exigem gestor.
Etiquetas do Card
Sincroniza as etiquetas de um card em uma única chamada (substitui as atuais). Exige escrita no quadro.
http
PUT /v1/timesheet/cards/:cardId/labels| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
labelIds | number[] | Sim | IDs das etiquetas (pode ser vazio para limpar). |
Responde 204 No Content.
Comentários (Card Comments)
Comentários no cartão. Somente o autor (ou um gestor) pode editar ou remover um comentário — 403 FORBIDDEN caso contrário.
http
GET /v1/timesheet/cards/:cardId/comments
POST /v1/timesheet/cards/:cardId/comments
PUT /v1/timesheet/comments/:id
DELETE /v1/timesheet/comments/:idPayload
| Atributo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
body | string | Sim | Texto do comentário (mín. 1 caractere). |
Listagem paginada (page/perPage); criação responde 201 com { "id": 1 }; edição e remoção (soft delete) respondem 204.