shoc-backend/docs/work-orders/phase-4/README.md

162 lines
5.5 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.

# Fase 4 — Search contextual + Advanced Search
**Programa:** Work Orders Board
**Objetivo:** Hardening da busca contextual no board semanal, endpoint de advanced search cross-week (Tier S), índices de suporte e harness de load test.
**Depende de:** [Fase 0](../phase-0/README.md), [Fase 1](../phase-1/README.md), [Fase 2](../phase-2/README.md), [Fase 3](../phase-3/README.md)
**Tier vigente (dev):** **S (provisório)** — ver [search-tier-decision.md](./search-tier-decision.md)
---
## Endpoints
### `GET /api/workorders/board?search=` (hardening)
Busca contextual na janela semanal. Campos cobertos:
| Campo | Origem |
|-------|--------|
| Site | `SiteCode` |
| WO# | `InternalWONumber`, `WorkerOrderNumber` |
| Location | `Locations.Name` |
| Dispatcher | `AssignToUser` nome |
| PM | `Trade`, `Problem` |
| Vendor | `PrimaryDispatch.Vendor.CompanyName` |
| Tech | `PrimaryDispatch.Vendor.ContactName` |
| Status legado | `Status` |
| Lifecycle | label enum (`Scheduled`, `In Progress`, etc.) |
**Regras:**
- `search` com trim; ignorado se vazio ou < 2 caracteres
- `counts.total` — agendadas na semana **sem** search
- `counts.returned` — agendadas **com** search
### `GET /api/workorders/board/search`
Advanced search cross-week paginado.
**Autenticação:** Bearer JWT
**Query params:**
| Param | Tipo | Descrição |
|-------|------|-----------|
| `search` | string | Texto livre (mesmos campos do contextual) |
| `datePreset` | enum | `thisWeek`, `lastWeek`, `thisMonth`, `last3Months`, `nextWeek`, `nextMonth`, `custom` |
| `dateFrom` / `dateTo` | date | Obrigatórios se `datePreset=custom` |
| `sites` | string[] | `SiteCode` |
| `types` | WorkOrderType[] | Tipo WO |
| `dispatchers` | string[] | GUIDs + `__unassigned__` |
| `statuses` | LifecycleStatus[] | Status operacional |
| `pmTypes` | string[] | Match em `Trade`/`Problem` (contains, case-insensitive) |
| `vendorIds` | int[] | Via `PrimaryDispatch.VendorId` |
| `docStatuses` | DocStatus[] | Enum `DocStatus` |
| `myWorkOrders` | bool | Filtro usuário logado |
| `page` | int | Default 1 |
| `pageSize` | int | Default 50; max 100 (Tier S/M) |
| `sortBy` | string | `scheduledDate` (default), `woNumber`, `dueDate` |
| `sortDir` | string | `asc` / `desc` |
**Response:** `PagedResult<WorkOrderBoardRowDto>`
```json
{
"items": [ /* WorkOrderBoardRowDto */ ],
"totalCount": 120,
"page": 1,
"pageSize": 50,
"totalPages": 3,
"hasNext": true,
"hasPrevious": false
}
```
**Exemplo:**
```bash
curl -H "Authorization: Bearer <token>" \
"https://localhost:5001/api/workorders/board/search?datePreset=thisMonth&sites=BK5&search=HVAC&page=1"
```
---
## Matriz preset → intervalo de datas
Base: **segunda-feira ISO** (`WorkOrderSearchDateRangeResolver`).
| Preset | Intervalo |
|--------|-----------|
| `thisWeek` | Seg–Dom da semana ISO corrente |
| `lastWeek` | Seg–Dom da semana ISO anterior |
| `nextWeek` | Seg–Dom da próxima semana ISO |
| `thisMonth` | 1º–último dia do mês corrente |
| `nextMonth` | 1º–último dia do mês seguinte |
| `last3Months` | Hoje − 3 meses → hoje |
| `custom` | `dateFrom` / `dateTo` (400 se ausentes) |
**Filtro de data:** `ScheduledDate` no intervalo **OU** `ScheduleWeekOnly && TargetWeek` intersectando o intervalo. Exclui templates e `IsDeleted`.
---
## Código entregue
| Camada | Arquivo |
|--------|---------|
| Search filter | `SeaHaven.DataServices/Helpers/WorkOrderBoardSearchFilter.cs` |
| Query filters | `SeaHaven.DataServices/Helpers/WorkOrderBoardQueryFilters.cs` |
| Projeção | `SeaHaven.DataServices/Helpers/WorkOrderBoardProjection.cs` |
| Date presets | `SeaHaven.Services/Helpers/WorkOrderSearchDateRangeResolver.cs` |
| Advanced data | `SeaHaven.DataServices/Implementation/WorkOrderAdvancedSearchDataService.cs` |
| Advanced service | `SeaHaven.Services/Implementation/WorkOrderAdvancedSearchService.cs` |
| DTOs | `SeaHaven.Services/DTOs/WorkOrderBoardDTOs.cs` |
| API | `WorkOrderController` — `GET board/search` |
| Migration | `20260624200000_Phase4_SearchIndexes.cs` |
| Testes | `SeaHavenIndustries.Tests/WorkOrderBoardSearchTests.cs` |
| Load test | `scripts/load-test/work-order-search.k6.js` |
| Seed | `scripts/seed-work-orders-search.ps1` |
---
## Gates de aceite
### Dev (implementação)
- [x] Helper de search compartilhado + testes por campo
- [x] `GET /board/search` paginado com filtros FE
- [x] Date presets alinhados ao SHOC (ISO Monday)
- [x] Migration índices Phase 4
- [x] Harness k6 + seed sintético (Tier S local)
- [x] Endpoints legados inalterados
- [x] ~12 testes unitários novos (total ~80)
### Staging/prod (GO — pendente)
- [ ] Volume Discovery preenchido — [volume-discovery-report.md](../phase-0/volume-discovery-report.md)
- [ ] Tier assinado — [search-tier-decision.md](./search-tier-decision.md)
- [ ] Load test em staging com volume real
- [ ] Latência dentro do SLO do tier confirmado
- [ ] Smoke Portal/Blazor inalterados
---
## SLOs Tier S (load test local)
| Cenário | Endpoint | p95 |
|---------|----------|-----|
| Board sem search | `GET /board?weekStart=...` | &lt; 800ms |
| Board com search | `GET /board?search=BK5` | &lt; 1000ms |
| Advanced preset | `GET /board/search?datePreset=thisMonth` | &lt; 1200ms |
| Advanced multi-filter | sites + types + search | &lt; 1500ms |
Ver [scripts/load-test/README.md](../../scripts/load-test/README.md).
---
## Fora de escopo
- Full-text search (Tier L)
- Search externo dedicado (Tier XL)
- Lookups PM catalog (`PM_TYPES`) — backlog #17
- Alterações em endpoints legados