Auditoria — API Work Orders vs Frontend (WorkOrders.tsx)
Data: 2026-06-19
Fonte da verdade (FE): seahaven.desing/src/pages/WorkOrders.tsx
Backend auditado: seaheven.api
Resumo executivo
| Métrica |
Valor |
| Compatibility Score |
24/100 |
| Backend Readiness |
Not Ready |
| Confidence |
High |
A API atual foi construída para CRUD legado (listagem paginada, detalhe rico, dispatch). O frontend WorkOrders.tsx define um Schedule Board operacional (visão semanal, 14 colunas, edição inline, advanced search, completion doc WO-level). Os contratos são fundamentalmente diferentes.
O que funciona hoje: id, dueDate, location (parcial), CRUD básico, detalhe rico, comments, audit field-based, mídia WO-level, reatribuição, dispatch.
O que falta: listagem window-based, 14 colunas board, PATCH inline, campos derivados, advanced search, completion doc WO-level, jobs Past Due/Carried Over, status 10 labels, WO# 11 dígitos.
Endpoints que existem hoje
| Endpoint |
O que entrega |
GET GetWorkOrderList |
Lista paginada (default 12): id, número, título, location, priority, status, dueDate, assignedTo, lastUpdated |
GET Getworkorders / GetworkordersDD |
Lista legada para admin/dropdown |
GET GetFilteredWorkorder / 2 |
Filtros legados (assignee, location, priority, status, due date buckets) — carrega tudo em memória |
GET GetWorkorderById / {id} |
Detalhe: título, descrição, datas, status, problem, trade, POC, attachments, comments, audit, dispatches |
POST AddWorkorder |
Criação via form: título, descrição, assignee, dueDate, location, priority, mídia, contacts/categories |
POST/PUT EditWorkorder |
Update parcial via form (subset mapeado ao service) |
POST ChangeStatus |
Muda status (string livre) + audit |
POST ChangeAssignment |
Reatribui dispatcher + audit |
POST AddComment / AddCommentJson |
Comentário + upload opcional |
GET GetComments / GetCommentsByWorkorderId |
Lista comentários |
DELETE DeleteWorkorder |
Delete físico (não soft cancel) |
| Dispatch endpoints |
Vendor, checklist, signoff, verify — nível dispatch, não board |
Lookups relacionados (outros controllers): Common/GetUsers, Location/GetLocationList, Vendor/GetVendorList — paginados, contrato diferente do FE.
Documentado mas não implementado no código: GET GetWorkOrdersBoard, IWorkOrderBoardMapper, IWorkOrderStatusMapper (ver docs/adr/work-orders-board-api.md).
1. Listagem da tela principal (visão semanal)
| Frontend espera |
API entrega hoje |
Gap |
1 call por semana (weekStart / weekEnd) |
Paginação page / pageSize sem janela temporal |
Sem fetch window-based |
| WOs agrupados por dia (Mon–Fri) |
Lista flat paginada |
Sem scheduledDate na projeção de listagem |
| Seção Unscheduled sempre visível no topo |
Só WOs da página atual |
Sem WOs sem data retornados independente da semana |
targetWeek (scheduling week-only) |
Campo inexistente na entidade/API |
Não implementado |
Contador X of Y da semana ativa |
totalCount global paginado |
Contagem inadequada para o board |
| Skeleton Mon–Fri vazios |
N/A (FE-only) |
OK — responsabilidade do FE |
Evidência BE: WorkOrderDataService.GetWorkOrderListPagedAsync — projeção L163-183, sem ScheduledDate, SiteCode, vendor, type.
2. Colunas da tabela (COLS)
Definidas no FE em WorkOrders.tsx L4234-4249.
| Coluna FE |
Campo(s) FE |
API hoje |
Gap |
| Grip |
drag reorder |
Ausente |
FE local-only; BE não persiste ordem |
| Flag |
flag pessoal |
Ausente |
FE session-only |
| SITE |
site, pocName, pocPhone, pocNotes |
List: location (name); Detail: POC via WorkOrderContacts |
Sem siteCode na listagem; sem POC na lista |
| WO |
woNumber, rescheduleCount, carriedOver |
internalWONumber / workerOrderNumber |
Formato ≠ 11 dígitos; sem badges ↻ ↷N |
| TYPE OF WO |
type (PM / Reactive / Emergency / Add-On / Overdue) |
Não exposto (WorkOrderType em db.txt, não mapeado em EF) |
Coluna inoperante |
| ASSIGNED TO |
dispatcherId + avatar/cor |
assignedTo (nome completo); AssignTo = GUID Identity |
Sem id/initials/color para avatar |
| SCHEDULE ON |
scheduledOn, targetWeek |
Detail: scheduledDate; list: ausente |
Listagem sem data de agendamento |
| DUE DATE |
dueDate |
dueDate |
OK na listagem |
| SERVICE |
pm |
Detail: trade / problem; list: ausente |
Coluna vazia na lista |
| VENDOR |
company, tech, techPhone |
Detail: dispatches → vendor; list: ausente |
Coluna vazia na lista |
| APPT TIME |
apptTime (ex: "07:00 – 09:00") |
Entidade: ScheduledStart; sem ScheduledEnd |
Janela de horário incompleta |
| STATUS |
10 labels + overlay Past Due |
String legada DB + enum 5 valores API |
Sem mapping para status operacionais do FE |
| COMP DOC |
docStatus (Yes / No / NN) |
Ausente no WO |
Completion existe só no dispatch (VerifyDispatch) |
| Actions |
View / Edit |
GetWorkorderById separado |
Detalhe existe; contrato diferente |
3. Filtros e busca
Barra principal (FE L5083-5099)
| Frontend |
API hoje |
Gap |
Dispatcher multi-select + __unassigned__ + default usuário logado |
assignee single string; __unassigned suportado em GetWorkOrderList |
Multi-select e default "My WOs" não cobertos |
| Semana ativa |
Sem filtro ScheduledDate |
Filtro semanal inexistente |
| Tipo (All / PM / Reactive / Emergency / Add-On / Overdue) |
Sem filtro por work order type |
Inexistente |
| Busca contextual na semana (site, wo#, dispatcher, location, pm, company, tech, status) |
Search em 5 campos (InternalWONumber, WorkerOrderNumber, Title, Location), escopo global paginado |
Campos e escopo incompatíveis |
Advanced Search (FE L4255-4324)
| Frontend |
API hoje |
Gap |
| Lista plana cross-week |
Ausente |
Sem endpoint dedicado |
| Date range (this-week, last-week, this-month, last-3-months, next-week, next-month, custom) |
GetFilteredWorkorder com due date buckets legados |
Semântica diferente |
| Filtros: sites[], types[], dispatchers[], statuses[], pmTypes[], vendorTechs[], docs[] |
Parcial em endpoints legados |
Cobertura incompleta |
4. Edição inline (spreadsheet-style)
| Frontend |
API hoje |
Gap |
| PATCH por campo (site, wo#, type, dispatcher, schedule, due, service, vendor, appt, status…) |
EditWorkorder (form multipart) + ChangeStatus + ChangeAssignment separados |
Sem update granular por campo |
Auto-schedule: Incomplete → Scheduled quando data + dispatcher |
Ausente no BE |
Regra maybeAutoSchedule só no FE |
rescheduleCount++ ao mudar scheduledOn |
Campo inexistente |
Badge ↻ impossível |
Limpar isPastDue ao reagendar para data futura |
Campo derivado inexistente |
Past Due não limpa via API |
Bloquear mudança de status se isPastDue |
ChangeStatus aceita qualquer string |
Sem validação 422 |
| WO# único 11 dígitos normalizado |
Gerador WO-{yyyyMMdd}-{random} ou sync sequencial 10000001 |
Formato e unicidade incompatíveis |
| WO cancelado read-only |
Sem enforcement no BE |
Só lógica no FE (WOSlideOver L2380) |
Evidência BE: WorkOrderController.Editworkorder L182-192 mapeia subset para UpdateWorkOrderDTO — ignora Problem, Trade, ScheduledDate, Source apesar de existirem em EditWorkorder_DTO.
5. Criação de WO
| Frontend |
API hoje |
Gap |
Wizard NewWOWizard + inline InlineRow |
POST AddWorkorder |
Campos do wizard majoritariamente ausentes |
| Campos: site, type, scheduledOn, targetWeek, pm, company, tech, appt, POC |
CreateWorkOrderDTO: title, description, assignTo, dueDate, location |
Contrato incompleto |
Status inicial Incomplete |
Cria com WorkOrderStatus.Open |
Status inicial diferente |
scheduleWeekOnly / targetWeek |
Ausente |
Week-only scheduling impossível |
| Navegação automática para semana do WO criado |
Depende de listagem semanal |
Listagem incompatível |
6. Cancelamento
| Frontend |
API hoje |
Gap |
Soft cancel → status Canceled |
POST ChangeStatus(id, "Canceled") manual |
Sem endpoint POST cancel dedicado |
| WO cancelado não editável |
Sem bloqueio no BE |
Enforcement só no FE |
| Delete permanente (Admin) |
DELETE DeleteWorkorder — delete físico |
Comportamento diverge do soft cancel FE |
7. Slide-over (WOSlideOver)
| Tab FE |
API hoje |
Gap |
| Info |
GET GetWorkorderById |
Omite siteCode; sem campos derivados FE (isPastDue, rescheduleCount, etc.) |
| Comments |
AddComment + GetCommentsByWorkorderId |
Formato FE {authorId, text, time} vs BE {Commenttext, FirstName, Documents} |
| Audit Log |
WorkOrderAuditLog retornado no detalhe |
Schema {fieldName, oldValue, newValue, action} vs FE {type: manual|system, dispatcherId?, action, time} |
| Completion Doc |
SignOffName / SignOffAttachment no WO; VerifyDispatch no dispatch |
Sem template por service type, PDF, docStatus WO-level |
| Extra Docs / Media |
BeforPhoto, AfterPhoto, workOrderAttachments |
Sem MediaFile.category; sem API extra docs dedicada |
8. Regras de sistema (background jobs)
| Frontend assume |
API hoje |
Gap |
Job Past Due: scheduledOn < hoje + não terminal → isPastDue=true |
Ausente (zero BackgroundService / Hangfire / Quartz no repo) |
Flag nunca setada automaticamente |
Job Carried Over: virada de semana → carriedOver++ |
Ausente |
Contador ↷N nunca incrementado |
| Type Overdue promotion |
Ausente |
Filtro/tipo Overdue não automático |
| Sync APM |
SyncController POST manual (DynamoDB → SQL) |
On-demand, não integrado à UX do board |
9. Lookups (catálogos)
| FE usa (mock estático) |
API relacionada |
Gap |
DISPATCHERS (id, name, initials, color) |
Common/GetUsers |
Sem initials/color; paginado; ids são GUIDs |
SITE_OPTIONS (code → city, state) |
Location/GetLocationList |
Sem lookup por site code; sem mapeamento BK5 → Dallas |
PM_TYPES |
Ausente |
Sem catálogo de service types |
TECHNICIANS (name, company, phone) |
Vendor/GetVendorList |
Sem endpoint technicians |
WEEK_RANGES (Mon–Fri + flag LIVE) |
Ausente |
Sem endpoint weeks |
Contrato de dados — campo a campo
Campo FE (WorkOrder) |
Campo BE |
Status |
id |
WorkOrder.Id |
SUPPORTED |
woNumber |
InternalWONumber / WorkerOrderNumber |
PARTIALLY_SUPPORTED — formatos conflitantes |
site |
SiteCode |
PARTIALLY_SUPPORTED — entidade tem; API omite na listagem |
type |
— (WorkOrderType só em SQL) |
NOT_SUPPORTED |
dispatcherId |
AssignTo (GUID) |
PARTIALLY_SUPPORTED |
scheduledOn |
ScheduledDate |
PARTIALLY_SUPPORTED — list omite |
dayGroup / dayLabel |
— |
NOT_SUPPORTED (derivado) |
location |
Locations.Name |
SUPPORTED (via join) |
pm |
Trade / Problem |
PARTIALLY_SUPPORTED |
company / tech |
Dispatches → Vendor |
PARTIALLY_SUPPORTED — não inline na lista |
techPhone |
— |
NOT_SUPPORTED |
apptTime |
ScheduledStart (sem end) |
PARTIALLY_SUPPORTED |
status |
Status (string livre) |
PARTIALLY_SUPPORTED — 10 vs 5+ formatos |
docStatus |
— |
NOT_SUPPORTED |
pocName / pocPhone / pocNotes |
WorkOrderContacts |
PARTIALLY_SUPPORTED — notes ausente |
dueDate |
DueDate |
SUPPORTED |
rescheduleCount |
— |
NOT_SUPPORTED |
carriedOver |
— |
NOT_SUPPORTED |
originalWeek / originalDate |
— |
NOT_SUPPORTED |
isPastDue |
— |
NOT_SUPPORTED (derivado) |
targetWeek |
— |
NOT_SUPPORTED |
Regras de negócio — FE vs BE
| Regra FE |
Evidência FE |
BE hoje |
Status |
| Auto-schedule Incomplete → Scheduled |
maybeAutoSchedule L500-506 |
Ausente |
NOT_SUPPORTED |
| Reschedule incrementa contador |
updateScheduledOn L4856 |
Ausente |
NOT_SUPPORTED |
| Reschedule limpa Past Due |
L4851-4857 |
Ausente |
NOT_SUPPORTED |
| Status bloqueado em Past Due |
StatusCell L1120-1159 |
ChangeStatus sem validação |
NOT_SUPPORTED |
| WO# único 11 dígitos |
findDuplicateWONumber L4897 |
Gerador random; InternalNumberExistsAsync sem normalização |
NOT_SUPPORTED |
| Cancel → Canceled, read-only |
cancelWO L4946; WOSlideOver L2380 |
ChangeStatus manual |
PARTIALLY_SUPPORTED |
| Carried over job semanal |
Audit derivado L2414-2416 |
Sem job |
NOT_SUPPORTED |
| Completion doc por tipo de serviço |
CompDocDialog L3902+ |
Dispatch verify only |
NOT_SUPPORTED (WO-level) |
| Emergency/Reactive → media flow |
isMediaWO L332-334 |
Mídia WO genérica |
PARTIALLY_SUPPORTED |
Diagrama — contrato atual vs esperado
HOJE (GetWorkOrderList) FRONTEND (WorkOrders.tsx)
───────────────────── ─────────────────────────
Paginação 12/page 1 call = semana inteira
Sem ScheduledDate Agrupamento Mon–Fri
Sem siteCode, type, vendor 14 colunas preenchidas
Sem unscheduled semantics Seção Unscheduled fixa
5 status legados 10 status + Past Due overlay
CRUD admin Schedule Board operacional
EditWorkorder (form) PATCH inline por célula
Cobertura por área
| Área |
Cobertura estimada |
| Listagem board (visão semanal) |
~5% |
| Colunas da tabela (14) |
~15% |
| Filtros e busca |
~10% |
| Edição inline |
~0% |
| Criação (wizard/inline) |
~25% |
| Slide-over (detalhe) |
~40% |
| Completion doc WO-level |
~0% |
| Background jobs |
~0% |
| Lookups/catálogos |
~20% |
Critical blockers
- Sem API window-based para visão semanal + Unscheduled — tela principal não carrega.
- Contrato de listagem incompatível com 14 colunas do board.
- Campos persistidos ausentes —
rescheduleCount, carriedOver, targetWeek, docStatus, isPastDue.
- Sem PATCH inline — edição spreadsheet-style impossível.
- Advanced search cross-week inexistente.
- Status 10 valores + Past Due sem mapping layer implementado.
- Completion doc WO-level inexistente — coluna COMP DOC inoperante.
- WO# 11 dígitos único não suportado.
- Jobs Past Due / Carried Over ausentes.
Non-critical gaps
- Reorder intra-dia persistido (FE já local-only)
- Flags pessoais (FE session-only)
- Paginação 12/24/48/96 (FE não implementou)
- Bulk select (FE não implementou)
[Authorize] comentado no WorkOrderController (risco de segurança)
Referências
- Frontend:
seahaven.desing/src/pages/WorkOrders.tsx
- Controller:
Api.SeaHavenIndustries/Controllers/WorkOrderController.cs
- Data service:
SeaHaven.DataServices/Implementation/WorkOrderDataService.cs
- Entidade:
Data.SeaHavenIndustries/Models/WorkerOrder.cs
- ADR (proposto, não implementado):
docs/adr/work-orders-board-api.md
- Spikes:
docs/spikes/consumer-audit-getworkorderlist.md, search-strategy.md, status-mapping.md, work-order-type.md
Classificação final
| Métrica |
Valor |
| Compatibility Level |
Minimally Compatible |
| Backend Readiness |
Not Ready |
| Confidence |
High |
Este documento reporta apenas findings — gaps entre o que a API entrega hoje e o que o frontend especifica. Não inclui propostas de implementação.