[CLAUDE] Docs: Session 25 chốt cuối — Plan AB→AF cumulative 7 commits + 4 agent MEMORY flush
S25 wrap final: - STATUS.md + HANDOFF.md prepend Plan AB→AF cumulative narrative (7 commits cdfd542..506cada + 7 CICD Runs #215-#221) - gotchas.md +2 NEW entries: - #48 Multi-Changelog.Add() SQLite frozen-clock tie-break (Run #215 catch, fix Plan AB Chunk A2) - #49 UI dual-phase badge confusion khi state machine self-loop (Plan AD drop + extractNextTargetHint helper) - Checklist debug bug mới +2 entries (24-25) - Session log NEW docs/changelog/sessions/2026-05-19-s25-pe-history-visibility.md (~360 LOC) - 4 agent MEMORY drift sync: - investigator/MEMORY.md (30→32KB) FIFO entry S25 wrap + count metadata - implementer/MEMORY.md (34→36KB) FIFO entry + patterns 16-18 saved - reviewer/MEMORY.md (31→32KB) FIFO entry + lesson SQLite tie-break + UAT skip risk reinforced - cicd-monitor/MEMORY.md (~72KB CRITICAL OVER) — 7 Run entries #215-#221 + curate flag MAX Memory user-level +2 NEW entries (separate commit memory dir, KHÔNG trong this commit): - feedback_fe_merge_synthetic_audit.md (Plan AC2 pattern) - feedback_fe_usermap_fallback.md (Plan AF pattern) Stats final S25: - 31 mig (no schema) · 59 tables · ~146 endpoints · 35 FE pages - 111 test unchanged (UAT defer test-after per §7) - 49 gotcha (+2: #48 + #49) - 23 memory user-level (+2 NEW S25 patterns) - 6 skills · 4 sub-agents active - 7 commits cumulative S25 · 7 CICD Runs (1 FAIL caught + 6 PASS) - 6× bundle rotate × 2 app (Run #220 BE-only unchanged) Critical pending S26+: - Memory curate cicd-monitor PRIORITY MAX (~72KB strongly over hard threshold) - Plan B Contract V2 wire HIGH priority (5-6 chunk pre-allocated S23 HANDOFF) Per §6.5 KEEP narrative — KHÔNG cut rationale/gotcha context, chỉ phân tầng prepend latest. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -775,6 +775,67 @@ paths-ignore:
|
||||
- CICD Monitor Run #187 (S21 t5 2026-05-13 20:12) — confirmed pattern + cache stale bonus
|
||||
- Memory `feedback_multi_agent_setup` Plan G Trial Week 1 evidence
|
||||
|
||||
### 48. Multi-Changelog.Add() trong cùng SaveChangesAsync → SQLite frozen-clock tie-break → tests `OrderByDescending(CreatedAt).First()` non-deterministic (Session 25 Plan AB + Run #215 catch)
|
||||
|
||||
**Triệu chứng:** Plan AB Chunk A `cdfd542` add SECOND Changelog.Add() entry vào `ApplyReturnModeAsync` (cover Bug 2 — Return mode log) end-of-function. Caller `TransitionAsync:100` đã có sẵn `LogTransitionAsync` add FIRST Changelog entry (Action=Transition + ContextNote=comment chứa "không lùi được"). 2 entries cùng `SaveChangesAsync` transaction → SQLite test fixture frozen clock → CreatedAt **identical microseconds** cho cả 2 rows.
|
||||
|
||||
Plan M edge case tests (S23 t3) query `.OrderByDescending(c => c.CreatedAt).FirstAsync()` assert `ContextNote.Contains("không lùi được")` — sau Plan AB, SQLite tie-break non-deterministic, pick Plan AB row (EntityType=Workflow, Action=Update, ContextNote=null) → `Expected ContextNote not to be <null>` FAIL.
|
||||
|
||||
**CI Run #215 sha=cdfd542** test_infra FAIL 2/53 (51 PASS, 2 FAIL):
|
||||
- `ApplyReturnMode_OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet` (line 350)
|
||||
- `ApplyReturnMode_OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet` (line 308)
|
||||
|
||||
Test gate caught regression → deploy never reached → prod spared broken state.
|
||||
|
||||
**Fix Option A (chốt):** Test query filter by `Summary.Contains("Chuyển phase")` để pick đúng LogTransition entry. Plan AB BE code stays clean.
|
||||
|
||||
```csharp
|
||||
// Trước Plan AB Chunk A2:
|
||||
var changelog = await db.PurchaseEvaluationChangelogs
|
||||
.Where(c => c.PurchaseEvaluationId == pe.Id)
|
||||
.OrderByDescending(c => c.CreatedAt)
|
||||
.FirstAsync();
|
||||
|
||||
// Sau Plan AB Chunk A2 fix (commit 8c05947):
|
||||
var changelog = await db.PurchaseEvaluationChangelogs
|
||||
.Where(c => c.PurchaseEvaluationId == pe.Id && c.Summary!.Contains("Chuyển phase"))
|
||||
.OrderByDescending(c => c.CreatedAt)
|
||||
.FirstAsync();
|
||||
```
|
||||
|
||||
**Pattern reusable:** Khi handler/service add NEW Changelog row trong existing flow đã có LogTransition row, tests query audit table MUST filter EntityType / Action / Summary keyword **discriminator** thay vì raw OrderByDescending timestamp. Cross-ref Contract V2 test setup tương lai.
|
||||
|
||||
**Severity:** Major — caught by CI before prod ship, no user impact. Lesson reinforced UAT mode `feedback_uat_skip_verify` skip `dotnet test` per chunk RISK khi BE refactor > 100 LOC + signature change → em main resumed local test verify post Plan AB Chunk A2.
|
||||
|
||||
**References:**
|
||||
- Plan AB Chunk A commit `cdfd542` (Run #215 FAIL)
|
||||
- Plan AB Chunk A2 fix commit `8c05947` (Run #216 PASS)
|
||||
- Memory `feedback_uat_skip_verify` lesson reinforced S25
|
||||
- File: `tests/SolutionErp.Infrastructure.Tests/Services/PurchaseEvaluationWorkflowServiceReturnModeTests.cs:304-310, 346-352`
|
||||
|
||||
### 49. UI dual-phase badge `fromPhase → toPhase` gây nhầm khi 3/4 Reject mode giữ Phase=ChoDuyet (Session 25 Plan AD)
|
||||
|
||||
**Triệu chứng:** Bro UAT 2026-05-19 Plan AC deploy: panel "Lịch sử duyệt" 6 entries TẤT CẢ hiện `Đã gửi duyệt → Đã gửi duyệt` (vì 3 mode Return OneLevel/OneStep/Assignee giữ Phase=ChoDuyet sau Mig 28 — chỉ Drafter mode set TraLai). Reject entry visually IDENTICAL Approve entry → user nhầm "Đã trả lại nhưng vẫn hiện đã duyệt".
|
||||
|
||||
**Fix Plan AD (commit `0aaf2df`):**
|
||||
|
||||
1. **Drop fromPhase → toPhase badges entirely** trong ApprovalsTab (cả `fe-user` + `fe-admin` mirror §3.9). Visual confusion gỡ bỏ.
|
||||
|
||||
2. **Thay bằng next-target hint parse từ comment** via helper `extractNextTargetHint(decision, toPhase, comment)`:
|
||||
- **Approve:** Summary "sang Cấp X" → "→ Cấp X", "sang Bước Y" → "→ Bước Y (Cấp 1)", "Duyệt vượt cấp" → "→ Vượt cấp tới Cấp cuối", toPhase=DaDuyet(20) → "→ Đã duyệt hoàn tất"
|
||||
- **Reject:** ContextNote "Người chỉ định" → "→ Trả về Người chỉ định (Bước X Cấp Y)" parse regex, "Người soạn thảo"/"Drafter" → "→ Trả về Người soạn thảo", "không lùi được" → "→ Không lùi được", "Trả về 1 Cấp"/"Trả về Cấp X" → "→ Lùi về Cấp X", toPhase=TuChoi(99) → "→ Từ chối hoàn toàn"
|
||||
|
||||
3. **Decision badge** (Plan AC `a734bf2` đã add): Duyệt emerald / Trả lại amber / Từ chối rose — phân biệt Action level KHÔNG dựa vào phase.
|
||||
|
||||
**Pattern reusable cross-project:** UI audit history KHÔNG nên render dual-phase badge khi state machine self-loop (e.g. ChoDuyet → ChoDuyet là advance pointer trong cùng phase, KHÔNG phải transition). Thay bằng Decision badge + semantic next-target hint parse từ structured comment.
|
||||
|
||||
**Severity:** UX confusion (KHÔNG functional bug). Bro UAT phản hồi sau Plan AC deploy.
|
||||
|
||||
**References:**
|
||||
- Plan AD commit `0aaf2df` (Run #219 PASS)
|
||||
- File: `fe-user/src/components/pe/PeDetailTabs.tsx:1995-2070` (ApprovalsTab + decisionBadge + extractNextTargetHint)
|
||||
- Mirror: `fe-admin/src/components/pe/PeDetailTabs.tsx`
|
||||
|
||||
## Checklist debug bug mới
|
||||
|
||||
1. Build pass không? → fail → check using + package version compat
|
||||
@ -800,3 +861,5 @@ paths-ignore:
|
||||
21. Nếu user phàn nàn "feature work cho admin nhưng user empty/403 silent" → check class-level Authorize policy có over-restrict cho non-admin không, split per action (#44)
|
||||
22. Nếu button workflow label nói "Trả lại" nhưng phiếu vẫn tiến approve → audit FE `isReject` payload condition vs button `isSendBack` label condition vs dialog `isSendBack` warning condition — phải sync 3 chỗ với CÙNG set target phase. BE thêm guard `(target ∈ terminalSet) ⇔ (decision=Reject)` chặn caller mismatch (#45)
|
||||
23. Nếu Gitea Actions API trả 404 trên `/actions/runs` → đúng path là `/actions/tasks` (Gitea naming khác GitHub). Cache `updated_at` stale ~2 min → cross-check VPS file LastWriteTime cho time-sensitive verify (#46)
|
||||
24. Nếu test `OrderByDescending(CreatedAt).First()` query audit table fail sau add Changelog mới → SQLite frozen-clock tie-break, MUST filter Summary/EntityType discriminator (#48)
|
||||
25. Nếu UI audit list show `Đã gửi duyệt → Đã gửi duyệt` lặp gây nhầm → drop dual-phase badge khi state machine self-loop, thay Decision badge + next-target hint parse từ comment (#49)
|
||||
|
||||
Reference in New Issue
Block a user