[CLAUDE] Docs: Session 17 wrap-up — PE Workflow V2 end-to-end consolidation

User chốt MD wrap-up Session 17 (13 commit từ c847dc0de0f38d) — PE
Workflow V2 schema + Service wire + UX iteration đầy đủ.

MD updates:
- STATUS.md — header counts (24 mig, 58 tables, 81 test, 43 gotcha) +
  Recently Done row consolidate Session 17 wrap-up (gộp 4 row iter cũ
  thành 1 row tổng, không cắt narrative quan trọng)
- HANDOFF.md — TL;DR Session 17 + Chunk E (Designer iter + State
  machine + Service wire + UX) + Pending Session 18+
- CLAUDE.md — count (22→24 mig, 77→81 test) + V2 schema overview
- changelog/migration-todos.md — section  Session 17 done với 7 task
  ticked + Defer Session 18+ explicit
- database/schema-diagram.md — §14 ApprovalWorkflow V2 schema (3 bảng
  + 2 column PE + state transitions + Service branch + Designer
  constraints + match approver V2 vs V1 table)
- gotchas.md — +#42 Dual schema branch + #43 Step.Order ≠ index 0-based
- skill contract-workflow — +section "Phase 9+ done Mig 22-24" với V2
  spec + Service branch + match logic table + Designer constraints +
  UX V2-aware + Defer Session 18+
- changelog/sessions/2026-05-08-1100-pe-workflow-v2-end-to-end.md (NEW)
  — full session log với 13 commit timeline + stats + gotchas + pending

Memory:
- project_solution_erp.md — entry Session 17 wrap-up đầy đủ (KHÔNG tạo
  file feedback mới — decisions specific cho project, không reusable
  cross-project per §9.5 anti-pattern)

Verify:
- 81 test pass (58 Domain + 23 Infra) — không thay đổi sau wrap-up
- 0 BE error
- 2 FE builds OK (đã verify ở các commit trước)
- Quy tắc consolidate §6.5: KHÔNG cắt narrative, chỉ phân tầng + remove
  duplicate. Session 17 row dài cố ý — cover full 13 commit context cho
  Session 18+ đọc lại.
This commit is contained in:
pqhuy1987
2026-05-08 16:40:49 +07:00
parent de0f38dd25
commit 8680f4c849
8 changed files with 411 additions and 19 deletions

View File

@ -166,6 +166,47 @@ Nếu đổi policy BE: chỉ cần update `WorkflowPolicies.Standard` hoặc `W
**Fix:** `IsolationLevel.Serializable` transaction trong `ContractCodeGenerator`. Không skip.
### 42. Dual schema workflow V1 vs V2 — Service phải branch theo pin field (Session 17)
**Symptom:** Phiếu PE pin V2 (`ApprovalWorkflowId` set qua workspace Select) nhưng Service vẫn match approver theo schema cũ (`Dept+PositionLevel`). Approver V2 không duyệt được, button Duyệt báo Forbidden.
**Root cause:** Sau Mig 23-24 entity PE có 2 field workflow pin:
- `WorkflowDefinitionId` (Mig 21 V1 legacy) — pin schema flat cũ
- `ApprovalWorkflowId` (Mig 23 V2 mới) — pin schema 3-table mới
Service trước đó chỉ đọc `WorkflowDefinitionId` → bỏ qua V2.
**Fix (`b41484b`):** `PurchaseEvaluationWorkflowService.TransitionAsync` branch:
```csharp
if (evaluation.ApprovalWorkflowId is Guid awId)
await ApproveV2Async(evaluation, awId, ...); // iterate ApprovalWorkflowSteps + Levels match ApproverUserId
else
await ApproveV1LegacyAsync(evaluation, ...); // iterate WorkflowSteps match Dept+PositionLevel
```
**Pattern reusable** khi wire schema mới song song schema cũ (Contract V2 sắp tới): pin field flag để rẽ logic, KHÔNG drop legacy ngay (giữ backward compat phiếu cũ).
### 43. Step.Order ≠ index 0-based — không thể EF query trực tiếp (Session 17)
**Symptom:** Implement `ResolveV2InboxIdsAsync` (V2-aware Inbox) bằng EF query thẳng:
```csharp
.Where(s => s.Order == e.CurrentWorkflowStepIndex.Value + 1) // FAIL — Step.Order là logical, không phải position
```
Logic sai: `WorkflowStep.Order` không phải position 0-based mà là số sort thứ tự (vd 5, 10, 20). `Steps.OrderBy(s => s.Order).ToList()[idx]` mới đúng.
**Fix:** Precompute candidates EF query → in-memory sort by Order → array index access:
```csharp
var candidates = await db.PE.Where(...).ToListAsync(ct); // Step 1: EF lấy phiếu V2 pending
var workflows = await db.AW.Include(...).ToDictionaryAsync(w => w.Id, ct);
foreach (var c in candidates) {
var steps = wf.Steps.OrderBy(s => s.Order).ToList(); // Step 2: in-memory sort
var step = steps[c.CurrentWorkflowStepIndex.Value]; // Step 3: array index
...
}
```
Trade-off: scalable đến vài trăm phiếu pending, không ngon cho >10k. Optimize sau nếu cần.
## Permission matrix
### 23. Permission update không real-time