Session 15 (2026-05-07) docs update: STATUS.md: - Last updated Session 15 (1 commit `835cc7f` tooltip + working tree drastic refactor revert) - Recently Done row Session 15 chi tiết (diagnose + plan drastic + attempt 12 file edits + REVERT decision) HANDOFF.md: - TL;DR Session 15 prepend với 2 phần: Diagnose tooltip + Drastic refactor DEFER decision - 4 cảnh báo Session 16+: Drastic refactor pending (8-10h dedicated hoặc fallback Approach Y), Task 2 sample seed pending, schema-diagram defer cron audit, Hard blockers giữ nguyên migration-todos.md: - Phase 9 + Session 15 block với 1 task done (tooltip) + 1 defer (drastic refactor) + memory entry note - Defer Session 16+ list Session log NEW `2026-05-07-2600-tooltip-defer-drastic.md`: - Bối cảnh user UAT báo button silent disabled - Phần 1 — Diagnose tooltip (root cause + fix UX + "trùng ID" KHÔNG phải bug FE) - Phần 2 — Plan drastic refactor flat workflow → DEFER: * User spec mới (Phòng × Cấp × Users[] flat) * Plan 6 chunk + estimate scope realistic ~8-10h * Attempt 12 file working tree edits → REVERT decision * Memory entry capture decision rule - Plan organization sau S15 (defer queue) Memory entry NEW `feedback_drastic_refactor_scope.md`: - Quy tắc: drastic refactor cần dedicated session, scope conservative 2x buffer - Anti-patterns mid-session big refactor + commit broken state - Defer pattern (revert working tree → document → memory entry → surface trade-off cho user) - Cross-ref `feedback_per_chunk_commit.md` discipline 🎉 Session 15 wrap-up. Cumulative since session start (13h17): 16 commit (1 button removal + 6 PE N-stage + 5 Contract N-stage + 1 3-button + 1 Session 14 wrap-up + 1 tooltip + 1 Session 15 wrap-up). Verify: dotnet test 96 pass + working tree clean. Defer Session 16+ priority order: 1. Drastic refactor flat workflow (dedicated session ~8-10h) OR fallback Approach Y (FE flat UI 5 phòng, 1-2h) 2. Task 2 sample data seed N-stage 3. Hard blockers Ops (UAT, SMTP, etc.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.4 KiB
Session 2026-05-07 (S15) — Tooltip diagnose "Lưu & Gửi Duyệt" + drastic refactor DEFER
Dev: Claude
Duration: ~1h
Base commit: 7c83ac8 (sau Session 14 wrap-up docs)
Final commit: 835cc7f (+ working tree refactor revert)
Total commits: 1
Bối cảnh
User UAT live screenshot phiếu PE Bản nháp "huy test 1" (PE/2026/A/004) trên eoffice.solutions.com.vn/purchase-evaluations/workspace?type=1&id=.... Báo button "Lưu & Gửi Duyệt" KHÔNG hoạt động + suy đoán "Hình nó đang bị trùng ID với thằng khác? Mỗi lần tạo mới Phiếu Duyệt NCC là 1 phiếu độc lập nhé".
Phần 1 — Diagnose tooltip (commit 835cc7f)
Root cause analysis
PeDetailTabs.tsx line 220: disabled={!canSubmitForApproval || submitForApproval.isPending}. Khi canSubmitForApproval=false button visually clickable nhưng không fire onClick → user không biết tại sao silent.
canSubmitForApproval = mode === 'workspace' && canEditPhase && !readOnly && evaluation.workflow.nextPhases.some(p => p !== TuChoi && p !== TraLai).
Hypothesis: phiếu pin WorkflowDefinitionId của 1 version cấu hình thiếu adjacent step → policy.NextPhasesFrom(DangSoanThao) empty (legacy data hoặc admin chưa setup workflow).
Fix UX (PeDetailTabs.tsx, fe-admin + fe-user mirror)
const forwardPhase = evaluation.workflow.nextPhases.find(p =>
p !== TuChoi && p !== TraLai)
const canSubmitForApproval = mode === 'workspace' && canEditPhase && !readOnly && forwardPhase != null
const submitDisabledReason = !canEditPhase
? `Phiếu đã ở phase X — chỉ Bản nháp / Trả lại mới sửa + gửi được.`
: readOnly
? 'Chế độ chỉ đọc.'
: !forwardPhase
? `Workflow không có phase tiếp theo từ X. Liên hệ admin kiểm tra cấu hình quy trình.`
: null
Button:
title={submitDisabledReason ?? "Gửi phiếu sang \"<forward phase label>\""}— hover tooltip show reason hoặc forward phase- Dialog confirm thay text generic "Gửi phiếu vào quy trình duyệt?" → explicit "Sẽ chuyển sang "Chờ Purchasing". Sau khi gửi sẽ KHÔNG sửa được nữa (trừ khi approver Trả lại)."
Mirror fe-admin + fe-user. KHÔNG đụng BE.
Build pass cả 2 app.
"Trùng ID" KHÔNG phải bug FE
PurchaseEvaluationWorkspacePage.tsx URL state đúng:
+ Thêm mới→setParams({ mode: 'new', id: null })- POST tạo phiếu → BE gen new GUID + MaPhieu mới (atomic SERIALIZABLE qua
PurchaseEvaluationCodeGenerator) - Save → URL set
id=<new>thay thế
Mỗi PE row unique GUID + MaPhieu (UNIQUE filtered). Không có path share ID. User suy đoán có thể do button silent disabled → tưởng load lại record cũ.
Phần 2 — Plan drastic refactor flat workflow → DEFER
User chốt drastic refactor: "bỏ phase enum hoàn toàn, dùng ChoDuyet=10 đơn nhất + currentStepIndex tracking".
Spec mới (theo user)
Workflow = list flat (Phòng × Cấp × Users[]). Ví dụ Quy trình A:
- Phòng A (2 cấp): cấp 1 NV A, cấp 2 NV B
- Phòng B (3 cấp): cấp 1 NV C, cấp 2 [NV D 1, D 2, D 3], cấp 3 NV E
- Phòng C (1 cấp): NV C
Rules:
- Phòng 1 cấp → 1 user duyệt = pass phòng đó
- Phòng N cấp → tuần tự cấp 1 → 2 → ... → N
- Cùng cấp + cùng phòng = OR (1 user duyệt = pass cấp)
- Hết tất cả phòng → DaDuyet
- PE pin Quy trình ID, không thay đổi giữa chừng
Plan refactor 6 chunk (theo feedback_per_chunk_commit.md)
| Chunk | Scope | Estimate |
|---|---|---|
| A | Domain enum + entity changes + Migration 21 | 50min |
| B | App CQRS + Policy registry rewrite | 45min |
| C | PE Service rewrite TransitionAsync flat | 2-3h |
| D | Contract Service rewrite + Tests update (drop 12 N-stage tests) | 1.5h |
| E | FE Designer flat UI (PeWorkflowsPage + WorkflowsPage) | 1.5h |
| F | FE PeWorkflowPanel + Docs | 1h |
Tổng realistic: ~8-10h focused. Vượt session boundary + risk session deep ~30 commits.
Attempt → REVERT
Edit working tree 12 file (Chunk A partial):
PurchaseEvaluationPhase.cs: + ChoDuyet=10 enum valueContractPhase.cs: + ChoDuyet=10PurchaseEvaluation.cs: + CurrentWorkflowStepIndex, RejectedAtStepIndexContract.cs: + same 2 fieldsWorkflowDefinition.cs(Contract): drop class WorkflowStepInnerStep + nav, WorkflowStep + DepartmentId, PositionLevelPurchaseEvaluationWorkflowDefinition.cs: same patternContractDepartmentApproval.cs: drop InnerStepIdPurchaseEvaluationDepartmentApproval.cs: drop InnerStepIdWorkflowDefinitionConfiguration.cs: drop InnerStep config + add DeptId/PositionLevel cấu hình + FK RestrictPurchaseEvaluationConfiguration.cs: sameDepartmentApprovalsConfiguration.cs: drop InnerStepId FK + filtered indexes, restore simple unique non-filteredApplicationDbContext.cs: drop DbSet<*WorkflowStepInnerStep> × 2
Realize codebase chưa compile (Service + App + Tests dùng WorkflowStepInnerStep đã drop). Need rewrite ALL dependent code trong cùng Chunk A → blow scope vượt session.
Decision REVERT working tree về 835cc7f clean. Tests 96 pass intact.
Memory entry mới
feedback_drastic_refactor_scope.md — decision rule: drastic refactor cần dedicated session với context fresh, scope estimation conservative (2x buffer), tránh mid-session big refactor (risk session context deep + breaking states giữa chunk + tests rewrite biggest risk).
Verify
- ✅
git restore12 files reverted - ✅
dotnet test96 pass (54 + 42) — state intact - ✅ working tree clean (chỉ 2 untracked .zip backup files)
- ✅ commit
835cc7f(tooltip) pushed gitea OK
Stats cumulative (sau Session 15)
| Trước S15 | Sau S15 | Diff | |
|---|---|---|---|
| BE LOC | ~15800 | ~15800 | 0 (FE-only commit + revert) |
| Migrations | 20 | 20 | 0 |
| DB tables | 57 | 57 | 0 |
| FE pages | 32 | 32 | 0 |
| Tests | 96 | 96 | 0 |
| Docs | ~58 | ~59 | +1 (session log này) |
| Memory entries | 11 | 12 | +1 (drastic refactor scope) |
| Commits S15 | — | +1 | 835cc7f |
Plan organization sau Session 15
Plan cha: Phase 9 active — UAT
├── Plan con A-S14: Tất cả ✅ DONE (xem session logs trước)
├── Plan con S15: Tooltip diagnose + drastic refactor DEFER
│ ├── ✅ FE PE button "Lưu & Gửi Duyệt" tooltip + dialog reason rõ
│ └── ⏸ Drastic refactor flat workflow — DEFER session sau (~8-10h)
└── Plan con Defer S16+:
├── Drastic refactor flat workflow (Mig 21, ~8-10h, dedicated session)
│ OR fallback Approach Y (FE flat UI giới hạn 5 phòng, 1-2h)
├── Task 2 sample data seed N-stage (block DesignTime vs Runtime DB)
├── Budget N-stage (cần migration `AddBudgetVersionedWorkflow`)
├── schema-diagram §17-19 Mig 18-20 (defer cron audit 2026-06-01)
└── Hard blockers Ops (UAT, SMTP, Rotate creds, SQL backup, Remove huypham.vn, win-acme)
Handoff
UAT iteration mode. Phiếu PE Bản nháp giờ có tooltip rõ reason khi không gửi được. User test hover → biết admin cần kiểm tra cấu hình workflow definition.
Drastic refactor pending dedicated session. Khi resume:
- Fresh session start với context clean
- Plan kỹ 6 chunk per-commit
- Buffer 2x estimate (~16h thực tế nếu phát sinh)
- Test rewrite biggest risk — pattern reusable nhưng nội dung phải mới hoàn toàn
Cron audit kế: 2026-06-01 (~25 ngày).