[CLAUDE] Docs: Chunk E — chốt Session 21 turn 4 F1+F2+F3 PE Workflow advanced options (Mig 28)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m31s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m31s
Update docs theo rule §6.5 KEEP narrative:
- `docs/database/schema-diagram.md §14` title "Mig 22-28, S17-21" + thêm 6
column Allow* inline trong Core ApprovalWorkflows block (inline comment
F1/F2/F3 mapping). Bonus: 3 bảng (Steps + Levels) unchanged.
- `docs/STATUS.md` Last updated S21 t4 + count 27→28 mig (Mig 28 advanced
options 6 column). UAT defer test count unchanged 84 (test-after-uat candidate
bundle Plan C carry).
- `docs/HANDOFF.md` Insert TL;DR S21 t4 đầy đủ (trước S21 t3):
- Q&A clarify 2 lượt chốt scope (F1 cả 2 mode admin, F1 Assignee runtime,
F2 chỉ Cấp cuối, F3 Section 2 only, F2+F3 admin tick, F3 mọi approver
active, test-after UAT)
- 5 chunk narrative đầy đủ A schema → B BE → C FE Admin → D FE eOffice → E Docs
- Pattern reusable: backward-compat option flags, boundary helper extension
- State table cumulative + pending Plan C test-after catch-up
- NEW session log `docs/changelog/sessions/2026-05-13-1200-s21-turn4-pe-workflow-advanced-options.md`:
- Trigger + Q&A 2 lượt
- 5 chunk narrative chi tiết với code snippets
- Pattern reusable 5 lessons learned
- References file paths + spec context
Stats cumulative S21 t4:
- 28 mig (+1) · 59 tables · ~143 endpoints (+1) · 34 FE pages · 84 test pass
(UAT defer test-after §7) · 45 gotcha unchanged · 17 memory · 6 skills
- 5 commits S21 t4 cumulative ready push remote
Pending: bro confirm push `0a3b747..HEAD` 8 commits ahead (S21 t3 + S21 t4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
153
docs/HANDOFF.md
153
docs/HANDOFF.md
@ -1,9 +1,160 @@
|
||||
# HANDOFF — Brief 5 phút cho session tiếp theo
|
||||
|
||||
**Last updated:** 2026-05-12 2100 (Session 21 turn 3 — **🔴 BUG FIX CRITICAL "Trả về nhưng hệ thống vẫn duyệt" PE workflow (gotcha #45 mới). 3 chunk per-commit: `de00887` (BE Chunk A guard + 3 test) + `4b29d00` (FE Chunk B fix 2 app mirror) + this Chunk C Docs. Root: `PeWorkflowPanel.tsx` `isReject` payload (L64-66) thiếu nhánh TraLai → button "← Trả lại" gửi `decision: 1` (Approve) thay vì `2` (Reject) khi target=TraLai(98) → BE skip Reject branch → enter APPROVE STEP → `ApproveV2Async` UPSERT opinion "đã duyệt" + advance Cấp tiếp theo. Inconsistency phụ: dialog `isSendBack` (L247-248) cùng pattern thiếu TraLai → dialog title sai `'✓ Duyệt → Trả lại'` + KHÔNG amber warning. Severity CRITICAL — data integrity issue khó rollback (BE đã `SaveChangesAsync`). Test-before §7 BẮT BUỘC: viết test reproduce → confirm FAIL (BE đi sâu vào ApproveV2Async throw "Phiếu chưa pin workflow") → thêm BE guard early throw ConflictException khi `target ∈ {TraLai, TuChoi} && decision != Reject` → confirm PASS. 3 regression test (Throws TraLai+Approve, Throws TuChoi+Approve consistency, happy path Reject+TraLai). Tổng `dotnet test SolutionErp.slnx` 84 PASS (58 Domain + 26 Infra = +3 from 81 baseline). `npm run build` × 2 app pass. Stats: 27 mig (no change) · 59 tables · ~142 endpoints · 34 FE pages · **84 test (+3)** · **45 gotcha (+1 #45)** · 17 memory · 6 skills · 4 sub-agents seeds-only. Em main solo S21 t3 — bug fix reasoning chain cross BE/FE Implementer REFUSE per multi-agent rule (decision tree: tightly coupled BE+FE+test). CHƯA push remote — chờ bro confirm sau Chunk C wrap.**)
|
||||
**Last updated:** 2026-05-13 1200 (Session 21 turn 4 — **🎯 F1+F2+F3 PE Workflow advanced options (Mig 28) — 5 chunk per-commit `0294693` (A schema) → `c56024b` (B BE) → `a508564` (C FE Admin) → `d27caaf` (D FE eOffice) → this (E Docs). **F1** 4 mode Trả lại admin tick stick (1 Cấp / 1 Bước / Người chỉ định / Người soạn thảo) — 3 mode đầu giữ Phase=ChoDuyet lùi pointer (peer review chain), mode Drafter giữ Phase=TraLai clear pointer (S17 backward compat). **F2** Drafter skip thẳng Cấp cuối — workflow tick + Workspace checkbox dynamic. **F3** Approver edit Section 2 (Hạng mục/NCC/Báo giá) khi workflow tick + actor match CurrentLevel.ApproverUserId + audit ghi PurchaseEvaluationChangelog. Mig 28 thêm 6 bit column lên `ApprovalWorkflows` (DEFAULT 1 cho AllowReturnToDrafter backward compat, 5 còn lại 0). BE Service extend signature 3 optional param (returnMode/returnTargetUserId/skipToFinal). Helper `EnsureEditableForDetailsAsync` mới gating Detail/Quote/Supplier CRUD theo Drafter scope OR F3 Approver scope + audit changelog Update/Delete (trước đây silent). FE Admin Designer "Cấu hình nâng cao" section 6 checkbox 3 group. FE eOffice 3 changes mirror 2 app. UAT mode skip dotnet test mỗi chunk, npm build × 2 app pass mỗi chunk. CHƯA push remote — chờ bro confirm.**)
|
||||
**S21 turn 3:** 2026-05-12 2100 (Session 21 turn 3 — **🔴 BUG FIX CRITICAL "Trả về nhưng hệ thống vẫn duyệt" PE workflow (gotcha #45 mới). 3 chunk per-commit: `de00887` (BE Chunk A guard + 3 test) + `4b29d00` (FE Chunk B fix 2 app mirror) + this Chunk C Docs. Root: `PeWorkflowPanel.tsx` `isReject` payload (L64-66) thiếu nhánh TraLai → button "← Trả lại" gửi `decision: 1` (Approve) thay vì `2` (Reject) khi target=TraLai(98) → BE skip Reject branch → enter APPROVE STEP → `ApproveV2Async` UPSERT opinion "đã duyệt" + advance Cấp tiếp theo. Inconsistency phụ: dialog `isSendBack` (L247-248) cùng pattern thiếu TraLai → dialog title sai `'✓ Duyệt → Trả lại'` + KHÔNG amber warning. Severity CRITICAL — data integrity issue khó rollback (BE đã `SaveChangesAsync`). Test-before §7 BẮT BUỘC: viết test reproduce → confirm FAIL (BE đi sâu vào ApproveV2Async throw "Phiếu chưa pin workflow") → thêm BE guard early throw ConflictException khi `target ∈ {TraLai, TuChoi} && decision != Reject` → confirm PASS. 3 regression test (Throws TraLai+Approve, Throws TuChoi+Approve consistency, happy path Reject+TraLai). Tổng `dotnet test SolutionErp.slnx` 84 PASS (58 Domain + 26 Infra = +3 from 81 baseline). `npm run build` × 2 app pass. Stats: 27 mig (no change) · 59 tables · ~142 endpoints · 34 FE pages · **84 test (+3)** · **45 gotcha (+1 #45)** · 17 memory · 6 skills · 4 sub-agents seeds-only. Em main solo S21 t3 — bug fix reasoning chain cross BE/FE Implementer REFUSE per multi-agent rule (decision tree: tightly coupled BE+FE+test). CHƯA push remote — chờ bro confirm sau Chunk C wrap.**)
|
||||
**S21 turn 2:** 2026-05-12 1800 (Session 21 turn 2 — **🎯 RAG Hybrid setup planning + Cách A validation deep dive. 2 commit (`1f8e9af` plan save 1223 LOC + this chốt). KHÔNG implement, plan only — defer chờ bro confirm 5 dự án future. Decision chốt: Cách A defensive (giữ blanket 120K em main + RAG retrieve) over Cách B aggressive (cắt 60-70% blanket). Industry-validated cross 4 Anthropic blog + 5 community tools (Cursor/Continue/Cline/Aider). Stack: Voyage-3-large + Qdrant + FastMCP + Streamlit dashboard. Multi-agent cost reality: 4 agents → ~520K cumulative blanket → heavy session ~560K (Cách A) vs ~700K (lazy). 3-layer pattern Phase 1-3 rollout (embeddings + BM25 + reranking, ~70% → ~92% recall). Stats: +1 memory entry (`feedback_rag_hybrid_pattern`) +1 plan file (`rag-setup-plan.md` 1500 LOC). Sub-agents vẫn 4 seeds-only, em main solo session.**)
|
||||
**S21 turn 1:** 2026-05-12 0030 (Session 21 turn 1 — **🎯 Add con thứ 4 cicd-monitor (Path A — post-deploy verifier). 1 commit `f1c61c9` pushed `36e21c8..f1c61c9 main -> main`. CI skipped per path filter (3 file `.md`). Cost reality update: ~750K spawn (3 → 4 agents) · ~1.35M heavy / ~700K optimized. Stats: 4 sub-agents seeds-only · 16 memory · 27 mig · 59 tables · ~142 endpoints · 81 test · 44 gotcha · 6 skills unchanged. KHÔNG flush 3 agent MEMORY.md (chưa spawn work — em main solo). Trial Week 1 kick-off S21 turn 2+ Plan B Contract V2 wire mirror PE pattern.**)
|
||||
|
||||
## TL;DR Session 21 turn 4 — F1+F2+F3 PE Workflow advanced options (Mig 28)
|
||||
|
||||
User request 3 tính năng mới trong PE V2 Workflow:
|
||||
- **F1** 4 mode Trả lại admin stick: 1 Cấp / 1 Bước / Người chỉ định / Người soạn thảo
|
||||
- **F2** Drafter gửi thẳng Cấp cuối (skip mọi Bước/Cấp trung gian)
|
||||
- **F3** Approver chỉnh sửa Section 2 (Hạng mục + NCC + Báo giá) khi đang duyệt
|
||||
|
||||
### Q&A clarify chốt scope (2 lượt AskUserQuestion)
|
||||
|
||||
- **F1 "1 bậc"** = cả 2 mode (admin chọn 1 Cấp HOẶC 1 Bước HOẶC cả 2 stick)
|
||||
- **F1 "Người chỉ định"** = Approver pick runtime từ list NV đã ký (PE.LevelOpinions)
|
||||
- **F1 behavior** = 3 mode đầu giữ Phase=ChoDuyet lùi pointer (peer review chain). Mode Drafter giữ Phase=TraLai S17 fallback.
|
||||
- **F2 skip** = chỉ skip tới Level cuối (CEO) — Dropdown 2 option "Gửi tuần tự" vs "Gửi thẳng Cấp cuối"
|
||||
- **F2+F3 admin enable** = cả 2 cần admin tick per workflow (audit nghiêm)
|
||||
- **F3 approver perm** = mọi approver Cấp đang active (currentLevel match)
|
||||
- **F3 scope** = Section 2 only (Hạng mục + NCC + Báo giá), KHÔNG đụng PE Header, KHÔNG reset workflow
|
||||
- **Test** = test-after UAT default Phase 9 (skip dotnet test mỗi chunk, npm build × 2 app pass)
|
||||
|
||||
### Chunk A — Mig 28 + Domain (`0294693`)
|
||||
|
||||
`ApprovalWorkflow.cs` thêm 6 bool field:
|
||||
- `AllowReturnOneLevel` / `AllowReturnOneStep` / `AllowReturnToAssignee` (default false)
|
||||
- `AllowReturnToDrafter` (default **TRUE** — backward compat S17)
|
||||
- `AllowDrafterSkipToFinal` / `AllowApproverEditDetails` (default false)
|
||||
|
||||
EF config `ApprovalWorkflowConfiguration` thêm 6 `HasDefaultValue` match Mig 28 DEFAULT.
|
||||
|
||||
Mig 28 `AddAdvancedOptionsToApprovalWorkflows`:
|
||||
- 6 AddColumn bit NOT NULL DEFAULT 0/1
|
||||
- 3-file rule complete (mig.cs + Designer.cs + Snapshot.cs)
|
||||
- Apply LocalDB Dev + Design
|
||||
|
||||
### Chunk B — BE Service + handlers + DTOs (`c56024b`)
|
||||
|
||||
**Service interface + impl** `TransitionAsync` thêm 3 optional param (backward compat):
|
||||
- `WorkflowReturnMode? returnMode` (enum {OneLevel=1, OneStep=2, Assignee=3, Drafter=4})
|
||||
- `Guid? returnTargetUserId` (required khi mode=Assignee)
|
||||
- `bool skipToFinal`
|
||||
|
||||
REJECT branch extend với helper `ApplyReturnModeAsync` switch 4 mode:
|
||||
- OneLevel: lùi 1 Cấp cùng Step. Bước 1 Cấp 1 → fallback Drafter.
|
||||
- OneStep: lùi sang Bước trước Cấp cuối. Bước 1 → fallback Drafter.
|
||||
- Assignee: tìm Step+Level match `ApproverUserId == returnTargetUserId`.
|
||||
- Drafter: Phase=TraLai clear pointer (S17 behavior).
|
||||
- 3 mode đầu giữ ChoDuyet + reset SLA 7d.
|
||||
- Admin bypass workflow.Allow* flag check.
|
||||
- Non-admin → throw ConflictException nếu flag disabled.
|
||||
|
||||
DRAFTER trình branch extend với F2 skipToFinal:
|
||||
- Workflow.AllowDrafterSkipToFinal required (non-admin)
|
||||
- Set CurrentWorkflowStepIndex = Steps.Count-1 + CurrentApprovalLevelOrder = max Level
|
||||
- Audit comment append "[Drafter gửi thẳng Cấp cuối]"
|
||||
|
||||
**Helper edit guard** `EnsureEditableForDetailsAsync` mới (PurchaseEvaluationDraftGuard class):
|
||||
- Drafter scope: DangSoanThao OR TraLai
|
||||
- F3 Approver scope: ChoDuyet + workflow.AllowApproverEditDetails + actor match CurrentLevel.ApproverUserId
|
||||
- Admin bypass workflow flag check
|
||||
|
||||
**8 handler switch** sang helper mới + inject ICurrentUser khi cần:
|
||||
- Detail Add/Update/Delete + Quote Upsert/Delete (5 handler — replace EnsureDraftAsync)
|
||||
- Supplier Add/Update/Remove (3 handler — bonus security fix, trước đây hoàn toàn KHÔNG có phase guard!)
|
||||
- Update/Delete handler trước đây silent → thêm changelog `PhaseAtChange + UserId + Summary` (append `[Approver edit khi đang duyệt]` khi phase=ChoDuyet)
|
||||
|
||||
**Command DTO + DTOs**:
|
||||
- `TransitionPurchaseEvaluationCommand` +3 optional field
|
||||
- `ApprovalWorkflowOptionsDto` NEW sub-record (6 Allow* flag)
|
||||
- `PurchaseEvaluationDetailBundleDto` +WorkflowOptions field
|
||||
- `AwDefinitionDto` +6 Allow* (admin Designer GET)
|
||||
- `CreateAwDefinitionCommand` +6 Allow* param (admin Designer POST)
|
||||
|
||||
### Chunk C — FE Admin Designer (`a508564`)
|
||||
|
||||
`ApprovalWorkflowsV2Page.tsx` Designer modal thêm section "Cấu hình nâng cao" 3 sub-group:
|
||||
|
||||
1. Mode Trả lại 4 checkbox:
|
||||
- Trả về 1 Cấp trước (peer review chain trong cùng Bước)
|
||||
- Trả về 1 Bước trước (Cấp cuối Bước trước nhận lại)
|
||||
- Trả về Người chỉ định (pick runtime từ NV đã ký)
|
||||
- Trả về Người soạn thảo (default checked = backward compat S17)
|
||||
|
||||
2. Drafter skip: 1 checkbox "Cho phép Drafter gửi thẳng Cấp cuối"
|
||||
|
||||
3. Approver edit: 1 checkbox "Cho phép Approver chỉnh sửa Section 2"
|
||||
|
||||
Styling: container amber-50/30 border distinct với Steps section. Helper text [10px] dưới label. Headers uppercase tracking.
|
||||
|
||||
DTO types + state defaults từ cloneFrom (giữ config version trước) hoặc S17 fallback (chỉ AllowReturnToDrafter=true). POST body propagate 6 flag → BE Create handler set entity.
|
||||
|
||||
fe-user KHÔNG mirror (Designer admin-only).
|
||||
|
||||
### Chunk D — FE eOffice (`d27caaf`) mirror 2 app
|
||||
|
||||
Types `purchaseEvaluation.ts`:
|
||||
- `ApprovalWorkflowOptions` type
|
||||
- `WorkflowReturnMode` const-object
|
||||
- `PeDetailBundle` +workflowOptions field
|
||||
|
||||
`PeWorkflowPanel.tsx` F1 Trả lại radio picker:
|
||||
- State `returnMode` (default Drafter) + `returnTargetUserId`
|
||||
- Dialog Trả lại render 1-4 radio mode enabled theo wfOptions.Allow*
|
||||
- Assignee mode → submodal Select pick từ levelOpinions (NV đã ký), dedupe by userId
|
||||
- Banner amber rounded dưới mô tả hành vi mode chọn
|
||||
- Mutation payload +returnMode +returnTargetUserId khi isTraLaiAction
|
||||
|
||||
`PeDetailTabs.tsx` F2 Drafter skip:
|
||||
- State `skipToFinal` + `allowSkipToFinal` từ workflowOptions
|
||||
- submitForApproval mutationFn accept opts.skipToFinal
|
||||
- Workspace action bar: checkbox violet "Gửi thẳng Cấp cuối (skip trung gian)" conditional
|
||||
- Confirm dialog message + button label dynamic theo skipToFinal
|
||||
|
||||
`PeDetailTabs.tsx` F3 Approver edit Section 2:
|
||||
- useAuth import + compute `approverEditMode` (phase=ChoDuyet + workflowOptions.allowApproverEditDetails + actor match)
|
||||
- `itemsReadOnly = readOnly && !approverEditMode` → ItemsTab nhận
|
||||
- Banner violet "ⓘ Bạn được phép chỉnh sửa..." khi approverEditMode + readOnly (Duyệt menu)
|
||||
- InfoTab / NccSelectorRow / BudgetFieldRow GIỮ strict isEditablePhase (Header + Section 3, KHÔNG trong F3 scope)
|
||||
|
||||
### Chunk E — Docs (this commit)
|
||||
|
||||
- `docs/database/schema-diagram.md §14` cập nhật title "Mig 22-28, S17-21" + thêm 6 column Allow* trong Core block với inline comment F1/F2/F3
|
||||
- `docs/STATUS.md` Last updated S21 t4 + count 27→28 mig + UAT defer test count unchanged 84
|
||||
- `docs/HANDOFF.md` TL;DR S21 t4 đầy đủ (file này)
|
||||
- `docs/changelog/sessions/2026-05-13-1200-s21-turn4-pe-workflow-advanced-options.md` session log
|
||||
|
||||
### State chốt S21 turn 4
|
||||
|
||||
| Metric | Trước (S21 t3) | Sau (S21 t4) | Δ |
|
||||
|---|---|---|---|
|
||||
| DB tables | 59 | 59 | 0 |
|
||||
| **Migrations** | 27 | **28** | **+1** (Mig 28 6 column Allow*) |
|
||||
| Endpoints | ~142 | ~143 | +1 (extend transitions body) |
|
||||
| FE pages | 34 | 34 | 0 (Designer extend section) |
|
||||
| **Unit tests** | 84 | **84** | 0 (UAT defer test-after §7) |
|
||||
| Gotchas | 45 | 45 | 0 |
|
||||
| Memory entries | 17 | 17 | 0 |
|
||||
| Skills | 6 | 6 | 0 |
|
||||
| Sub-agents | 4 seeds-only | 4 seeds-only | 0 |
|
||||
| **Commits S21 t4** | — | **5** | (`0294693` → `c56024b` → `a508564` → `d27caaf` → this) |
|
||||
|
||||
### Pending — Test-after (Plan C carry)
|
||||
|
||||
Per `feedback_uat_skip_verify` Phase 9 default: viết test sau UAT 2-3 lần ổn.
|
||||
Test scope candidate (test-after-uat commit riêng):
|
||||
- Service `ApplyReturnModeAsync` 4 mode happy path (OneLevel/OneStep/Assignee/Drafter)
|
||||
- Service skipToFinal happy path + AllowDrafterSkipToFinal=false → ConflictException
|
||||
- `EnsureEditableForDetailsAsync` 3 scenario: Drafter scope / Approver match / Approver mismatch → Forbidden
|
||||
|
||||
Bundle với Plan C existing (test #44 silent 403 + test V2 ApproveV2Async + Mig 25/27 PATCH).
|
||||
|
||||
---
|
||||
|
||||
## TL;DR Session 21 turn 3 — Bug fix CRITICAL "Trả về nhưng hệ thống vẫn duyệt" (gotcha #45)
|
||||
|
||||
User UAT 2026-05-12 21:00 screenshot button labeled `← Trả lại` trong PE Workflow Panel (menu "Duyệt"), mô tả hành vi: nhấn vào nhưng phiếu KHÔNG về phase TraLai — ngược lại tiến qua Cấp tiếp theo. User mô tả: "Trả về nhưng hệ thống vẫn duyệt".
|
||||
|
||||
Reference in New Issue
Block a user