5.1 KiB
Fase 6 — Completion Doc e Slide-over
Programa: Work Orders Board
Objetivo: Contrato SHOC para slide-over (WOSlideOver): detalhe unificado, docStatus WO-level com templates por serviço, e tabs Comments/Audit/Media alinhadas ao frontend.
Endpoints
GET /api/workorders/{id}/detail
Payload único para abrir o slide-over.
Autenticação: Bearer JWT ([Authorize])
Response:
{
"info": { /* WorkOrderDetailInfoDto — board row + description/trade/original* */ },
"completion": {
"docStatus": "No",
"template": { "id": 1, "name": "HVAC PM Completion", "serviceKey": "HVAC PM", "templateUrl": "..." },
"signOffName": null,
"signOffAttachment": null,
"signOffSignature": null,
"dispatchSignoffs": []
},
"comments": [{ "id": 1, "authorId": "guid", "text": "...", "time": "2026-06-01T12:00:00.0000000Z" }],
"audit": [{ "type": "manual", "dispatcherId": "guid", "action": "FieldChanged", "fieldName": "DocStatus", "oldValue": "No", "newValue": "Yes", "time": "..." }],
"media": [{ "id": 5, "category": "Extra", "url": "...", "isLegacy": false }]
}
curl -H "Authorization: Bearer <token>" \
"https://localhost:5001/api/workorders/42/detail"
GET /api/workorders/{id}/audit?limit=50
Audit tab lazy refresh. Schema FE: { type, dispatcherId?, action, fieldName?, oldValue, newValue, time, dispatchId? }.
GET /api/workorders/{id}/comments
POST /api/workorders/{id}/comments
{ "text": "Called vendor" }
Response: { id, authorId, text, time, documents? }.
Completion templates
| Método | Rota | Auth | Descrição |
|---|---|---|---|
| GET | /api/workorders/completion-templates |
JWT | Query serviceKey, workOrderType |
| GET | /api/workorders/completion-templates/{id} |
JWT | Detalhe |
| POST | /api/workorders/completion-templates |
Admin | Criar template |
| PUT | /api/workorders/completion-templates/{id} |
Admin | Atualizar |
| DELETE | /api/workorders/completion-templates/{id} |
Admin | Soft delete |
Lookup na WO: Trade → fallback WorkOrderType.
POST /api/workorders/{id}/completion-doc
Upload PDF preenchido (multipart).
| Campo form | Obrigatório |
|---|---|
file |
Sim |
signOffName |
Não |
signOffSignature |
Não |
workOrderVersion |
Recomendado (Base64 RowVersion) |
Regras:
- WO read-only (
Canceled/Complete/Closed) → 422 - Sucesso →
SignOffAttachment+DocStatus=Yes+ auditFieldChanged - Dispatch signoffs → somente leitura no slide-over
curl -X POST -H "Authorization: Bearer <token>" \
-F "file=@completion.pdf" \
-F "signOffName=Jane Doe" \
"https://localhost:5001/api/workorders/42/completion-doc"
Inline toggle: PATCH /api/workorders/{id}/board com field=docStatus (Fase 2).
Media
| Método | Rota | Descrição |
|---|---|---|
| GET | /api/workorders/{id}/media |
Lista unificada com category |
| POST | /api/workorders/{id}/media |
multipart: category (Before/After/Extra/Completion) + file |
| DELETE | /api/workorders/{id}/media/{mediaId} |
Soft delete (somente attachments com id > 0) |
Legacy columns (BeforPhotoAttachment, AfterPhotoAttachment, SignOffAttachment) aparecem na projeção com isLegacy: true.
Schema
Migration Phase6_CompletionSlideOver:
- Tabela
CompletionDocTemplates - Coluna
CategoryemworkOrderAttachments - Backfill SQL:
SignOffAttachmentpreenchido →DocStatus=Yes
Script ops: scripts/backfill-docstatus.ps1
Código entregue
| Camada | Arquivo |
|---|---|
| Model | CompletionDocTemplate.cs, WorkOrderMediaCategory enum |
| Migration | 20260625120000_Phase6_CompletionSlideOver.cs |
| Data | WorkOrderDetailDataService, CompletionDocTemplateDataService |
| Services | WorkOrderDetailService, WorkOrderCommentService, WorkOrderCompletionService, WorkOrderMediaService |
| DTOs | WorkOrderDetailDTOs.cs |
| Helpers | WorkOrderAuditProjection, WorkOrderCommentProjection, WorkOrderMediaProjection |
| API | WorkOrderController — rotas /detail, /comments, /audit, /completion-doc, /media, /completion-templates |
| Testes | WorkOrderPhase6Tests.cs |
Critérios de aceite
GET /detailretorna Info + Completion + Comments + Audit + Media no contrato FE- Coluna COMP DOC do board via
docStatusnoWorkOrderBoardRowDto(Fase 1) CompletionDocTemplateCRUD admin + lookup porserviceKey/workOrderTypePOST completion-docpersiste attachment, defineDocStatus=Yes, audit- Comments/Audit tabs sem adapter no FE
- Media com
category; legado mapeado - Endpoints legados (
GetWorkorderById,GetCommentsByWorkorderId) inalterados - Testes: DocStatus PATCH, detail, completion upload, comments, media
Fora de escopo
- Geração de PDF server-side
- Alteração Vendor Portal checklist/signoff
- Rollout / sunset Blazor (Fase 7)