Files
solution-erp/docs/changelog/sessions/2026-05-07-2600-tooltip-defer-drastic.md
pqhuy1987 38d10b7897 [CLAUDE] Docs: chốt Session 15 wrap-up — tooltip diagnose + drastic refactor DEFER
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>
2026-05-07 21:03:56 +07:00

7.4 KiB
Raw Blame History

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ớisetParams({ 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 value
  • ContractPhase.cs: + ChoDuyet=10
  • PurchaseEvaluation.cs: + CurrentWorkflowStepIndex, RejectedAtStepIndex
  • Contract.cs: + same 2 fields
  • WorkflowDefinition.cs (Contract): drop class WorkflowStepInnerStep + nav, WorkflowStep + DepartmentId, PositionLevel
  • PurchaseEvaluationWorkflowDefinition.cs: same pattern
  • ContractDepartmentApproval.cs: drop InnerStepId
  • PurchaseEvaluationDepartmentApproval.cs: drop InnerStepId
  • WorkflowDefinitionConfiguration.cs: drop InnerStep config + add DeptId/PositionLevel cấu hình + FK Restrict
  • PurchaseEvaluationConfiguration.cs: same
  • DepartmentApprovalsConfiguration.cs: drop InnerStepId FK + filtered indexes, restore simple unique non-filtered
  • ApplicationDbContext.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 restore 12 files reverted
  • dotnet test 96 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:

  1. Fresh session start với context clean
  2. Plan kỹ 6 chunk per-commit
  3. Buffer 2x estimate (~16h thực tế nếu phát sinh)
  4. 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).