[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>
This commit is contained in:
pqhuy1987
2026-05-07 21:03:56 +07:00
parent 835cc7f17f
commit 38d10b7897
4 changed files with 227 additions and 2 deletions

View File

@ -0,0 +1,158 @@
# 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)
```javascript
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 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).