shoc-frontend-new/docs/work-orders/board-search-api.md
Arthur Bassi 8a2bc21845 fix(work-orders): sync addon-indicator with platform-polish parent
[recover] remove malicious eslint payload (was 692598b7)
2026-08-11 15:08:27 -03:00

153 lines
6.7 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.

# Work Orders Board & Search API
Frontend integration contract for weekly board and advanced search filters.
## Base
| Item | Valor |
| ------------ | ------------------------------------------- |
| Prefixo | `/api/workorders` (alias: `/api/WorkOrder`) |
| Auth | `Authorization: Bearer {token}` (JWT) |
| Content-Type | Não necessário (GET) |
Paths no FE: `API_PATHS.workOrder.board`, `boardSearch`, `lookupsDispatchers`.
## Quando usar qual endpoint
| Modo FE | Endpoint | Quando |
| --------------------------------------- | -------------------------- | ------------------------------------------------ |
| Barra principal (`advApplied === null`) | `GET /board` | Semana + dispatchers + tipo segment + search |
| Filtros avançados aplicados | `GET /board/search` | Todos os filtros avançados + paginação/ordenação |
| Lookup dispatchers | `GET /lookups/dispatchers` | Popular multi-select de dispatchers |
**Não misture parâmetros:** `weekStart`/`weekEnd` só no `/board`; `datePreset` só no `/search`.
## Query builders (FE)
- [`board-query-params.ts`](../../src/domain/work-orders/utils/board-query-params.ts) — `toBoardQueryParams`, `toBoardSearchQueryParams`
- Arrays na query: repetição simples (`types=2&types=6`), via `toUrlSearchParams` em `work-orders-api.ts`
## Barra → `GET /board`
| FE state | API param | Regra |
| --------------- | ---------------------- | ----------------------------------------------------------- |
| `search` | `search` | Enviar só se `length >= 2`; com 1 char, filtrar client-side |
| `weekMonday` | `weekStart` | ISO `YYYY-MM-DD` (segunda) |
| — | `weekEnd` | `weekStart + 4` (sexta) |
| `dispatcherIds` | `dispatchers` | `__unassigned` → `__unassigned__` |
| "My WOs" | `dispatchers={userId}` | Equivalente a `myWorkOrders=true` |
| `typeFilter` | `types` / `overdue` | Tipos reais em `types`; past-due via `overdue=true` (OR) |
## Advanced → `GET /board/search`
| FE state | API param | Regra |
| ---------------- | --------------------- | ------------------------------------------- |
| `page` | `page` | **0-based** (primeira página = `0`) |
| `pageSize` | `pageSize` | Default `100`, max `100` |
| `sortBy` | `sortBy` | `scheduledDate` \| `woNumber` \| `dueDate` |
| `sortDir` | `sortDir` | `asc` \| `desc` |
| `search` | `search` | `>= 2` chars |
| `dateRange` | `datePreset` | PascalCase (ver abaixo) |
| `customFrom/To` | `dateFrom` / `dateTo` | Obrigatórios se `datePreset=Custom` |
| `sites` (IDs UI) | `sites` | **Site codes**, não location ID |
| `types` | `types` | Integers de `WorkOrderType` reais |
| overdue (UI) | `overdue` | `true` = past-due (`isPastDue`); ver abaixo |
| `dispatchers` | `dispatchers` | `__unassigned` → `__unassigned__` |
| `statuses` | `statuses` | Integers 1–10 |
| `pmTypes` | `pmTypes` | Strings (labels Problem dropdown) |
| `vendorTechs` | `vendorIds` | Integers (resolvidos por companyName) |
| `docs` | `docStatuses` | No=2, Yes=1, NN=3 |
### `datePreset`
| FE key | API value |
| --------------- | ------------- |
| `this-week` | `ThisWeek` |
| `last-week` | `LastWeek` |
| `this-month` | `ThisMonth` |
| `last-3-months` | `Last3Months` |
| `next-week` | `NextWeek` |
| `next-month` | `NextMonth` |
| `custom` | `Custom` |
### `types` — WorkOrderType
Somente tipos reais de work order. **Não** use sentinel `99` para overdue.
| Label FE | API |
| --------- | -------------------------------------------- |
| PM | `2` |
| Emergency | `3` |
| Reactive | `6` |
| Add-On | `7` |
| Other | tipo real do enum (não é filtro de past-due) |
### `overdue` — past-due
| FE / UI | API param | Regra |
| ------- | -------------- | ----------------------------------------- |
| Overdue | `overdue=true` | Filtra work orders past-due (`isPastDue`) |
`types` e `overdue` combinam com **OR**: uma WO entra no resultado se corresponder a algum `types` **ou** estiver overdue (quando `overdue=true`).
Exemplos:
- Só PM e Emergency: `types=2&types=3`
- Só past-due: `overdue=true`
- PM **ou** past-due: `types=2&overdue=true`
### `statuses` — LifecycleStatus
Incomplete=1, Pending=2, Scheduled=3, En Route=4, On Site=5, In Progress=6, Completed=7, Rescheduled=8, Canceled=9, Pending Quote=10.
### `docStatuses`
Pending (`No`)=2, Uploaded (`Yes`)=1, N/N (`NN`)=3.
## Respostas
### `/board`
```json
{
"weekStart": "2026-07-14",
"weekEnd": "2026-07-18",
"counts": { "total": 42, "returned": 10 },
"scheduled": [],
"unscheduled": []
}
```
### `/board/search`
```json
{
"items": [],
"totalCount": 150,
"page": 0,
"pageSize": 100,
"totalPages": 2,
"hasPrevious": false,
"hasNext": true
}
```
## Erros HTTP
| Situação | Status |
| --------------------------------------------------- | ------ |
| `weekEnd < weekStart` ou janela > 7 dias | 400 |
| `datePreset=Custom` sem datas / `dateTo < dateFrom` | 400 |
| `sortBy` inválido | 400 |
| Sem token / expirado | 401 |
Body típico: `{ "status": "Error", "message": "..." }` — o FE exibe `message` via `ApiError`.
## Add-On indicator
See [addon-indicator.md](./addon-indicator.md) (SH-184): backend recalculates
`isAddOn` on schedule move/clear with audit; FE only reflects the API value.
## Validação UI
O side sheet de filtros avançados valida Custom (From/To obrigatórios e `dateTo >= dateFrom`) antes de aplicar, para evitar 400 desnecessário.