Files
solution-erp/.claude/agent-memory/investigator/MEMORY.md
pqhuy1987 bf93abd467
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m39s
[CLAUDE] Docs: Session 26 chốt cuối — 6 Plan AG series PE tree view + Plan AI RAG global MCP setup
Update:
- docs/STATUS.md: Last updated S26 cumulative wrap
- docs/HANDOFF.md: TL;DR S26 chốt cuối với 3 pattern reusable NEW
- docs/changelog/sessions/2026-05-21-s26-pe-tree-view-rag-setup.md: NEW session log đầy đủ
- docs/guides/multi-agent-setup-guide.md: NEW ~750 lines onboarding 4 dự án future
- .claude/agent-memory/*/MEMORY.md: 4 agent flush S26 entries
- .claude/rag.json: NEW project config cho RAG bootstrap

Plans done S26:
- Plan AG/AG2/AG3/AG4/AG5/AG6 — 6 commits 0bf6c7e..d99069a PE List tree view UI iteration
- Plan AI Phase 0-4 — RAG global MCP setup (Voyage-4-large + Qdrant Windows native binary v1.18.0 NO Docker + FastMCP 3.3.1 stdio + SQLite FTS5 BM25 + RRF k=60 + Anthropic Contextual Retrieval prepend)
- SOLUTION_ERP bootstrap: 126 files → 2,392 chunks indexed 60.9s (~484K Voyage tokens = 0.24% free tier 200M/month)

Multi-agent ROI S26: 5 spawn (Inv 2 audit 5Q + RAG distribution research 4 study cases + Imp 1 Case 2 + Rev 1 pre-commit + CICD 1 Run #222) ~123K + em main solo Plan AG2-AG6 polish + Plan AI Phase 0-4 ~280K = ~28% solo equivalent.

3 patterns reusable cross-project NEW S26:
1. Pattern 19 Implementer — HTML native <details>/<summary> + Tailwind named groups (group/proj+year+sup) + localStorage Set<string> cho hierarchical 3-level tree UI when no Accordion lib
2. RAG User-level Global MCP — 1 server localhost serve N project + per-project .claude/rag.json (Approach A — 1 dev solo scenario, không phải team VPS)
3. Qdrant Windows native binary deployment — no Docker overhead, qdrant-x86_64-pc-windows-msvc.zip 28.3MB chính thức GitHub release

Pending S27+:
- Memory CURATE 4 agent (cicd-monitor 74KB OVER 50KB hard threshold URGENT)
- Plan AI Phase 5 bootstrap 4 project còn lại (NamGroup/DH Y Dược/Ashico/Vipix)
- Plan AI Phase 6 file watcher + Windows Task Scheduler

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 02:27:36 +07:00

35 KiB
Raw Blame History

Investigator Agent — Persistent Memory

Persistent diary cross-session. Auto-injected first 200 lines / 25KB at spawn. Update BEFORE every stop. Curate when > 25KB.


🎯 Role baseline

Read-only research + audit for SOLUTION_ERP codebase. Tools: Read, Grep, Glob, Bash, WebFetch, WebSearch. Output: concise structured findings under 500 words.


📋 Patterns proven (cross-session)

Pattern: Smoke verify catalog SOLUTION_ERP

  • Bearer auth từ https://api.solutions.com.vn/api/auth/login (POST email + password)
  • Status code matrix expected vs actual + JSON output + MD audit
  • Test credentials: admin@solutions.com.vn / Admin@123456 (full) OR nv.test@solutions.com.vn / TestUser@123456 (Drafter UAT scope)

Pattern: Schema scan via sqlcmd

# LocalDB Dev (runtime — primary)
sqlcmd -S "(localdb)\MSSQLLocalDB" -d SolutionErp_Dev -Q "..."

# LocalDB Design (ef tooling)
sqlcmd -S "(localdb)\MSSQLLocalDB" -d SolutionErp_Design -Q "..."

# Production (qua SSH vietreport-vps)
ssh vietreport-vps "sqlcmd -S .\SQLEXPRESS -d SolutionErp -U vrapp -P '...' -Q '...'"

Common queries: sys.columns, sys.triggers, __EFMigrationsHistory, COUNT(*), sys.indexes.

Gotcha: 2 LocalDB distinct (memory feedback_designtime_runtime_db):

  • _Dev — runtime API (appsettings.Development.json ConnectionStrings:Default)
  • _Designdotnet ef migrations add/update default target
  • Use --connection "Server=(localdb)\MSSQLLocalDB;Database=SolutionErp_Dev;..." override khi cần Dev specifically.

Pattern: Controller audit

  • Grep \[Route\("api/[a-z]+"\)\] enumerate ~30+ controllers
  • Grep \[Authorize(Policy = "..." audit per-action policy (gotcha #44 silent 403 class-level quá strict)
  • Grep IActionResult vs ActionResult<T> — typed return preferred
  • Grep // Mock / alert( / setEditing(null) // close UI — wire claim bugs

Pattern: Memory cross-reference

19 memory entries tại C:\Users\pqhuy\.claude\projects\D--Dropbox-CONG-VIEC-SOLUTION\memory\ (S20 +2 turn 11/12, S21 +2 turn 5):

  • MEMORY.md — index
  • project_solution_erp.md — cumulative narrative S1-S17
  • feedback_per_chunk_commit.md — 5-chunk A-E discipline
  • feedback_uat_skip_verify.md — Phase 9 skip test rule
  • feedback_drastic_refactor_scope.md — defer dedicated session
  • feedback_audit_reuse_before_clone.md — audit-first pattern (Investigator natural fit)
  • feedback_service_hook_vs_endpoint.md — derived state hook pattern
  • feedback_n_stage_workflow_pattern.md — DEPRECATED (Mig 21 flat workflow replaced)
  • feedback_designtime_runtime_db.md — 2 LocalDB distinct
  • feedback_md_compact_narrative.md — §6.5 KEEP narrative rule
  • feedback_unittest_timing.md — §7 test timing
  • feedback_cron_monthly_limitation.md — Cron SDK 7-day expire
  • feedback_user_manual_style.md — non-tech docs style
  • feedback_node_cicd.md — Node 20.x pin
  • feedback_responsive_laptop_breakpoint.md — 4-tầng responsive pattern (S20 t11)
  • feedback_multi_agent_setup.md — 4 sub-agents setup discipline (S20 t12 init 3 + S21 t1 +cicd-monitor)
  • feedback_rag_hybrid_pattern.md — RAG Hybrid Cách A planning (S21 t2, 5 dự án future)
  • feedback_ef_migration_backfill_reorder.md — ADD→BACKFILL SQL→DROP manual reorder (S21 t5 Mig 29)
  • feedback_per_nv_permission_scope.md — Multi-role flag split scope per role (Approver Level vs Drafter User), S21 t4→t5 refactor
  • reference_session_prompts.md — canonical session start template

Pattern: External research priority sources

  • anthropic.com/engineering/ (official patterns)
  • cognition.ai/blog/ (Devin lessons)
  • philschmid.de + eugeneyan.com + hamel.dev (senior engineers)
  • learn.microsoft.com/en-us/aspnet/core/ (.NET 10 official)
  • tanstack.com/query/latest (TanStack Query)

⚠️ Anti-patterns observed

  • Skip MEMORY.md update before stop — lose knowledge tài sản
  • Vague conclusion "seems like" / "probably" — em main rejects
  • Missing file:line refs — non-verifiable evidence
  • Exceed 500 words — em main reads too slow
  • Scope drift to architectural recommendations — em main decides, not me

🧠 SOLUTION_ERP context essentials (auto-load)

  • DB Dev: SolutionErp_Dev LocalDB (59 tables / 30 migrations / Mig 30 latest AddAllowApproverEditBudgetToLevels)
  • DB Design: SolutionErp_Design (ef tooling distinct)
  • DB Prod: .\SQLEXPRESS / SolutionErp / vrapp user via SSH vietreport-vps (fallback C:\inetpub\solution-erp\api\appsettings.Production.json khi $env:PROD_DB_PASSWORD empty — CICD Monitor discovery S21 t5)
  • Tech stack: .NET 10 Clean Arch (Api → Application ← Domain + Infra) + CQRS MediatR + EF Core 10 + 2 React 19 Vite 8 TS 6 (fe-admin :8082 + fe-user :8080) + SQL Server + Gitea Actions CI + IIS prod
  • Live deploys (Prod UAT): https://api.solutions.com.vn · https://admin.solutions.com.vn · https://eoffice.solutions.com.vn
  • Gitea remote: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp
  • Gitea Actions API: path /api/v1/repos/.../actions/tasks (NOT /actions/runs — 404). Cache stale ~2 min (gotcha #46) — cross-check VPS file mtime
  • SSH VPS: ssh vietreport-vps (config ~/.ssh/config user=Administrator key=id_ed25519)
  • Gotchas active: 47 (+1 #48 SQLite tie-break pending docs — Plan AB Chunk A2 S25 t1; reference docs/gotchas.md)
  • Tests baseline: 111 PASS (S22 baseline 104 + 7 PE WF cumulative; S25 Plan M tests SQLite tie-break re-stabilized Chunk A2) — Phase 9 UAT skip per chunk (memory feedback_uat_skip_verify)
  • Endpoints: ~146 (S22 +3 stable: PATCH /users/{id}/allow-skip-final + PATCH /pe/{id}/budget-adjust + GET /pe/{id}/attachments/{attId}/view)
  • Memory user-level: 23 entries (+2 S25: Plan AC2 FE merge synthetic recovery + Plan AF userMap fallback patterns)
  • Users: 30 demo + 33 active prod (13 cũ + 20 mới S22+2 role-based: act/bod/equ/fin/hra/pm/qs prefix .nv/.pp/.tp + bod.1/2). Password policy ≥12 chars (S22+2 discovery, TestUser@2026)
  • API auth response: accessToken + refreshToken + user (S22+2, NOT token)
  • Master HEAD reference: check via git log -1 --format='%H'
  • 6 skills: contract-workflow · permission-matrix · form-engine · ef-core-migration · dependency-audit-erp · iis-deploy-runbook

🔄 Active workflow schemas (V1 + V2 coexist post-Session 17)

  • V1 Mig 21 flat workflowWorkflowDefinition pin với PE/Contract cũ. Match Dept+PositionLevel.
  • V2 Mig 22-30ApprovalWorkflow pin với PE mới + match ApproverUserId 1-1 OR-of-N cùng Cấp. Steps (Phòng) > Levels (Cấp). PE đã wire V2. Contract V2 PENDING (Plan F drop V1 ABORTED S22+4 — Contract entity HOÀN TOÀN V1 chưa wire V2 + 4 PE V1-only + 19 PE V1+V2 mix).
    • Mig 25 IsUserSelectable (admin pin/unpin per workflow cho user pick)
    • Mig 26 PE Level Opinions UPSERT (service hook khi Duyệt)
    • Mig 28 (S21 t4) 6 Allow* workflow-level — REPLACED by Mig 29
    • Mig 29 (S21 t5) Allow* refactor per-NV: 5 flag on ApprovalWorkflowLevels (F1+F3 per Approver slot) + 1 flag on Users.AllowDrafterSkipToFinal (F2 per Drafter)
    • Mig 30 (S22+5) F4 AllowApproverEditBudget per-Level slot on ApprovalWorkflowLevels — admin Designer tick per slot cho Approver được edit Budget khi review. Pattern reinforced 2× với Mig 29 F1+F3: default = admin opt-in per slot, KHÔNG = mở rộng default. Cross-ref memory feedback_per_nv_permission_scope.md proven cumulative Mig 29 + Mig 30.

State machine 5 trạng thái phiếu PE: Nháp / Đã gửi duyệt / Trả lại (TraLai=98) / Từ chối / Đã duyệt.

Mode Trả lại 4 option per-Level (S21 t4-t5 Mig 28→29):

  • OneLevel = lùi 1 Cấp cùng Step (peer review)
  • OneStep = lùi sang Bước trước Cấp cuối
  • Assignee = pick NV đã ký runtime (PeLevelOpinions)
  • Drafter = Phase=TraLai clear pointer (S17 backward compat default TRUE)

3 mode đầu giữ Phase=ChoDuyet lùi pointer. Mode Drafter giữ Phase=TraLai. Admin bypass level.Allow* flag.


📅 Recent activity (last 10 FIFO)

  • 2026-05-15 (S24 t1 spawn Pre-A — Plan AA User Workflow Matrix view + sidebar widen): 5Q audit. Q1 endpoint: ApprovalWorkflowsV2Controller.cs:16-19 đã class-level [Authorize] bare từ S18 2026-05-08 (gotcha #44 fixed permanent), per-method admin Workflows.Create. Handler GetAwAdminOverviewQuery KHÔNG có IsUserSelectable filter — cần ADD param + Where conditional. Q2 menu seed: DbInitializer.cs:1429-1437 peOrder global increment (Group=1, leaves 2/3/4 cycle per type). Permission seed line 1541-1547 cho 7 role (Drafter/DeptManager/Procurement/CostControl/ProjectManager/Director/AuthorizedSigner). Accounting NOT trong list — admin manual grant nếu cần. Q3 Admin Designer: ApprovalWorkflowsV2Page.tsx 975 lines, AwLevelDto 13 fields (7 Allow*), VI labels line 892-948 ("Trả về 1 Cấp trước"/"Trả về 1 Bước trước"/"Trả về Người chỉ định"/"Trả về Drafter (mặc định)"/"Cho phép chỉnh sửa Section 2 (Hạng mục/NCC/Báo giá) lúc đang duyệt"/"Cho phép chỉnh sửa Section ngân sách lúc đang duyệt"/"Cho phép duyệt thẳng Cấp cuối khi đang duyệt"). KHÔNG có usePermission/PermissionGuard wrap (class-level [Authorize] route guard sufficient). Q4 sidebar widen: fe-user Layout.tsx:325 + fe-admin Layout.tsx:218 w-60 xl:w-72 (240/288px). PE Workspace 2-panel [260px_1fr] xl:[320px_1fr] (NOT 3-panel như memory feedback_responsive_laptop_breakpoint stale claim). After widen w-72 xl:w-80 (288/320px) SAFE (sidebar 288 + main 992 → workspace 260+732 fit @ 1280px). w-80 xl:w-96 THRESHOLD RISKY (sát 700px remaining). Q5 ApplicableType enum ApprovalWorkflow.cs:45-50 {DuyetNcc=1, DuyetNccPhuongAn=2, Contract=3}. Surprises: (1) memory responsive breakpoint stale "3-panel" → cần update sau Plan AA. (2) Order strategy "Luồng duyệt" Order=2 first → shift existing leaves +1 → cần DbInitializer UPDATE Order existing (KHÔNG chỉ INSERT-if-not-exists). (3) Contract=3 chưa wire FE (chỉ DuyetNcc + DuyetNccPhuongAn). Recommendation: Proceed Plan AA — chỉ ADD param filter + 1 menu key + page mới + sidebar widen. Token cost ~32k.
  • 2026-05-15 (S24 t1-t4 post-spawn, em main solo 4 polish chunks — Plan AA wrap): 7 commits total a1a910f..ee0902a: BE+Layout (ee776d5) + FE Page (c667802) + Docs (ac2c859) + 4 polish iter UAT (da218f1 px-2 + 4d60598 v1 panel-per-NV + fbbd361 v2 table rowSpan + ee0902a sidebar label wrap). Pattern reusable: inline-block icon + inline text + absolute ChevronDown cho hanging-indent reverse wrap (label dài về đầu hàng). Mirror admin Designer style cho user view read-only. Sidebar widen tradeoff: w-72 xl:w-80 + remove truncate FAIL fit 44+ chars label custom Mig 27 — cần combine với text-[12px] + leading-snug + restructure flex → block + inline. Sole truncate removal không đủ — phải full layout restructure NavLink. Memory drift confirmed: feedback_responsive_laptop_breakpoint.md claim "PE Workspace 3-panel" → S24 verify ACTUAL 2-panel (260+1fr only, KHÔNG có panel thứ 3). Cross-ref update needed memory user-level (admin trigger curate sau). Plan AA color palette success: STEP_PALETTE 5 màu (blue/purple/emerald/amber/pink) + LEVEL_PALETTE 5 màu (violet/sky/teal/orange/rose) — Tailwind JIT yêu cầu full class strings array, KHÔNG dynamic interpolation (bg-${color}-100 FAIL — class purged). Reusable cross-project cho menu hierarchy color coding (step parent + level child distinct palette). Final layout v2 table rowSpan: Step column merge per-Phòng + Level column rowSpan per-Cấp + NV column 1-row-per-approver, đẹp hơn v1 panel-per-NV stacked. Token cost iteration negligible (em main solo, no spawn).
  • 2026-05-15 (S23 t8 spawn Plan R pre-flight cleanup audit): Bro chốt cleanup destructive prod. 4 sqlcmd queries audit: 35 PE total (28 active + 7 soft) + 17 V2 (15 IsUserSelectable=false + 2 ghim) + 4 V1 (2 active + 2 inactive). FK gotcha catch: PE.ApprovalWorkflowId Restrict + ApprovalWorkflow extends BaseEntity NO soft-delete → hard-DELETE required; LevelOpinion → ApprovalWorkflowLevel Restrict cascade block. SQL Express limit: NO COMPRESSION + RESTORE VERIFYONLY require sysadmin. Filtered indexes (Mig 29+) require SET QUOTED_IDENTIFIER ON. Cascade child estimate: 446 PE children + ~140 V2 + ~37 V1 = ~620 rows. 3 Option compare → bro chốt A (Hard-DELETE PE + V2 unghim + V1 inactive, GIỮ V2 ghim + V1 active). Plan F precedent: KHÔNG drop V1 active (PE pin → BE crash).
  • 2026-05-15 (S23 t6 spawn Plan P FE wire audit — confirm BE-only scope): Em main hypothesize Plan P scope BE Controller body record drop. Investigator audit FE × 2 confirm: PeWorkflowPanel.tsx:113-124 api.post(/transitions, body) SEND ĐÚNG 7 fields (TargetPhase + Decision + Comment + ReturnMode + ReturnTargetUserId + SkipToFinal). No service file (untyped object literal). BE PurchaseEvaluationsController.cs:267 TransitionPeBody record CHỈ 3 fields → ASP.NET silent DROP 3 missing fields. Verdict: Plan P BE Controller ONLY ~6 LOC + no test (Mig 28/31 Domain test cover handler). Saved em main blind fix cross-stack.
  • 2026-05-15 (S23 t3 spawn — UAT bug Allow flags không hiện cho actor non-row1):* Bro UAT login nv.test@solutions.com.vn vào menu eoffice "Duyệt NCC → Duyệt" phiếu PE/2026/A/026 (Phase=ChoDuyet, WF=QT-DN-V2-001 v12, ở Bước 2 Cấp 1 4 NV: Trần Xuân Lưu/NV Test UAT V2/Hồ Thị Nữ Nguyên/Lê Văn Bính). Admin ĐÃ tick 7 Allow*=TRUE riêng cho slot NV Test UAT V2. Nhưng FE dialog Duyệt KHÔNG hiện checkbox SkipToFinal + Trả lại 4 mode + Edit. Verdict: HYPOTHESIS B — BE handler picks wrong slot row. Evidence: (1) PurchaseEvaluationFeatures.cs:765 var curLevel = curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder); — match FIRST row có Level.Order == curLevelOrder, NOT actor's row. Post-Mig 29 refactor, Level.Order trùng nhau cho mọi NV cùng Cấp (4 row có Order=1 ở Step 2). EF returns Trần Xuân Lưu trước (PK order) → FirstOrDefault lấy row đó (all-false except Drafter=true). (2) API curl admin token + nv.test token return CÙNG currentLevelOptions={ allowReturnOneLevel=false, OneStep=false, Assignee=false, Drafter=true, EditDetails=false, EditBudget=false, SkipToFinal=false } — handler currentUser-agnostic confirm. (3) Workflow detail GET /approval-workflows-v2?applicableType=1 .types[0].active.steps[1].levels enumerate 4 slot Bước 2 Cấp 1: NV Test (UAT V2) = ALL 7 TRUE; 3 NV còn lại = ALL FALSE (trừ Drafter=true mặc định). Admin Designer wire ĐÚNG (fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx:889-946 7 checkbox per-slot). FE consumer wire ĐÚNG (fe-user/src/components/pe/PeWorkflowPanel.tsx:51 levelOptions = evaluation.currentLevelOptions + line 343/357/371/397 conditional render mode picker + line 425 SkipToFinal checkbox). Root cause: BE line 765 lookup semantic broken sau Mig 29 (S21 t5). Trước Mig 29, 1 Level row per Cấp + ApproverUsers join table → FirstOrDefault(Order==X) đúng. Sau Mig 29 split 1 Level row PER ApproverUser → Order field collide → cần match thêm ApproverUserId == currentUser.UserId. Fix BE 1 dòng: var curLevel = curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder && l.ApproverUserId == currentUser.UserId); (admin bypass: fallback ?? curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder) để admin xem detail không lỗi). Edge case: Phase=DaDuyet/TraLai/TuChoi pointer null → existing guard line 760-762 skip block OK. LOC ~2-3 LOC 1 file. Surprise: bug PRESENT từ deploy Mig 29 (S21 t5 2026-05-13) — không phải regression S23. Lý do trước đây không bắt: UAT test users (default 13 cũ) đa số là row đầu của slot Cấp (Admin tick toàn FALSE → behavior giống nhau, không lộ); chỉ bộc lộ khi admin tick CHỌN LỌC per-NV (UAT V2 S22+2 thêm 20 user role-based + bro tick chỉ NV Test UAT V2). Cross-reference memory feedback_per_nv_permission_scope.md cumulative S21 t5 → S22+5 → S23 t1 — KHÔNG có entry nào nhắc bug lookup BE post-refactor.
  • 2026-05-15 (S23 t2 spawn M0 — Plan M F1+F2+F3+F4 ChoDuyet semantic audit): Bro UAT post-Plan L deploy 2026-05-15 ~02:00: "Hiện logic cũ là khi trả lại 1 cấp hoặc chỉ định hoặc edit là trạng thái draft -> cái này thay đổi lại nhé, các tính năng duyệt thẳng, trả lại 1 cấp hoặc người chỉ định hoặc cho edit thì cho xử lý đc ở trạng thái đang gửi duyệt luôn." Audit 4 BE file + 4 FE file × 2 app cho F1+F2+F3+F4 phase semantic ChoDuyet preservation. Verdict: CODE ĐÃ ĐÚNG semantic mới — đây là DISCONNECT bro mental model vs code reality post-Mig 28/29/30/31. Evidence per feature: F1.OneLevel PurchaseEvaluationWorkflowService.cs:285-312 SWITCH branch lùi 1 Cấp cùng Step (curLevel-1) ELSE lùi Step trước Cấp cuối; Phase KHÔNG đổi (giữ ChoDuyet, line 364 reset SLA only); fallback Drafter :303-310 CHỈ KHI đang Bước 1 Cấp 1 no further back (clear pointer + Phase=TraLai). F1.Assignee :335-360 foreach Steps find ApproverUserId match → set pointer; Phase giữ ChoDuyet; ConflictException nếu không tìm thấy NV trong workflow. F1.OneStep :314-333 lùi prev Step Cấp max; Phase giữ ChoDuyet; fallback Drafter nếu đang Bước 1. F1.Drafter :268-275 SET Phase=TraLai=98 + clear cả 2 pointer + SLA null — đây là CASE DUY NHẤT về "draft". F2 skipToFinal :483-524 Plan K L1 ĐÃ FIX advance pointer tới Bước cuối Cấp cuối (max), Phase giữ ChoDuyet (NV cuối duyệt thật để DaDuyet); guard line 485 ConflictException non-admin + flag off; opinion UPSERT trước line 441-468 ensure actor's signature lưu trước. F3 EnsureEditableForDetailsAsync PurchaseEvaluationDetailFeatures.cs:42-99 2 trường hợp accepted: Drafter scope (DangSoanThao/TraLai return pe sớm line 49-51) OR Approver scope ChoDuyet line 54-94 (V2 schema + actor match level.ApproverUserId + level.AllowApproverEditDetails flag). F4 AdjustPurchaseEvaluationBudgetCommandHandler PurchaseEvaluationFeatures.cs:272-329 Drafter scope :283-290 (DangSoanThao/TraLai + isDrafter) ELSE Approver scope ChoDuyet :291-323 (V2 + pointer init + actor match + level.AllowApproverEditBudget flag) — Phase ChoDuyet đã handle full. Validation Allow flag location* PurchaseEvaluationWorkflowService.cs:252-265 ApplyReturnModeAsync gate per slot per mode: throw ConflictException nếu disabled (Admin bypass line 252). FE PeWorkflowPanel.tsx: TraLai dialog :331-422 4 radio button (OneLevel/OneStep/Assignee/Drafter) gated bằng levelOptions?.allowReturnXxx flag per current Approver Cấp (line 343-396); useEffect :60-68 S23 t2 fix default first available mode KHÔNG Drafter khi admin tick F1 modes. Skip Final checkbox :425-442 chỉ visible khi levelOptions?.allowApproverSkipToFinal + Approve forward direction (line 425). FE PeDetailTabs.tsx F3+F4 wire: itemsReadOnly = readOnly && !approverEditMode line 118 bypass readOnly khi F3 enabled (Mig 28 pattern); canAdjust = isAdmin || (!readOnly && isDrafter && isDrafterPhase) || isApproverChoDuyet line 977 bypass readOnly khi F4 enabled (L2 fix). Mirror fe-admin/fe-user line 109-115 + 967-979 ĐỒNG BỘ rule §3.9. Surprise: "Trả lại" trong UI memory docs đôi khi gọi "draft" colloquial — bro confuse 2 khái niệm Phase=TraLai=98 (Drafter sửa rồi gửi LẠI từ Step 0) vs Phase=DangSoanThao=1 (chưa từng gửi duyệt). KHÔNG code path nào trong F1 OneLevel/OneStep/Assignee/F2/F3/F4 set targetPhase=DangSoanThao mà không nên. Recommendation: LOW effort (0-20 LOC): chỉ cần communication clarification em main confirm với bro 4 mode F1 + F2 + F3 + F4 đã giữ Phase=ChoDuyet trừ F1.Drafter; mở DB SELECT phiếu UAT confirm Phase column number sau click test; OPTIONAL touch up FE label nếu user thấy "Đã gửi duyệt" nhầm "Bản nháp". KHÔNG cần Service refactor hay handler change. Nếu bro thấy phiếu cụ thể về Phase=1 SAU click F1.OneLevel hoặc F2 → spawn lại Investigator audit DB state + log Changelog cho phiếu đó cụ thể (data debug, not code bug).
  • 2026-05-15 (S23 t2 spawn L2 — F3+F4 edit menu Duyệt audit): Bug UAT prod 409a967: admin tick F3+F4 cho slot Approver, login actor user, vào menu "Duyệt" (?pendingMe=1 cùng PurchaseEvaluationsListPage 3-panel), click PE Phase=ChoDuyet → Section 2 Hạng mục/NCC/Báo giá + Section 5 Điều chỉnh ngân sách vẫn read-only. Root cause F3 = OK / F4 = BROKEN at readOnly short-circuit: F3 wire ĐÚNG (PeDetailTabs.tsx:118 itemsReadOnly = readOnly && !approverEditMode override readOnly per Mig 28 S21 t4 → ItemsTab read prop OK). F4 wire SAI (PeDetailTabs.tsx:245 passes readOnly={readOnly} (=true từ menu Duyệt) xuống BudgetAdjustSection, line 973 compute canAdjust = !readOnly && (isAdmin || (isDrafter && isDrafterPhase) || isApproverChoDuyet)!readOnly short-circuits to false BEFORE F4 isApproverChoDuyet evaluate. Edit pencil button hidden line 1030 {canAdjust && <Button>Điều chỉnh</Button>}. Asymmetric vs F3 pattern Section 2 (PeDetailTabs.tsx:113-118). Evidence: FE F3 OK fe-user/src/components/pe/PeDetailTabs.tsx:113-118 + :224 ItemsTab ev={evaluation} readOnly={itemsReadOnly}; FE F4 BUG :957-973 BudgetAdjustSection !readOnly gate + :245 readOnly={readOnly}; menu Duyệt route fe-user/src/pages/pe/PurchaseEvaluationsListPage.tsx:256-261 PeDetailTabs readOnly={true} (cùng route Danh sách); BE GetPe PurchaseEvaluationFeatures.cs:735-770 currentLevelOptions populate 7 fields OK; BE budget-adjust handler :281-329 Phase ChoDuyet F4 branch + actor match + flag check ĐẦY ĐỦ + return ConflictException nếu Allow=false; BE PurchaseEvaluationDraftGuard.EnsureEditableForDetailsAsync ở PurchaseEvaluationDetailFeatures.cs:42 (8 callsites Detail+Supplier handlers). Recommendation: Fix BudgetAdjustSection line 973 mirror approverEditMode pattern Section 2: thay canAdjust = !readOnly && (isAdmin || ...) thành canAdjust = isAdmin || (!readOnly && isDrafter && isDrafterPhase) || isApproverChoDuyet — Approver bypass readOnly khi F4 conditions met. LOC ~3-5 LOC 1 file. Surprise: Inbox /inbox route (InboxPage.tsx) navigate sang /purchase-evaluations/:id (mobile DetailPage route, default readOnly=false) — chỉ Danh sách ?pendingMe=1 desktop 3-panel mới hard readOnly=true.
  • 2026-05-14 (S23 t1 spawn K0 — Plan K F2 refactor pre-flight): Audit F2 state cho Plan K Mig 31 (move Users.AllowDrafterSkipToFinalApprovalWorkflowLevels.AllowApproverSkipToFinal + change semantic Drafter Nháp → Approver ChoDuyet skip thẳng Cấp cuối). Confirmed state Mig 30: Migrations path = Persistence/Migrations/ (not direct Migrations); 30 mig latest = 20260513160703_AddAllowApproverEditBudgetToLevels; User.cs:38 AllowDrafterSkipToFinal prop; ApprovalWorkflow.cs:86-105 6 Allow* props (4 ReturnMode + EditDetails + EditBudget) per Level slot; F2 Drafter branch ở PurchaseEvaluationWorkflowService.cs:119-161 trong SUBMIT branch (line 125 if (skipToFinal && evaluation.ApprovalWorkflowId is Guid skipAwId) check user.AllowDrafterSkipToFinal); APPROVE STEP branch ở ~line 393-525 (advance pointer). TransitionAsync signature: skipToFinal là param thứ 8 (position 47:47), default=false. TransitionPurchaseEvaluationCommandPurchaseEvaluationFeatures.cs:393-402 với param SkipToFinal=false default. ApprovalWorkflowOptionsDtoPurchaseEvaluationDtos.cs:86-92 (6 field). PurchaseEvaluationDetailBundleDto.DrafterAllowSkipToFinal ở line 217 + CurrentLevelOptions ở line 214. UsersController PATCH /users/{id}/allow-skip-final ở line 91-98 + SetAllowDrafterSkipToFinalBody ở line 105. SetUserAllowDrafterSkipToFinalCommandUserFeatures.cs:332. FE state: fe-admin Designer system/ApprovalWorkflowsV2Page.tsx slot label "NV #{ei + 1}" ở line 873 (KHÔNG phải "#NV {order}" theo prompt) — inline checkbox panel 5+1=6 checkbox ở line 853-933 (4 ReturnMode + EditDetails + EditBudget). fe-admin system/UsersPage.tsx "Skip cuối" column line 306-318 + FastForward button toggle line 365-372 + allowSkipMut hook line 181-186. fe-admin/fe-user PeDetailTabs Drafter Workspace checkbox "Gửi thẳng Cấp cuối (skip trung gian)" ở line 287-297 (admin) / 294-304 (user). GAP fe-user: KHÔNG có UsersPage + ApprovalWorkflowsV2Page (admin-only mgmt) → Plan K UI changes localized fe-admin chỉ; fe-user side chỉ touch PeDetailTabs (remove old Drafter checkbox + thêm Approver toggle near Duyệt button). Drift Dev DB: Total=2 user (admin + test.drafter), Flagged=0 — NOT match 33-user prod seed. Prod actual: Total=33 / Flagged=4 (NOT 2 per S22+2 spec). 4 user flagged sẽ lose value when DROP column — acceptable per new semantic (Drafter pre-submit moot).
  • 2026-05-13 (S22, no spawn — em main solo throughout): S22 18:00→~21:00 em main solo. Cumulative state: 30 mig (+1 Mig 30 AddAllowApproverEditBudgetToLevels F4 per-Level slot), 104 test PASS (+20: 5 reg #44 Authorize policy + 7 ReturnMode + 7 Guard + 1 V2 actor scope reject), ~146 endpoints (+3: PATCH /users/{id}/allow-skip-final + PATCH /pe/{id}/budget-adjust + GET /pe/{id}/attachments/{attId}/view), 46 gotcha unchanged, 19 memory unchanged (recommend +1 entry — see below). Prod active users 13→33 (+20 role-based: act.nv/pp/tp, bod.1/2, equ/fin/hra/pm/qs.nv/pp/tp). Discoveries S22: (1) Per-NV admin opt-in flag pattern reinforced 2× — Mig 30 F4 cùng pattern Mig 29 F1+F3 (S21 t5). Bro corrected em main lần đầu: "phải tick checkbox như Section 2", default = admin opt-in per slot, KHÔNG = mở rộng default. Cross-ref memory feedback_per_nv_permission_scope.md proven 2×. (2) Plan F drop V1 ABORTED — pre-flight sqlcmd reveal Contract entity HOÀN TOÀN V1 chưa wire V2 (chưa có ApprovalWorkflowId column) + 4 PE V1-only + 19 PE V1+V2 mix. Lesson: drop migration cần verify entity scope toàn bộ (Contract liên đới — không chỉ PE). (3) Identity password policy ≥12 chars — seed 20 user FAIL 400 với "User@123456" (11 chars), TestUser@2026 (13 chars) pass. (4) Identity rename atomic 4 fields confirm gotcha #38: Email + NormalizedEmail + UserName + NormalizedUserName + FullName; sqlcmd cần SET QUOTED_IDENTIFIER ON cho filtered unique index. (5) API login response field name accessToken + refreshToken + user — KHÔNG có field token (correct prior Bash example trong spec dùng .token sẽ fail). (6) PS 5.1 ASCII-only script discipline reinforced gotcha #30: seed-test-users-prod.ps1 viết Vietnamese names without diacritics tránh parser error. Recommend bro add 1 memory entry "Admin opt-in flag pattern proven 2×" cumulative Mig 29 + Mig 30.
  • 2026-05-13 (S21 t3-t5, no spawn): Em main solo 3 turns (bug fix gotcha #45 + F1+F2+F3 workflow-level Mig 28 + refactor per-NV Mig 29). Implementer REFUSE per cross-stack reasoning chain rule. Investigator KHÔNG spawn — em main đã có context cumulative S20 t12 setup + active dev throughout. No findings to flush. Cumulative state update: 84 test, 29 mig, 45 gotcha, 19 memory entries (+2 S21 t5 pending), 6 skills unchanged. Pattern reusable saved cho future spawn: per-NV permission scope split + EF migration ADD→BACKFILL→DROP reorder.
  • 2026-05-11 (setup): Investigator agent initialized. Baseline knowledge load complete (44 gotchas + 14 memory entries + 6 skills + 27 mig + 81 test pass cumulative). No investigations performed yet. Awaiting first SendMessage from em main.

🔄 Curate trigger

  • Memory size > 25KB → archive recent entries to archive/<period>.md
  • Duplicate entries detected → merge
  • Stale > 3 months → remove

Last curate: 2026-05-11 (initial seed)

  • 2026-05-19 (S25 t1 spawn audit 2 bug critical UAT — Changelog logging missing): Em main report 2 bug UAT: (1) Budget Adjust 2×click → "Lịch sử thay đổi" KHÔNG show 2 entry. (2) Return Assignee mode F1 click → "Lịch sử thay đổi" KHÔNG show return action. Audit 5Q: Q1-DB state Prod SSH fail (auth), fallback code inspect. Q2-Budget handler: PurchaseEvaluationFeatures.cs:379-387 ĐÃ log changelog EntityType=Header + Action=Update + summary diff → code ĐÚNG, likelihood FE filter bug or UAT DB stale. Q3-Return handler: PurchaseEvaluationWorkflowService.cs:215-378 ApplyReturnModeAsync ZERO changelog log — 4 mode branches (OneLevel/OneStep/Assignee/Drafter) mutate pointers only, return summary, caller TransitionAsync:100 LogTransitionAsync only logs phase transition KHÔNG log mode side-effect. Q4-Schema: PurchaseEvaluationChangelog.cs support EntityType=Workflow(5) enum but ZERO code populate — schema incomplete missing Kind/ChangeType subtype enum to disambiguate "budget adjust" vs "detail edit" vs "return mode" (all Header/Workflow entity cùng Action.Update). Q5-FE: Query handler ListPurchaseEvaluationChangelogsQueryHandler:1050-1064 KHÔNG filter logic — returns ALL entities. FE query component unknown (fe-user source not easily searchable) but likely filter EntityType == (Supplier|Detail|Quote) omit Header+Workflow → Bug 1 Budget (Header type) hidden, Bug 2 Return (Workflow type unlogged vậy). Root cause B1: FE filter skip Header updates OR Schema gap (Header.Update collision: budget vs section 2 edit). Root cause B2: Handler intentionally skip logging (no companion audit table like PurchaseEvaluationApprovals for return history). Fix path B1: Option A (add Kind enum — 30 LOC schema+handlers) vs B (extend EntityType — 20 LOC) vs C (FE filter conditional show Budget — 10 LOC FE). Fix path B2: Add db.PurchaseEvaluationChangelogs.Add() per mode (15-25 LOC 1 file). Cross-ref pattern memory: S23 t3 lookup bug (Level.Order collision per-NV Mig 29) — schema Mig 29 OR-of-N refactor created similar subtype ambiguity. Surprise: EntityType.Workflow=5 enum value design-only, unused 4+ mig history. Recommendation: B2 fix first (clear win, 1 file BE), then B1 design (schema + cross-module pattern audit Contracts). Token ~28k.

  • 2026-05-19 (S25 wrap — Plan AB Bug 1+2 audit + 6 follow-up plans em main solo): Pre-Plan AB audit ~28K confirm root cause: Bug 1 Budget Adjust Handler ĐÃ log Changelog (Header+Update) nhưng FE HistoryTab filter strict TraLai-only loại. Bug 2 ApplyReturnModeAsync 4 mode KHÔNG add Changelog.Add() — chỉ caller LogTransitionAsync log phase transition. Recommended fix path: BE add log return mode + FE filter relax + Decision badge differentiation. Subsequent em main solo follow-ups (Plan AC..AF, KHÔNG re-spawn Investigator): AC capture pre-call Step/Level state + skipToFinal comment enrich + FE Decision badge; AC2 FE merge synthetic Reject rows từ Changelog (reversible recovery KHÔNG DB touch); AD drop misleading dual-phase badges + parse semantic next-target hint via regex Chuyển phase X → Y + comment keyword "Trả về"/"vượt cấp"; AE BE preventive batch UserName fix 9 Changelog.Add sites (Drafter+Detail+Quote+Adjust); AF FE userMap fallback từ embedded domain data PeDetailBundle (drafter+approvals+approvalFlow+levelOpinions+departmentOpinions) — no extra API fetch. Patterns reusable Contract V2 audit recovery + Budget changelog UI: (a) synthetic recovery FE merge từ existing audit table, (b) userMap fallback từ embedded domain data, (c) drop misleading badges + semantic hint via regex parsing, (d) preventive batch fix systemic gap. Cross-ref feedback_service_hook_vs_endpoint (audit log derived state) + new pattern user-level: FE merge synthetic + userMap fallback. Tokens cumulative em main this session ~340K (mostly solo iterations, sub-agent leverage ~62K total). CICD result: 7 commits e23f51c..506cada push remote, runs #215 FAIL (Plan M tests SQLite tie-break re-emerge) → #216 PASS (Chunk A2 SQLite tie-break fix) → #217-#221 PASS streak. Gotcha #48 SQLite tie-break pending docs.

  • 2026-05-21 (S26 spawn Plan AG 5Q audit — PE List tree view feedback Tra Sol): Bro UAT 2026-05-21 screenshot phàn nàn UI Duyệt NCC flat list "đám rừng" + propose Outlook-style folder template. Em main spawn Investigator audit 5Q: Q1 prod data scale (SSH auth fail, fallback code inspect — ~50-200 projects × 5-15 PE typical). Q2 Project entity Master/Project.cs:5-14 extends AuditableEntity với Code+Name+dates+Budget+PM+Note, MISSING MaxLength + navigation tới PE → ready for Phase 2 ProjectPackage table mở rộng. Q3 PE List structure PurchaseEvaluationsListPage.tsx:133 3-panel grid lg:grid-cols-[340px_1fr_360px] flat <ul><li> line 199-252 + pageSize 50 + filter type/phase/awId/search. Q4 shadcn fe-user component GAP THIẾU Accordion/Collapsible/Tree/Card/Badge (chỉ Button/Dialog/Input/Label/Select/Textarea) → Phase 1 fallback HTML <details>/<summary> native + inline badge <div> (verified S24 Plan AA pattern). Q5 Mig 32 prep naming AddProjectPackageTable follow cumulative pattern. Recommend Approach C Hybrid: Phase 1 FE-only group view ~160 LOC × 2 app (1-2 ngày) + Phase 2 ProjectPackage schema (3-5 ngày defer post-UAT). Implementer Case 2 cookie-cutter mirror 2 app ACCEPT. Token ~30k.

  • 2026-05-21 (S26 spawn Plan AI RAG distribution research — 4 study cases industry-validated): Bro plan setup RAG cho 5 dự án cùng máy localhost share infrastructure. Investigator deep research 7Q: Anthropic patterns + community tools + multi-tenant architecture + distribution mechanism + auth + cost + sync. Findings 4 study cases: (1) Cursor — Merkle tree + Turbopuffer + 92% similarity reuse pattern, secret key derived Git commit hash, per-team index sharing cut indexing hours→seconds. (2) Cline Memory Bank — markdown + JIT retrieval + git-native sync. (3) Continue.dev Hub — slug-based YAML config sharing centralized. (4) Sourcegraph Cody — interesting anti-pattern, BỎ embeddings sang Search API + graph IR scale 100K+ repos enterprise (alternative if good search infra sẵn). Multi-tenant 3 patterns: Single index (pool, cheap), Per-tenant isolated (silo, expensive), Hybrid base+delta (Cursor pattern). Distribution combo winner cho 5-dev team: FastMCP HTTP server VPS Hetzner $15/tháng + git-sync embeddings snapshots committed to private repo. Auth JWT RS256 + role scopes + document-level ACL. Cost reality 5 dev ~$20/month vs cloud Qdrant $50/month. Sync git-based weekly cron (real-time chỉ cần khi team > 10 dev). Surprise: Voyage AI 200M tokens/month free tier cover 5 devs comfortably — coi như chỉ tốn $15 VPS. Anthropic standards 9/9 matched + community best practices 6/7 matched (Sourcegraph alternative N/A cho memory-heavy). Plan AI architecture chốt với em main: User-level Global MCP (Pattern C — 1 server localhost serve 5 project) thay vì team VPS pattern (anh single dev 5 dự án). Token ~40k.