Files
trackgo-be/docs/api.md
T
shancheas 2955b974d2 Add reporting features with new report engine and bookmark management
- Introduced a comprehensive report engine for generating and managing reports, including sales and logistics reports.
- Added new API endpoints for retrieving report configurations, data, and metadata, ensuring secure access with privilege checks.
- Implemented a report bookmarks system to allow users to save and manage report filters and configurations.
- Created database migrations for the `report_bookmarks` table and updated the schema to support new report functionalities.
- Developed services and controllers for handling report queries and bookmarks, including CRUD operations for bookmarks.
- Enhanced API documentation to reflect the new reporting features and endpoints.
- Added unit and integration tests to validate the new functionalities and ensure data integrity across report operations.
2026-09-01 08:45:52 +07:00

116 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```json
{ "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 332, `^[a-zA-Z0-9_]+$`, stored lowercased. Password 872, 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:**
```json
{
"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`.
## Reports
Privilege keys: `SALES.REPORT`, `LOGISTICS.REPORT` (seeded in migration `0013_reports`).
### `GET /reports/config` — bearer — `200`
Query: `groupNames` (e.g. `sales_report`). Returns report configs visible to the caller, each with optional `activeFilter` and `activeTableConfig` bookmarks.
### `POST /reports/data` — bearer — `200`
Body: `{ groupName, uniqueName, queryModel }`. Returns row array keyed by column id.
### `POST /reports/meta` — bearer — `200`
Same body as data. Returns `{ totalRow, limit, offset }`.
### Report bookmarks
| Method | Path | Notes |
| --- | --- | --- |
| `GET` | `/report-bookmarks` | List for current user (`@Pagination()`) |
| `GET` | `/report-bookmarks/label-history` | Distinct labels |
| `GET` | `/report-bookmarks/applied` | Query: `groupName`, `uniqueName`, `type` |
| `POST` | `/report-bookmarks` | Create (`201`) |
| `PUT` | `/report-bookmarks/applied/:id` | Apply (unapplies siblings) |
| `PUT` | `/report-bookmarks/unapplied/:id` | Clear applied |
| `DELETE` | `/report-bookmarks/:id` | `204` |
Bookmark `type`: `FILTER_TABLE` | `TABLE_CONFIG`. `configuration` is opaque JSON (filter form values or AG Grid column state).