Files
solution-erp/docs/changelog/sessions/2026-05-15-s23-turn4-plan-n-per-nv-lookup-bug.md
pqhuy1987 fb3c22c90f
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m25s
[CLAUDE] Docs: Chunk N4 — S23 t4 Plan N HOTFIX wrap: docs + session log + 2 agent MEMORY drift
Plan N 2 commits:
- N1+N2 atomic (commit 0326458) BE fix line 765 ApproverUserId discriminator + 2 regression test
- N4 (this) docs + memory update

Docs update:
- docs/STATUS.md — Last updated S23 t4 + stats 108 test (+2 từ 106)
- docs/HANDOFF.md — TL;DR S23 t4 với Investigator pre-flight catch root cause
- docs/changelog/sessions/2026-05-15-s23-turn4-plan-n-per-nv-lookup-bug.md — Session log Plan N

Memory user-level update (1 entry CRITICAL HOTFIX section):
- feedback_per_nv_permission_scope.md — Wire checklist 9 surface points (NOT 8)
  + Point 9 mới: Handler lookup site `currentLevelOptions` MUST discriminate
  ApproverUserId. 3× cumulative gap analysis Mig 29 + 30 + 31.

Agent MEMORY drift (auto-flush):
- Investigator (.claude/agent-memory/investigator/MEMORY.md) — S23 t4 spawn N0
  audit Hypothesis B verdict + sqlcmd verify + API curl verify
- CICD Monitor (.claude/agent-memory/cicd-monitor/MEMORY.md) — S23 t3 Plan M
  Run #200 anomaly note (docs-only trigger CI mặc dù paths-ignore)

Stats final S23 t4:
- 31 mig · 59 tables · ~145 endpoints · 34 FE pages
- **108 test PASS (+2: per-NV lookup discrimination regression)**
- 47 gotcha · 20 memory (1 entry reinforced CRITICAL section)
- 6 skills · 4 sub-agents (1 Investigator spawn ~80K)
- 2 commits Plan N `0326458..HEAD` ready push

Pending: CICD Monitor post-deploy verify Plan N

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 12:42:21 +07:00

11 KiB
Raw Blame History

Session 23 turn 4 — 2026-05-15 — Plan N HOTFIX per-NV lookup site discrimination

Dev: Claude Opus 4.7 1M (4 sub-agents active + em main coordinator) Duration: ~1h Base commit: f4055a1 (S23 t3 Plan M wrap) Final HEAD: <pending> (Plan N batch + docs) Total commits Plan N: 2 (atomic N1+N2 BE+test + N4 docs)

🎯 Trigger session

Bro UAT screenshot post-Plan M deploy phát hiện disconnect cực nghiêm trọng:

"Hiện User UAT test v2 vẫn chưa thấy cho chuyển tiếp đến người cuối hoặc các option trả lại trong menu Duyệt NCC → Duyệt → Chưa thấy xuất hiện option duyệt thẳng, trả lại theo option và cho Edit"

4 screenshots evidence:

  • Workflow Designer: Admin tick TRUE 7 flag cho NV Test (UAT V2) slot Bước 2 Cấp 1, 3 NV khác CHỈ Drafter flag
  • Dialog ✓ Duyệt: Chỉ có "Ghi chú (tùy chọn)" + Xác nhận — KHÔNG có checkbox F2 skipToFinal
  • Dialog ← Trả lại: Chỉ có 1 radio "Trả về Người soạn thảo (mặc định)" — KHÔNG có 3 mode F1 khác (OneLevel/OneStep/Assignee)
  • PE detail UI: KHÔNG có F3 Edit Section 2 + F4 Edit ngân sách

🔍 Investigator pre-flight audit (~80K spawn, Hypothesis B verify)

🟦 Investigator spawn audit DB + API + FE wire cross-stack:

API curl verify (admin token):

  • GET /api/purchase-evaluations/<id>currentLevelOptions = {allowReturnToDrafter: true, 6 flag khác: false} — KHÔNG match flag admin tick cho NV Test
  • GET /api/approval-workflows-v2/<wfId> → 4 Level cùng Order=1, NV Test slot có 7 flag TRUE, 3 NV khác CHỈ AllowReturnToDrafter=true

sqlcmd prod verify:

  • Schema ApprovalWorkflowLevels 4 rows cùng (ApprovalWorkflowStepId, Order=1) trong Step 2 — đúng OR-of-N Mig 29 pattern
  • NV Test (UAT V2) row có 7 flag TRUE: AllowReturnOneLevel + OneStep + ToAssignee + ToDrafter + EditDetails + EditBudget + SkipToFinal
  • 3 NV khác chỉ AllowReturnToDrafter=true

FE wire grep verify:

  • fe-user/src/components/pe/PeWorkflowPanel.tsx:51,335-425 đọc evaluation.currentLevelOptions.allow* đúng tên field, conditional render đủ
  • fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx:889-946 Designer wire 7 checkbox per slot đúng

Verdict: HYPOTHESIS B confirm — BE handler bug line 765:

// BUG ([PurchaseEvaluationFeatures.cs:765])
var curLevel = curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder);

Schema Mig 29 (S21 t5 2026-05-13) refactor: 1 ApprovalWorkflowLevel row per ApproverUserId (OR-of-N cùng Order). 4 NV cùng Cấp = 4 row có Order=1. FirstOrDefault(Order==X) không có discriminator → luôn lấy row đầu DB (Trần Xuân Lưu / Lê Văn Bính / etc. tuỳ ordering EF nội bộ, đều chỉ Drafter flag) → bỏ qua admin tick per-NV của NV Test.

Bug present từ Mig 29 deploy 2026-05-13 (2 ngày prod) nhưng chỉ bộc lộ khi lần đầu admin tick selectively per-NV. Trước đây tất cả slot FALSE → behavior giống nhau (mọi actor đều thấy "không có options"), không lộ.

🌳 Plan N 2 chunk execution

Chunk N1 + N2 — BE fix + regression test (atomic commit)

👤 Chủ trì Solo (bug fix reasoning chain cross-stack — Implementer auto-refuse criteria #4).

N1 BE fix (PurchaseEvaluationFeatures.cs:765-781):

-                var curLevel = curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder);
+                // Match actor.UserId trong slot (per-NV admin opt-in flag).
+                // Admin / non-approver fallback row đầu (giữ behavior view detail).
+                var curLevel = curStep?.Levels.FirstOrDefault(l =>
+                    l.Order == curLevelOrder && l.ApproverUserId == currentUser.UserId)
+                    ?? curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder);

5 LOC delta. ICurrentUser currentUser đã có DI sẵn line 652.

N2 Regression test (tests/SolutionErp.Infrastructure.Tests/Application/GetPurchaseEvaluationCurrentLevelOptionsTests.cs):

2 test method (~210 LOC test new file):

  • GetPe_PerNvLookup_ActorMatchesSlot_ReturnsActorSpecificFlags:
    • Seed 1 Workflow + 1 Step + 4 Level cùng Order=1, mỗi Level distinct flag profile (A=Drafter / B=OneLevel / C=SkipToFinal / D=EditBudget)
    • 4 actor scenarios → assert mỗi actor nhận flag-set RIÊNG (KHÔNG profile khác)
    • Critical assertion: Actor C → AllowApproverSkipToFinal=true (regression bug bro UAT)
  • GetPe_PerNvLookup_AdminNonApprover_FallsBackToFirstRow:
    • Admin actor (KHÔNG match) → fallback FirstOrDefault EF SQLite non-deterministic ordering
    • Weak assertion: NOT null + match 1 trong 4 distinct profile (mỗi Level distinct flag → fallback pick exactly 1)

Verify:

  • dotnet build src/Backend/SolutionErp.Application clean (0 warning, 0 error)
  • dotnet test SolutionErp.slnx 108/108 PASS (+2 từ 106: 58 Domain + 50 Infra)
  • 2 test scenario N2 PASS individually + full suite no regression

Chunk N4 — Docs + memory update + commit (this commit)

  • docs/STATUS.md Last updated S23 t4 entry
  • docs/HANDOFF.md TL;DR S23 t4 đầy đủ
  • Session log file này
  • Memory user-level feedback_per_nv_permission_scope.md reinforcement S23 t4 wire checklist 9 surface points (NOT 8)

📊 Stats Plan N chốt

Metric Trước (S23 t3) Sau (S23 t4) Δ
DB tables 59 59 0
Migrations 31 31 0
Endpoints ~145 ~145 0
FE pages 34 34 0
Unit tests 106 108 +2 (per-NV lookup discrimination regression)
Gotchas 47 47 0
Memory entries 20 20 0 (1 entry feedback_per_nv_permission_scope.md reinforced — wire 9 points checklist)
Skills 6 6 0
Sub-agents 4 4 (1 Investigator spawn ~80K) active
Commits Plan N 2 (atomic N1+N2 + N4 docs) pending push

🎯 Multi-agent ROI evidence Plan N

Spawn Agent Cost (tokens) Output Catch
Pre-flight 🟦 Investigator ~80K Hypothesis B verdict + file:line + DB sqlcmd verify + API curl verify + FE wire grep verify Critical root cause — em main lần đầu hypothesize 3 candidates (A: admin chưa tick + B: BE handler bug + C: FE wire bug), Investigator confirm B với evidence-based file:line, avoid em main spam fix WRONG
N1 fix 👤 Chủ trì ~self 5 LOC BE Service handler line 765
N2 test 👤 Chủ trì ~self 210 LOC test new file 2 scenario First iteration EF SQLite ordering non-deterministic → fix weak assert fallback test
Reviewer (skip) 0 LOW effort 5 LOC BE + isolated test, em main solo per criteria small scope < 30 min
Post-deploy 🟩 CICD Monitor TBD (pending) Bundle hash + smoke + sqlcmd Spawn sau push

Total Plan N spawn cost (excl CICD): ~80K tokens — Investigator chính, em main solo execute.

Multi-agent value caught:

  1. Investigator catch root cause precisely — file:line + sqlcmd + API + FE evidence-based. Em main solo có thể đã spawn fix sai (vd suspect admin chưa tick → ask bro re-tick → vô ích vì admin đã tick đúng).
  2. 3-spawn cumulative pattern caught — Mig 29 + 30 + 31 + Plan N reveal: 3× refactor wire 8 surface points đúng nhưng MISS point 9 lookup discrimination. Pattern reinforced cho future flag F5+.

⚠️ Pattern reinforced — Per-NV admin opt-in wire 9 surface points (KHÔNG 8)

Old (S23 t1 K9 catch — 8 points): Mig 29 + 30 + 31 wire checklist 8 points (Domain + EF config + Mig 3-file + Service guard + PE bundle DTO + Admin AwLevelDto + CreateAwLevelInput + FE Designer).

NEW S23 t4 Plan N catch: Thêm point 9:

9. Handler lookup site currentLevelOptions MUST discriminate ApproverUserId == currentUser.UserId (fallback row đầu cho admin/non-approver). Áp dụng cho TẤT CẢ handler đọc Allow* flag từ Level slot khi schema OR-of-N approvers cùng Cấp.

Audit checklist trước commit cho future flag F5+:

  • Grep FirstOrDefault.*Order == trong codebase → enumerate all lookup sites
  • Verify mỗi site có discriminator role-context (ApproverUserId hoặc role-specific column)
  • Test regression: seed N rows cùng Order × N actor distinct → assert actor-specific flag returned

3× cumulative gap analysis (Mig 29 + 30 + 31):

Migration Wire 9 points Bug surface Caught when
Mig 29 F1+F3 1-8 OK, 9 GAP Lookup row đầu DB Plan N S23 t4 (2 ngày prod)
Mig 30 F4 1-8 OK, 9 GAP Same Same (cumulative)
Mig 31 F2 1-8 OK, 9 GAP Same Same

→ 3× cumulative refactor wire SAME bug — point 9 lookup discrimination chưa có precedent → em main + Reviewer + Implementer all MISS xuyên 3 plan.

⏭ Pending S23 t5+

  • 🟩 CICD Monitor post-deploy verify — spawn sau push remote
  • 🟦 Investigator follow-up gotcha #41/#48 candidate controlled test paths-ignore (carry from Plan M)
  • 🟡 Plan B Contract V2 wire (Mig 32+33) — HIGH priority next
  • Plan F drop V1 — defer sau Plan B + UAT 2-3 tuần
  • 🟢 Plan H PE PDF Export — LOW priority carry
  • 🟡 Plan I RAG Hybrid setup — defer chờ bro confirm
  • 🔧 Gotcha #47 paths-ignore agent-memory — PENDING bro confirm

📋 Pattern reinforced Plan N

  1. Per-NV admin opt-in flag wire 9 surface points (NOT 8) — point 9 handler lookup discrimination added. Memory user-level feedback_per_nv_permission_scope.md updated CRITICAL HOTFIX S23 t4 section.
  2. Investigator pre-flight audit BẮT BUỘC cho bug fix cross-stack — em main solo có thể spam fix WRONG hypothesis. Investigator file:line + sqlcmd + API + FE grep evidence base.
  3. Atomic commit BE fix + regression test cùng commit (per feedback_uat_skip_verify updated rule Plan L lesson) — Service semantic refactor BẮT BUỘC test cùng commit.
  4. EF SQLite non-deterministic ordering test gotcha — weak assertion cho fallback path (NOT null + match 1 distinct profile), KHÔNG assume "row đầu" deterministic.

References