- Created a new `api.md` file detailing the TrackGo HTTP API, including authentication, user management, and employee operations. - Updated `Employee` type to simplify user relation handling by replacing `UserRelation` with a more concise structure. - Enhanced filtering capabilities in employee queries to support an array of positions. - Refactored employee-related services and repositories to accommodate the new position filtering logic. - Added unit and e2e tests to validate the new API documentation and employee management functionalities.
4.2 KiB
TrackGo HTTP API
JSON keys are camelCase. IDs are UUID v4. List endpoints return { data, meta }.
List query includes shared pagination (page/limit or offset/limit) plus orderBy (resource field name) and orderType (ASC or DESC, default ASC). Unknown orderBy values are rejected. Defaults when omitted: users username; cycles cycleNumber; plans date; privilege-keys sortOrder then code; other lists code. Foreign keys on list/detail responses are nested objects ({ id, code, name } or { id, username } / { id, code }), not bare UUIDs.
List filters: username, privilegeId, status, search (username), orderBy, orderType.
Auth
POST /auth/register — public — 201
Creates a draft user. Does not issue tokens.
{ "username": "alice", "password": "password123" }
Response: { "id": "uuid", "username": "alice", "status": "draft" }.
Activate with PATCH /users/:id/status { "status": "active" } (or SQL bootstrap) then POST /auth/login.
POST /auth/login — public — 200
Same body as register. Returns { accessToken, refreshToken }.
Login, refresh, and JWT validation require user.status === "active". If the user is assigned to an employee, that employee must also be active. Failures use 401 with a generic credentials message.
POST /auth/refresh — public — 200
POST /auth/revoke — public — 204
GET /auth/me — bearer — 200
Users
Key: USERS. Standard CRUD + import (list, detail, create, update, status, delete, bulk-delete, bulk-status, import). Extra: PATCH /users/:id/privilege.
| Method | Path | Action | Status |
|---|---|---|---|
GET |
/users |
view | 200 |
GET |
/users/:id |
view | 200 |
POST |
/users |
create | 201 |
PATCH |
/users/:id |
update | 200 |
PATCH |
/users/:id/status |
update | 200 |
PATCH |
/users/:id/privilege |
update | 200 |
DELETE |
/users/:id |
delete | 204 |
POST |
/users/bulk-delete |
delete | 200 |
POST |
/users/bulk-status |
update | 200 |
POST |
/users/import |
import | 200 |
Create: { username, password, privilegeId?, status?, employeeId? }. Username 3–32, ^[a-zA-Z0-9_]+$, stored lowercased. Password 8–72, write-only. Omit status → draft. Never send isSuperadmin / passwordHash.
Optional employeeId links an existing employee. Unique assigned user → 409.
Update PATCH /users/:id: username?, password?, privilegeId? (null clears), employeeId? (null unlinks). No status. employeeId reassigns the linked employee.
Privilege: { privilegeId } (null clears). Assigned privilege must be active. Response is the full UserDto.
List filters: username, privilegeId, status, search (username).
DTO:
{
"id": "uuid",
"username": "alice",
"isSuperadmin": false,
"privilege": { "id": "uuid", "code": "ADMIN", "name": "Administrator" },
"employee": { "id": "uuid", "code": "EMP_01", "name": "Ada Lovelace" },
"status": "active",
"createdAt": 1710000000000,
"updatedAt": 1710000000000,
"createdBy": { "id": "uuid", "username": "admin" },
"updatedBy": { "id": "uuid", "username": "admin" }
}
privilege / employee may be null. CSV required: username, password. Optional: privilegeId, status. Delete of a user still referenced as created_by / updated_by → 409.
Bootstrap: first user is draft until UPDATE users SET status = 'active'.
Employees
Create/update optional userId (assign an existing login user) or nested user (id?, username?, password?). Nested user without id creates a login user (username + password required) or updates the currently linked username. user.id / userId links an existing user; username may be updated, but password is rejected (use PATCH /users/:id). Nested user cannot set privilegeId. user: null or userId: null unlinks. Users link the other way with employeeId. DTO nests user: { id, username } | null. List filter userId. List filter position as one or more of sales | driver | crew (?position=sales&position=driver). CSV optional userId. Unique assigned user → 409.