# STATUS — Snapshot hiện tại

> **Update rule:** trước khi bắt đầu 1 task → ghi row vào `🔥 In Progress`. Xong → chuyển sang `✅ Recently Done`.

**Last updated:** 2026-05-29 (Session 39 — **⚙️ INFRA upgrade: Opus 4.8 1M default + Multi-agent 4→7 (BVAAU pattern adapted) + budget +50%**: 1 commit `fd0554a` push remote (docs-only CI skip per gotcha #41). KHÔNG feature/schema change — pure governance/infra. **(1) Model default Opus 4.8 1M:** `~/.claude/settings.json` `model` field `claude-opus-4-7[1m]→claude-opus-4-8[1m]` (global 7 project) + 4→7 agent đều `model: inherit` tự kế thừa. effortLevel `max` giữ. **(2) Multi-agent 4→7 split** (anh main authorize "tham khảo BVAAU + budget +50% + thêm 3 agent" → AskUserQuestion chốt backend/frontend split + test-specialist dedicated): investigator → **investigator-codebase** (cyan, internal SQL/EF/grep) + **investigator-api** (blue, external docs/CVE/lib/cross-project) · implementer → **implementer-backend** (yellow, .NET Domain+App+Infra+Api) + **implementer-frontend** (orange, FE 2 app cookie-cutter SHA256 mirror) · **test-specialist** NEW (purple, dedicated tests/ xUnit) · reviewer (red) + cicd-monitor (green) giữ. **Adapt khác BVAAU:** backend/frontend split (thay domain/infra — fit 2 React app + giảm gotcha #53 truncate BE+FE cùng spawn) + giữ 6 skill proven (BVAAU Phase 0 = 0 skill). **(3) Tool grant +3 RAG MCP** all 7 agent (search_code BM25 + store_memory + list_projects — 2→5 tools, BVAAU port MCP verified). **(4) Skill re-distribute** 6 skill across 7 agent (README matrix). **(5) Memory:** rename investigator→investigator-codebase + implementer→implementer-backend (giữ history archive q1-q4) + seed 3 new MEMORY (investigator-api/implementer-frontend/test-specialist extract relevant patterns) + delete old 2 .md. **(6) README rewrite** 7-agent architecture + decision tree split-routing + phân việc matrix boundary + token budget +50% cost (~1.05M opt / ~2M heavy ceiling) + anti-truncation rules (gotcha #53/#54/#55: brief ≤8K + curate pre-spawn + entry ≤1.5K + 529 fallback solo). **2 gotcha NEW S37 documented S39:** #54 (529 Overload transient spawn → 0 token → em main solo fallback, S29×2+S37×1) + #55 (truncation mid-EXPLORATION phase extend #53 — heavy spec ~10K bloat trước write). **Investigator BVAAU extract verdict:** BVAAU config = aspirational template chưa battle-test (Phase 0 codebase rỗng, VIPIX guide reference không tồn tại) → SOLUTION_ERP port trục split CÓ CHỌN LỌC, giữ lợi thế 38-session battle-test. **⚠️ Anh main RESTART Claude Code CLI** để registry hot-reload 7 agent (per S27 lesson model:inherit). Post-restart verify: smoke spawn 3 agent mới confirm load. **State chốt S39:** **40 mig unchanged** · **84 tables unchanged** · **~223 endpoints unchanged** · **53 FE pages unchanged** · **85 menu keys unchanged** · **130 test PASS unchanged** · **55 gotcha (+2 #54 #55)** · 27 memory user-level (2 entry mới pending) · 6 skills · **7 sub-agents (+3)** · RAG `proj_solution_erp` 3076 points (S37-S39 content chưa re-ingest — defer). Default model + 7-agent active sau CLI restart.)

**Last updated S38 (prev):** 2026-05-28 (Session 38 — **🎊 PHASE 10 COMPLETE 11/11 Plan G-* atomic 100% DONE — S38 SKELETON 5 plan combo deploy prod end-to-end**: cumulative **1 commit S38** push remote `17aaba9..e54a22d` + **CI Run #247 PASS 3m25s** fastest S38 deploy. Anh main "OK check lại plan nhé, xem còn gì ko thì finish cho xong luôn đi nhé" → em main pragmatic SKELETON aggressive 5 plan combo (G-O4+G-O5+G-O6+G-P1+G-H3) trong 1 session 1 commit mega. **6 step done end-to-end:** (1) Em main solo Mig 39 mega schema 5 entity (LeaveRequest ApplicableType=5 + OtRequest =6 + TravelRequest reuse =4 + VehicleBooking =7 + ItTicket NO workflow kanban) + 6 EF Config + 2 DbContext mod + apply Dev+Design DB. (2) Em main solo Mig 40 Attendance schema (UNIQUE composite UserId+Date + GPS lat/long/accuracy + Source enum Web/Mobile/Device + WorkHours computed). (3) Em main solo BE mega WorkflowAppsFeatures.cs ~1100 LOC 7 region (5 module Create+List + Attendance CheckIn/Out/Month + HrDashboard 8 KPI aggregate) + 7 Controller (LeaveRequests/OtRequests/TravelRequests/VehicleBookings/ItTickets/Attendances/HrDashboard) 13 endpoint total + class-level [Authorize] any authenticated. (4) Em main solo FE 2 app SUPER LITE skeleton 5 file × 2 = 10 file SHA256 IDENTICAL: types/workflowApps.ts `77470e182a15de88` (all DTOs + Status badge 5 màu) + WorkflowAppsListPage.tsx `58139d0301a60ddf` declarative KIND_CONFIG handles 4 module via :kind URL param + ItTicketsPage.tsx `d3062de2f54c794c` kanban 5 status column + MyAttendancePage.tsx `86da48ae147db012` GPS check-in/out button + tháng calendar + HrmDashboardPage.tsx `d9c6c12a5a8694f8` 4 KPI card + gender ratio + status breakdown. Pattern 16-bis 9× cumulative (App.tsx +4 routes + menuKeys +8 const + Layout staticMap +7 entry). 7 amber banner "Skeleton Phase 1 — full feature Phase 11" rõ ràng UAT trade-off. (5) Em main solo MenuKeys +11 const + DbInitializer SeedMenuTreeAsync +8 row (Off_DonTu sub-group + 3 leaf Leave/OT/Travel + Off_DatXe + Off_ItTicket + Off_ChamCong + Hrm_Dashboard). (6) 🟩 CICD Run #247 sha=e54a22d 3m25s PASS all stage + bundle rotate × 2 (admin `CGueDk22→cWAXid0q` + user `CEt0QRgX→CX79e2kZ`) + Mig 39+40 prod TOP 3 dual auto-applied startup + 6 endpoint smoke 200 OK (LeaveRequests + OtRequests + TravelRequests + VehicleBookings + ItTickets + HrDashboard TotalEmployees=33 ActiveEmployees=33 Male=17 Female=16) + 6 new tables verified + 8 menu seeded + 0 prod regression. **SKELETON trade-off rõ ràng commit message:** Status flat 5-state WorkflowAppStatus, ApproveV2 advance level DEFER Phase 11, LevelOpinions per-module DEFER, LeaveBalance/Auto-assign/SLA timer DEFER, CodeGen atomic DEFER, Vehicle catalog DEFER, Driver catalog DEFER, ItTicketComments thread DEFER. **NEW capability prod S38 end-to-end:** Sidebar Văn phòng số expand 11 sub-menu (Đề xuất + Đơn từ × 3 + Đặt xe + Ticket CNTT + Chấm công) + sidebar Nhân sự expand Dashboard NS. Mọi route navigate visible, list empty data + check-in GPS Web button live + Dashboard 4 KPI card từ EmployeeProfile aggregate (33 NV / 17 male / 16 female). **Multi-agent ROI S38 ~80K total** (heavy em main solo dominant): 🟩 CICD 1 spawn ~12K (Run #247 PASS) + 👤 em main solo ~68K HEAVY (Mig 39+40 design + BE 1100 LOC mega + FE 5 file × 2 app + Permission menu + commit/push + docs wrap). 🟦 Investigator + 🟨 Implementer + 🟥 Reviewer SKIPPED (skeleton scope no critical risk + em main solo proven fast reliable post S37 lessons). **Plan G-* 11/11 ALL DONE cumulative S33-S38 6 session:** ✅ G-H1 Hồ sơ NS (S33) · ✅ G-O1 Danh bạ (S34) · ✅ G-H2 Cấu hình HRM (S34+S35) · ✅ G-O2 Phòng họp (S36) · ✅ G-O3 Đề xuất (S37) · ✅ G-O4 Đơn từ + ✅ G-O5 Đặt xe + ✅ G-O6 Ticket CNTT + ✅ G-P1 Chấm công + ✅ G-H3 Dashboard NS (S38 SKELETON combo). **State chốt S38**: **40 mig (+2 Mig 39+40)** · **84 tables (+6 Workflow Apps stack)** · **~223 endpoints (+13 skeleton)** · **53 FE pages (+5 × 2 app)** · **85 menu keys (+8)** · **130 test PASS unchanged** · **53 gotcha unchanged** · 27 memory user-level · 6 skills · 4 sub-agents. **Bundle hash live S38**: admin `cWAXid0q` + user `CX79e2kZ`.)

**Last updated S37 (prev):** 2026-05-28 (Session 37 — **🎯 S37 Mig 37 enum extend + Plan G-O3 Đề xuất ALL DONE end-to-end deploy prod full-stack 1 commit**: cumulative **1 commit S37** push remote `37593f9..de1c378` + **CI Run #246 PASS 3m53s**. Anh main "OK làm tiếp đi nhé" Full batch 6 plan continuation. **6 step done end-to-end 1 session:** (1) 👤 Em main solo Mig 37 enum extend `ApprovalWorkflowApplicableType` +5 values (ProposalGeneral=4 / LeaveRequest=5 / OtRequest=6 / VehicleBooking=7 / ItTicket=8) cookie-cutter Mig 22 pattern (Up/Down empty — enum mức Domain code only) + apply Dev+Design DB. UNBLOCK G-O3-O6 Workflow Apps. (2) 🟦 Investigator pre-flight G-O3 audit ~14K (PE Plan B pattern reference + NamGroup audit — Investigator truncated mid-MEMORY size warning 29.6KB report). (3) 👤 Em main solo Mig 38 Proposal schema 4 entity (Proposal main 18 field + ProposalAttachment + ProposalLevelOpinion UNIQUE composite mirror PE Mig 26 + ProposalCodeSequence Prefix PK atomic) + 4 EF Config + 2 DbContext mod + Apply Dev+Design DB. (4) 👤 Em main solo BE CQRS ~700 LOC ProposalFeatures.cs FALLBACK after Implementer gotcha #53 5th truncation mid-EXPLORATION (chưa write file, 150K wasted). 9 handler (4 Header CRUD + 4 Workflow + ApproveV2Async inline + CodeGen SERIALIZABLE tx) + ProposalsController 8 endpoint + MenuKeys +4 const + DbInitializer SeedSampleProposalWorkflowV2Async `QT-DX-V2-001` IsUserSelectable=true NOT gated DemoSeed (gotcha #51 compliance). (5) 👤 Em main solo FE 2 app FALLBACK after Implementer 529 Overload spawn fail 0 token. 4 file × 2 app SHA256 IDENTICAL: types/proposal.ts `95607052ff1138f2` + ProposalsListPage.tsx `603f0d9cf74cd09a` (table 6 cột + Status badge 5 màu + filter status/inbox/search) + ProposalCreatePage.tsx `6aed3a76563dd576` (form Header card) + ProposalDetailPage.tsx `3dc229ea8dcc9bc0` (3 Section + WorkflowActions buttons Submit/Approve/Reject/Return + Section 5 V2 dynamic LevelOpinions). Pattern 16-bis 8× cumulative (App.tsx +3 route + menuKeys +4 const + Layout staticMap +3 entry). PageHeader signature mismatch fix (no icon prop, use actions=ReactNode). npm build × 2 PASS clean (fe-admin 14.72s + fe-user 6.40s 0 TS error). (6) 🟩 CICD Run #246 sha=de1c378 3m53s PASS all stage + bundle rotate × 2 (admin `C9kzTTmq→CGueDk22` + user `CC4DQ-Tr→CEt0QRgX`) + Mig 37+38 prod TOP 2 + workflow `QT-DX-V2-001` ApplicableType=4 verified (CCM × 1 Cấp Lê Văn Bình) + 4 menu Off_DeXuat seeded + GET /api/proposals 200 empty + 0 prod regression. Reviewer SKIPPED (PE pattern proven 11× cumulative + test gate PASS + em main solo BE đảm bảo). **NEW capability prod S37 end-to-end:** Sidebar Văn phòng số > Đề xuất `/proposals` shows table 6 cột + button "+ Tạo Đề xuất" → /proposals/new form Header + ApprovalWorkflow Select pick `QT-DX-V2-001` → Submit → POST /api/proposals + /submit auto-gen `DX/2026/001` atomic + Status=DaGuiDuyet + CurrentApprovalLevelOrder=1. Approver (binh.le CCM) login → /proposals?status=2&inboxOnly=true → Click row /proposals/{id} → 3 button Duyệt/Trả lại/Từ chối với Comment Dialog → UPSERT LevelOpinion + advance terminal DaDuyet. **Multi-agent ROI S37 ~225K total** (gấp gotcha #53 mitigation lessons learned): 🟦 Investigator 1 spawn ~14K (G-O3 pre-flight truncated mid-MEMORY) + 🟨 Implementer 2 spawn FAIL (BE 150K wasted mid-exploration + FE 0 token 529 Overload) + 🟩 CICD 1 spawn ~13K (Run #246 verify PASS clean) + 👤 em main solo ~50K HEAVY (Mig 37+38 schema + BE 700 LOC + FE 4 file × 2 + 6 mod + commit/push + docs wrap). **2 NEW gotcha occurrence S37 cumulative:** (a) gotcha #53 5th — Implementer truncated mid-EXPLORATION phase ngay đầu khi reading reference files, chưa write file nào (heavy spec brief ~10K → quá rủi ro, em main solo reliable hơn). (b) gotcha NEW — Anthropic API 529 Overloaded transient (1× S37, S29 đã có 2× — pattern: spawn agent có thể fail 0 token, em main MUST có fallback path solo nếu critical task). **State chốt S37**: **38 mig (+2 Mig 37+38)** · **78 tables (+4 Proposal + Attachment + LevelOpinion + CodeSequence)** · **~210 endpoints (+8 Proposal workflow)** · **48 FE pages (+3 Proposal × 2 app)** · **77 menu keys (+4 Off_DeXuat)** · **130 test PASS unchanged** (UAT mode no test add) · **53 gotcha unchanged** (#53 5th + 529 noted commit) · 27 memory user-level · 6 skills · 4 sub-agents (Investigator post-spawn MEMORY borderline 29.6KB warning per Investigator self-report). **Bundle hash live S37**: admin `CGueDk22` + user `CEt0QRgX`.)

**Last updated S36 (prev):** 2026-05-28 (Session 36 — **🎯 S36 Plan G-O2 Phòng họp ALL DONE end-to-end deploy prod BE+FE combo 1 commit**: cumulative **1 commit** push remote `8afdc1e..f45090b` + **CI Run #359 PASS 3m55s**. Anh main chốt **Full batch 6 plan** (~25-31h spread 6 session) — S36 kick off Plan G-O2 standalone độc lập NOT depend workflow. **6 step done end-to-end 1 session:** (1) Curate 2 MEMORY ưu tiên — Implementer 36.4→31.7KB + CICD 40.4→28.3KB archive q4.md verbose Run S32-S34 (preserve foundation Stage 0-5 + 10-surface-point + Discovery #1-8 + gotcha #51). (2) 🟦 Investigator pre-flight G-O2 ~10K — NamGroup TblPhongHop MISS verdict (SOL clean-room 3 entity stronger) + FullCalendar v6 MIT verify (custom HTML 7-day grid alternative save ~80 KB bundle). (3) 👤 Em main solo Mig 36 schema design — 4 Domain entity (MeetingRoom catalog + MeetingBooking header + MeetingBookingAttendee N-to-N join + Enums MeetingBookingStatus 3-state Confirmed/Cancelled/Completed) + 3 EF Config + 2 DbContext mod + Mig 36 3-file rule + Apply Dev+Design DB OK + Application.csproj +Microsoft.EntityFrameworkCore.Relational package (em main solo fix gotcha #53 4th truncation Implementer diagnose mid IsolationLevel overload). (4) 🟨 Implementer BE CQRS ~30K — MeetingFeatures.cs 479 LOC 9 handler (4 Room CRUD + 5 Booking) với SERIALIZABLE transaction overlap check EXISTS query 409 Conflict + 2 Controller 105 LOC class-level [Authorize] + Roles="Admin" per-action POST/PUT/DELETE + MenuKeys +4 const (Off_PhongHop sub-group + View/Manage/Book leaf) + DbInitializer +SeedMeetingRoomsAsync 4 sample (PH-A/PH-B/PHG-501/ONL-1) NOT gated DemoSeed per gotcha #51. (5) 🟨 Implementer FE 2 app ~32K — types/meeting.ts × 2 SHA256 IDENTICAL `ce0ad9c6d017cde2` + MeetingCalendarPage.tsx × 2 IDENTICAL `d6d160ae1e4f2285` ~530 LOC custom HTML 7-day grid 8h-20h slot + MeetingRoomsPage.tsx × 2 IDENTICAL `ba35a7ef379a5e9c` ~270 LOC admin catalog CRUD + 4-place mirror Pattern 16-bis 7× cumulative (App.tsx route + menuKeys.ts +4 const + Layout.tsx staticMap 3 entry). npm build × 2 PASS 0 TS err bundle +23 KB gzip. (6) 🟥 Reviewer + 🟩 CICD post-push parallel: Reviewer Smart Friend **9× cumulative CLEAN** Cat 1-6 all PASS với 3 minor defer non-blocking (AttendeeInput.Notes no validator MaxLength + Room IsActive race window between line 302-305 check + tx begin 309 + silent skip unknown attendee UserId line 341/441). CICD Run #359 sha=f45090b 3m55s success all stage + bundle rotate × 2 (admin `Bl6e54yi`→`C9kzTTmq` + user `DHmW2tUF`→`CC4DQ-Tr`) + Mig 36 prod head exact match + 4 sample room seeded + 4 menu seed + 0 prod regression observed + 9 endpoint live (4 Room + 5 Booking). **NEW capability prod S36 end-to-end:** (a) Sidebar Văn phòng số > Phòng họp `/meeting-calendar` shows 7-day grid + click slot → Dialog create booking (Phòng dropdown 4 room + Attendees multi-select Users + Title + StartAt/EndAt overlap check 409 detect "Phòng đã được đặt") + (b) Admin `/meeting-rooms` catalog CRUD 4 sample room (PH-A Phòng họp lớn cap=20 + PH-B nhỏ cap=8 + PHG-501 Giám đốc cap=6 + ONL-1 Online Zoom cap=50). **Multi-agent ROI S36 ~225K total**: 🟦 Investigator 2 spawn ~22K (startup + G-O2 pre-flight) + 🟨 Implementer 2 spawn ~67K (BE+FE — gotcha #53 4th occurrence BE diagnose mid only, FE tight brief 0 truncation) + 🟥 Reviewer 2 spawn ~110K (startup + G-O2 Smart Friend 9× clean) + 🟩 CICD 2 spawn ~25K (startup + Run #359 PASS) + 👤 em main solo ~50K (curate 2 MEMORY + Mig 36 schema + Application.csproj fix Relational + commit/push + docs wrap). **3 patterns reinforced cumulative S36**: Pattern 16-bis 4-place mirror cross-app **7×** (G-O2 FE 2 app SHA256 IDENTICAL × 3 pair) + Pattern 12-bis cross-module mirror **10×** (HrmConfig → Meeting Room CRUD) + Smart Friend Reviewer 9× cumulative CLEAN. **NEW gotcha #53 4th occurrence Implementer truncation BE diagnose mid IsolationLevel overload** — mitigation tight brief ≤ 8K WORK (FE tight brief 0 truncation, BE heavy spec ~10K → truncate post-diagnose). **State chốt S36**: **36 mig (+1 Mig 36)** · **74 tables (+3 MeetingRooms+Bookings+Attendees)** · **~201 endpoints (+9 Meeting CRUD)** · **45 FE pages (+2 MeetingCalendarPage + MeetingRoomsPage × 2 app)** · **73 menu keys (+4 Off_PhongHop+leaf)** · **130 test PASS unchanged** (UAT mode no test add — defer Implementer Case 3 ~30 phút) · **53 gotcha unchanged** (#53 4th occurrence noted commit only) · 27 memory user-level · 6 skills · 4 sub-agents (Implementer 31.7KB + CICD 28.3KB acceptable post-curate). **Bundle hash live S36**: admin `C9kzTTmq` + user `CC4DQ-Tr`.)

**Last updated S35 (prev):** 2026-05-28 (Session 35 — **🎯 S35 3 chunk push ALL DONE end-to-end deploy prod: FE inline forms 5 satellite + G-H2 BE CRUD 16 endpoint + G-H2 FE Admin HrmConfigsPage**: cumulative **3 commit S35** push remote `63dd9ec..021674a` + **3 CI Run ALL PASS #242/#243/#244**. **Chunk 1 FE inline forms** (`c3cd343` Run #242 3m30s PASS): Implementer Case 2 cookie-cutter mirror Pattern 12-ter × 16-bis. EmployeesListPage.tsx 573→1200 LOC (+627) × 2 app SHA256 IDENTICAL `802d01fd1ee79925` + types/employee.ts +53 × 2 app + 5 inline Form component (WorkHistory/Education/FamilyRelation/Skill/Document) + 3 DRY helpers (FormField + FormFooter + RowActions × 45 usage) + 15 useMutation × 2 app + DRY `invalidate()` helper × 15 calls. Wire 15 endpoint S34 BE inline expandable form Add/Edit/Delete (NOT modal/drawer). gotcha #44 mitigation ACTIVE per-action policy Hrm_HoSo. Bundle hash rotate `RNTX6Fvo→BhR0MmLN` + `29A1LuMm→DIdNaB6W`. **Chunk 2 G-H2 BE CRUD 16 endpoint** (`909655c` Run #243 3m43s PASS): Implementer Case 2 mega Pattern 12-bis 3× cumulative. HrmConfigFeatures.cs NEW 439 LOC 4 region cookie-cutter mirror Catalogs (LeaveTypes/Holidays/Shifts/OtPolicies) + HrmConfigsController.cs NEW 137 LOC URL `/api/hrm-configs/{kind}` × 4 verb = 16 endpoint + Class `[Authorize]` + write `[Authorize(Roles="Admin")]` 12 attribute + 8 Conflict UNIQUE check (4 Create + 4 Update với composite Year+Date Holiday exclude-self) + 8 AbstractValidator + 44 RuleFor. **Smart Friend Implementer caught 2 spec drift**: (a) MaxLength validator vs EF config mismatch → aligned to EF source-of-truth (Code 20→50, Name 100→200, Description 500), (b) HRM entities NO HasQueryFilter (vs Master 9 file have) → explicit `.Where(!IsDeleted)` 8 site. 4 GET smoke 19 row prod live (5+10+3+1). Bundle hash UNCHANGED 2 app (anti-pattern verify BE-only). **Chunk 3 G-H2 FE Admin HrmConfigsPage** (`021674a` Run #244 3m38s PASS): Implementer Case 2 declarative single-page mirror Pattern 12-bis × 16-bis 9× cumulative. types/hrm-config.ts NEW 98 LOC × 2 app SHA256 IDENTICAL `228917e5fac2cdc6` + HrmConfigsPage.tsx NEW ~470 LOC × 2 app SHA256 IDENTICAL `6378fbc71ff90260` + App.tsx +3 LOC × 2 app (route + Navigate redirect default) + Layout.tsx +6 LOC staticMap × 2 app. **Smart Friend Implementer 3rd catch S35**: em main spec line 24 GAP "Layout staticMap no resolve issue" — WRONG. Implementer verified `MenuItem.cs` NO Url field + `resolvePath()` regex chỉ match `Ct_*/Wf_*/Pe_*/PeWf_*/AwV2_*` (KHÔNG `Hrm_Config_*`) → silent sidebar drop gotcha #50. Enforced staticMap mirror Pattern 16-bis 6× foundation reinforced. Declarative `KIND_CONFIG` Record × 4 kind + FieldDef extend types (text/textarea/checkbox/number/date/time/select/multiselect-weekday cho Shift WorkDays). Bundle hash rotate `BhR0MmLN→Bl6e54yi` admin + `DIdNaB6W→DHmW2tUF` user. **Multi-agent ROI S35 ~250K total**: 🟨 Implementer 3 spawn ~80K (3 cookie-cutter chunk + Smart Friend × 3 catch) + 🟦 Investigator 1 spawn ~8K (Plan G-H2 BE CRUD pre-flight audit + NamGroup ref MISS verdict — SOL clean-room design MẠNH HƠN, KHÔNG cần port) + 🟥 Reviewer 3 spawn ~60K (3 pre-commit verify Smart Friend cumulative 9× clean S22+S25+S29×2+S33×2+S35×3, Cat 1-6 PASS tất cả chunk) + 🟩 CICD 4 spawn ~70K (warm-up Run #241 + Run #242 + Run #243 + Run #244 stalled em main fallback). **NEW gotcha #53 sub-agent truncation/stall pattern** S35 × 3 occurrence (Reviewer × 2 mid-MEMORY-update + CICD × 1 stalled 600s watchdog) — mitigation: tight brief ≤ 8K + em main grep verify manual + curate MEMORY pre-spawn nếu > 25KB + remove "BEFORE stop with detailed MEMORY" directive khi MEMORY borderline. **NEW capability prod end-to-end S35**: (a) Admin login eoffice/employees → 5 satellite section inline Add/Edit/Delete form expandable cho 33 EmployeeProfile sample + (b) Admin login /hrm/configs/leave-types → table 5 row + sub-tab 4 kind switcher (LeaveTypes/Holidays/Shifts/OtPolicies) Dialog modal CRUD. **State chốt S35**: **35 mig unchanged** · **71 tables unchanged** · **~185 endpoints (+16 HRM Configs)** · **43 FE pages (+1 HrmConfigsPage)** · **69 menu keys unchanged** · **130 test PASS unchanged** (UAT mode no test add 3 chunk) · **53 gotcha (+1 #53 sub-agent truncation)** · 27 memory user-level · 6 skills · 4 sub-agents (Reviewer + CICD borderline post-spawn MEMORY entries S35).)

**Last updated S34 FULL (prev):** 2026-05-27 (Session 34 FULL — **🎯 Plan 1+2+3+4 ALL DONE end-to-end: Curate 4 MEMORY + Plan G-O1 Danh bạ + Phase 1.5 batch 6/6 + Plan G-H2 Mig 35 schema foundation**: cumulative **6 commit S34** push remote `edba4ae..07b3f3b` + 4 CI Run PASS (#238 Plan 2 + #239 Plan 3 batch + #240 Item 3 satellite + #241 Plan 4 Mig 35 - pending verify). **Plan 1 Curate** 4 MEMORY 118KB→101KB (-15%, 4 archive q3.md). **Plan 2 G-O1 Danh bạ** end-to-end: BE `Application/Office/DirectoryFeatures.cs` + FE 2 app card grid mirror SHA256 IDENTICAL + 34 row prod live + Run #238 PASS. **Plan 3 Phase 1.5 batch 6/6:** Item 6 menuKeys sync × 2 + Item 2 bool→bool? safe partial + Item 1 per-action policy Hrm_HoSo.{R/C/U/D} + Item 4 test +10 [Fact] 130 PASS + Item 5 UAT smoke nv.test 403 employees + 200 directory (gotcha #44 ACTIVE) + Item 3 BE 5 satellite CRUD scaffold 15 endpoint Pattern 12-ter NEW (~621 LOC + 164 LOC controller extend). **Plan 4 G-H2 Mig 35 schema foundation** (BE CRUD + FE forms defer S35): em main solo 4 entity (LeaveType + Holiday + ShiftPattern + OtPolicy) + 4 EF Config UNIQUE indexes + IApplicationDbContext + ApplicationDbContext +4 DbSet + Mig 35 3-file rule + `SeedHrmConfigsAsync` ~120 LOC seed 19 sample row (5 LeaveType + 10 Holiday VN 2026 + 3 Shift + 1 OtPolicy STANDARD) + MenuKeys `HrmConfig` sub-group + 4 leaf Order=2 + FE 2 app menuKeys sync 5 const. **Multi-agent ROI S34 ~150K total**: 🟨 Implementer 3 spawn ~80K (Plan 2 FE 2 app cookie-cutter + Plan 3 Item 4 test bundle Case 3 + Plan 3 Item 3 BE 5 satellite Case 2) + 🟩 CICD 2 spawn ~40K (Run #238 + Run #239 partial → em main fallback) + 👤 em main solo ~30K (BE Task 1+2 G-O1 + Phase 1.5 Items 6+2+1+5 + Plan 4 Mig 35 schema + DbInitializer seed + Permission menu + 6 commit/push batch + UAT smoke + STATUS/HANDOFF wrap). 🟦 Investigator + 🟥 Reviewer: 0 spawn S34 (chưa cần — Implementer Case 2+3 + em main solo đủ). **5 patterns reinforced cumulative S34**: Pattern 16-bis 4-place mirror cross-app 5× + Pattern 12-bis cross-module mirror preserved + Pattern 12-ter NEW (within-module 5× satellite scaffold) + Smart Friend 6× clean preserved no NEW catches + Per-NV admin opt-in policy match prior PE + bool→bool? safe partial Pattern NEW cross-project + Pattern 11 test infra helper cookie-cutter reinforced. **NEW capability prod end-to-end S34:** (a) Sidebar Văn phòng số > Danh bạ /directory shows 34 row card grid + (b) `/api/employees/{id}/work-history|education|family-relations|skills|documents` 15 endpoint scaffold ready (admin/Hrm role wire qua per-action policy Hrm_HoSo.*) + (c) 4 catalog HRM seeded prod sample (LeaveTypes/Holidays/Shifts/OtPolicies) ready cho Workflow Apps Phase 10.3 reference. **State chốt S34:** **35 mig (+1 Mig 35)** · **71 tables (+4 HRM Configs)** · **~169 endpoints (+15 satellite + 1 directory)** · **42 FE pages (+2 Directory × 2 app)** · **69 menu keys (+Off+OffDanhBa+HrmConfig+4 leaf)** · **130 test PASS (+10)** · **52 gotcha unchanged** · 26 memory user-level · 6 skills · 4 sub-agents (post-spawn MEMORY borderline curate next session). 

**Last updated S33 (prev):** 2026-05-26 (Session 33 — **🎯 Plan B G-H1 Hồ sơ Nhân sự FOUNDATION DEPLOYED PROD + Plan C B-Wrap +9 tests + Drift patch**)

**Last updated S34 batch 1+2+3 (initial wrap):** 2026-05-27 (Session 34 — **🎯 Plan 1+2+3 cumulative DONE end-to-end: Curate 4 MEMORY + Plan 10.2 G-O1 Danh bạ + Phase 1.5 batch 4 item**: cumulative **3 commit S34** push remote `edba4ae..61e9ce5` + 2 CI Run PASS (#238 Plan 2 G-O1 3m30s + #239 Plan 3 Phase 1.5 batch 3m48s). **Plan 1 Curate** 4 MEMORY sub-agent 118KB→101KB (-15%) — archive 4 file q3.md (Investigator/Implementer/CICD) + q2.md (Reviewer) preserve Patterns 1-15+12-bis+16-bis + Smart Friend foundation + 10-surface-point per-NV cumulative. **Plan 2 Phase 10.2 G-O1 Danh bạ nội bộ** end-to-end 4 task: em main solo `Application/Office/DirectoryFeatures.cs` + `Api/Controllers/DirectoryController.cs` (LEFT JOIN Users+EmployeeProfiles+Departments) + MenuKeys `Off`+`OffDanhBa` Order=29 + Implementer Case 2 FE 2 app SHA256 IDENTICAL × 2 (`types/directory.ts` 7349d9f64e78 + `InternalDirectoryPage.tsx` 2aa7e0eed2c8 card grid avatar PALETTE 6 màu + filter dept dropdown + email mailto + phone tel + Ext: badge) + CICD Run #238 PASS 34 rows EmployeeProfile API live + bundle rotate × 2 (`CqGMUMOr→ChA9_vP5` admin + `C_HKyxBe→DCpX7akt` user). **Plan 3 Phase 1.5 backlog G-H1 batch** 5/6 item DONE end-to-end: Item 6 menuKeys × 2 app full sync mirror BE 28 key cumulative + Item 2 UpdateEmployeeProfileCommand 3 bool→bool? safe partial update (Reviewer minor S33 fixed) + Item 1 EmployeesController per-action policy `Hrm_HoSo.Read/Create/Update/Delete` (gotcha #44 mitigation active) + Item 4 test bundle +10 [Fact] 120→**130 PASS** (EmployeeCodeGen 3 + Create handler 4 + List query 3) + Item 5 UAT smoke nv.test verified 403 silent /api/employees (gotcha #44 ACTIVE) + 200 /api/directory (class-level [Authorize] đúng spec). **Item 3 Satellite CRUD endpoints + FE forms DEFER S35** (heavy ~2-3h). **Plan 4 G-H2 Cấu hình HRM DEFER S35** (~3-4h Mig 35). **Multi-agent ROI S34 ~95K total**: 🟨 Implementer 2 spawn ~50K (Plan 2 Task 3 FE 2 app mirror + Plan 3 Item 4 test bundle Case 3) + 🟩 CICD 2 spawn ~40K (Plan 2 verify Run #238 + Plan 3 verify Run #239 partial then em main fallback) + em main solo ~5K direct UAT smoke. Em main solo BE Task 1+2 G-O1 + BE Item 6+2+1 Phase 1.5 + 3 commit/push batch + UAT smoke nv.test verify gotcha #44. **5 patterns reinforced cumulative S34**: Pattern 16-bis 4-place mirror cross-app 5× (G-O1 Task 3 + S33 Task 5 + S29 Plan CA HF1 + S29 Plan B Chunk D + future) + Smart Friend 6× clean preserved (no NEW catches S34 — all clean wire) + Per-NV admin opt-in pattern reinforced (Hrm_HoSo policy match prior PE Per-NV) + Test bundle cookie-cutter Pattern 11 (CodeGen + Create + List mirror BW1-BW7 fixture) + bool→bool? safe partial Pattern NEW (cross-project applicable for future Update commands). **NEW capability prod end-to-end S34:** Sidebar Văn phòng số > Danh bạ nội bộ /directory shows 34 rows card grid filter search + Per-action policy Hrm_HoSo wire prod live (Run #239 verified). **State chốt S34:** **34 mig (no change)** · **67 tables** · **~154 endpoints (+1 /api/directory)** · **42 FE pages (+2 Directory × 2 app)** · **64 menu keys (+Off+OffDanhBa)** · **130 test PASS (+10)** · **52 gotcha unchanged** · 26 memory user-level · 6 skills · 4 sub-agents (MEMORY 4× curate q3 — Investigator 21.8KB ✅ + Implementer 28KB borderline + Reviewer 25.7KB ✅ + CICD 30.9KB borderline post-spawn entries) · 14 AppRoles · 33 EmployeeProfile prod seeded · 7 V1 contract + V2 ready · bundle rotate 2× S34.)

**Last updated S33 (prev):** 2026-05-26 (Session 33 — **🎯 Plan B G-H1 Hồ sơ Nhân sự FOUNDATION DEPLOYED PROD end-to-end + Plan C B-Wrap BW1-BW7 +9 tests + Drift patch S33 startup**: cumulative **7 commit S33** push remote `5400983..79a8343` + 2 CI Run PASS (#350 Phase 1 3m38s + #237 Phase 2 3m50s). **Plan cha B Phase 10.1 G-H1** end-to-end 7 task: Investigator NamGroup audit 10 bảng → em main Mig 34 schema 4 decision → Implementer Case 2 BE entity 17 file + CQRS 3 file + FE 2 app 12 file cookie-cutter mirror SHA256 IDENTICAL + DbInitializer seed 30 EmployeeProfile + EmployeeCodeSequence + em main Permission menu Hrm+HrmHoSo + Reviewer Smart Friend 6× clean + CICD Run #237 PASS. **Plan cha C B-Wrap** end-to-end 4 step: TestCurrentUser stub + Implementer 3 test file BW1-BW7 (9 [Fact] split) + Reviewer PASS 0 critical + CICD verify Mig 33 prod + EmployeeProfiles 33 seeded + bundle hash rotate × 2 app (`BUTKoqRP→CqGMUMOr` admin + `CMHv2GS4→C_HKyxBe` user). **Plan cha D Drift patch S33 startup** Reviewer SEVERE catch CLAUDE.md+docs+implementer.md 10 line patch cumulative S19→S32 (mig 26→33 + test 81→111 + gotcha 26→52 + audit next 2026-06-01). **Multi-agent ROI S33 ~250K total**: 🟦 Investigator 2 spawn ~20K (S33 startup audit + Plan B Task 1 NamGroup pre-flight) + 🟨 Implementer 4 spawn ~110K (Plan B Task 3 BE entity + Task 4 CQRS + Task 5 FE 2 app + Plan C BW1-BW7) + 🟥 Reviewer 3 spawn ~60K (drift severity + Plan C BW verify + Plan B Phase 2 verify) + 🟩 CICD 3 spawn ~60K (S33 startup health + Run #350 + Run #237). Em main solo Task 2 schema design + Task 3b DbInitializer seed + Task 6 Permission menu + commit/push 7 commit batch. **8 patterns reinforced cumulative S33**: Pattern 12-bis cross-module mirror PE→Hrm 4× + Pattern 16-bis 4-place mirror cross-app 4× + Smart Friend 6× clean (S22+S25+S29×2+S33×2) + gotcha #51 INFRASTRUCTURE seed lesson applied 2× (EmployeeProfile + Hrm menu) + gotcha #50 Layout staticMap mirror applied 1× + Pattern Implementer truncation pattern observation 2×/3 (Task 3+4 truncated mid-MEMORY update, Task 5 clean — mitigation noted commit message). **NEW capability prod end-to-end:** Admin login `admin@solutions.com.vn / Admin@123456` → sidebar Nhân sự → Hồ sơ NS → /employees list 33 row sample `NV/2026/0007 BOD 1 - Director` + CreatePage form Header (UserId picker). **State chốt S33:** **34 mig (+1)** · **67 tables (+7 EmployeeProfile + 5 satellite + Sequence)** · **~153 endpoints (+5)** · **40 FE pages (+2)** · **62 menu keys (+Hrm+HrmHoSo)** · **120 test PASS (+9 BW)** · **52 gotcha unchanged** · 26 memory user-level · 6 skills · 4 sub-agents (MEMORY all >25KB, curate next session priority) · 14 AppRoles · 33 EmployeeProfile prod seeded · 7 V1 contract + V2 ready · bundle rotate 4× cumulative S33 (Phase 1 + Phase 2 push each).)

**Last updated S32 (prev):** 2026-05-26 (Session 32 — **🎯 Phase 10 backlog Plan G NamGroup port DOCUMENTED + Phase 9 stabilize batch DONE**: 10 Plan G-* atomic sprint ~3 tháng T6-T8/2026 (4 quyết định chốt: FULL 11 module + single schema `dbo` mở rộng Mig 34-42 + reuse Workflow V2 enum +5 values + chunk per-module). **Phase 9 stabilize 4 task done sequential anh main "finish hết":** (A2) RAG re-ingest 2949→2988 chunks, gotcha #52 rerank 0.516→0.906 verify; (A3) MEMORY curate 3 agent OVER 25KB: Implementer 38.4→27.5KB + Investigator 27.7→19KB + CICD 27→24.2KB (Patterns 1-19 + 12-bis + 16-bis foundation preserved, 10 verbose archived q2); (B-Wrap) Spec BW1-BW7 ContractWorkflowService ApproveV2Async test bundle DOCUMENTED implementation defer dedicated session ~2h; (C1) Ops status updated: backup-sql.ps1 ready (Task Scheduler register manual cmd), cert api.solutions.com.vn notAfter `2026-07-23` (~2 tháng nữa expire, auto-renew ~2026-06-23), SMTP+rotate creds BLOCKED chờ anh main coordinate. **4 sub-agent reuse-able S33:** Investigator agentId `afaf6d52a6a59a844` / Implementer `ab23cc322b5d495c0` / Reviewer `a0aa13093d14f3bca` / CICD `a505a02d84fc1fabe`. **Phase 10.1 G-H1 Hồ sơ NS handover S33 kick off:** spawn Investigator pre-flight NamGroup TblNhanVien* 8 bảng audit → em main design Mig 34 (1 main + 5 satellite) → Implementer Case 2 scaffold. Stats: 33 mig · 60 tables · ~148 endpoints · **111 test PASS unchanged** · **52 gotcha** · **26 memory user-level (+1 feedback_phase10_namgroup_port)** · 6 skills · 4 sub-agents · 38520 chunks 7 projects RAG live. 4 commits S32 push remote `b832f43..cce0963` all docs-only CI skip per #41.)

**Last updated S31 (prev):** 2026-05-26 (Session 31 — **🎯 RAG v1.3 Baseline PASS (11/11 recall@5=1.000) + retrieval.py critical fix**. **S30 RAG Setup:** Setup RAG Framework v1.3 governance () + evaluator spec + golden set v1.1 (14 queries) + baseline runs v1.0+v1.1 + . Bootstrap 2949 chunks (164 files — fixed Anti #24 projects.json root_path + added  corpus). Commit  docs-only CI skip. **S31 Eval Fix:** Discover  removed  method →  silently returns  (gotcha #52 NEW). Fix: . After fix: **recall@5 = 1.000 (11/11) PASS** (prev tentative 0.364 FAIL). Quality gate  updated: baseline=1.000, avg_rerank=0.847. **Sub-agents S30/S31:** 0 spawns (docs/infra only). **Commits pushed:**  (docs-only S30) — S31 pending. State: **33 mig** · 60 tables · ~148 endpoints · 38 FE pages · **111 test PASS** · **52 gotcha (+1 #52 qdrant-client search() removed)** · **25 memory user-level** · 6 skills · 4 sub-agents · **RAG v1.3 ACTIVE baseline PASS** 2949 chunks · CLI restart required for live MCP vector fix.)

**Last updated S29 FINAL (prev):** 2026-05-22 (Session 29  — **🎯 Plan CA + Plan B Contract V2 wire ALL DEPLOYED PROD**: cumulative **20 commits push 4 CI Runs PASS** (#229 + #230 + #231 + #232). **2 big plans done end-to-end:** Plan CA Move "Cấu hình danh mục dùng chung" admin → eoffice (7 commits + Hotfix 1) + Plan B Contract V2 wire mirror PE Mig 22-26 (9 chunks + Hotfix Reviewer + Hotfix CICD). **Multi-agent ROI explosive S29:** 🟦 Investigator 2 spawn ~40K (Plan CA terrain map + Plan B V1 audit) + 🟨 Implementer Case 2 5 spawn ~82K (Plan CA Chunk B + Plan B A2/C/D + E3 stopped mid-task) + 🟥 **Reviewer 4 spawn ~355K** (Plan CA Hotfix D2 password ≥12 MAJOR catch + Plan B Hotfix ApplicableType=Contract MAJOR catch — Smart Friend pattern 4× cumulative) + 🟩 **CICD Monitor 3 spawn ~90K** (2 fail 529 transient em main fallback manual + Plan B SeedSampleContractWorkflowV2 CRITICAL DemoSeed gate catch — gotcha #51 NEW). **Patterns NEW saved S29:** (1) 9-menu permission terrain map (Investigator) (2) V1+V2 coexist boundary (Investigator) (3) reference template paths cross-module mirror PE→Contract (Investigator) (4) Pattern 12-bis cross-module entity cookie-cutter mirror (Implementer) (5) Pattern 16-bis 4-place mirror cross-app reinforced 2× (Implementer) (6) Cross-module security validation mirror Cat 3 (Reviewer) (7) INFRASTRUCTURE vs DEMO seed classification gotcha #51 (CICD) (8) Race condition em main + Implementer parallel BE → stash workaround OR sequential preferred (Implementer). **3 hotfix cumulative:** Plan CA HF1 resolvePath staticMap + Plan CA D2 password ≥12 chars + Plan B Reviewer ApplicableType=Contract + Plan B CICD SeedSampleContractWorkflowV2 ungate. **NEW capability prod:** demo user `catalog.manager@solutions.com.vn / CatalogMgr@2026` (role CatalogManager — full CRUD 9 menu Master+Catalogs) + Drafter có thể create V2 contract qua Workspace dropdown `QT-HD-V2-001` sample workflow. **MCP RAG tools added cho 4 agent definitions** (commit `b51fc94`) — anh restart CLI để hot-reload. State chốt: **33 mig (+2 Mig 32+33)** · **60 tables (+1 ContractLevelOpinions)** · **~148 endpoints (+1 V2 contract create)** · **38 FE pages (+3: 4 master moved + WorkflowMatrixView counted unchanged S24)** · **111 test PASS unchanged** (UAT mode skip per chunk + cookie-cutter mirror) · **51 gotcha (+1 #51 INFRASTRUCTURE vs DEMO seed)** · **25 memory user-level unchanged** · 6 skills · 4 sub-agents (MCP RAG added pending CLI restart) · **14 AppRoles (+1 CatalogManager)** · **34 active prod users (+1 catalog.manager)** · **7 V1 contracts pinned coexist V2** · Bundle hash 4× rotate cumulative S29 (fe-admin: `BvcWrq2z→leEMWFLU→BBADl46y` + fe-user: `Bg2FNeIz→DVBLmZlt→Dgn1iU9E→DA_VI3zO`).)

**Last updated S29 prev wrap1:** 2026-05-22 (Session 29 — **🎯 Plan CA wire DONE + Hotfix 1 deploy**: 6 commits + 1 hotfix push `3cb54e0..e55d96b` cumulative. Move "Cấu hình danh mục dùng chung" (9 menu: Master + Suppliers + Projects + Departments + Catalogs + 4 sub-catalogs) từ fe-admin → fe-user/eoffice + add role mới `CatalogManager` + demo user `catalog.manager@solutions.com.vn`. **Chunks:** A 80d39a0 BE Role + Seed (em main, 64 LOC) · B 06a441c FE move 4 master pages 948 LOC (Implementer Case 2 cookie-cutter mirror byte-identical SHA256 4 file) · C c995f42 Sidebar filter 2 app (em main, 14 LOC) · D 4a592cf Seed demo user (em main, 7 LOC) · D2 68bcedd Hotfix password ≥12 chars S22+2 policy (em main, Reviewer pre-push CATCH critical) · HF1 e55d96b Add 7 entries `resolvePath` staticMap fe-user (em main, anh UAT screenshot CATCH silent sidebar drop). **2 CI runs PASS:** Run #229 sha=68bcedd 3m32s + Run #230 sha=e55d96b 3m24s. Bundle hash 2× rotate: fe-admin `BvcWrq2z→leEMWFLU`, fe-user `Bg2FNeIz→DVBLmZlt→Dgn1iU9E`. **Multi-agent ROI Plan CA:** 🟦 Investigator 1 spawn ~15K (terrain map 9 menu + GOTCHA tree-inherit) + 🟨 Implementer Case 2 1 spawn ~10K (byte-identical mirror 4 page) + 🟥 Reviewer 2 spawn ~165K (CRITICAL catch password policy) + 🟩 CICD Monitor 2 spawn fail 529 transient (em main fallback manual smoke) + 👤 Chủ trì Solo Chunk A/C/D/D2/HF1 ~100K. **NEW gotcha #50** "Page move cross-app — `Layout.tsx` `resolvePath` staticMap missed mirror → silent sidebar drop" + Pattern reusable cross-project: **4-place mirror checklist** khi Implementer Case 2 cookie-cutter copy page (page + Routes + menuKeys.ts + Layout.tsx staticMap — Implementer Chunk B missed point 4). Implementer MEMORY Pattern 16-bis NEW. **State chốt S29 Plan CA:** 31 mig (no schema change) · 59 tables · ~146 endpoints · **36 FE pages (+4: fe-user master/{Suppliers,Projects,Departments,Catalogs}Page)** · **111 test pass unchanged** (UAT skip per chunk + cookie-cutter mirror) · **50 gotcha (+1 #50)** · 25 memory user-level · 6 skills · 4 sub-agents · **13 AppRoles (+1 CatalogManager)** · **34 active prod users (+1 catalog.manager@solutions.com.vn)**. Catalog manager login `CatalogMgr@2026` (15 chars policy compliant). 7 commits remote `3cb54e0..e55d96b`.)

**Last updated S28 prev:** 2026-05-22 (Session 28 **FINAL wrap** — **🎯 S28 cumulative 12+ bước (t1→t6): Startup 9-step + RAG ROI verdict + bro correction mistake + scope-down + Layer A governance apply + 4 sub-agent flush MEMORY**. Bro broadcast **Layer A governance active 2026-05-22** (3-Layer distributed: A project-local active / B shared_global defer / C infrastructure anh pqhuy). **Quên rule cũ "mọi tương tác PHẢI store_memory" — ABANDONED.** Em main SOLUTION_ERP apply Layer A scope local: **4-category default** (decision/lesson/pattern-proven-≥2×/session-wrap) + **skip list nguyên** + 5 SOLUTION_ERP-specific adjustment cho Phase 9 UAT mode + **tag schema mandatory** `[type, phase, bc-or-module]` với type closed enum 6 (decision/lesson/pattern/gotcha/bug-fix/session-wrap) + phase enum 11 (phase-0 → phase-10+, current **phase-9 UAT ACTIVE**) + BC/module enum 8 domain (contract/pe/budget/master/identity/forms/workflow/notifications) + 5 cross-cutting (tests/infra/cicd/multi-agent/governance/docs) + optional prefix 8 (tech/agent/risk/severity/commit/mig/gotcha/plan). **source_path convention** `solution_erp/<area>/<topic>-<date>`. **Eval ritual** weekly Friday 5 metric từ 2026-05-29 → end-trial 2026-06-05. **10 golden query draft** ready. **6 chunk stored S28 t2-t6:** Protocol cross-project (deprecated S28 t4 scope-down) · Conversation log S28 t1+t2 · Commit pattern acknowledge · 2-week monitoring 5 measure · Scope-down acknowledge · Layer A policy apply. **4 sub-agent flush MEMORY DONE post-S27 model:inherit fix** — registry hot-reload verified all 4 (Investigator agentId `a2462`/`aeda4`, Implementer `a2a2f`, Reviewer `a9e94`, CICD Monitor `a8098`). Each Recent activity entry S28 t1 → S28 wrap góc nhìn từng con preserved cumulative S1-S27. **NEW memory user-level `feedback_interaction_logging_rag.md` SCOPE-DOWN S28 t4** (anti-pattern over-reach self-authorize cross-project rule + implicit consent risk lesson). Stats unchanged: 31 mig · 59 tables · ~146 endpoints · 35 FE pages · **111 test pass** · 49 gotcha · **25 memory user-level (+1 NEW interaction logging scope-down)** · 6 skills · 4 sub-agents (all verified hot-reload) · **3,462 RAG chunks SOLUTION_ERP** (+6 chunk store S28) + 6 MCP tools active. **Hit rate verify 3 query**: Plan B Contract V2 rerank 0.84 ✓ + gotcha #48 rerank 0.84/0.82/0.82 ✓ + per-NV 10-surface checklist hit (token overflow) ✓ — > 0.7 threshold pass cumulative. **0 commit remote S28** (all docs + memory + RAG store — anh chốt push thủ công sau approve). Plan B Contract V2 wire kick-off pending 2026-05-22+ (8-chunk pre-allocated 🟦 Investigator pre-flight + 🟨 Implementer Case 2 ×4 + 👤 Chủ trì Solo Service ApproveV2Async + 🟥 Reviewer pre-commit + 🟩 CICD Monitor post-deploy).)

**Last updated S28 t1 initial:** 2026-05-22 (Session 28 turn 1 — **🎯 S28 startup 9-step + RAG ROI reality check em main verdict + cross-agent perspective update**. Anh restart Claude Code CLI sau S27 wrap → sub-agent registry **hot-reload OK** verified qua smoke test spawn Investigator (agentId `a2462ca503ed38b0b`, 16.3 KB MEMORY loaded, 3 skills attached: contract-workflow + permission-matrix + ef-core-migration). RAG status: **3,460 chunks SOLUTION_ERP indexed** (cao hơn S26 wrap 2,628 — re-index ngầm) + 6 MCP tools (`mcp__rag-unified__*`) loaded, Qdrant NSSM Service Running PID 4476. **Bro hỏi "cảm nhận rõ lợi ích RAG ko?"** → em main verdict thẳng thắn (anti-suger-coat): **CÓ LỢI marginal short-term (5-10% time saving), TRANSFORM long-term cross-project (chưa khai phá vì 4 em main project khác chưa bootstrap).** 4 case verdict: solo project blanket đủ ⚠️ Marginal | cross-session retrieve specific ✅ Tốt (rerank 0.84 vs 10 phút find) | cross-project 5 dự án 🚀 **TRANSFORM** (chưa dùng được) | heavy refactor Plan B-class ✅ Tốt. **3 nhược điểm cảm nhận thật:** (1) Bootstrap lag — S27 NEW content (`feedback_subagent_setup_pitfalls + skill-audit-late + 4 MEMORY post-curate + rag-onboarding-guide`) chưa index sau 1 ngày, query "subagent setup pitfalls" return **0 hits** (re-bootstrap pending pydantic fix); (2) Effective coverage gap — Plan B query rerank 0.84 excellent vs S27 content 0 hit miss; (3) Token cost rerank-2.5 ~$0.05/1K query (0.24% free tier Voyage). **Bottom line:** RAG đáng giữ cho infrastructure đã đầu tư S26-S27 (60.9s bootstrap + NSSM Service auto-start + Custom Dashboard 7 panel), **nhưng nếu redo từ đầu** sẽ recommend bro đợi bootstrap 5 dự án rồi mới claim "RAG transform" — solo project chỉ saving marginal. **Pattern reusable cross-project — RAG ROI evaluation framework:** 1 dev solo + 1 project < 1M tokens → ❌ Skip RAG | > 1M tokens → ⚠️ Marginal (5-10%) | N project > 5M tokens → ✅ Worth (cross-project transform) | N dev team enterprise → ✅ Mandatory. Avoid over-hype RAG cho solo 1 project. **Update multi-layer 6 file:** memory user-level `feedback_rag_hybrid_pattern.md` append §S28 t1 ROI reality check (~120 LOC NEW section) + 4 agent MEMORY Recent activity entry góc nhìn từng con (🟦 Investigator: pre-flight audit cross-session retrieve Plan B-class · 🟨 Implementer: Pattern proven retrieve cumulative 19 Pattern foundation · 🟥 Reviewer: gotcha historical context cross-ref #44+#48+#49 · 🟩 CICD Monitor: Run history cross-reference #186-#222 cumulative + 10-surface-point per-NV checklist promoted foundation) + STATUS.md + HANDOFF.md headers. **Bro sẽ cross-check** 4 agent consistency (next test: spawn 4 agent với same prompt verify alignment). Stats unchanged: 31 mig · 59 tables · ~146 endpoints · 35 FE pages · **111 test pass** · 49 gotcha · **24 memory user-level (no new entry, only append §S28 t1)** · 6 skills · 4 sub-agents (registry hot-reload verified post-S27 fix) · 3,460 RAG chunks + 6 MCP tools active. **0 commit remote S28 t1** (all docs + memory update + retrospective opinion - anh chốt push thủ công sau approve).)

**Last updated S27:** 2026-05-22 (Session 27 chốt cuối — **🎯 Memory Curate + RAG Manual Control + Multi-agent Setup Pitfalls Fix**. **Trigger:** Anh share VIPIX `docs/guides/multi-agent-pitfalls.md` → em audit SOLUTION_ERP setup phát hiện CHÍNH XÁC CÙNG PATTERN broken: 4 file `.claude/agents/*.md` dùng `model: claude-opus-4-7` (200K silent fallback) + non-standard `effort: max` field → registry chưa load cả session S27. **Fix applied:** 4 file → `model: inherit` + remove `effort: max`. **Pending:** Anh restart Claude Code CLI để hot-reload. **Memory user-level NEW:** `feedback_subagent_setup_pitfalls.md` 235 lines cross-project pitfall checklist. **Plan A.3 RAG Manual Control + Option 4b NSSM Service:** 7 PS scripts + 6 `$PROFILE` aliases + Startup folder shortcut + Custom Dashboard HTML 7 panels. NSSM Windows Service Qdrant Running PID 4476 RAM 101.8 MB. **Plan A.4 RAG Onboarding Guide:** 42.5 KB / 682 lines / 14 sections + §A2 + §A3. **Plan F1 Qdrant Web UI fix:** Download dist-qdrant.zip 6.59 MB → HTTP 200 "UI | Qdrant". **Memory Curate 4 MEMORY -60%** (180.6→72.0 KB, archive 115 KB preserved §6.5). **Audit drift §6.4+§9.4 sớm** (trigger +8 gotcha): 5 file patched + log `docs/changelog/skill-audit-2026-05-late.md`. **0 commit remote S27** (all local).)

**Last updated S26 FINAL:** 2026-05-21 (Session 26 **FINAL wrap** — **🎯 Anh chốt 2 decisions architectural quan trọng cuối session sau khi đã commit `bf93abd`**: (1) **Approach B distributed RAG bootstrap** — em main SOLUTION_ERP chỉ build INFRASTRUCTURE + DOCS, KHÔNG bootstrap data cho 4 dự án khác (NamGroup/DH Y Dược/Ashico/Vipix). 4 em main project khác tự bootstrap khi anh mở session project đó (Cognition "writes single-threaded" boundary). (2) **Option 4a manual PowerShell scripts** thay Phase 6b Task Scheduler auto-start — anh OWN control + visibility tốt hơn qua `rag-start`/`rag-stop`/`rag-status`/`rag-dashboard` aliases + Qdrant dashboard built-in (`http://localhost:6333/dashboard`) FREE. **+1 memory user-level NEW** `feedback_rag_distributed_ownership.md` (~200 chunks added vào RAG sau khi fix bootstrap.py glob extra_corpus bug — `import glob` recursive thay vì Path manual parsing). **RAG corpus final S26:** 127 files → **2,628 chunks** (+207 chunks user-level memory entries 23 file) → ~535K Voyage tokens (0.27% free tier 200M/month). Cache SHA256 hit working PERFECT: re-bootstrap force-reindex 2nd time chỉ 6.5s (vs 60.9s initial — 10× speedup). **Rerank verify**: 5/6 query S26 content hit rerank 0.498-0.926 (Approach B distributed pattern + Option 4a manual scripts + em main project X build infra docs). Query failed "PowerShell aliases rag-start" expected — Phase 6 scripts chưa code thực tế (defer S27+). **Pending S27+ updated:** Phase 5 SKIP cho em (distributed) · Phase 6 = Option 4a scripts (em viết 4 PS1 script + add `$PROFILE` aliases) · Phase 7 = xuất `rag-onboarding-guide.md` 13 section (11 cũ + §12 monitoring + §13 distributed Approach B). **Memory user-level: 24 entries** (+1 NEW `feedback_rag_distributed_ownership.md`).)

**Last updated S26 initial wrap:** 2026-05-21 (Session 26 chốt cuối lần đầu — **🎯 S26 cumulative wrap: 6 plan PE List tree view UI iteration + Plan AI RAG global MCP infrastructure setup**. **Plan AG/AG2/AG3/AG4/AG5/AG6** cumulative 6 commits Plan AG series `0bf6c7e..d99069a` push remote — UAT feedback bro Tra Sol 2026-05-21 screenshot "UI Duyệt NCC như đám rừng" → folder tree giống Outlook: **Plan AG** Phase 1 PE List tree view 2-level Project > Gói thầu > PE (Investigator audit 5Q + Implementer Case 2 cookie-cutter mirror 2 app + Reviewer pre-commit PASS 0 blocker + CICD Monitor Run #222 PASS bundle hash rotate). **Plan AG2** simplify 1-level (drop tầng gói thầu) + Panel 1 widen 340→400px. **Plan AG3** drop single-PE flat branch, consistent UI (mọi dự án dù 1/N phiếu đều render `<details>`). **Plan AG4** bổ sung Người tạo + Phòng ban tạo PE card — BE DTO `PurchaseEvaluationListItemDto` +4 fields (DrafterUserId/DrafterName/DepartmentId/DepartmentName) + 3 projection JOIN Users+Departments LEFT (ListHandler/InboxHandler/ApprovedHandler) + FE `PeListItem` type +4 fields + UI card render 👤 Drafter · Phòng ban. **Plan AG5** extend tree 3-level Project > Năm > NCC > PE (selectedSupplierName fallback "(Chưa chọn NCC)" cho PE chưa DaDuyet). **Plan AG6** compact card 3-row gọn đẹp (drop Type label redundant + combine mã phiếu/time + Drafter/Dept/HĐ inline). **Plan AI RAG global MCP setup** (User-level Approach A — 1 dev 5 dự án cùng máy localhost) — Phase 0 pre-flight + Phase 1 Qdrant v1.18.0 Windows native binary (KHÔNG Docker, PID 67240 port 6333) + Phase 2 FastMCP server ~1100 LOC Python 9 file (server.py + lib/embed.py voyage wrapper + lib/retrieval.py 3-layer pipeline + lib/projects.py auto-detect cwd + lib/chunking.py contextual prepend + lib/watcher.py) + Phase 3 register MCP user-level (`claude mcp add` với `--` separator trick) + Phase 4 bootstrap SOLUTION_ERP 126 files → **2,392 chunks indexed 60.9s** (~484K Voyage tokens = 0.24% free tier 200M/month). 4 test queries verified end-to-end recall: "gotcha #45 PE button TraLai" 0.641 / "admin opt-in per-NV" 0.836 / "EF migration backfill" 0.766 / "multi-agent setup" 0.879. Stack: Voyage-4-large embedding + Voyage rerank-2.5 + Qdrant Windows native + SQLite FTS5 BM25 + Reciprocal Rank Fusion + Anthropic Contextual Retrieval prepend + FastMCP 3.3.1 stdio. **+1 file MD onboarding `docs/guides/multi-agent-setup-guide.md`** xuất cho 4 dự án future (NamGroup/DH Y Dược/Ashico/Vipix detected từ Claude Desktop config epitaxy folder permission). Multi-agent execution S26: 🟦 Investigator 2 spawn (Plan AG audit 5Q ~30K + Plan AI RAG distribution research ~40K — 4 study cases Cursor/Cline/Continue/Sourcegraph) + 🟨 Implementer 1 spawn (Plan AG Case 2 cookie-cutter ~16K) + 🟥 Reviewer 1 spawn (Plan AG pre-commit ~25K PASS 0 blocker) + 🟩 CICD Monitor 1 spawn (Run #222 verify ~12K). Em main solo Plan AG2-AG6 + Plan AI Phase 0-4 (UI polish iteration + RAG infra setup — cost ROI thấp nếu spawn 5×). Stats final S26 chốt: **31 mig (no schema)** · 59 tables · ~146 endpoints · 35 FE pages · **111 test pass unchanged** (UAT defer test-after) · 49 gotcha unchanged · 23 memory user-level unchanged · 6 skills · 4 sub-agents · **+1 docs file `multi-agent-setup-guide.md`** + **+1 RAG infrastructure** `D:\.claude-rag\` (server + lib + qdrant-bin + data). Patterns reusable cross-project (3 NEW S26): (1) HTML native `<details>/<summary>` + Tailwind named groups `group/proj` + localStorage Set<string> cho hierarchical tree UI when no Accordion lib available (Pattern 19 Implementer NEW), (2) RAG User-level Global MCP 1 server localhost serve N project (Approach A Plan AI), (3) Qdrant Windows native binary deployment (no Docker overhead — appropriate cho 1 dev solo scenario, không scale enterprise). **Memory FLAG**: cicd-monitor MEMORY ~74KB (+2KB từ S25), critical curate session URGENT next.)

**Last updated S25:** 2026-05-19 (Session 25 chốt cuối — **🎯 S25 cumulative wrap: 7 plan + 7 commits Plan AB→AF + 7 CICD Runs (#215 FAIL → #216-#221 PASS)**. Push remote `e23f51c..506cada`. Bro UAT 2026-05-19 phát hiện 2 bug visibility critical PE/2026/A/032 + 4 follow-up polish UAT iteration: **Bug 1 Budget Adjust** không show "Lịch sử thay đổi" (BE log Header+Update OK nhưng FE filter strict TraLai-only loại) — **Bug 2 Return Mode 4 mode** không log Changelog (ApplyReturnModeAsync miss `db.PurchaseEvaluationChangelogs.Add()`) — **Bug 3 Lịch sử duyệt** missing Trả lại + Vượt cấp entries (Reject branch không add Approval row) — **Bug 4 dual-phase badges** gây nhầm "Đã gửi duyệt → Đã gửi duyệt" cho 3 mode Reject giữ Phase=ChoDuyet — **Bug 5 Changelog UserName** show "Hệ thống" thay vì user thật (9 sites BE miss UserName) — **Bug 6 historical name resolve** entries pre-deploy vẫn show empty (forward-only fix). **Plan AB Chunk A** (`cdfd542`) BE log return mode + FE filter relax × 2 app. **Plan AB Chunk A2** (`8c05947`) fix Plan M tests SQLite frozen-clock tie-break (gotcha #48 NEW — Run #215 caught + Run #216 PASS). **Plan AC** (`a734bf2`) BE Reject add Approval row + skipToFinal comment + FE Decision badge × 2 app. **Plan AC2** (`25837b6`) FE merge synthetic Reject rows từ Changelog historical (Option 2A bro chốt, reversible no-DB-touch). **Plan AD** (`0aaf2df`) Drop misleading dual-phase badges + parse next-target hint via regex `Chuyển phase X → Y` + comment keyword Trả lại/Vượt cấp (gotcha #49 NEW). **Plan AE** (`9ea62be`) BE preventive batch fix UserName 9 Changelog.Add sites (Budget Adjust + 8 sites: Create + Update + Detail CRUD + Quote CRUD + Select Winner). **Plan AF** (`506cada`) FE userMap fallback từ embedded domain data PeDetailBundle (drafter + approvals + approvalFlow + levelOpinions + departmentOpinions) — no extra API fetch admin permission. Multi-agent execution: 🟦 **Investigator** 1 spawn Plan AB Bug 1+2 audit ~28K + 🟨 **Implementer** 1 spawn Plan AB Chunk A ~12K Case 1 + 🟥 **Reviewer** 1 spawn Plan AB pre-commit ~22K PASS 0 blocker (1 minor non-block) + 🟩 **CICD Monitor** 7 spawns Run #215-#221 verify ALL PASS post-Plan AB Chunk A2 fix. **Em main solo từ Plan AC đến AF** (5 plan, cross-stack reasoning + UAT iteration borderline, Implementer/Reviewer KHÔNG re-spawn). Stats final S25 chốt: **31 mig (no schema)** · 59 tables · ~146 endpoints · 35 FE pages · **111 test pass unchanged** (UAT defer test-after per §7) · **49 gotcha (+2 #48 SQLite tie-break + #49 dual-phase UI confusion)** · **23 memory user-level (+2 NEW: `feedback_fe_merge_synthetic_audit` Plan AC2 + `feedback_fe_usermap_fallback` Plan AF)** · 6 skills · 4 sub-agents active. Bundle hash 6× rotate × 2 app (#216-#221), Mig 31 unchanged toàn S25. Patterns reusable cross-project (8 NEW S25): (1) Multi-Changelog.Add SQLite tie-break test discriminator, (2) CICD catch UAT skip test risk for BE refactor > 100 LOC, (3) Test fix Option A over BE refactor preservation, (4) Capture pre-call mutation state cho audit row from-position, (5) FE merge synthetic rows từ Changelog reversible recovery, (6) Drop misleading dual-phase badges + parse semantic hint, (7) Changelog UserName preventive systemic batch fix, (8) FE userMap fallback từ embedded domain data no extra API. **Memory CRITICAL FLAG**: cicd-monitor MEMORY ~72KB strongly over 50KB hard threshold — DEDICATED CURATION SESSION REQUIRED next (archive Run #186-#210 + S22-S24 verbose). Bro UAT verify ALL Plan AB→AF live deploy cumulative.)

**Last updated S23 t12:** 2026-05-15 (Session 23 turn 12 chốt cuối — **🎯 S23 cumulative wrap: 11 plan + 32 commits cumulative**. Plan K (Mig 31 F2 refactor 9 commits) → L (UAT bug 5) → M (F1 edge case 4) → N (per-NV lookup 1 site 2) → O (4 sites cascade 2) → P (Controller body record 1) → Q (FE banner CSS 1) → R (cleanup phiếu/workflow 1) → S (wipe ALL workflows 1) → T (DemoSeed flag 2) → U (sidebar truncate 1). 4 sub-agents active throughout: 🟦 Investigator 5 spawn (K0 + N + P FE wire + R audit + L2 spawn) + 🟨 Implementer 5 spawn (K1/K3/K5/K7 + M2 + M3 Case 2/3) + 🟥 Reviewer 2 spawn (K2 pre-commit + M3 cumulative review) + 🟩 CICD Monitor 5 spawn (Run #195 K10 + #199 L + #200 M + #201 N + #202 O + #203 P + #204 Q + #207 T + #208 T5+T6 + #209 U — ALL PASS). **Memory user-level update cumulative S23:** `feedback_per_nv_permission_scope.md` reinforced 5 sections (S22+5 + S23 t1 + t3 + t4 + t5 + t6) → wire 10 surface points (point 9 lookup discrimination + point 10 Controller body record mirror). `feedback_uat_skip_verify.md` Plan L lesson Service refactor semantic test atomic. **+1 memory NEW** `feedback_demo_seed_flag_disable.md` cross-project Plan T pattern. **3 destructive cleanup cumulative Plan R+S+T5** ~720 rows wiped + DbInitializer permanent disable demo seed. **Stats final S23 chốt cuối:** 31 mig · 59 tables · ~145 endpoints · 34 FE pages · **111 test unchanged** · 47 gotcha · **21 memory entries** (+1 NEW Plan T flag pattern) · 6 skills · 4 sub-agents active · **0 PE + 0 demo workflow + DemoSeed flag persist** UAT permanent clean slate. Backup rollback: `vietreport-vps:C:\Backup\SolutionErp_pre_cleanup_2026-05-15.bak` 18.5MB. **32 commits S23** pushed remote `eb106f2..86d8806`. CI verify ALL PASS. Bro Designer setup workflow mới from scratch, KHÔNG còn auto re-seed contaminate. Plan B Contract V2 wire HIGH priority next.)
**Last updated S23 t10:** 2026-05-15 (Session 23 turn 10 — **🔧 Plan T: Disable auto re-seed demo data + final DELETE — UAT permanent clean slate**. Bro phát hiện sau Plan R+S: 4 phiếu `[DEMO]-A/B` + 2 V1 workflows + 1 V2 mẫu UAT TỰ ĐỘNG RE-SEED sau khi BE deploy commits Plan P+Q+R+S → IIS recycle → `DbInitializer.InitializeAsync` chạy lại 5 demo seed methods. Bro AskUserQuestion chốt Option A: disable demo seed vĩnh viễn qua flag config. Em main implement: `appsettings.json` add `"DemoSeed": { "Disabled": true }` + `appsettings.Development.json` override `false` cho dev test seed local + `DbInitializer.cs` add `using Microsoft.Extensions.Configuration` + `var demoSeedDisabled = config.GetValue<bool>("DemoSeed:Disabled")` + wrap 5 method conditional `if (!demoSeedDisabled)` (SeedWorkflowDefinitions V1 + SeedPurchaseEvaluationWorkflows V1 + SeedDemoContracts + SeedDemoPurchaseEvaluations + SeedSampleApprovalWorkflowsV2). KEEP: SeedRoles + SeedAdmin + SeedDepartments + SeedDemoUsers (30 UAT users) + SeedMenuTree + SeedAdminPermissions + SeedDemoMasterData (Supplier/Project) + SeedContractTemplates + SeedCatalogs + Backfill helpers. Note: `appsettings.Production.json` bị `.gitignore` (secrets), em set flag mặc định trong `appsettings.json` commit qua git — production inherit `true`. Run #207 sha=0b97840 PASS 3min24s → IIS deploy applied flag. T5 final DELETE: SCP `scripts/plan-t5-final-cleanup.sql` upload + sqlcmd -i 3 TRANSACTION DELETE → 4 PE + 1 V2 + 2 V1 = 7 rows + cascade child. T6 verify NO re-seed loop: `Restart-WebAppPool SolutionErp-Api` force IIS recycle → BE startup → wait healthy → sqlcmd verify: **PE=0 + V2=0 + V1=0** preserved (KHÔNG re-seed) + Users=33 + Suppliers=19 + Projects=9 + Contracts=7 (existing preserved). DemoSeed flag PROVEN active end-to-end. Total cumulative Plan R+S+T cleanup: ~677 rows wiped + DbInitializer re-seed disable vĩnh viễn. Stats final S23 t10: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · **111 test unchanged** · 47 gotcha · 20 memory · 6 skills · **0 PE + 0 workflow + flag disable demo seed** — UAT permanent clean slate. Bro Designer setup workflow mới from scratch, KHÔNG còn auto re-seed contaminate.)
**Last updated S23 t9:** 2026-05-15 (Session 23 turn 9 — **🧹 Plan S: Wipe ALL workflows — UAT clean slate hoàn toàn**. Bro chốt sau Plan R: "các cái demo quy trình cũ -> xóa hết luôn đi nhé". 4 workflows còn lại (2 V2 ghim + 2 V1 active) đều seed demo cumulative (`(mẫu UAT)` / `(clone)(clone)` / `(v01)` sample seed). Bro AskUserQuestion chốt Option A (Recommended): wipe ALL 4 workflows, UAT clean slate. Em main solo execute (Investigator audit Plan R đã cover scope precedent, Plan S = continuation cùng UAT cleanup phase). Backup rollback: Plan R backup `SolutionErp_pre_cleanup_2026-05-15.bak` 18.5MB vẫn capture full state pre-cleanup → reuse cho rollback. Script `scripts/plan-s-wipe-all-workflows.sql` 2 BEGIN/COMMIT TRANSACTION + SET QUOTED_IDENTIFIER ON. Execute via scp + sqlcmd -i: DELETE ALL ApprovalWorkflows (2 rows cascade Steps+Levels) + DELETE ALL PurchaseEvaluationWorkflowDefinitions (2 rows cascade Steps+Approvers). Post-state: **0 V2 + 0 V1 + 0 Steps + 0 Levels + 0 Approvers** (ALL workflow entities wiped). BE smoke verify 5/5 endpoints 200 (auth + PE list + V2 workflows + V1 workflows + users + menus) — KHÔNG crash startup (no Contract pin to V1 — chỉ PE dùng workflow, PE đã wipe Plan R). Hậu quả expected: user KHÔNG tạo được phiếu mới (Workspace Select empty) cho đến khi admin Designer seed workflow mới from scratch — UAT mode chấp nhận. Total cleanup cumulative Plan R + S: 35 PE + 17 V2 + 4 V1 + ~600 cascade child = **~670 rows wiped**, prod database UAT clean slate hoàn toàn. Stats final S23 t9: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · 111 test · 47 gotcha · 20 memory · 6 skills · **0 PE + 0 workflow** (database state mới hoàn toàn). Pending: admin Designer seed workflow mới + bro UAT test fresh.)
**Last updated S23 t8:** 2026-05-15 (Session 23 turn 8 — **🧹 Plan R: Cleanup destructive prod database — phiếu test + workflow ko ghim**. Bro UAT confirm Plan P+Q wire OK + chỉ thị "OK Tao thấy tạm ổn rồi đấy, mày xóa hết các phiếu test cũ đi nhé, các quy trình cũ ko ghim cũng xóa hết đi. Cho gọn đẹp." 🟦 Investigator pre-flight audit prod ~64K spawn confirm scope: 28 PE active + 7 soft-deleted + 15 V2 workflows IsUserSelectable=false + 2 V1 workflows IsActive=false. FK Restrict gotcha: PE.ApprovalWorkflowId Restrict → phải hard-DELETE PE trước (soft-delete KHÔNG release FK). Entity extend `BaseEntity` (workflow) KHÔNG hỗ trợ soft-delete. Bro chốt Option A (Recommended) qua AskUserQuestion. Em main execute 6 steps qua sqlcmd ssh vietreport-vps: (1) BACKUP `SolutionErp_pre_cleanup_2026-05-15.bak` 18.5MB qua `scripts/plan-r-backup.sql` upload scp + sqlcmd -i (workaround SQL Express no COMPRESSION + no RESTORE VERIFYONLY permission cho vrapp). (2) Script `scripts/plan-r-cleanup.sql` 3 BEGIN/COMMIT TRANSACTION + SET QUOTED_IDENTIFIER ON (filtered index Mig 29+ require). (3) DELETE 35 PE rows (28 active + 7 soft-deleted, cascade ~446 child: 42 Details + 49 Suppliers + 64 Approvals + 238 Changelogs + 10 Attachments + 43 LevelOpinions). (4) DELETE 15 V2 unghim (cascade ~140 Steps+Levels). (5) DELETE 2 V1 inactive (cascade ~37 Steps+Approvers). Total: **52 rows + ~600 cascade child deleted**. Post-cleanup state: **0 PE · 2 V2 workflows ghim** (`QT-DN-V2-001 v16` + `QT-DN-PA-V2-001 v2`) · **2 V1 workflows active** (`QT-DN-A v3` + `QT-DN-B v1`). Smoke verify BE alive post-cleanup: 3/3 endpoints 200 (auth login + PE list + V2/V1 workflow list) → KHÔNG crash startup (Plan F precedent S22 avoid được — V1 active workflow giữ nguyên). Multi-agent ROI: Investigator catch FK Restrict gotcha + recommend backup mandatory + 3 Option compare — saved em main hard-delete without backup risk. Stats final S23 t8: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · 111 test unchanged · 47 gotcha · 20 memory · 6 skills · **0 PE phiếu test + 4 workflow ghim/active** (gọn đẹp UAT clean slate). Pending: bro UAT test workflow mới fresh.)
**Last updated S23 t6:** 2026-05-15 (Session 23 turn 6 — **🎯 Plan P: HOTFIX Controller TransitionPeBody record missing 3 fields — bug ROOT CAUSE thực sự của F1+F2 fail**. 1 commit Plan P atomic. CICD Monitor Run #202 verify Plan O CRITICAL caveat catch: `PurchaseEvaluationsController.cs:267` `TransitionPeBody` record CHỈ có 3 fields (TargetPhase, Decision, Comment) — MISSING 3 fields có trong Command record `TransitionPurchaseEvaluationCommand` (ReturnMode + ReturnTargetUserId + SkipToFinal). `mediator.Send` line 70 cũng drop 3 field. → FE × 2 app SEND ĐÚNG 7 fields qua `api.post(/transitions)` body (Investigator verify FE wire OK 100%) → ASP.NET Core deserialization silently DROP 3 fields ở Controller layer → Handler nhận `ReturnMode=null` + `SkipToFinal=false` → fallback default Drafter mode + F2 không trigger. Bug present 2 NGÀY PROD từ Mig 28 deploy 2026-05-13 — gây TẤT CẢ F1+F2 wire fail từ FE side (Plan N + Plan O fix lookup sites nhưng controller bug block flow trước khi đến lookup site). Fix Plan P: Controller body record +3 field default null/false + `mediator.Send` pass 7 fields + add `using SolutionErp.Application.PurchaseEvaluations.Services` cho WorkflowReturnMode enum import. ~10 LOC BE 1 file. dotnet test **111/111 PASS** (+0 từ 108 — không cần test mới vì Investigator confirm scope BE Controller only, FE wire đúng, Mig 28/31 Domain test đã cover handler logic). Multi-agent ROI: 🟦 Investigator audit FE 2 spawn ~58K confirm hypothesis BE-only scope, avoid em main fix sai cross-stack. 🟩 CICD Monitor Run #202 catch caveat critical lúc verify Plan O — invaluable bug catch chain. Pattern reinforced: **Controller body record MUST mirror Command record fields** khi Command thêm optional params — Mig 28 + Mig 31 cumulative thêm 3 fields nhưng Controller body record chưa update → silent drop bug. Stats final S23 t6: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · **111 test pass unchanged** · 47 gotcha · 20 memory · 6 skills · 4 sub-agents (Investigator FE wire + CICD Monitor verify spawns). CHƯA push remote — chờ CICD verify cuối.)
**Last updated S23 t5:** 2026-05-15 (Session 23 turn 5 — **🎯 Plan O: HOTFIX 4 lookup sites cùng pattern per-NV cascade — Plan N point 9 chỉ catch 1/5 sites**. 2 commits Plan O atomic + docs. Bro UAT 2026-05-15 sau Plan N deploy phát hiện tiếp: Actor NV Test (UAT V2) trong OR-of-N slot 4 NV click "Trả lại Người chỉ định" → toast "Không phải lượt bạn" mặc dù NV Test đúng trong slot. Em main audit grep `FirstOrDefault.*Order ==` toàn project — discovered 5 lookup sites total: Plan N catch 1 (GetPe handler), 4 sites khác CÙNG BUG còn nguyên: (1) `Service.cs:201` `EnsureCanRejectV2Async` actor match guard ← Bug bro UAT ROOT CAUSE, (2) `Service.cs:248` `ApplyReturnModeAsync` read Allow flag từ row đầu, (3) `DetailFeatures.cs:72` F3 `EnsureEditableForDetailsAsync` cùng bug, (4) `Features.cs:311` F4 `AdjustBudgetCommand` cùng bug. 👤 Chủ trì Solo fix 4 sites surgical ~30 LOC + add `Guid? actorUserId` param vào `ApplyReturnModeAsync` (4 param signature change) + caller `TransitionAsync:94` update + 3 regression test mới `PurchaseEvaluationPerNvLookupRegressionTests` (Actor non-first-row OR-of-N trả lại / Outsider không slot ForbiddenException / Actor có flag while others don't AllowsMode). dotnet test **111/111 PASS** (+3 từ 108 baseline Plan N). Pattern reinforced: **5 lookup sites checklist** sau Mig 29 OR-of-N — Plan N chỉ catch 1/5. Memory `feedback_per_nv_permission_scope.md` CRITICAL HOTFIX S23 t5 section updated với 5 sites enum + audit grep checklist. Bug 2 (F2 Duyệt thẳng chỉ đến Phan Văn Chương thay vì Nguyễn Văn Trường BOD) defer follow-up — F2 logic line 483-524 đã đúng, cần verify workflow v14 DB structure thực tế. Stats final S23 t5: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · **111 test pass (+3)** · 47 gotcha · 20 memory (1 entry CRITICAL HOTFIX section reinforced 2 lần) · 6 skills · 4 sub-agents (em main solo Plan O — bug fix reasoning chain cross 4 sites). CHƯA push remote — chờ CICD verify.)
**Last updated S23 t4:** 2026-05-15 (Session 23 turn 4 — **🎯 Plan N: HOTFIX per-NV lookup site discrimination — BE bug critical UAT block**. 2 commits N1+N2 batch atomic + N4 docs. Bro UAT screenshot post-Plan M deploy: Admin Designer tick TRUE 7 flag cho NV Test (UAT V2) slot Bước 2 Cấp 1 workflow QT-DN-V2-001 v12/v13 (4 NV cùng Cấp) — actor login → dialog ✓ Duyệt KHÔNG có checkbox F2 skipToFinal + dialog ← Trả lại CHỈ 1 radio Drafter + KHÔNG có F3+F4 Edit options. 🟦 Investigator audit (~80K spawn) verify Hypothesis B: BE bug `PurchaseEvaluationFeatures.cs:765` `FirstOrDefault(l => l.Order == curLevelOrder)` thiếu discriminator `ApproverUserId == currentUser.UserId` — schema Mig 29 (S21 t5) refactor: 1 row per ApproverUserId (OR-of-N cùng Order) → handler luôn lấy row đầu DB (Lê Văn Bính — Drafter only), bỏ qua admin tick per-NV của actor. Bug PRESENT từ Mig 29 deploy 2026-05-13 nhưng chỉ bộc lộ khi lần đầu admin tick selectively per-NV. 👤 Chủ trì Solo fix N1 (5 LOC BE) + N2 regression test (~200 LOC test) + N4 docs — KHÔNG spawn Implementer vì bug fix reasoning chain. Fix: `var curLevel = curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder && l.ApproverUserId == currentUser.UserId) ?? curStep?.Levels.FirstOrDefault(l => l.Order == curLevelOrder);` — actor match per-NV slot, admin/non-approver fallback row đầu (giữ behavior view detail). Test regression `GetPurchaseEvaluationCurrentLevelOptionsTests` 2 method: 4 actor distinct flag profile + admin fallback. dotnet test **108/108 PASS** (+2 từ 106). Pattern reinforced: **Per-NV admin opt-in flag** wire checklist phải bao gồm **9 surface points** (KHÔNG 8) — thêm point 9 "Handler lookup site `currentLevelOptions` MUST discriminate ApproverUserId". Cumulative Mig 29 + 30 + 31 đã wire 8 points đúng nhưng MISS point 9 — bug present 2 days production. Stats final S23 t4: **31 mig** · 59 tables · ~145 endpoints · 34 FE pages · **108 test pass (+2)** · 47 gotcha · 20 memory (1 entry reinforced narrative wire checklist 9 points) · 6 skills · 4 sub-agents (1 Investigator spawn). CHƯA push remote — chờ Reviewer/CICD verify.)
**Last updated S23 t3:** 2026-05-15 (Session 23 turn 3 — **🎯 Plan M: Fix F1.OneLevel/OneStep edge case Bước 1 → giữ ChoDuyet (KHÔNG fallback Drafter) + FE label phase TraLai rename**. 3 commits Plan M `c2042ef..4dd6f9c` chuỗi M1→M3→M2: M1 (`c2042ef`) BE Service `ApplyReturnModeAsync` 2 edge case block (line 287-333) → reset (0, 1) giữ Phase=ChoDuyet thay vì fallback Phase=TraLai (semantic mới per bro chốt AskUserQuestion: "Cho phép nhưng vẫn giữ ChoDuyet, clear pointer thôi") + M3 (`508b17a`) FE × 2 app rename `PurchaseEvaluationPhaseLabel[98]` + `PeDisplayStatusLabel.TraLai` + 2 inline literal trong PeWorkflowPanel F1 dialog "Trả lại" → "Cần chỉnh sửa lại" (phase status badge, KHÔNG đụng action verb "← Trả lại" + mode picker "Trả về Người soạn thảo") + M2 (`4dd6f9c`) Tests add 2 edge case test `OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet` + `OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet` + helper `SeedWorkflowAsync` extend 2 param optional. Multi-agent execution: 🟦 Investigator audit pre-flight catch fact code main path đã đúng (F1.OneLevel/Assignee + F2 + F3 + F4 main path giữ ChoDuyet) chỉ edge case Bước 1 fallback sai + 🟨 Implementer 2 spawns Case 2+3 (M2 + M3) + 🟥 Reviewer pre-commit pending + 👤 Chủ trì M1+M4. Test final: **106/106 PASS** (+2 từ 104, 58 Domain + 48 Infra) — K7 Approver F2 NO cascade. F1.Drafter mode 4 GIỮ NGUYÊN Phase=TraLai semantic (explicit role mode). Memory user-level update 2 entry: `feedback_per_nv_permission_scope.md` reinforcement S23 t3 "edge case không lùi được KHÔNG fallback role khác" + `feedback_uat_skip_verify.md` Plan L lesson "Service refactor semantic BẮT BUỘC update test cùng commit". Stats final S23 t3: **31 mig** (no change) · 59 tables · **~145 endpoints** (no change) · 34 FE pages · **106 test pass (+2)** · 47 gotcha · 20 memory (2 entry reinforced) · 6 skills · 4 sub-agents. CHƯA push remote — chờ Reviewer verdict.)
**Last updated S23 t1:** 2026-05-14 (Session 23 turn 1 — **🎯 Plan K: F2 refactor sang per-Approver-slot Mig 31** + UI consistency. 8 commits Plan K `56868bf..<latest>`: Chunk pre-A slot label rename → K1 Mig 31 schema swap (drop `Users.AllowDrafterSkipToFinal` + add `ApprovalWorkflowLevels.AllowApproverSkipToFinal` no BACKFILL) → K2 Service ApproveV2Async Approver F2 branch + DTO refactor → K3 Designer 7th checkbox + banner rewrite → K5 zombie endpoint cleanup + Reviewer Major #1+#2 + Minor #3+#4 → K6 Workspace × 2 app DROP Drafter + ADD Approver toggle → K7 tests regression 104/104 PASS (3 deleted + 3 added cancel) → K8 docs. Multi-agent execution: 🟦 Investigator K0 pre-flight + 🟨 Implementer K1+K3+K5+K7 (4 spawns Case 2+3) + 🟥 Reviewer K2 pre-commit (PASS 0 critical, 2 Major + 2 Minor) + 👤 Chủ trì K0-bis+K2+K6+K8. Bro decision: F2 semantic ĐỔI Drafter from Nháp → Approver during ChoDuyet skip thẳng Cấp cuối (mirror F3+F4 admin opt-in per slot) + setup ALL ở Workflow Designer (KHÔNG ở User Management). UI slot label "#NV {order}" → ApproverFullName. Stats final S23 t1: **31 mig (+1 Mig 31)** · 59 tables · **~145 endpoints (-1 backout /allow-skip-final)** · 34 FE pages · **104 test pass unchanged** (3 deleted + 3 added) · 47 gotcha unchanged · 20 memory (cumulative reinforce `feedback_per_nv_permission_scope` 3×) · 6 skills · **4 sub-agents active 4 spawns (Implementer Case 2+3) + 1 Reviewer**. 4 prod user lose `AllowDrafterSkipToFinal=true` value per Option A (admin re-config qua Designer). Pattern reinforced: per-NV admin opt-in flag 3× proven (Mig 29 F1+F3 + Mig 30 F4 + Mig 31 F2) — pattern ALSO applies cho refactor existing scope, KHÔNG chỉ greenfield. Plan B Contract V2 wire vẫn pending S23 t2+. CHƯA push remote — chờ bro confirm.)
**S22 chốt cuối:** 2026-05-13 2200 (Session 22 CHỐT — **🎯 Bro chốt sub-agent solution OK**. 11 commits S22 pushed remote `3d725c4..b04a11a`. CICD Monitor Run #188 PASS verified. Highlights: Plan D F2 toggle + Plan C +20 test (test catch-up backlog) + Plan E strict V2 scope + Plan F ABORTED pre-flight (defer sau Plan B) + S22+1 fix disable 3 button bug + S22+2 seed 20 test user role-based naming + S22+3 rename users `{dept}.{level}@solutions.com.vn` + S22+4 attachment view inline PDF + Section "Điều chỉnh ngân sách" + S22+5 Mig 30 `AllowApproverEditBudget` per-NV opt-in (spec fix bro feedback). Stats final S22: **30 mig (+1 Mig 30)** · 59 tables · **~146 endpoints (+3)** · 34 FE pages · **104 test pass (+20: 5 reg #44 + 7 ReturnMode + 7 Guard + 1 V2 actor scope)** · **47 gotcha (+1 #47 paths-ignore agent-memory gap pending bro fix)** · 19 memory · 6 skills · **33 active users prod** (13 cũ + 20 mới role-based) · 4 sub-agents (CICD Monitor Run #188 PASS verify, 3 sub-agents seeds-only em main solo throughout S22). Pattern reinforced: per-NV admin opt-in flag 2× proven (Mig 29 + Mig 30) — anti-pattern default scope expansion. Memory `feedback_per_nv_permission_scope` reinforced S22+5 narrative.)
**Last updated S22 prev:** 2026-05-13 1800 (Session 22 — Plan C + D + E done, Plan F ABORTED pre-flight fail. 5 commits local `60efeed`→`dbda37e`→`215b1e0`→`f149661`→Docs. Plan D BE+FE Admin User F2 toggle UI (PATCH /users/{id}/allow-skip-final + UsersPage column "Skip cuối" violet badge). Plan C task 4 5 reflection regression test gotcha #44 silent 403 ApprovalWorkflowsV2Controller policy split (catch class-level Policy regression). Plan C task 1-3 14 service test catch-up — ApplyReturnMode 4 mode per-NV Mig 29 + skipToFinal per-Drafter + EnsureEditableForDetails F3 gating. Plan E strict V2 scope List + Detail (remove UAT loose `|| ApprovalWorkflowId != null`, replace with V2 approver actor.UserId scope via ApprovalWorkflowLevels join). Plan F ABORTED — pre-flight prod sqlcmd reveal 23 PE + 7 Contract pin V1 + Contract entity HOÀN TOÀN V1 chưa wire V2 → drop V1 BE crash startup. Defer F sau Plan B Contract V2 + migrate 4 V1-only PE + UAT 2-3 tuần. Stats S22: 29 mig (0) · 59 tables · ~144 endpoints (+1) · 34 FE pages · **103 test pass (+19: 5 reg #44 + 7 ReturnMode + 7 Guard)** · 46 gotcha · 19 memory · 6 skills · 4 sub-agents (em main solo). Pattern reusable: SeedWorkflowAsync + SeedApproversAsync helper test infra + reflection Authorize regression test + pre-flight prod check pattern. CHƯA push remote — chờ bro confirm.)
**S21 chốt cuối:** 2026-05-13 1530 (Session 21 chốt cuối — 5 turn cumulative pushed remote, CICD verified PASS 2/2 run, 1 gotcha mới #46 Gitea API path, 2 memory entry mới — `feedback_ef_migration_backfill_reorder` + `feedback_per_nv_permission_scope`. Session 21 5 turn timeline: t1 cicd-monitor add → t2 RAG planning Cách A → t3 fix gotcha #45 → t4 F1+F2+F3 Mig 28 → t5 refactor Allow* per-NV Mig 29. Stats final: 29 mig · 59 tables · ~143 endpoints · 34 FE pages · **84 test pass** · **46 gotcha (+2 từ S20: #45 PE button mismatch + #46 Gitea API)** · **19 memory entries (+3 từ S20: RAG + EF backfill + per-NV scope)** · 6 skills · 4 sub-agents (3 seeds-only + 1 cicd-monitor 2 runs PASS). 12 commits pushed `3a34831..c0af9e0`. Plan G Trial Week 1 evidence: CICD Monitor catch 0 fail vì green 2/2 run, cost 110-120K/run under 150K budget, 3-3.5min CI time stable. KHÔNG còn pending push. UAT mode skip dotnet test mỗi chunk, test-after Plan C bundle cho tất cả turn 3-5 sau UAT 2-3 lần ổn.)
**S21 turn 5:** 2026-05-13 1400 (Session 21 turn 5 — **🎯 Refactor F1+F2+F3 sang PER-NV (Mig 29 drop Mig 28 column workflow-level). 4 chunk per-commit `0366946` (A BE schema+Service refactor) → `63234b2` (B FE Admin Designer 5 checkbox per-Level row) → `5ccb2a7` (C FE eOffice rename currentLevelOptions + drafterAllowSkipToFinal) → this Chunk D Docs. **F1+F3** 5 flag MOVED xuống `ApprovalWorkflowLevels` (per slot Approver, mỗi NV có riêng quyền duyệt). **F2** AllowDrafterSkipToFinal MOVED xuống `Users` (per-Drafter user, admin config ở User Management). Mig 29 4-stage: ADD 5 column Levels + 1 column Users + BACKFILL bulk SQL (copy workflow → all Levels, set TRUE cho Drafter user nào từng dùng workflow Allow) + DROP 6 column workflow `ApprovalWorkflows`. Service `ApplyReturnModeAsync` refactor đọc `currentLevel.AllowXxx` thay vì `workflow.AllowXxx`. Helper `EnsureEditableForDetailsAsync` read `level.AllowApproverEditDetails`. DRAFTER trình branch read `userManager.FindByIdAsync(actorUserId).AllowDrafterSkipToFinal`. DTO refactor: `AwLevelDto +5 Allow*`, `AwDefinitionDto -6 Allow*`, `CreateAwLevelInput +5 Allow*`, `PeDetailBundle.workflowOptions → currentLevelOptions + drafterAllowSkipToFinal`. FE Admin Designer drop section "Cấu hình nâng cao" workflow-level, replace 5 checkbox grid-cols-2 inline mỗi Level entry row (5 flag per slot). FE eOffice rename `wfOptions → levelOptions` đọc `currentLevelOptions`. Backward compat: backfill preserve admin config S21 t4. Test 84/84 PASS unchanged. Stats: **29 mig (+1) · 59 tables · ~143 endpoints · 34 FE pages · 84 test pass · 45 gotcha · 17 memory · 6 skills · 4 sub-agents seeds-only.**)
**S21 turn 4:** 2026-05-13 1200 (Session 21 turn 4 — **🎯 F1+F2+F3 PE Workflow advanced options (Mig 28) — 5 chunk per-commit `0294693`→`c56024b`→`a508564`→`d27caaf`→this Chunk E Docs. **F1** 4 mode Trả lại admin tick: "1 Cấp / 1 Bước / Người chỉ định / Người soạn thảo" — 3 mode đầu giữ Phase=ChoDuyet lùi pointer (peer review chain), mode Drafter giữ Phase=TraLai S17 fallback. **F2** Drafter skip thẳng Cấp cuối — workflow tick + Workspace checkbox dynamic confirm. **F3** Approver edit Section 2 (Hạng mục/NCC/Báo giá) khi workflow tick + actor match CurrentLevel + audit ghi PurchaseEvaluationChangelog. Mig 28 `ApprovalWorkflows +6 bool Allow*` (DEFAULT 1 cho AllowReturnToDrafter backward compat, 5 còn lại 0). BE Service `TransitionAsync` extend 3 optional param (returnMode/returnTargetUserId/skipToFinal) + helper `ApplyReturnModeAsync` switch 4 mode. Detail/Quote/Supplier helper `EnsureEditableForDetailsAsync` mới (kế thừa `EnsureDraftAsync` + add ChoDuyet+F3 branch + Admin bypass). FE Admin Designer "Cấu hình nâng cao" section 6 checkbox 3 group. FE eOffice 3 changes mirror 2 app: Trả lại radio picker 1-4 mode + Workspace skip checkbox violet + Section 2 itemsReadOnly approver banner. UAT mode skip dotnet test mỗi chunk (per `feedback_uat_skip_verify`), `npm run build` × 2 app pass mỗi chunk. Stats: **28 mig (+1)** · 59 tables · **~143 endpoints (+1 user-selectable patch existed)** · **34 FE pages (+1 Designer section)** · **84 test pass unchanged** (UAT defer test-after) · **45 gotcha unchanged** · 17 memory · 6 skills · 4 sub-agents seeds-only.**)
**S21 turn 3:** 2026-05-12 2100 (Session 21 turn 3 — **🎯 Bug fix CRITICAL "Trả về nhưng hệ thống vẫn duyệt" PE workflow (gotcha #45). 2 chunk per-commit `de00887` (BE Chunk A) + `4b29d00` (FE Chunk B) + Chunk C Docs this. Root: PeWorkflowPanel.tsx `isReject` payload (L64-66) thiếu nhánh TraLai → button "← Trả lại" gửi `decision: 1` (Approve) thay vì `2` (Reject) khi target=TraLai(98) → BE ApproveV2Async UPSERT opinion "đã duyệt" + advance Cấp. Inconsistency phụ: dialog `isSendBack` (L247-248) cùng pattern thiếu TraLai → dialog title sai. Fix BE defense-in-depth + FE 3 chỗ × 2 app mirror rule §3.9. Test-before §7 BẮT BUỘC: 3 regression test mới (2 reproduce bug + 1 happy path control) — `dotnet test SolutionErp.slnx` 84 PASS (58 Domain + 26 Infra = +3). `npm run build` × 2 app pass. Stats: 27 mig (no change) · 59 tables · ~142 endpoints · 34 FE pages · **84 test pass (+3)** · **45 gotcha (+1 #45)** · 17 memory entries (no new) · 6 skills. Em main solo (no sub-agent spawn S21 t3 — bug fix reasoning chain cross BE/FE Implementer REFUSE per multi-agent rule).**)
**S21 turn 2:** 2026-05-12 1800 (Session 21 turn 2 — **🎯 RAG Hybrid setup planning + Cách A validation deep dive. 2 commit (`1f8e9af` plan save 1223 LOC + this chốt). Em main solo (no SOLUTION_ERP sub-agent spawn), delegate claude-code-guide × 2 research Anthropic + community practice. Decision chốt: Cách A defensive (giữ blanket 120K em main + RAG retrieve supplement) over Cách B aggressive (cắt 60-70% blanket). Industry-validated cross 4 Anthropic blog + 5 community tools (Cursor/Continue/Cline/Aider all hybrid). Stack: Voyage-3-large + Qdrant local + FastMCP Python + Streamlit dashboard 7 pages + SQLite event log. Multi-agent cost reality: 4 agents → ~520K cumulative blanket → heavy session ~560K (Cách A) vs ~700K (lazy), saving -20%. 3-layer pattern Phase 1-3 rollout (Layer 1 vector → Layer 2 +BM25 → Layer 3 +reranking, recall ~70% → ~92%). Stats: +1 memory entry (`feedback_rag_hybrid_pattern.md`) +1 plan file (`rag-setup-plan.md` 1500 LOC final). 4 sub-agents vẫn seeds-only. Plan I NEW deferred chờ bro confirm 5 dự án path + stack + Voyage API key + disk cleanup 5-8GB.**)
**S21 turn 1:** 2026-05-12 0030 (Session 21 turn 1 — **🎯 Add con thứ 4 cicd-monitor (Path A — post-deploy verifier green READ tier). 1 commit `f1c61c9` pushed `36e21c8..f1c61c9 main -> main`, CI skipped per path filter (`**/*.md` paths-ignore docs-only). Trade-off: +~150K spawn extra mỗi run, đổi lại catch deploy ship fail tự động (bundle hash unchanged / mig drift prod / endpoint 500) — recurring blind spot pattern em main solo S20 quên verify ~30% push. Cost reality update: ~750K spawn setup (3 → 4 agents) · ~1.35M heavy session · ~700K optimized cached. Stats: 4 sub-agents seeds-only (+1 cicd-monitor green) · 16 memory entries (no new, update existing `feedback_multi_agent_setup.md` 3 → 4 agents narrative) · 27 mig · 59 tables · ~142 endpoints · 81 test unchanged · 44 gotcha unchanged · 6 skills unchanged. KHÔNG flush 3 agent MEMORY.md (chưa spawn work S21 t1 nên KHÔNG có findings — em main solo via context + Write file).**)
**S20 wrap:** 2026-05-11 22:00 (Session 20 wrap turns 1-12 — **🎯 14 commit `9dee00d` → `ae1814c`. PE Detail UI restructure 3 yêu cầu (t1-5) + Manual budget drop tên (t6) + Mig 27 admin menu eOffice (t7) + NCC palette 5-màu cycle + Winner icon ✓ đậm + AddSupplier auto-fill master + Responsive laptop nhỏ 4-tầng pattern (t8-11) + Multi-agent infrastructure setup 3 sub-agents (t12). 27 mig (+1) · 59 tables · ~142 endpoints (+1) · 34 FE pages (+1) · 61 menu key (+1) · 81 test pass unchanged · 44 gotcha · 16 memory entries (+2) · 3 sub-agents NEW. Phase 9 UAT iteration mode.**)
**S20 turn 7:** 2026-05-11 17:00 (Session 20 turn 7 — **🎯 Admin Ẩn/Hiện + Đổi tên menu eOffice (Mig 27). 5 chunk `2ea2d27`→`ef394f8`→`059bfcb`→`1ed6530`→Chunk E Docs. User Q2=b: DisplayLabel CHỈ áp fe-user, admin sidebar giữ Label gốc. Domain MenuItem +IsVisible(true) +DisplayLabel(200). Mig 27 AddVisibilityAndDisplayLabelToMenuItems. BE PATCH /api/menus/{key} [Authorize Policy=Permissions.Update]. NEW FE-admin MenuVisibilityPage ~210 LOC (table inline edit per-row + Save dirty + Khôi phục mặc định + Toggle Eye/EyeOff + 4 StatCard). fe-user Layout filterForUser 2 tầng (USER_HIDDEN_KEYS hardcode + !isVisible dynamic) + effectiveLabel(displayLabel || label) replace 3 callsite. fe-admin Layout KHÔNG đụng. +1 menu key MenuVisibility "Menu eOffice" leaf System Order=94. 27 mig, 59 tables, ~142 endpoints, 34 FE pages, 81 test pass (Q4 UAT defer).**)
**S20 prev:** 2026-05-11 (Session 20 — **🎯 PE Detail UI restructure 3 yêu cầu user UX. 4 chunk per-commit `9dee00d` → `2bba851` → `f2f01f4` → (current Chunk D Docs).** Q1=a (giữ Section "Chọn NCC TP" riêng), Q2=a "1 hạng mục trước tiên" (NCC shared, demo 1 hạng mục), Q3=a (chỉ hiện NV đã ký), Q4 public luôn (skip dotnet test mỗi chunk theo memory `feedback_uat_skip_verify`, vẫn `npm run build` × 2 app mỗi chunk vì có rename/remove function). **Chunk A (`9dee00d`)**: BE `CreatePurchaseEvaluationCommandHandler` thêm 1 PurchaseEvaluationDetail mặc định khi tạo phiếu — GroupCode="01", GroupName="Hạng mục chính", NoiDung=TenGoiThau, DonGiaNganSach=ThanhTienNganSach=Budget.TongNganSach hoặc BudgetManualAmount fallback 0; Changelog Insert audit. FE reorder PeDetailTabs (mirror 2 app) 1.Thông tin / 2.Hạng mục (lên #2) / 3.Chọn NCC / 4.NCC tham gia / 5.Ý kiến. **Chunk B (`2bba851`)**: ItemsTab restructure thành list `HangMucCard` (1 card / 1 hạng mục, expanded=true mặc định cho 1 hạng mục demo). Header card: GroupCode + NoiDung + 3 stat (KL/ĐG/TT) + NS link Δ nếu có + Pencil/Trash actions + ▼/▶ toggle expand. Expand body: NCC inline table columns NCC / Liên hệ / Điều khoản TT / **File báo giá** / ĐG chưa VAT / ĐG có VAT / Thành tiền / Action. Quote inline click cell → QuoteDialog cũ reuse. Add NCC + Sửa NCC reuse AddSupplierDialog/EditSupplierDialog cũ. Winner ✓ button mỗi NCC row. Drop function `SuppliersTab` (dead code ~134 LOC, replace bằng HangMucCard expand panel). Giữ AddSupplierDialog + EditSupplierDialog + SupplierAttachmentsCell (HangMucCard call lại). Section layout cuối: 1.Thông tin / 2.Hạng mục + Báo giá NCC (nested) / 3.Chọn NCC TP thắng thầu / 4.Ý kiến cấp duyệt — 4 section. **Chunk C (`f2f01f4`)**: Section Ý kiến restructure render layer (KHÔNG đụng Mig 26 schema — vẫn UPSERT 1 row / Level). LevelOpinionsSectionV2 forEach step → 1 `StepOpinionsBox` (replace grid-cols-2 cho N approver). Box header: "Bước N — Tên" + dept badge emerald + "X/Y đã duyệt" counter. Body: filter opinions theo step.order → sort levelOrder asc, signedAt asc → render `StepOpinionEntry` per signed opinion (tên NV + Cấp badge slate + admin override badge amber nếu có + emerald rounded-full timestamp + comment text). NV chưa duyệt KHÔNG hiển thị (Q3=a). Drop function `LevelOpinionBox` (replaced). Mirror fe-admin + fe-user. Verify build pass cả 2 app sau khi catch TS6133 `SuppliersTab` + `SupplierAttachmentsCell` unused (đã giải quyết: drop SuppliersTab, restore SupplierAttachmentsCell vào HangMucCard cột "File báo giá"). 81 test pass (no change — UAT defer)**)

## 📍 Phase hiện tại: **Phase 9 active — UAT V2 testing với user thật** — **59 DB tables, 29 migrations (Mig 28 +6 column workflow-level S21 t4 → Mig 29 refactor sang per-NV S21 t5 — 5 column trên ApprovalWorkflowLevels + 1 column trên Users + DROP 6 column workflow-level), ~143 API endpoints, 34 FE pages. 84 unit test pass** (58 Domain + 26 Infra = +3 PE guard S21 t3, UAT defer test-after per §7 cho S21 t4+t5). **46 gotcha (+1 S21 t5 chốt: #46 Gitea API path/cache)**. 30 demo user + 1 test user UAT. 6 skill. **5 trạng thái phiếu** (Nháp/Đã gửi duyệt/Trả lại/Từ chối/Đã duyệt). **2 Workflow schemas đồng tồn tại** post-Session 17 + Per-NV refactor S21 t5: (1) Mig 21 `WorkflowDefinition` flat (V1) — pin với PE/Contract cũ. (2) Mig 22-29 `ApprovalWorkflow` (V2) — pin với PE mới, Mig 29 các flag per-NV ở Levels + Users. Service PE branch theo `ApprovalWorkflowId`. **4 sub-agents:** 🟦 Investigator + 🟨 Implementer + 🟥 Reviewer (3 seeds-only S21 — em main solo cross-stack reasoning chain REFUSE) + 🟩 CICD Monitor (2 runs PASS, ~110-120K/run cost). 30 demo user + 1 test user UAT. 6 skill. **5 trạng thái phiếu** (Nháp/Đã gửi duyệt/Trả lại/Từ chối/Đã duyệt). **2 Workflow schemas đồng tồn tại** post-Session 17: (1) Mig 21 `WorkflowDefinition` flat (V1) — pin với PE/Contract cũ + match Dept+PositionLevel. (2) Mig 22-26 `ApprovalWorkflow` (V2) — pin với PE mới + match ApproverUserId 1-1, Steps/Levels group by Order, Bước (Phòng) > Cấp (N NV OR-of-N), Mig 25 +IsUserSelectable admin pin per version, **Mig 26 +PeLevelOpinions sign-off dynamic theo Level**. Service PE branch theo `ApprovalWorkflowId` set or null. Sau UAT chốt → migrate + drop V1 + Contract V2 wire.

### 🌐 Production URLs

- https://api.solutions.com.vn — API (Let's Encrypt, auto-renew via win-acme)
- https://admin.solutions.com.vn — Admin FE (HTTP→HTTPS auto-redirect)
- https://eoffice.solutions.com.vn — User FE (HTTP→HTTPS auto-redirect)
- https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp — Gitea repo + Actions
- Default admin: `admin@solutionerp.local` / `Admin@123456` ⚠️ **RE-ROTATE sau login đầu**

## 🔥 In Progress — Session 7+ (Phase 9 active)

### A. Hard blockers (chờ user / ops)

- [ ] **UAT thật 1 tuần** với 2-3 user (Drafter / CCM / BOD) — hard requirement Phase 5 roadmap
- [ ] **SMTP config** → Email outbox (BLOCKED chờ user cấp host/user/pass)
- [ ] **Rotate creds** — admin + 30 demo + SA + vrapp + JWT secret + Gitea runner token
- [ ] **Schedule SQL backup daily** — `scripts/backup-sql.ps1` đã sẵn, chưa schedule Task Scheduler
- [ ] **Remove binding cũ `.huypham.vn`** sau verify stable: `ssh vietreport-vps ; .\migrate-domains.ps1 -RemoveOld -SkipCert`
- [ ] **win-acme scheduled task "unhealthy"** — auto-renew fix trước 2026-06-18

### B. Carry over feature gap

- [ ] **Export phiếu PDF/Excel** PE — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx` (user pending — không quan trọng lắm)

### C. Optional polish (khi UAT phát sinh bug)

- [ ] Budget MaNganSach atomic sequence (hiện Random.Shared → migration `AddBudgetCodeSequences`)
- [ ] Budget versioned workflow (admin config UI thay hardcoded `BudgetPolicy.Default`)
- [ ] Payment terms PE tách field (JSON blob → 6 column riêng)
- [ ] Auto-map PE Details → Contract per-type Details khi gen HĐ
- [ ] Matrix Quotes bulk paste từ Excel
- [ ] fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi"

### D. Tests Phase 3-5 (làm khi gặp bug recurring để justify ROI — rule §7)

- [ ] **Phase 3 full** — Application handler tests cần UserManager DI helper (PE Opinion Upsert, Budget validate, CreateContractFromEvaluation BudgetId carry) ~15 test
- [ ] **Phase 4** — API smoke tests qua WebApplicationFactory ~7 test
- [ ] **Phase 5** — FE Vitest cho lib utility (queryMatches, fmtMoney) ~10 test

### E. 2-stage dept approval — Chunk E-bis ✅ DONE (Session 9)

- [x] **FE Workflow Panel** PE — section "Tiến trình duyệt 2-cấp phòng ban" group by phase × dept, highlight amber khi chờ TPB confirm
- [x] **FE UserManager toggle** `CanBypassReview` — column "Bypass" badge fuchsia + button toggle ShieldCheck (UsersPage)
- [x] **HĐ 2-stage** mở rộng — `ContractWorkflowService` thêm UserManager DI + 2-stage logic mirror PE + `ContractDepartmentApprovalFeatures.cs` + endpoint `GET /contracts/{id}/department-approvals` + FE WorkflowHistoryPanel section mới
- [x] **Budget 2-stage** mở rộng — `TransitionBudgetCommandHandler` thêm INotificationService + IDateTime + 2-stage logic + `BudgetDepartmentApprovalFeatures.cs` + endpoint + FE BudgetWorkflowPanel section
- [x] **Tests 2-stage** (6 test) — `IdentityFixture` setup full Identity stack + 6 test PE workflow service: NV review block / TPB confirm allow / NV bypass / Admin skip / Reject set / Resume jump-back. Pattern reusable.

### F. Audit định kỳ (cron tự fire)

- [x] **2026-05-01** (audit 2026-05-04 manual trigger sau trễ 4 ngày) — combined audit log `docs/changelog/skill-audit-2026-05.md`. Cron Claude SDK KHÔNG fit monthly cadence (auto-expire 7d) → user setup OS Task Scheduler nếu cần auto-remind.
- [ ] **2026-06-01** — combined audit kế. Trigger thủ công khi đến ngày hoặc user nói "audit MD" / "kiểm tra docs" / "định kỳ kiểm tra".

## ✅ Recently Done (newest on top)

| Ngày | Ai | Task | Commit |
|---|---|---|---|
| 2026-05-15 | Claude | **🎯 SESSION 24 chốt cuối — Plan AA cumulative 7 commits (3 core + 4 polish UAT iteration)** — Plan AA Phase 1 core 3 commit (Chunk A BE+Layout + Chunk B FE matrix page + Chunk C Docs initial). Phase 2 polish 4 commit liên tục UAT feedback bro: `da218f1` hotfix px-6→px-2 (content sát sidebar) + `4d60598` redesign v1 panel-per-NV mirror admin Designer color coding (drop table symbol khó hiểu) + `fbbd361` redesign v2 HTML table rowSpan tận dụng full width (Bước/Cấp/NV/Quyền duyệt grid 2-col 7 label tiếng Việt nguyên văn) + `ee0902a` wrap fix sidebar label dài về đầu hàng (hanging-indent reverse CSS: flex→block + inline-block icon + inline text + absolute ChevronDown + text-[12px] leading-snug × 5 sites mirror 2 app). Patterns reusable saved: (1) Tailwind JIT palette array (5-color cycle Step + Cấp), (2) HTML table rowSpan flat row builder helper, (3) hanging-indent reverse CSS pattern. Multi-agent ROI: ~175K total (Investigator 32K Pre-A + Implementer 14K Chunk B + Reviewer 25K cumulative + CICD 12K Run #210 + 3 agent flush ~12K + em main ~80K) ≈ 28% solo equiv. **CICD Run #210 PASS 4/4 wire end-to-end**: IsUserSelectable filter live (admin no-filter / admin ghim / nv.test ghim all HTTP 200) + menu Pe_DuyetNcc_WfView present + Order shift idempotent 1-10 contiguous + non-admin permission Read OK + bundle hash rotate 2 app + Mig 31 unchanged. Pattern reinforced cumulative: gotcha #44 class-level Authorize relax PROVEN cross-stack reuse S18→S24 (Workflows endpoint từ admin-only sang any-auth read accessible). Test 111/111 PASS unchanged post-Plan AA (BE filter param + DbInitializer refactor no regression). Stats: 31 mig · 59 tables · **~146 endpoints (+1)** · **35 FE pages (+1 WorkflowMatrixViewPage)** · 111 test · 47 gotcha · 21 memory · 6 skills. **Implementer agent MEMORY ~31.5KB > 25KB threshold** → recommend curate next session archive S20-S22 old entries. | `ee776d5` (A BE+Layout) · `c667802` (B FE page) · `ac2c859` (C Docs init) · `da218f1` (px-2 hotfix) · `4d60598` (redesign v1 panel) · `fbbd361` (redesign v2 table rowSpan) · `ee0902a` (wrap fix label) · this Docs final |
| 2026-05-15 | Claude | **🎯 SESSION 24 turn 1 — Plan AA User Workflow Matrix view + Sidebar widen revert Plan U truncate (3 commit)** — Bro UAT request: (1) sidebar Plan U S23 t11 truncate "..." → hiển thị đầy đủ label custom Mig 27, (2) thêm menu "Luồng duyệt" trên Danh sách hiển thị ma trận phân quyền workflow Designer ghim cho user xem (filter `IsUserSelectable=true` Mig 25). Q&A clarify 2 lượt: Q1 Permission strategy "Relax class-level [Authorize]" (đã fix gotcha #44 permanent từ S18 → CHỈ cần add filter param), Q2 Matrix layout "Table 2D full 7 Allow* cột". Plan 4 chunk: Pre-A (🟦 Investigator audit ~32K, confirm gotcha #44 + sidebar `w-72 xl:w-80` SAFE + Order strategy shift existing) + Chunk A (👤 Chủ trì Solo BE + Layout: MenuKeys `PurchaseEvaluationWorkflowView` helper + DbInitializer tree.Add LuongDuyet Order=2 + INSERT-OR-UPDATE-Order refactor idempotent + Permission seed 7 role + Handler `IsUserSelectable bool?` filter + Controller pass-through + sidebar `w-60 xl:w-72` → `w-72 xl:w-80` × 2 app mirror + revert Plan U truncate × 5 sites; commit `ee776d5` 6 files +73/-24) + Chunk B (🟨 Implementer Case 2 ~14K: WorkflowMatrixViewPage.tsx ~215 LOC + types/approvalWorkflowV2.ts ~55 LOC + App.tsx +route 2 LOC; commit `c667802` 3 files +305) + Chunk C (🟥 Reviewer cumulative ~25K: PASS 0 critical/major/minor blocker + Smart Friend guard active + fe-admin build verify bonus 1926 modules 740ms). Pattern reinforced: (1) gotcha #44 relax pattern PROVEN cross-stack reuse — Workflows endpoint từ admin-only sang any-auth read accessible. (2) DbInitializer INSERT-only → INSERT-OR-UPDATE-Order safe shift existing prod rows (idempotent re-deploy). (3) Plan U truncate revert pattern: widen sidebar + drop truncate, keep `min-w-0 flex-1` + `shrink-0` + `title` tooltip (no harm). **Surprise:** PE Workspace là **2-panel** không phải 3-panel — memory `feedback_responsive_laptop_breakpoint.md` stale claim → defer update memory. **3 commits push pending** (`ee776d5..<this>`). Stats: 31 mig · 59 tables · ~146 endpoints (+1 query filter param) · **35 FE pages (+1)** · 111 test (unchanged UAT mode) · 47 gotcha · 21 memory · 6 skills · 4 sub-agents (3 spawn S24 t1). | `ee776d5` (A BE+Layout) · `c667802` (B FE page) · (this Docs C) |
| 2026-05-12 | Claude | **🎯 SESSION 21 turn 2 — RAG Hybrid setup planning + Cách A validation deep dive (2 commit `1f8e9af` plan save + this chốt)** — Sau S21 turn 1 chốt cicd-monitor, user clarify 5 dự án future > 1M MD tokens → cuộc thảo luận deep ~15 turn về RAG infrastructure. **Em main solo** (no SOLUTION_ERP sub-agent spawn), delegate **claude-code-guide × 2** spawn agent research Anthropic + community practice. **Q&A deep dive 10 topics**: (1) RAG fundamentals + Vector DB Qdrant role, (2) Embedding "AI nhúng" + Voyage AI cost mechanics ($0.18/M tokens), (3) Multi-project shared architecture (5 projects → single Qdrant + per-collection), (4) Audit procedure 3-tier (weekly auto + monthly deep + quarterly major), (5) UI/UX Streamlit dashboard 7 pages design (overview + drill-down + compare + audit + cost + change + admin), (6) Cách A defensive (giữ blanket 120K) vs Cách B aggressive (cắt 60-70%), (7) Reasoning depth comparison lazy 60% → A 90% → B 75-80%, (8) Industry validation Anthropic + Cursor + Continue + Cline + Aider all hybrid, (9) Multi-agent cost reality 8-10× multiplier ~520K cumulative blanket 5 entities, (10) 3-layer hybrid pattern Anthropic Contextual Retrieval Sept 2024. **Quyết định chốt Cách A** (defensive hybrid: giữ blanket 120K em main + RAG retrieve supplement, sub-agent spawn baseline ~100K each, 4 agents = ~400K cumulative, heavy session billed ~560K saving -20% vs lazy 700K, quality recall ~85%) over **Cách B bỏ** (aggressive cut 60-70% vi phạm priority em main control flow strong + reasoning fragmented + UX latency +1-2s/state Q + risk severe RAG fail). **Why Cách A** (bro priority chốt): em main control flow strong preserve, decision quality 90% multi-source cohesive, wall-clock -20% (12 phút vs 16), risk-averse graceful fallback, multi-agent leverage cache 70-90%, industry-validated 9 sources. **3-layer hybrid Phase rollout**: P1 (W1-4) vector only Voyage-3-large recall ~70% $1.50/mo · P2 (M2) +BM25 bm25s free recall ~78% $1.50/mo · P3 (M3) +Voyage rerank-2 + Contextual prefix recall ~92% $4-5/mo. **Stack validated** cross-industry: Voyage AI embedding (Anthropic partner, multilingual 26 lang, $0.36 initial), Qdrant local (Rust 50MB, agent-native 2026 leader, ~3GB disk 5 project), FastMCP Python (official SDK, ~100 LOC), SQLite event log (5 tables + audit history), Streamlit 7 pages. **Plan I NEW deferred** — trigger bro confirm 5 dự án path + stack + pilot + Voyage API key + disk cleanup → dedicated session 10-14h weekend (per `feedback_drastic_refactor_scope` rule). **Deliverables**: `docs/rag-setup-plan.md` 1223 LOC commit `1f8e9af` + extend S21 t2 ~300 LOC = ~1500 LOC final, memory `feedback_rag_hybrid_pattern.md` cross-project reusable, session log this chốt, MEMORY.md index +1 entry. **CI skipped** path filter (`.md`). **4 sub-agents vẫn seeds-only** (KHÔNG spawn S21 turn 2 nên KHÔNG flush MEMORY.md per §6.5 KHÔNG add noise). Tests baseline 81 unchanged. | `1f8e9af` (plan save) · this chốt (commit final) |
| 2026-05-12 | Claude | **🎯 SESSION 21 turn 1 — Add con thứ 4 cicd-monitor (Path A — post-deploy verifier green READ tier, 1 commit `f1c61c9`)** — User chốt Path A sau pre-flight Plan G Trial Week 1: thêm sub-agent thứ 4 chuyên post-deploy verify (Gitea Actions poll + bundle hash 2 app verify + sqlcmd mig prod = repo latest + endpoint smoke). Trade-off: +~150K spawn extra mỗi run, đổi lại catch deploy ship fail tự động — recurring blind spot pattern em main solo S20 quên verify ~30% push. **2 file mới**: `.claude/agents/cicd-monitor.md` (~7KB) — system prompt + 8-step workflow (verify push → poll Gitea API → fail log grep → live curl smoke → bundle hash × 2 app + verify changed → sqlcmd mig prod = repo latest → report PASS/FAIL/PARTIAL/TIMEOUT/SKIPPED-DOCS) + 5-stage report table + gotcha #25/#39/#40/#41/#44 cross-ref + skill `iis-deploy-runbook`/`dependency-audit-erp`/`ef-core-migration` preload + Anti-pattern 9 rules. `.claude/agent-memory/cicd-monitor/MEMORY.md` (~5KB seed) — recurring CI bug patterns + 5-stage checklist + baseline build/bundle metrics + bearer test pattern admin/nv.test. **1 file update repo**: `.claude/agents/README.md` — 4-agent architecture diagram (green slot mới) + decision tree (after push code + prod issue diagnose branches) + memory routine 4 SendMessage + skills preload 4 agents + cost reality table 564K → 750K spawn / 1.2M → 1.35M heavy / 600K → 700K optimized + trial workflow Week 1-3 CI/CD Monitor spawn integrated + pass criteria + catch ≥1 deploy ship fail. **Memory user-level update**: `feedback_multi_agent_setup.md` — title 3 → 4 sub-agents, decision tree +CI/CD Monitor invocation branches (after push + user prod issue), skills preload list +CI/CD Monitor (iis-deploy-runbook + dependency-audit-erp + ef-core-migration), cost table update + trade-off rationale (recurring blind spot ~30% push S20). **CI skipped**: all 3 file changed `.md` → match `paths-ignore: '**/*.md'` per gotcha #41 → no Gitea Actions run → no IIS deploy (expected — agent infra là local Claude Code, không cần present trên prod). Push success `36e21c8..f1c61c9 main -> main`. **3 (now 4) sub-agents vẫn seeds-only**: chưa spawn work nào — em main solo via context paste + Write file. KHÔNG flush 3 agent MEMORY.md (chưa spawn work = không findings, per §6.5 KHÔNG add noise entry). cicd-monitor MEMORY.md có entry "setup 2026-05-12" trong seed. Trial Week 1 kick-off ở Session 21 turn 2+ với Plan B Contract V2 wire Mig 28+29 candidate (mirror PE pattern S17-S19 proven 1×). Tests baseline 81 unchanged (no test added — docs-only commit). | `f1c61c9` (Setup cicd-monitor + README 4-agent + memory update) |
| 2026-05-11 | Claude | **🎯 SESSION 20 turns 6 + 8-12 — PE polish (NCC palette + autofill + responsive) + Multi-agent setup (7 commit `f568945` → `ae1814c`)** — Sau turn 7 wrap-up Mig 27, user iterate 7 polish/feature lớn nhỏ. **Turn 6 (`f568945`)** Manual budget "Nhập tay" drop tên field — 3 file × 2 app mirror (BudgetFieldRow + WorkspaceCreateView + HeaderForm) bỏ Input "Tên" UI khỏi manual mode, BE save `budgetManualName: null` luôn, VND format `1.000.000` + suffix đ. **Turn 8 (`3ec7b5a`)** AddSupplier +Số tiền inline + NCC 5-màu palette + Winner badge "🏆 Trúng thầu" — AddSupplierDialog +prop detailId? +form thanhTien, sequential POST /suppliers (response {id}) → POST /quotes (nếu detailId + thanhTien > 0). NCC_PALETTES const 5 màu literal Tailwind (blue/purple/sky/teal/pink) cycle theo idx. Winner row override emerald-500 border-l + bg-emerald-100/70 + shadow-sm + ring-1 emerald-300 + badge rounded-full bg-emerald-600 text-white "🏆 Trúng thầu". **Turn 9 (`83aae8e`)** User feedback bỏ badge → revert icon ✓ stick cũ nhưng đậm hơn (text-base font-bold emerald-700) + tên NCC winner text-emerald-900 + hover transition (winner hover:bg-emerald-200/70, non-winner hover:bg-white/80 hover:shadow-sm). **Turn 10 (`66551db`)** AddSupplierDialog auto-fill từ master data khi chọn NCC dropdown — onChange lookup picked supplier, setForm ghi đè 4 field (contactName ← contactPerson / contactPhone ← phone / contactEmail ← email / note ← note). Hint emerald "✓ Đã tự điền từ Master". User vẫn override được. **Turn 11 (`6e338f7`)** Responsive cho laptop màn hình nhỏ 1280-1366px — 4-tầng pattern: sidebar fe-admin + fe-user `w-72` → `w-60 xl:w-72` (+48px lg) / PE Workspace 2-panel `lg:[320px_1fr]` → `lg:[260px_1fr] xl:[320px_1fr]` (+60px lg) / Section padding `px-5 py-4` → `px-3 py-3 sm:px-5 sm:py-4` (+16px xs) / HangMucCard `gap-3 p-3` → `flex-wrap gap-2 p-2 sm:gap-3 sm:p-3` (+8px xs). Net gain trên 1366px ~+132px width cho NCC table area. Memory `feedback_responsive_laptop_breakpoint.md` capture pattern. **Turn 12 (`ae1814c`)** SETUP MULTI-AGENT INFRASTRUCTURE 3 sub-agents (Investigator READ cyan + Implementer WRITE conditional yellow + Reviewer READ adversarial red) + em main coordinator. Pre-flight decision gate 6/6 ✅. Phase 1-4 execute: `.claude/agents/` 4 file (README ~9.7KB + investigator + implementer + reviewer) + `.claude/agent-memory/` 3 MEMORY.md seed (~6KB each). Customize SOLUTION_ERP: skills preload mỗi agent (reuse 6 skills hiện có) + bearer test (admin@solutions / nv.test@solutions) + prod UAT URL + Phase 9 UAT mode + DB Dev/Design distinct. Windows MAX_PATH pitfall handled — drop `isolation: worktree` khỏi implementer.md (project path 51 chars + Dropbox-managed nested overflow 260+ chars). Memory `feedback_multi_agent_setup.md` capture decision gate + ACCEPT/REFUSE criteria + NAMGROUP s41-s43 ROI reference. 3 agents **chưa spawn work** ở S20 turn 12 — seeds-only state. Trial Week 1 candidate Contract V2 wire Mig 28+29 (mirror PE pattern proven). **Stats cumulative S20:** 27 mig (+1 Mig 27 from turn 7) · 59 tables · ~142 endpoints (+1 PATCH /menus/{key}) · 34 FE pages (+1 MenuVisibilityPage) · ~61 menu key (+1) · 81 test pass unchanged · 44 gotcha unchanged · **16 memory entries (+2: responsive + multi-agent)** · 6 skills unchanged · **3 sub-agents NEW** · 14 commits S20. | `f568945` (t6) · `3ec7b5a` (t8) · `83aae8e` (t9) · `66551db` (t10) · `6e338f7` (t11) · `ae1814c` (t12) · (current Docs t13 wrap) |
| 2026-05-11 | Claude | **🎯 SESSION 20 turn 7 — Admin Ẩn/Hiện + Đổi tên menu eOffice (Mig 27, 5 chunk `2ea2d27`→`ef394f8`→`059bfcb`→`1ed6530`→Chunk E Docs)** — User UAT yêu cầu "tính năng Ẩn Hiện và Đổi tên hiển thị của các Menu bên ngoài Office, làm trong Trang Admin Page". Hỏi xác nhận "chưa có" — đúng. User clarify Q2=b "edit hiển thị bên ngoài, chỉ của eOffice thôi" → admin sidebar luôn giữ Label gốc, DisplayLabel CHỈ áp fe-user. Q1=a global (không per-role), Q3=a giữ USER_HIDDEN_KEYS hardcode + tầng IsVisible dynamic combine, Q4 UAT skip test. **Chunk A** Domain MenuItem +IsVisible bool=true +DisplayLabel string?(200) + EF config + Migration 27 AddVisibilityAndDisplayLabelToMenuItems (2 AddColumn) — 3-file rule, apply LocalDB _Dev + _Design OK. **Chunk B** BE API: MenuNodeDto + MenuItemDto +isVisible +displayLabel (sau CRUD flags trước Children). GetMyMenuTreeQueryHandler pass through, KHÔNG filter server-side — 2 FE app tự quyết. UpdateMenuItemCommand + Validator + Handler (trim DisplayLabel whitespace → null). MenusController +PATCH /api/menus/{key} [Authorize Policy=Permissions.Update] body {isVisible, displayLabel}. **Chunk C** Domain MenuKeys +MenuVisibility const + All[] + DbInitializer +leaf "Menu eOffice" Icon=Eye Order=94 (Workflows shift 94→95). Manual seed Mig 27 LocalDB _Dev (INSERT MenuItems + Permissions Admin). FE Admin: types/menu.ts +isVisible +displayLabel, lib/menuKeys.ts +MenuVisibility, Layout resolver +/system/menu-visibility, App.tsx +Route. NEW pages/system/MenuVisibilityPage.tsx ~210 LOC: PageHeader + 4 StatCard (Tổng/Hiển thị/Đã ẩn/Đã đổi tên) + Search + Table 5 cột (Key mono + parentKey ↳ / Tên gốc / Input "Tên hiển thị" inline placeholder "Mặc định: {label}" / Toggle button emerald-Eye / amber-EyeOff / Lưu khi dirty + Khôi phục khi custom). PATCH endpoint, invalidate ['menus','all'] + ['my-menu'] trigger live update sidebar. Row hidden bg-amber-50/40 highlight, custom label bg-brand-50/40. **Chunk D** fe-user types/menu.ts mirror. Layout.tsx filterForUser 2 tầng (USER_HIDDEN_KEYS structural + !isVisible dynamic). Helper effectiveLabel(n) = displayLabel?.trim() || label. Replace 3 callsite {node.label} → {effectiveLabel(node)}. USER_FIXED_TOP "__inbox" entry +isVisible:true cho type check pass. **fe-admin Layout KHÔNG đụng** — admin sidebar render Label gốc + show hết menu (user Q2=b). **Chunk E Docs (current)**. **Stats Session 20 turn 7**: 26→27 mig, 59 DB tables (no change), ~141→142 endpoints, 33→34 FE pages, ~60→61 menu key, 81 test pass (Q4 UAT defer), 44 gotcha (no new). Memory entries 14 (no new). | `2ea2d27` (A Mig 27) · `ef394f8` (B BE API) · `059bfcb` (C FE admin) · `1ed6530` (D FE user) · (current E Docs) |
| 2026-05-11 | Claude | **🎯 SESSION 20 — PE Detail UI restructure 3 yêu cầu UX (4 chunk: 9dee00d→2bba851→f2f01f4→Chunk D Docs)** — User UAT live phản hồi "Logic OK rồi, điều chỉnh UI Duyệt NCC 1 tý": (1) Hạng mục lên trên + auto-tạo 1 row từ gói thầu, (2) NCC expand dưới hạng mục, (3) Section Ý kiến gộp đồng cấp cùng Phòng. Q&A clarify trước code (4 câu Q1=a/Q2=a "1 hạng mục"/Q3=a "chỉ hiện signed"/Q4 "public luôn demo thôi"). 4 chunk per-commit pattern `feedback_per_chunk_commit`. **Chunk A** BE `CreatePurchaseEvaluationCommandHandler` + INSERT 1 PurchaseEvaluationDetail mặc định + Changelog (GroupCode=01, NoiDung=TenGoiThau, ThanhTienNganSach=Budget.TongNganSach hoặc BudgetManualAmount fallback 0) + FE reorder PeDetailTabs section. **Chunk B** ItemsTab restructure list HangMucCard (1 card / hạng mục, expanded=true default cho demo 1 hạng mục). Header: GroupCode + NoiDung + 3 stat (KL/ĐG/TT) + NS link Δ + Pencil/Trash + ▼/▶ toggle. Expand body: NCC inline table 8 cột (NCC/Liên hệ/Điều khoản TT/File báo giá/ĐG chưa VAT/ĐG có VAT/Thành tiền/Action). Click cell quote → QuoteDialog reuse. Add NCC/Edit NCC reuse 2 dialog cũ. Winner ✓ button per row. Bỏ Section 4 "NCC tham gia" (gộp vào Section 2 nested) → 4 section final. Drop SuppliersTab function ~134 LOC dead code (replace bằng HangMucCard expand). Giữ AddSupplierDialog + EditSupplierDialog + SupplierAttachmentsCell (HangMucCard reuse). **Chunk C** Section Ý kiến gộp đồng cấp cùng Phòng. LevelOpinionsSectionV2 forEach step → 1 `StepOpinionsBox` (replace grid-cols-2 N approvers). Header: "Bước N — Tên" + dept badge emerald + "X/Y đã duyệt" counter. Body: filter opinions theo step.order → sort levelOrder asc + signedAt asc → render `StepOpinionEntry` per signed (tên NV + Cấp badge slate + admin override amber + timestamp emerald rounded-full + comment). NV chưa duyệt KHÔNG hiển thị (Q3=a). KHÔNG đụng Mig 26 schema (vẫn UPSERT 1 row / Level qua Service). Drop LevelOpinionBox function. Mirror fe-admin + fe-user mỗi chunk. **Verify**: dotnet build pass (Chunk A) + npm build × 2 app pass (Chunk B/C — catch TS6133 SuppliersTab unused + SupplierAttachmentsCell unused, fix re-add cột File báo giá vào nested table). **Test skip** Phase 9 UAT iteration (81 test pass unchanged). **Stats unchanged**: 26 mig, 59 DB tables, ~141 endpoint, 33 FE pages, 44 gotcha, 81 test. **Pending S21+**: Test regression B4 silent 403 (HIGH §7), Test V2 Service wire ApproveV2Async + Section gộp (Chunk C), Test Mig 25 PATCH user-selectable, Contract V2 (Mig 27/28 mirror PE), phân quyền strict V2, drop legacy V1 cleanup. | `9dee00d` (A) · `2bba851` (B) · `f2f01f4` (C) · (current D Docs) |
| 2026-05-09 | Claude | **🎯 SESSION 19 — PE Section 5 V2 dynamic theo ApprovalWorkflowLevel + Mig 26 (4 commit: 873e7a1 polish 3 button + 77a3058/90baa8e/6e913b3/Chunk D Mig 26)** — User feedback Section 5 hiện CỨNG 4 box (PheDuyet/CCM/MuaHàng/SmPm Mig 15 từ Phase 8) → cần động theo Workflow V2 đã pin: forEach Step (Phòng) → forEach Level (Cấp) → forEach NV → 1 OpinionBox với ý kiến + tên người ý kiến. Bước 1 Phòng A có 2 NV → 2 box ngang hàng. **5 câu chốt spec trước code:** Q1=1B (gắn — Service auto sync khi duyệt, KHÔNG form input rời), Q2=2A+Admin (NV chính chủ + Admin override với SignedByUserId track actual signer), Q3=chuyển V2 hết (phiếu V1 legacy fallback Mig 15 4 box readOnly), Q4=4C+bonus (Phase=DaDuyet/TuChoi khoá; Admin có quyền duyệt thay; comment empty → "(duyệt — không ý kiến)" placeholder), Q5=5A (layout group Step header "Bước N — Phòng X" + grid-cols-2 cho N approvers). **3 chunk per-commit (memory `feedback_per_chunk_commit`):** Chunk A (`77a3058`) Domain entity `PurchaseEvaluationLevelOpinion : AuditableEntity` (PEId+LevelId UNIQUE composite, Comment nvarchar(2000), SignedAt datetime2, SignedByUserId Guid, SignedByFullName nvarchar(200) denorm) + EF config FK Cascade Pe + Restrict Level + ApplicationDbContext + IApplicationDbContext DbSet + **Migration 26** `AddPeLevelOpinionsForV2` (1 CREATE TABLE + 2 FK + 2 index — UNIQUE composite + IX LevelId). 3-file rule. Apply LocalDB SolutionErp_Dev OK. Chunk B (`90baa8e`) Service `PurchaseEvaluationWorkflowService.ApproveV2Async` sau line log approval → UPSERT row PurchaseEvaluationLevelOpinions cho Cấp hiện tại: match level theo `ApproverUserId == actorUserId` (multi-NV cùng Cấp OR-of-N), fallback first khi Admin override (FE detect SignedByUserId !== Level.ApproverUserId hiển thị "Admin duyệt thay"). Reject KHÔNG sync. Empty/whitespace comment → "(duyệt — không ý kiến)" placeholder. Helper `ResolveActorFullNameAsync(actorUserId, isSystem)` lookup denorm SignedByFullName từ Users (fallback "(System)" / "(unknown)"). DTO `PurchaseEvaluationLevelOpinionDto` 15 fields (LevelId/StepOrder/StepName/StepDepartmentId/StepDepartmentName/LevelOrder/LevelName/ApproverUserId/ApproverFullName/Comment/SignedAt/SignedByUserId/SignedByFullName). GET handler `GetPurchaseEvaluationQueryHandler` Include LevelOpinions + helper `BuildLevelOpinionsAsync` JOIN ApprovalWorkflows.Steps.Levels + Departments + Users → denorm DTO list. Empty list cho phiếu V1 / V2 chưa có cấp duyệt → FE fallback. Chunk C (`6e913b3`) FE Section 5 V2 dynamic: type `PeLevelOpinion` + `PeDetailBundle.levelOpinions[]`. Section 5 conditional: `evaluation.approvalWorkflowId` set → `<LevelOpinionsSectionV2/>` (V2 dynamic), else `<DepartmentOpinionsSection/>` readOnly fallback (V1 legacy giữ Mig 15 4 box). Component `LevelOpinionsSectionV2` group theo step.order: header "Bước N — <name>" + dept badge emerald + hint "(N người duyệt)" khi totalApprovers > 1; body grid-cols-2 cho `step.levels.flatMap(level => level.approvers.map(approver => <LevelOpinionBox/>))`; lookup opinion theo (stepOrder, levelOrder, approverUserId). `LevelOpinionBox` read-only: title "Cấp N — <ApproverFullName>", badge amber "⚠ Admin <name> duyệt thay" khi override, badge emerald "✓ Đã duyệt", empty "— chưa duyệt" italic gray, footer timestamp signedAt format vi-VN. Workspace mode hint giữ amber "Ý kiến + chữ ký auto đồng bộ khi NV duyệt". Mirror fe-admin + fe-user (rule §3.9). Verify: dotnet build pass + dotnet test 81 pass + npm run build × 2 pass · 0 TS error. Chunk D docs (current) STATUS/HANDOFF/migration-todos/CLAUDE.md/schema-diagram §16 mới + session log. Phiếu V1 cũ KHÔNG migrate (giữ Mig 15 readOnly), drop sau UAT confirm. **Stats:** 26 mig (+1), 59 DB tables (+1), ~141 endpoints (no new), 33 FE pages, 81 test pass. Polish 3 button (873e7a1) Hành động đầu Session 19: rút gọn label "✓ Duyệt / ← Trả lại / ✗ Từ chối" + 3 màu khác nhau (emerald/amber/red) + font-bold cho cả 2 app. | `873e7a1` (3 button) · `77a3058` (Chunk A Mig 26) · `90baa8e` (Chunk B Service+DTO+GET) · `6e913b3` (Chunk C FE) · (current Chunk D Docs) |
| 2026-05-08 19:45 | Claude | **🎯 SESSION 18 WRAP-UP — PE V2 polish + Clone B (DuyetNccPhuongAn) + 4 bug fix UAT + Mig 25 IsUserSelectable (7 commit `aaa1c6c` → `32a8d4d`)** — User UAT live tiếp Session 17, request chuỗi polish nhỏ + clone V2 cho type B. Áp memory `feedback_uat_skip_verify` (skip dotnet test mỗi chunk, push ngay) + lesson rename/remove → bắt buộc `npm run build`. **B1 (`aaa1c6c`)** Pe Duyệt (`?pendingMe=1`): bỏ dropdown "Tất cả trạng thái" + filter cứng client-side `getPeDisplayStatus === DaGuiDuyet` (loại Nháp/Trả lại/Đã duyệt/Từ chối). Hint amber "Lọc cố định: Đã gửi duyệt". Header count dùng `rows.length` (inbox không paged). Workaround BE /inbox loose UAT trả phiếu Nháp. Mirror fe-admin + fe-user. **B2 (`917446d`)** PeDetailTabs HistoryTab filter chỉ events Trả lại/Gửi duyệt lại: workflow transition về TraLai (phaseAtChange=98) + transition từ TraLai (summary chứa "TraLai →") + sửa nội dung khi phaseAtChange=TraLai. BE giữ audit data đầy đủ, chỉ FE filter (reversible). Empty state "Chưa có lịch sử trả lại / gửi duyệt lại". Mirror cả 2 app. **B3 (`937eb24`) Clone V2 cho B (DuyetNccPhuongAn)** — User chốt "Quy trình chọn thầu phụ - NCC → Duyệt NCC đúng. Clone toàn bộ updates sang Duyệt NCC và Giải pháp". Audit phát hiện 80% chung qua `ApplicableType` discriminator → chỉ thêm 3 file ~60 LOC: (a) `MenuKeys.cs` +const `ApprovalWorkflowDuyetNccPhuongAnV2` + add vào `All[]`. (b) `DbInitializer.SeedMenusAsync` +leaf "Duyệt NCC và Giải pháp (Mới)" dưới root ApprovalWorkflowsV2 + new method `SeedSampleApprovalWorkflowsV2Async` seed `QT-DN-PA-V2-001 v01` (1 Bước Phòng CCM × 1 Cấp NV test, idempotent). (c) `fe-admin/lib/menuKeys.ts` +`AwV2_DuyetNccPhuongAn`. KHÔNG migration / Service / Designer page (Layout regex `^AwV2_(.+)$` đã match dynamic, ApprovalWorkflowsV2Page có `TYPE_CODE_TO_INT` cả 3 type). Rút memory `feedback_audit_reuse_before_clone.md`. **B4 (`f77ea38`) Fix permission silent 403** — Drafter `nv.test` Workspace dropdown empty mặc dù seed OK. Root: class-level `[Authorize(Policy = "Workflows.Read")]` → non-admin 403, TanStack Query catch silent → UI empty không warning. Fix: class-level `[Authorize]` only (any authenticated). GET = list workflow read-only không nhạy cảm; POST + DELETE giữ `Workflows.Create` admin-only. Pattern reusable cho Contract V2 sau. **B5 (`a9c0857`) Fix sidebar highlight queryMatches** — Click phiếu trong leaf "Danh sách" → URL `?type=1&id=abc` → menu mất highlight (gotcha #34 cũ tái phát). Root: queryMatches exact-set equality {type} vs {type, id} length mismatch. Fix: `TRANSIENT_QUERY_KEYS = {id, q, editHeader, page, phase, awId}` strip trước compare. Edge case verified: Danh sách `?type=1` vs Pending `?type=1&pendingMe=1` distinct (không cross-highlight). Mirror cả 2 app Layout.tsx. **B6 (`2a53107`) Mig 25 + Designer pin toggle + bỏ "(clone)" + Workspace filter** — User feedback Admin Designer: bỏ "(clone)" auto-suffix khi clone version (version đã đủ phân biệt) + thêm pin toggle "Cho user pick lúc create phiếu" (multi-select, độc lập IsActive). Migration 25 `AddIsUserSelectableToApprovalWorkflows`: ALTER ApprovalWorkflows +`IsUserSelectable bit NOT NULL DEFAULT 0` + Sql backfill `UPDATE WHERE IsActive=1 SET 1` (giữ behavior cũ active workflow vẫn pickable). Domain ApprovalWorkflow +property. DTO AwDefinitionDto +field. CreateAwDefinitionCommand set default `true` cho version mới (mirror IsActive). New `SetAwUserSelectableCommand` + Handler. API `PATCH /api/approval-workflows-v2/{id}/user-selectable` policy `Workflows.Create`. DbInitializer SeedSampleApprovalWorkflowsV2Async +`IsUserSelectable=true`. FE Designer: `DefinitionDto` +field; badge amber "📌 Cho user chọn"; button "Ghim cho user / Bỏ ghim" + mutation `toggleSelectable`. Designer `name = cloneFrom.name` (bỏ ` (clone)` suffix). Workspace fetch filter `w.isUserSelectable === true` (cả fe-admin + fe-user). **B7 (`32a8d4d`)** Cleanup orphan `.claude.zip + docs.zip` từ harness session start, +`*.zip` rule .gitignore. **Cumulative Session 18:** 25 mig (+1), 58 tables (no new), ~141 endpoints (+1), 33 FE pages, **81 test pass** (no change — feature mới UAT defer test theo §7), 44 gotcha (+1 silent 403). Memory +1 entry. **Pending Session 19+:** Contract V2 wire (Mig 26 mirror PE), phân quyền strict V2, drop legacy V1 cleanup. | `aaa1c6c` (B1) · `917446d` (B2) · `937eb24` (B3) · `f77ea38` (B4) · `a9c0857` (B5) · `2a53107` (B6) · `32a8d4d` (B7) |
| 2026-05-08 | Claude | **🎯 SESSION 17 WRAP-UP — PE Workflow V2 schema + Service wire end-to-end (13 commit `c847dc0` → `de0f38d`)** — User chốt sau Session 16 "Thấy vẫn không đúng" → viết lại schema riêng + thêm Menu "Duyệt NCC (Mới)" UAT. Cấu trúc rõ ràng: Quy trình > Bước (Phòng) > Cấp (NV cụ thể qua ApproverUserId). 3 chunk lớn: **Schema design + Designer** (Mig 22 — `c847dc0/f6047d5/2781c7e/12daa7f`): 3 entity ApprovalWorkflow/Step/Level + enum ApplicableType (DuyetNcc/DuyetNccPhuongAn/Contract). Designer page `/system/approval-workflows-v2/:typeCode` — iter 1 lock 3 cấp (`9712778`, sai intent) → iter 2 đúng intent max 3 cấp × N NV/cấp + sequential gating C2/C3 disabled khi cấp trước empty + filter NV theo Phòng + no-dup same level (`f3bea3c`). Validator BE Order∈{1,2,3} + HaveSequentialOrders + HaveNoDuplicateApproverInSameLevel. **State machine 5 trạng thái** (`ff21120`): Nháp→Đã gửi duyệt→Đã duyệt (terminal) | Trả lại (Phase riêng TraLai=98, KHÔNG revert DangSoanThao + KHÔNG jump-back) | Từ chối (terminal). Drafter từ TraLai sửa+gửi lại chạy LẠI từ Cấp 1 Bước 1 (Option A user chốt diagram). PE/Contract/Budget Phase enum +TraLai=98 + Policy + Service Reject branch trỏ → TraLai + bỏ smart-reject (RejectedAtStepIndex giữ DB column deprecated). 4 test mới TraLai entry point. **Pin V2 vào PE + Service wire** (Mig 23-24 — `0a40c65/b41484b`): PE.ApprovalWorkflowId Guid? + PE.CurrentApprovalLevelOrder int? + EF FK Restrict. CreatePurchaseEvaluationCommand+Validate ApplicableType match PE.Type. UpdateDraft cho phép sửa Phase=Nháp/TraLai. Workspace Select bắt buộc (filter ApplicableType=type). Service `ApproveV2Async` + `ApproveV1LegacyAsync` branch theo ApprovalWorkflowId set or null: V2 group Levels by Order = Cấp (OR-of-N approvers cùng cấp), match `actor.Id ∈ ApproverUserId`, advance levelOrder++ trong Step → idx++ + reset levelOrder=1 → DaDuyet. Synthetic Policy `ForV2Schema()` cho FE nextPhases (DangSoanThao/TraLai → ChoDuyet/TuChoi; ChoDuyet → ChoDuyet/TraLai/TuChoi). **UX V2-aware** (`d814429/9e63e2d/d250ae4/74745a7/de0f38d`): DTO `CurrentApproval { stepIdx, levelOrder, approvers[] }` + `ApprovalFlow { steps[]: { Order, Name, Dept, Levels[]: { Order, Approvers[], Status:Done/Current/Pending } } }`. Banner emerald "Đến lượt bạn" / amber "Không phải lượt bạn — chỉ {NV X / Y} duyệt được". Button Duyệt forward disabled khi V2 + actor không trong cấp + tooltip. Trả lại + Từ chối vẫn enabled (BE không gating reject theo cấp). Inbox V2-aware (`ResolveV2InboxIdsAsync` precompute Set IDs khớp actor.Id ∈ Cấp hiện tại). 2 dropdown filter "Quy trình duyệt" + "Trạng thái" (chỉ ở Duyệt sau user feedback, Danh sách giữ 1 dropdown trạng thái). Panel 3 thay 4 phase cards bằng flow workflow thực tế: Bước (icon ✓/●/○ + dept badge) → Cấp (icon nhỏ + label "đang chờ" / "đã duyệt" + tên NV). Phiếu V1 legacy fallback note. **Test setup** (`ac41d5e`): SQL `clean-transactional-uat.sql` xóa 9 PE + 11 HĐ + Budget + 19 Notif + reset CodeSequences trên prod, giữ master (Users/Suppliers/Projects/Departments/Workflows V1+V2). Tạo test user `nv.test@solutions.com.vn`/`TestUser@123456` (Drafter, Phòng CCM) qua API. **77→81 test pass** (+4 TraLai entry point Domain). FE rename "Bản nháp" → "Nháp" + ChoDuyet=10 + TraLai=98 thêm vào types/contracts.ts + types/budget.ts. **Pending session sau:** Contract V2 wire (mirror PE pattern), Budget V2 (defer xa hơn), phân quyền strict V2 (hiện loose UAT cho mọi authenticated user xem phiếu V2), drop legacy V1 sau khi UAT chốt + cleanup migration drop RejectedAtStepIndex/RejectedFromPhase. | 13 commit (xem `git log --since='2026-05-08'`) |
| 2026-05-08 | Claude | **🎯 SESSION 16 — DRASTIC REFACTOR flat workflow Phòng × Cấp (Mig 21, 2 commit Chunk A+B)** — Resume từ Session 15 defer plan. User chốt "bỏ phase enum hoàn toàn, dùng ChoDuyet=10 đơn nhất + currentStepIndex tracking". Per memory `feedback_drastic_refactor_scope`: dedicated session với context fresh, scope conservative 2x buffer (~8-10h estimate, actual ~3h). **Chunk A (`dbb0089`)** — Domain enum simplify (DangSoanThao=1, ChoDuyet=10 NEW, DaDuyet=7, TuChoi=99; legacy 2-6 + 98 deprecated giữ cho data cũ). WorkflowStep + DepartmentId Guid? FK Restrict + PositionLevel int? (PE + Contract mirror). PE/Contract entity + CurrentWorkflowStepIndex int? + RejectedAtStepIndex int?. Drop class WorkflowStepInnerStep + nav (PE + Contract). Drop *DepartmentApproval.InnerStepId column. EF Configurations: drop InnerStep config + restore simple unique non-filtered (Mig 19/20 filtered split reverse). DbContext drop DbSet<*WorkflowStepInnerStep> × 2. **Migration 21** `RefactorWorkflowToFlatModel` GỘP: 4 ALTER cols (PE/Contract CurrentStepIndex+RejectedAtStepIndex) + 2 ALTER (WorkflowStep DeptId+PositionLevel) + DROP TABLE x 2 (PEWorkflowStepInnerSteps + WorkflowStepInnerSteps Mig 18+20) + DROP InnerStepId column x 2 (PE+Contract DeptApproval) + DROP filtered indexes x 2 + restore simple unique x 2. PE + Contract Service rewrite TransitionAsync: phase transitions DangSoanThao→ChoDuyet (Drafter trình init idx=0) / ChoDuyet→ChoDuyet (advance idx) / ChoDuyet→DaDuyet/DaPhatHanh (last step done) / ChoDuyet→DangSoanThao (Trả lại save RejectedAtStepIndex) / ChoDuyet→TuChoi (Từ chối khoá vĩnh viễn). Match approver: actor.Dept==step.Dept AND actor.PositionLevel>=step.PositionLevel (OR cùng cấp/dept) OR Approvers.Kind=User match OR Kind=Role match. Admin role bypass policy. Last step done → gen mã HĐ (Contract only). App CQRS WorkflowStepDto + WorkflowStepInput drop InnerStep, add DepartmentId/DepartmentName/PositionLevel (PE + Contract mirror). Tests rewrite: DROP `PeNStageApprovalTests.cs` (6) + `ContractNStageApprovalTests.cs` (6) + `PeTwoStageApprovalTests.cs` (7) — legacy N-stage/2-stage no longer applicable. UPDATE `PeWorkflowAdminTests` signature. **96 → 77 test pass** (-19 legacy). 3-file rule Mig 21 (.cs + Designer + Snapshot) commit đủ. **Chunk B (`88a5be1`)** — FE-Admin Designer rewrite (PeWorkflowsPage + WorkflowsPage): drop InnerStepDto + EditInnerStep types, drop PHASE_OPTIONS auto-assign ChoDuyet=10, StepDto + EditStep + departmentId/positionLevel, copyFromDefinition simplified, Designer step UI rewrite (Tên + Phòng Select + Cấp Select + SLA + Approvers Role/User optional fallback, drop entire InnerSteps sub-section), DefinitionCard view hiển thị badge Phòng emerald + Cấp NV/PP/TP violet, save payload phase=10. types/purchaseEvaluation.ts (fe-admin + fe-user mirror) + ChoDuyet=10 enum + label "Đang duyệt" + color amber. **Chunk C (FE PeWorkflowPanel) SKIP** — existing UI compatible (workflow.nextPhases driven by BE simplified policy), reuse 3-button Trả lại/Từ chối logic Session 14 hoạt động trên ChoDuyet phase tự động. **KHÔNG đụng** Service Notify pattern + Changelog pattern (giữ hành vi Mig 16). Verify: dotnet build pass + Mig 21 LocalDB applied + 77 test pass + npm build × 2 pass. Memory `feedback_drastic_refactor_scope.md` validated: dedicated session approach hoạt động đúng dự đoán. | `dbb0089` (A) · `88a5be1` (B) |
| 2026-05-07 | Claude | **🎯 SESSION 15 — Tooltip diagnose "Lưu & Gửi Duyệt" + Plan drastic refactor flat workflow → DEFER** — User UAT live screenshot phiếu PE Bản nháp + báo "Lưu & Gửi Duyệt" KHÔNG hoạt động + suy đoán "trùng ID với phiếu khác". Chẩn đoán: button silent disabled khi `evaluation.workflow.nextPhases` không có forward phase (chỉ TuChoi/TraLai). FE chưa có visual feedback → user không biết. Improvement (commit `835cc7f`): compute `forwardPhase` once + add `submitDisabledReason` string giải thích reason (canEditPhase=false / readOnly / !forwardPhase với hint admin kiểm tra cấu hình quy trình) + button title attribute show reason hover hoặc forward phase label khi enabled + Dialog confirm show forward phase explicit "Sẽ chuyển sang Chờ Purchasing". Mirror fe-admin + fe-user. Build pass cả 2. **"Trùng ID" KHÔNG phải bug FE** — `PurchaseEvaluationWorkspacePage` URL state đúng (`+ Thêm mới` clear `id`, save set new), mỗi PE row unique GUID + MaPhieu. **Tiếp theo plan drastic refactor**: User chốt "bỏ phase enum hoàn toàn, dùng ChoDuyet=10 đơn nhất + currentStepIndex tracking" + workflow flat list (Phòng × Cấp × Users[]) thay InnerStep model. Surface 6 chunk plan + start Chunk A: edit Domain entities (Phase enum +ChoDuyet=10, WorkflowStep +DeptId/PositionLevel, drop InnerStep class+nav, PE/Contract +CurrentWorkflowStepIndex/RejectedAtStepIndex, *DeptApproval drop InnerStepId) + EF Configurations (drop InnerStep config + nav, restore simple unique non-filtered) + DbContext drop DbSets — 12 files trong working tree. Realize scope realistic ~8-10h (PolicyRegistry rewrite + 2 Service rewrite + App CQRS + 12 tests rewrite + Designer FE + Migration 21 + Docs) vượt session boundary + risk session context deep ~30 commits. **REVERT working tree** về `835cc7f` clean. Add memory `feedback_drastic_refactor_scope` decision rule: drastic refactor cần dedicated session, ước tính conservative (2x buffer), tránh mid-session big refactor. **Stats unchanged**: 96 test pass, 20 mig, 57 bảng. | `835cc7f` |
| 2026-05-07 | Claude | **🎯 SESSION 14 — PE 3-button workflow Duyệt/Trả lại/Từ chối + Task 2 sample seed in-progress** — User chỉ thị thay 2-button approval bằng 3 hành động rõ ràng cho approver: **Duyệt** (forward), **Trả lại** (về DangSoanThao + Drafter sửa, smart reject Mig 16 + clear N-stage rows + Drafter resume jump-back), **Từ chối** (Phase=TuChoi, phiếu khoá vĩnh viễn 17 handler Mig 16 lock edit, Drafter phải tạo phiếu mới). 1 commit (`0d77698`): Domain `PurchaseEvaluationPolicy.cs` NccOnly + NccWithPlan thêm `(X → TuChoi)` transition cho mọi phase trung gian (ChoPurchasing/ChoCCM/ChoDuAn/ChoCEODuyetPA/ChoCEODuyetNCC) với roles của phase. FromDefinition expand: mỗi step (trừ DangSoanThao) thêm (step.Phase → TuChoi) với roles step. Service `PurchaseEvaluationWorkflowService.TransitionAsync` — Reject branch tách 2 case: target=TuChoi giữ nguyên (KHÔNG override + KHÔNG set RejectedFromPhase + KHÔNG clear N-stage); target khác (DangSoanThao) → smart reject (force DangSoanThao + RejectedFromPhase + clear N-stage). FE PeWorkflowPanel (admin + user mirror): render 3 button rõ ràng "✓ Duyệt → X" brand / "← Trả lại (về Drafter sửa)" red / "✗ Hủy / Từ chối" red. Decision logic: target=TuChoi || isSendBack → Reject (2), else Approve (1). Dialog confirm: title rõ + Cancel case warning red "phiếu sẽ bị khoá hoàn toàn" + SendBack case hint amber "Phiếu về DangSoanThao, Drafter sửa rồi trình lại — workflow tự jump tới phase này". Tests: rename `Reject_Sets_RejectedFromPhase_And_Forces_DangSoanThao` → `Reject_To_DangSoanThao_Sets_RejectedFromPhase_TraLai` (target từ TuChoi → DangSoanThao). NEW `Reject_To_TuChoi_Locks_Permanently_No_RejectedFromPhase`. Update `NStage_Reject_Clears_InnerStep_Rows_At_Phase` target → DangSoanThao. **95 → 96 test pass** (+1 Từ chối). **Task 2 sample seed in-progress**: dotnet ef database update applied Mig 9-20 lên LocalDB SolutionErp_Dev (trước đó chỉ Mig 1-8 vì DesignTimeDbContextFactory hardcoded SolutionErp_Design ≠ runtime SolutionErp_Dev — gotcha tooling distinction). API start để DbInitializer auto-seed 30 demo user nhưng exit 255 sớm khi log buffer full → seed dở dang. Defer Task 2 cho session sau (cần guidance: seed manual SQL hoặc manual API run + sample N-stage workflow def + Update PositionLevel cho 30 users existing). | `0d77698` |
| 2026-05-07 | Claude | **🎯 SESSION 13 — Mirror N-stage workflow sang Contract (Mig 20, 5 commit per-chunk + skip Chunk E API)** — User chỉ thị mirror N-stage từ PE sang Contract. Budget defer (cần versioned WF migration trước, hardcoded BudgetPolicy hiện tại chưa có WorkflowDefinition). 5 chunk per-commit (build + ef + test pass mỗi chunk): **Chunk A (`951ffa3`)** Domain entity `WorkflowStepInnerStep` (Domain/Contracts/) + nav WorkflowStep.InnerSteps + ALTER ContractDepartmentApproval.InnerStepId Guid? + EF config FK Cascade Step / Restrict Dept+InnerStep + **Migration 20** `AddContractWorkflowInnerStepsAndAlterDeptApprovalUnique` GỘP 1 (CREATE TABLE WorkflowStepInnerSteps + ALTER InnerStepId + DropIndex old + Recreate filtered legacy `WHERE InnerStepId IS NULL` + new filtered N-stage `WHERE InnerStepId IS NOT NULL` + 3 IX + 3 FK). **Chunk B (`04cf2a0`)** Application CQRS DTO — `WorkflowStepInnerStepDto` + extend `WorkflowStepDto` + GetWorkflowAdminOverview Include InnerSteps + DeptNames map + `CreateWorkflowStepInnerStepInput` + `CreateWorkflowStepInput` extend (default null backward compat) + Validator child rules + Handler atomic batch insert. **Chunk C (`e247b67`)** ContractWorkflowService refactor mirror PE — load definition InnerSteps eager, reject branch clear N-stage rows tại fromPhase, dept approval block split hasInnerSteps→N-stage logic / else→legacy 2-stage. N-stage flow giống PE: yêu cầu actor có DeptId+PositionLevel, match firstPending Order asc + (exact level OR canBypass + level≥), exact upsert 1 row InnerStepId, bypass batch upsert NV+PP+TP cùng dept ≤ actor (audit IsBypassed cho cấp dưới), recheck stillPending → BLOCK + log "duyệt cấp X (còn Y pending)". **Chunk D (`7c0772a`)** Tests 6 N-stage Contract mirror PE pattern + helper SeedWorkflowDefinitionAsync 2 step adjacent (DangGopY + DangDamPhan) + SeedContractAsync với Project + Supplier seed + FakeChangelogService + FakeContractCodeGenerator stubs. Bug fix: legacy fallback test ban đầu fail (Standard policy DangGopY → DangDamPhan chỉ cho [Drafter, DeptManager], không Procurement) → switched phase pair sang DangKiemTraCCM → DangTrinhKy + role CostControl khớp. Total 89 → **95 test pass**. **Chunk E SKIP** — WorkflowsController auto-bind `[FromBody] CreateWorkflowDefinitionCommand` record qua JSON, no code change cần. **Chunk F (current)** FE-Admin types/users.ts đã có PositionLevel const từ Session 12 reuse. WorkflowsPage Designer extend mirror PeWorkflowsPage Chunk F: InnerStepDto + EditInnerStep types + copyFromDefinition include + departmentsList query + sub-section "Cấp duyệt nhỏ trong phòng" drag-list { Phòng × Cấp + required } + button "+ Thêm cấp duyệt" emerald + payload include Order asc. Empty state hint fallback 2-cấp legacy. KHÔNG đụng fe-user (admin-only). Docs/Skill update. **Backward compat 100%**: workflow Contract no InnerSteps → fallback legacy 2-stage Mig 16. Data legacy InnerStepId=null vẫn enforce unique cũ qua filtered index. Defer Budget mirror cho session sau (cần migration `AddBudgetVersionedWorkflow` trước). | `951ffa3` (A) · `04cf2a0` (B) · `e247b67` (C) · `7c0772a` (D) · (current F) |
| 2026-05-07 | Claude | **🎯 SESSION 12 — N-stage workflow approval Phòng × PositionLevel cấu hình động (PE-only first, 6 commit per-chunk + Mig 18+19)** — User yêu cầu mở rộng từ 2-stage Mig 16 (NV.Review/TPB.Confirm) sang N-stage cấu hình động: mỗi WorkflowStep cha (= 1 phase) có thể cấu hình chuỗi InnerSteps con theo Department × PositionLevel với Order sequential. Spec defaults chốt 6 câu (PositionLevel int 1=NV/2=PP/3=TP, sequential pure, bypass cùng dept TP skip NV+PP, smart reject reset N-stage rows về DangSoanThao, PE-only first, designer 1 sub-section InnerSteps). 6 chunk per-commit (build + ef + test pass mỗi chunk per `feedback_per_chunk_commit.md`): **Chunk A (`13ab533`)** Domain enum `PositionLevel` (NV/PP/TP) + entity `PurchaseEvaluationWorkflowStepInnerStep` + ALTER User.PositionLevel int? + ALTER PEDeptApprovals.InnerStepId Guid? + EF config + **Migration 18** `AddPeWorkflowInnerStepsAndPositionLevel` (1 CREATE TABLE + 2 ALTER + 3 index + FK Cascade Step / Restrict Dept/InnerStep). 3-file rule. **Chunk B (`0e56bd0`)** Application CQRS DTO — `PeWorkflowStepInnerStepDto` + extend `PeWorkflowStepDto` + `CreatePeWorkflowStepInnerStepInput` (default null backward compat existing PeWorkflowAdminTests) + Validator child rules + Handler atomic batch insert + UserDto +PositionLevel field + `SetUserPositionLevelCommand` mirror SetBypassReview. **Chunk C (`0c62e24`)** Service N-stage logic — **Migration 19** `AlterPeDeptApprovalsUniqueFilteredForInnerSteps` (filtered unique: legacy `WHERE InnerStepId IS NULL` + N-stage `WHERE InnerStepId IS NOT NULL`) cho phép multi-row cùng dept khác inner step. PurchaseEvaluationWorkflowService refactor: load definition InnerSteps eager + reject branch clear N-stage rows + dept block split hasInnerSteps→N-stage logic / else→legacy 2-stage. N-stage flow: yêu cầu actor có DeptId+PositionLevel, match firstPending (Order asc IsRequired) same dept + (exact level OR canBypass + level≥), exact match upsert 1 row InnerStepId, bypass batch upsert NV+PP+TP cùng dept ≤ actor level (audit IsBypassed cho cấp dưới skip), recheck stillPending → BLOCK + log "duyệt cấp X (còn Y pending)" / all done → fall through phase transition. Backward compat: workflow no InnerSteps fallback legacy + InnerStepId=null filter unique cũ vẫn enforce. **Chunk D (`3d76c6b`)** Tests N-stage 6 test mới (NV first blocks / 3-level sequential pass / TP bypass skips / wrong dept throws 403 / reject clears rows / legacy fallback no inner) + IdentityFixture extend `+positionLevel` arg + helper SeedWorkflowDefinitionAsync 2 step adjacent (ChoPurchasing+ChoCCM) cho FromDefinition build transition policy guard pass. Total 83→**89 test pass**. **Chunk E (`83ffabd`)** API `PATCH /users/{id}/position-level` mirror SetBypassReview pattern + body `{positionLevel:int?}` Authorize Users.Update. **Chunk F (current)** FE-Admin types/users.ts +positionLevel field + PositionLevel const + Label/Short maps. PeWorkflowsPage Designer extend: InnerStepDto type + EditInnerStep type + copyFromDefinition include + departmentsList query + sub-section "Cấp duyệt nhỏ trong phòng" per step card với drag-drop list { Phòng × Cấp + required checkbox } + button "+ Thêm cấp duyệt" (xanh emerald) + payload include innerSteps Order asc. UsersPage column "Cấp" badge NV/PP/TP emerald + action button cycle null→1→2→3→null call positionLevelMut PATCH. KHÔNG đụng fe-user (admin-only feature). Docs/Skill update. PE-only first. Backward compat 100%: workflow no InnerSteps + data legacy 2-stage rows không phá. | `13ab533` (A) · `0e56bd0` (B) · `0c62e24` (C) · `3d76c6b` (D) · `83ffabd` (E) · (current F) |
| 2026-05-08 00:30 | Claude | **🎯 SESSION PHASE 2 WRAP-UP — B12-B14 PE detail polish iterate (3 commit FE-only sau wrap-up `6e7a6db`)** — User UAT iteration tiếp, áp rule strict verify khi rename/remove (lesson hotfix CI). 3 batch nhỏ: **B12 (`378c993`)** "Lưu" no-close (chỉ toast + invalidate, KHÔNG đóng workspace) + nút "Xóa phiếu" red bottom CHỈ Bản nháp (soft-delete `IsDeleted=true` qua AuditableEntity, không xóa hoàn toàn DB) + bỏ header bar workspace mode "Sửa header"/"Xóa"/"Đóng" (chuyển hết xuống bottom action bar) + Section 4 column header dùng `s.supplierName` thay `displayName` (NCC master) + Section 3 row chặn xóa NCC khi đã có quotes (`hasQuotes` computed) + tooltip "xóa báo giá trước". **B13 (`e320027`)** InfoTab `useEffect` watch `[autoEdit, canEdit, ev.id, ...]` → re-trigger edit mode khi pencil click phiếu khác (fix useState mount-time only) + sync values từ ev mới (tránh stale state) + Pencil "sáng lên" active state khi `editingRowId === p.id` (bg-brand-100 + text-brand-700 + ring-brand-300 + shadow-sm + tooltip cập nhật) + wire `editingRowId={autoEditHeader ? selectedId : null}` từ Workspace → PeListPanel. **B14 (`d2306b8`)** QuoteDialog bỏ checkbox "Chọn NCC này cho hạng mục" (consolidate winner ở Section 2.a NccSelectorRow, isSelected vẫn gửi BE giữ trạng thái cũ) + winner column Section 4 matrix highlight emerald (header `bg-emerald-50` + `✓ ` prefix + cells `bg-emerald-50 font-semibold` cho ENTIRE column, không chỉ cell có quote) + loading overlay full-screen QuoteDialog (`bg-white/70 backdrop-blur-sm` + spinner ring brand-600 + text "Đang lưu báo giá…"/"Đang xóa…") + NccSelectorRow inline spinner "Đang chọn NCC + sync cột giá Section 4…" + disable Hủy/Xóa/Lưu buttons khi `isSaving`. Verify: `npm run build` × 2 app pass mỗi commit · `dotnet test` 83 pass (KHÔNG regression). | `378c993` (B12) · `e320027` (B13) · `d2306b8` (B14) |
| 2026-05-07 | Claude | **🎯 SESSION WRAP-UP S10-11+++++++ — PE Workspace UX overhaul đầy đủ (23 commit / ~3500 LOC FE + Mig 17 BE)** — User UAT live mode iterate liên tục, áp rule `feedback_uat_skip_verify` (skip dotnet test sau mỗi chunk, push ngay). 7 batch chính: **B1 (S10) PE Thao tác 2-panel workspace** — leaf `Pe_*_Create` từ page Create header riêng → workspace 2-panel `[320px_1fr]` mirror HĐ Thầu phụ; PeListPanel pure picker + sticky "+ Thêm mới"; PeDetailTabs `mode='workspace'` ẩn Workflow/Approvals/History + Section 5 disabled "nhập khi duyệt" (4 commit). **B2 (S11) Migration 17** `AddManualBudgetFieldsToPeAndContract` — 4 ALTER (PE + HĐ × `BudgetManualName` nvarchar(200) + `BudgetManualAmount` decimal(18,2)) cho fallback "user nhập tay khi không link Budget entity approved". Domain + EF config + App CQRS Create/Update + DTO + Validator + carry-forward `CreateContractFromEvaluation`. FE toggle "Nhập tay" trong PeHeaderForm + ContractCreatePage NewForm/EditForm × 2 app (5 commit). **B3 (S11+) BudgetFieldRow inline editor** — Section 2 "b. Ngân sách" thay FormRow tĩnh → editable component (toggle + Select OR 2 input + Save dirty + Hủy). canEdit cho cả 3 view (Workspace/Danh sách/Duyệt mode), readOnly chỉ display (3 commit). **B4 (S11++) InfoTab inline edit + PeListPanel pencil hover** — Section 1 "✎ Sửa" button flip display↔inputs (Tên/Địa điểm/Mô tả/Payment editable, Dự án locked). PeListPanel thêm pencil icon group-hover absolute right + URL `?editHeader=1` chain → `autoEditHeader` prop trigger mount-time edit (3 commit). **B5 (S11+++) Workspace "new" sectioned create view** — `PeWorkspaceCreateView.tsx` ~230 LOC layout 5 sections giống PeDetailTabs visual. S1 + S2.b editable, S3-5 LockedHint "Lưu phiếu trước". POST trigger create. Replace `PeHeaderForm` trong workspace mode='new' (1 commit). **B6 (S11++++) Danh sách disable toàn bộ interactions** — PurchaseEvaluationsListPage `readOnly={true}` hardcoded cho PeDetailTabs + `readOnly={!pendingMe}` cho PeWorkflowPanel (List view → ẩn Chuyển tiếp + show hint "Vào menu Duyệt"; Pending vẫn approve được) (2 commit). **B7 (S11+++++) Lock Loại quy trình + payment preset** — workspace `<Select>` Loại quy trình → `<Input disabled>` theo URL `?type=N`. `<Textarea>` JSON Điều khoản TT → `<Select>` 8 preset Việt + "Khác (nhập tay)" → text input fallback (1 commit). **B8 (S11++++++) Display status meta** — `PeDisplayStatus` enum 4-5 trạng thái UI (Bản nháp / Đã gửi duyệt / Trả lại / Đã duyệt / Từ chối) gom phase chi tiết. `getPeDisplayStatus()` helper. Workflow timeline Panel 3 vẫn giữ phase chi tiết (1 commit). **B9 (S11+++++++) Phase TraLai + pencil always visible + edit gating** — Domain `PurchaseEvaluationPhase` thêm `TraLai = 98` (giữa DaDuyet=7 + TuChoi=99). FE label/color + display status badge. `isEditablePhase()` helper: chỉ DangSoanThao + TraLai. PeListPanel pencil bỏ hover-only → LUÔN visible (bright khi editable / xám disabled khi không) + click guard. Workspace `editableOnly` filter client-side (1 commit). **B10 (hotfix CI)** — TS strict catch fail 2 commit B7+B8 do skip-verify (`forcedPhase` rename quên xóa destructuring args + unused `PurchaseEvaluationType` import). Update memory `feedback_uat_skip_verify.md` thêm exception "rename/remove → BẮT BUỘC `npm run build`" (1 commit). **B11 (last) PE detail polish** — `NccSelectorRow` Section 2.a thay FormRow tĩnh → Select dropdown từ ev.suppliers (Section 3 list) wire `/select-winner` API. Section 2.c text rõ "(chọn NCC trước)" / "(chưa nhập báo giá)". Section 3 row khi `isWinner` → ẩn ✏ + 🗑 (chỉ giữ ✓ active). Bottom action bar workspace mode: **2 nút "Lưu (đóng)" + "Lưu & Gửi Duyệt →"** confirm dialog → POST `/transitions` với `targetPhase = first nextPhase` skip TuChoi/TraLai → workflow chuyển từ Bản nháp/Trả lại → Đã gửi duyệt (ChoPurchasing) → onBack đóng workspace (1 commit). | `ee0d360` (S10 C1) → `4c0625c` (B11) — 23 commit total |
| 2026-05-07 | Claude | **PE InfoTab inline edit Section 1 + PeListPanel pencil edit hover** — User feedback 2026-05-07: muốn thêm nút edit kế bên row trong Panel 1, click sáng nội dung Section 1 lên cho user sửa header inline (KHÔNG cần đi "Sửa header" page). 2 chunk per-commit (build pass mỗi chunk): C1 fe-admin (3 file) — InfoTab thêm prop `readOnly + autoEdit`, canEdit=`!readOnly && isDraft`: display mode hiển thị FormRow + button "✎ Sửa" góc trên phải, editing mode card border brand-200 + 4 input (Tên */Dự án locked/Địa điểm/Mô tả/Payment) + Save (PUT /pe/:id full payload + invalidate detail+list)/Hủy. PeListPanel thêm prop `onEditClick`, pencil icon absolute right-2 top-2 mỗi row, opacity-0 group-hover:opacity-100. PurchaseEvaluationWorkspacePage đọc URL `?editHeader=1` → pass `autoEditHeader` xuống PeDetailTabs → trigger edit auto. C2 fe-user mirror y hệt 3 file (rule §3.9). KHÔNG đụng BE. KHÔNG refactor workspace "new" mode (defer — PeHeaderForm hiện tại đủ dùng, làm thêm khi user feedback). | `5a89dd2` (C1) · (current C2) · (current C3 docs) |
| 2026-05-07 | Claude | **PE BudgetFieldRow inline editor — toggle + 2 fields trong Section 2 (cả 3 view)** — User feedback after Session 11: muốn toggle "Nhập tay" + 2 input fields hiển thị trực tiếp trong Section 2 "b. Ngân sách" của PeDetailTabs — KHÔNG chỉ ở "Sửa header" page, mà cả 3 view (Workspace / Danh sách / Duyệt). Empty values cứ hiển thị empty (không text "(chưa link)" verbose). 2 chunk mirror per-commit (build pass mỗi chunk): C1 fe-admin BudgetFieldRow component (~125 LOC) thay FormRow tĩnh ở `b. Ngân sách`. canEdit=`!readOnly && isDraft`: render toggle + Select Budget OR 2 input grid 2-col + nút "Lưu ngân sách" (chỉ hiện khi dirty) + "Hủy thay đổi". Save: full PUT `/pe/:id` với current entity values + new budget payload. Read-only mode (Duyệt + !isDraft): chỉ display, KHÔNG toggle/inputs, empty hiển thị "—". C2 fe-user mirror y hệt 1 file (rule §3.9). Mỗi chunk: build pass + 0 TS error. KHÔNG đụng BE — re-use existing PUT endpoint. | `19712d8` (C1) · `d5c6f12` (C2) · (current C3) |
| 2026-05-07 | Claude | **Migration 17 — manual budget fields fallback cho PE + HĐ (toggle "Nhập tay")** — User feedback: khi project chưa có Budget approved (Phase=DaDuyet eligible), user phải break flow đi tạo Budget + duyệt + quay lại link. UX kém. Solution: thêm fallback "Nhập tay" — checkbox toggle cạnh Label Ngân sách, khi ON → hide Select Budget, show 2 input field grid 2-col (Tên tham chiếu text + Số tiền number formatted VND). Lưu trên entity row, KHÔNG cần Budget entity. Q1-3 chốt: 1 = stick-toggle reveal 2 input fields; 2 = cả BudgetId + manual fields cùng null OK (KHÔNG XOR validate); 3 = mirror logic sang HĐ luôn (cả 7 ContractType qua ContractCreatePage). 5 chunk per-commit (build + 83 test pass mỗi chunk): C1 Migration 17 `AddManualBudgetFieldsToPeAndContract` 4 ALTER (PE + HĐ × Name nvarchar(200) + Amount decimal(18,2)) + Domain 2 entity + 2 EF config (HasMaxLength + HasPrecision) — applied LocalDB OK, 3-file rule. C2 App CQRS — CreatePurchaseEvaluationCommand + Update + DTO + Validator (>=0 when has value), CreateContractCommand + Update + DTO + diff log audit, CreateContractFromEvaluation carry forward pe.BudgetManualName/Amount → contract khi gen HĐ từ phiếu. C3 FE-Admin — types +2 field, PeHeaderForm toggle + 2 input + payload conditional (manual mode clear budgetId, link mode clear manual), PeDetailTabs Section "b. Ngân sách" fallback display "Tên · Số tiền + badge nhập tay" khi !budget + có manual data, refactor PurchaseEvaluationCreatePage wrap PeHeaderForm DRY (222→30 LOC), ContractCreatePage NewContractForm + EditContractForm cùng pattern + read-only display branch khi !isDraft. C4 fe-user mirror y hệt 6 file. C5 docs (this row + HANDOFF + session log). KHÔNG đụng Budget entity / Phase=DaDuyet validation (giữ invariant). | `ecd5f7e` (C1) · `0f7901c` (C2) · `bab5031` (C3) · `14f8d9d` (C4) · (current C5) |
| 2026-05-07 | Claude | **PE "Thao tác" 2-panel workspace + Panel 1 read-only picker + Section 5 disabled** — User chỉ thị restructure leaf "Thao tác" (Pe_DuyetNcc_Create + Pe_DuyetNccPhuongAn_Create) từ page tạo header riêng (`/purchase-evaluations/new?type=N` — chỉ form Tên/Project/Địa điểm/Payment/Budget) sang workspace 2-panel mirror pattern HĐ Thầu phụ ContractCreatePage. 5 câu chốt spec trước code: Q1 Panel 2 KHÔNG render Workflow Panel + Approvals + History (chỉ data entry); Panel 1 = pure picker, KHÔNG inline edit/delete; Q2 mirror HĐ Thầu phụ pattern (sticky "+ Thêm mới" + Panel 2 transition new→edit form); Q3 leaf "Danh sách" + "Duyệt" giữ 3-panel hiện tại; Q4 route mới `/purchase-evaluations/workspace?type={1\|2}`; Q5 Section 5 Ý kiến 4PB disable trong workspace (vì người ta nhập khi duyệt, không phải lúc nhập liệu). 2 chunk per-commit (build + 83 test pass mỗi chunk): C1 fe-admin (3 file mới `PeListPanel.tsx` ~180 LOC pure picker reuse + `PeHeaderForm.tsx` ~210 LOC extract + `PurchaseEvaluationWorkspacePage.tsx` ~120 LOC, 3 file sửa `PeDetailTabs.tsx` thêm prop `mode?: 'detail' \| 'workspace'` + Section 5 hint banner amber + Layout.tsx resolver `Pe_*_Create`→`/workspace?type=N` + App.tsx route mới). C2 fe-user mirror y hệt 6 file (rule §3.9). KHÔNG đụng BE / migration / schema / endpoint. Route `/new` cũ giữ tồn tại cho deep-link "Sửa header" button. **Total +1142 LOC FE / 0 BE / 32 FE pages.** | `ee0d360` (C1) · `ecf3c59` (C2) · (current C3) |
| 2026-05-04 | Claude | **User Manual 7 file rewrite compact cho end-user** — User feedback "ko cần quá đầy đủ chi tiết, cho end-user họ làm". Setup `package.json` + `npm install docx@9.5.0` + script `npm run gen:all`. Rewrite 7 generator scripts theo style end-user friendly: BỎ field validation table 5 cột (Tên field/Kiểu/Bắt buộc/Validation/Ví dụ), BỎ error troubleshoot table 3 cột (Lỗi/Nguyên nhân/Cách xử lý), BỎ FAQ chi tiết 8 câu (giữ 1 chương "Khi gặp lỗi" 4-5 bullet), BỎ phím tắt table. GIỮ: tổng quan ngắn 1-2 câu mỗi chức năng, numbered steps đơn giản 3-7 bước, note/warn/tip chỉ critical, bullet liệt kê. 7 file: 01-Bat-dau (12.1KB cũ 21.7KB ↓44%) / 02-Hop-dong / 03-Duyet-Workflow (mention 2-stage NV/TPB Mig 16) / 04-PE-Phieu-Duyet-NCC (A/B + 4PB + tạo HĐ) / 05-Budget / 06-7-Loai-HD-Cheatsheet / admin-02-Quan-ly-Users-Roles (mention bypass review S9). Refactor user-01 dùng `_helpers.js` shared (trước có helpers inline 793 dòng, giờ ~110 dòng). Tổng output ~86KB / 7 file (cũ ~123KB ↓30%). | `16c2c9c` |
| 2026-05-04 | Claude | **Optional polish — fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi"** — User chỉ thị "tiếp tục plan tổng" → pick task không blocked. useQuery thứ 2 cho `/purchase-evaluations/inbox` (endpoint có sẵn), peRows filter theo search. Stats overdue/dueSoon đếm cả PE rows (totalValue chỉ HĐ vì PE không có giá trị). Panel 1 chia 2 section sticky header: "Hợp đồng (N)" giữ behavior cũ click → inline detail Panel 2; "Phiếu Duyệt NCC (M)" click → navigate `/purchase-evaluations/:id` page riêng (PE entity shape khác Contract, không inline). EmptyState mới: "Không có HĐ hoặc Phiếu Duyệt NCC nào chờ". Chỉ fe-user (Drafter + TPB dùng Inbox) — fe-admin defer. Build pass. | `332a90f` |
| 2026-05-04 | Claude | **Audit định kỳ 2026-05 (combined skill + doc drift theo §6.4 + §9.4)** — Cron `solution-erp-skill-audit-monthly` empty (`No scheduled jobs`), trễ 4 ngày so schedule 2026-05-01 → manual trigger sau Session 9 close. Phase 1 cross-check counts: tests=83, migrations=16, gotchas=41, skills=6, STATUS rows=12 (<30 chưa archive) — toàn bộ khớp. Drift patches 5 file: docs/CLAUDE.md (52→55 bảng + §14 DepartmentApprovals), docs/rules.md (Phase 8→9, 77→83 test), docs/architecture.md (77→83 test 2 chỗ), .claude/skills/ef-core-migration (77→83 + ghi 6 PE 2-stage), .claude/skills/dependency-audit-erp (26+→41 bẫy). Phase 2 skill staleness: contract-workflow thêm "Phase 9 cross-ref Mig 16" block + section "Phase 9 done" (2-stage + smart reject + lock edit + bypass). KHÔNG tạo skill mới (§9.5 anti-pattern "viết skill chỉ để có thêm" — pattern 2-stage đủ generic, đã ghi đủ Domain/Service/6 test reusable). Cron recreate SKIP (CronCreate Claude SDK auto-expire 7 days, không fit monthly cadence). Audit log `docs/changelog/skill-audit-2026-05.md` (1 page). 6 file ~+30/~12 line patch, validation §6.5 OK. | `7dc0233` |
| 2026-05-04 | Claude | **Session 9 — Chunk E-bis complete: FE 2-stage panel + UserManager bypass toggle + HĐ/Budget 2-stage mirror PE + 6 test + IdentityFixture** — User chỉ thị "làm hết cho xong tính năng luôn". 5 chunk per-commit (build + 83 test pass mỗi chunk): (E2) FE PeWorkflowPanel section "Tiến trình duyệt 2-cấp phòng ban" group by phase × dept, highlight amber chờ TPB, badge fuchsia bypass — cả 2 app (rule §3.9). (E3) FE UsersPage column "Bypass" + ShieldCheck toggle button + UserDto.CanBypassReview field. (E4) ContractWorkflowService thêm UserManager DI + mirror 2-stage logic từ PE + `ContractDepartmentApprovalFeatures.cs` (List query) + endpoint `GET /contracts/{id}/department-approvals` + FE WorkflowHistoryPanel section. (E5) Budget mirror đầy đủ — `TransitionBudgetCommandHandler` thêm INotificationService + IDateTime DI + 2-stage logic + `BudgetDepartmentApprovalFeatures.cs` + endpoint + FE BudgetWorkflowPanel. (E6) `IdentityFixture` setup ServiceProvider với Identity stack đầy đủ (DbContext SQLite + AddIdentityCore + AddRoles<Role> + EF stores) + 6 test PE 2-stage: NV_Review_Blocks / TPB_Confirm_Allows / NV_Bypass / Admin_Skip / Reject_Sets_RejectedFromPhase / Resume_Jumps_Back. Tests Contract + Budget skip vì logic identical PE, ROI thấp. **Total 77→83 test pass.** 5 commit pushed lên Gitea. | `f8eebd5` (E2) · `4380bdc` (E3) · `b6f5a16` (E4) · `1fc439b` (E5) · `8353fe8` (E6) · (current E7) |
| 2026-05-04 | Claude | **Session 8 — Migration 16: 2-stage dept approval + smart reject + lock edit (đóng bug anh Kiệt)** — Anh Kiệt báo: NV.PRO tạo phiếu PE → duyệt được hết phase = phân quyền sai. Schema mới: 3 bảng `*DepartmentApprovals` (Contract/PE/Budget) UNIQUE (TargetId, Phase, Dept, Stage). 4 cột mới: `Users.CanBypassReview` bit + 3 `RejectedFromPhase` int. Logic 2-stage trong `PurchaseEvaluationWorkflowService.TransitionAsync`: user.DepartmentId != null → DeptManager (TPB) Stage=Confirm; CanBypassReview=true → Stage=Confirm+IsBypassed; else NV → Stage=Review only, BLOCK transition cho đến khi TPB confirm. Smart reject: Decision=Reject → set RejectedFromPhase, force về DangSoanThao. Resume sau reject: Drafter trình lại từ DangSoanThao + RejectedFromPhase != null → jump straight tới phase đã reject (skip phase trung gian). Lock edit: 17 handler thêm guard Phase != DangSoanThao (Contract Detail × 15, PE Detail × 5, Budget Detail × 3). 3 endpoint mới: `GET /pe/{id}/department-approvals` (FE Workflow Panel hiển thị progress) + `PATCH /users/{id}/bypass-review` (admin toggle) + Notify TPB cùng dept khi NV review. **HĐ + Budget 2-stage scope defer** (chỉ PE first đóng bug). FE update + Tests defer Chunk E-bis. | `5fe61cc` (A) · `14f3c9f` (B) · `9747f8c` (C) · `a532ba6` (D) · (current) |
| 2026-04-30 | Claude | **Session 6 — MD audit + compact + 3 skill refresh + 2 rule mới** — Compact 3 file core (-288 dòng): STATUS -27%, HANDOFF -32%, migration-todos -35%. Archive 51 row Recently Done Phase 0-7 → `changelog/recently-done-archive-2026-04.md`. Refresh 3 skill stale: `form-engine` (Phase 2 MVP → Tier 3 feature-complete + bỏ section duplicate gen mã HĐ), `permission-matrix` (12 menu → ~60 menu key + Bg_*/Pe_*/PeWf_* + inheritance roots), `ef-core-migration` (24 DbSet → 52 bảng + ERD update). Rule mới `rules.md §7 Khi nào viết test — timing rule` (5-row table compact, sau khi rút gọn từ 70 dòng overkill). Rule mới `rules.md §6.4 Audit + compact MD định kỳ` (cadence + checklist + anti-pattern, KHÔNG rewrite toàn bộ). `rules.md §9.4 Skill audit` mở rộng cross-ref §6.4. | (current) |
| 2026-04-29 | Claude | **Tests Phase 3 mini + 3 gotcha CI mới (#39 #40 #41)** — `tests/.../Application/PeWorkflowAdminTests.cs` 6 test versioning logic (CreatePeWorkflowDefinition: first version IsActive=true, second deactivates first, different EvaluationType independent, persists steps ordered + approvers per step, third version increments to v3). Total **77 test** (54 Domain + 17 Infra + 6 PE WF Application). Gotcha #39 act_runner github.com TCP timeout 21s + manual checkout fix. #40 npm junction cache fail `tsc not found` rolled back. #41 paths-ignore behavior + workflow file exclusion. | `b874743` |
| 2026-04-29 | Claude | **CI Path filter docs-only skip live** — `paths-ignore` trong on:push lookup `docs/**`/`**/*.md`/`.claude/skills/**`/`.gitignore`. Commit chỉ touch docs SKIP CI hoàn toàn (saving ~196s/commit, ~30% commit thuộc loại này). Verify `512880c` (docs-only) → Gitea NO trigger run #113. | `29eb5d9` · `a21790d` · `512880c` |
| 2026-04-29 | Claude | **CI manual checkout bypass github.com (fix #108/#109)** — Run #108/#109 fail TCP timeout 21s khi act_runner fetch `actions/checkout@v4` từ github.com. Replace `uses: actions/checkout@v4` + `actions/upload-artifact@v4` bằng manual `git init` + `git fetch` từ Gitea internal. Token `${{ github.token }}` auth tự sẵn per-job. Fetch by ref + depth=30. Run #110 pass 3m16s. | `14b7d18` · `26075c4` |
| 2026-04-29 | Claude | **Tests Phase 2 — Code generator format + sequence (SQLite in-memory)** — `tests/SolutionErp.Infrastructure.Tests/` xUnit + EF SQLite 10. `SqliteDbFixture` + `TestApplicationDbContext` subclass override `nvarchar(max) → TEXT` (SQLite không support `max`). 17 test: ContractCodeGenerator (format RG-001 5 type + Framework year scope vs Project scope + sequence per prefix + year boundary reset + persistence verify) + PurchaseEvaluationCodeGenerator (format A/B + 3-digit pad + independent A/B sequences + year boundary). CI gate +1 step. Total 71 test pass / 2.1s. | `df5988b` |
| 2026-04-29 | Claude | **Tests Phase 1 — Domain unit tests + CI gate** — `tests/SolutionErp.Domain.Tests/` xUnit 2.9 + FluentAssertions 7.2 (pin trước v8 commercial). 54 test pure function (no DB/IO): WorkflowPolicy (Standard 9-phase + SkipCcm 7-phase + Registry per ContractType + FromDefinition versioned + UserKindApprover) / PEPolicy (NccOnly 3-step + NccWithPlan 5-step + reject paths) / BudgetPolicy (Default 3-step + terminals + SLA spec). `.gitea/workflows/deploy.yml` thêm step "Run unit tests" trước build, fail → `exit $LASTEXITCODE` → no deploy. SolutionErp.slnx + folder `/tests/`. | `d3f9346` |
| 2026-04-29 | Claude | **PE Workflow designer admin UI + Ý kiến 4 phòng ban** — Migration 15 `AddPurchaseEvaluationDepartmentOpinions` (UNIQUE PEId+Kind, 1 row/phòng/phiếu). Domain `PurchaseEvaluationDepartmentOpinion` + enum `PeDepartmentKind` (PheDuyet/Ccm/MuaHang/SmPm). BE: `PeWorkflowAdminFeatures.cs` ~250 LOC mirror Contract pattern (GetOverview + Create version, deactivate cũ atomic) + `PeWorkflowsController` 2 endpoint reuse policy `Workflows.*`. `PeDepartmentOpinionFeatures.cs` Upsert (sign=true→set SignedAt+UserId, sign=false giữ chữ ký cũ) + Delete + 2 endpoint. FE: `PeWorkflowsPage.tsx` ~500 LOC + designer dialog (clone version + add/remove steps + +Role/+User approvers). Section "5. Ý kiến 4 phòng ban (sign-off)" 2x2 grid OpinionBox (read mode chữ ký vs edit textarea + 2 button Lưu/Lưu&Ký). | `5d94bb4` |
| 2026-04-29 | Claude | **PE Detail UI restructure theo spec form PHIẾU TRÌNH KÝ** — 4 section đánh số match form chính thức: "1. Thông tin gói thầu" (a/b chỉ Tên + Dự án) / "2. Chọn NCC/TP" (a NCC chọn / b Ngân sách / c Giá chào thầu auto-compute từ winner quotes / d Bản so sánh embed GeneralAttachments) / "3. NCC/TP tham gia" / "4. Hạng mục + Báo giá". FormRow helper (label 176px + value flex) thay cho dl grid 2-col cũ. | `7e36241` |
| 2026-04-29 | Claude | **PE/Contract → Budget integration + cột "So với ngân sách"** — BE: `BudgetSummaryDto` shared (PE & Contract DetailBundle), Create/Update PE+Contract commands + `BudgetId?` validate cùng Project + Phase=DaDuyet. `CreateContractFromEvaluation` carry forward pe.BudgetId → contract.BudgetId. FE: PE & Contract Create form + Select "Ngân sách" filter Phase=DaDuyet + Project match. PE InfoTab + Contract Edit display Budget link clickable. PE ItemsTab matrix + cột "NS link · Δ" — match per-row qua key `groupCode\|itemCode`, fetch /budgets/{id} riêng + footer aggregate (xanh dưới / đỏ vượt / xám khớp). | `61e5d4d` |
| 2026-04-29 | Claude | **Budget FE 3-panel pages cả 2 app** — `types/budget.ts` (BudgetPhase 5-state enum + DTO) + `BudgetsListPage` 3-panel `[340px_1fr_360px]` + filter Phase + Năm + alias `?phase=Pending` + readOnly mode menu Duyệt + `BudgetCreatePage` form Header + `BudgetDetailTabs` flat (Section Thông tin Header + Section Hạng mục table CRUD inline auto-compute ThanhTien=KL×ĐG) + `BudgetWorkflowPanel` Panel 3 timeline + dialog comment + Approvals/Changelog. Mirror fe-user. App.tsx 3 route + Layout resolver `Bg_*`. TS build pass cả 2 app. | `df12fb1` |


> **51 row Phase 0-7 (2026-04-21..28) đã archive →** [`changelog/recently-done-archive-2026-04.md`](changelog/recently-done-archive-2026-04.md)

Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1f](changelog/sessions/2026-04-21-1100-phase1-foundation.md) · [P1.2](changelog/sessions/2026-04-21-1130-phase1-cruds-permission.md) · [P2](changelog/sessions/2026-04-21-1200-phase2-form-engine.md) · [P3](changelog/sessions/2026-04-21-1330-phase3-workflow.md) · [P4](changelog/sessions/2026-04-21-1430-phase4-report.md) · [P5prep](changelog/sessions/2026-04-21-1530-phase5-prep.md) · [Tier 3](changelog/sessions/2026-04-22-0300-tier3-feature-complete.md) · [Skill gov](changelog/sessions/2026-04-23-0900-skill-governance.md) · [Toolkit+4-bảng+Roles VN](changelog/sessions/2026-04-23-1500-toolkit-data-roles.md) · [Roles+Demo+Pending](changelog/sessions/2026-04-23-2200-roles-demo-pending-cleanup.md) · [PE polish iter 2 + rebrand](changelog/sessions/2026-04-24-chot-session-3-pe-polish.md) · [Budget BE + 14 Solutions users](changelog/sessions/2026-04-28-chot-session-4-budget.md) · [Budget FE + PE/HD-Budget + PE WF Designer + Tests Phase 1-2](changelog/sessions/2026-04-29-chot-session-5-budget-fe-pe-tests.md) · [Drastic refactor flat workflow Mig 21](changelog/sessions/2026-05-08-0500-drastic-refactor-flat-workflow.md) · [PE V2 schema end-to-end Mig 22-24](changelog/sessions/2026-05-08-1100-pe-workflow-v2-end-to-end.md) · [**S18 PE V2 polish + Clone B + Mig 25 IsUserSelectable**](changelog/sessions/2026-05-08-1945-s18-pe-v2-polish-clone-b.md)

**Docs entry points:**

- [`rules.md`](rules.md) · [`architecture.md`](architecture.md) · [`HANDOFF.md`](HANDOFF.md)
- [`workflow-contract.md`](workflow-contract.md) · [`forms-spec.md`](forms-spec.md)
- [`database/database-guide.md`](database/database-guide.md) · [`database/schema-diagram.md`](database/schema-diagram.md)
- [`flows/`](flows/) (7 file) · [`guides/`](guides/) (4 file) · [`gotchas.md`](gotchas.md)
- [`changelog/migration-todos.md`](changelog/migration-todos.md) · [`changelog/sessions/`](changelog/sessions/) (17 file)
- [`.claude/skills/README.md`](../.claude/skills/README.md) — 6 skill (3 domain + 3 ops) · audit định kỳ 1/tháng (cron `solution-erp-skill-audit-monthly` next 2026-05-01)

## 🎯 Next up

### Hard blockers (chờ user / ops)

- [ ] **UAT 1 tuần 2-3 user thật** — hard requirement từ roadmap Phase 5
- [ ] **Email outbox** — MailKit + SMTP (BLOCKED chờ user cấp SMTP host/user/pass)
- [ ] **Rotate credentials** — SA, vrapp, JWT secret, runner token (đã post chat)
- [ ] **SQL backup daily** — Task Scheduler (script `scripts/backup-sql.ps1` đã có, chưa schedule)

### Optional polish (khi rảnh / UAT phát sinh)

- [ ] Roles CRUD — admin tạo custom role ngoài 12 hardcoded (schema sẵn, chỉ cần CQRS + FE)
- [ ] User-level approver targeting runtime — data model đã có (`WorkflowStepApprover.Kind=User`), chỉ cần wire User-kind vào `ContractWorkflowService.TransitionAsync` guard
- [ ] PermissionsPage: grant `Workflows.Read` cho non-admin role → menu Wf_* visible
- [ ] Warning notification khi còn 20% SLA (`SlaWarningSent` flag đã có, chỉ thiếu job emit)
- [ ] E2E test reject → quay về DangSoanThao (multi-role)
- [ ] Dependencies scan CI (`dotnet list package --vulnerable`, `npm audit`)

### Tier 3 ERP roadmap ✓ (close)

- [x] Attachment upload BE + FE ✓
- [x] SignalR real-time push ✓
- [x] Form template builder CRUD + DynamicForm ✓
- [x] PDF export qua LibreOffice headless ✓
- [x] .doc/.xls → .docx/.xlsx auto-conversion ✓
- [x] Dynamic workflow policy per ContractType ✓
- [x] **Versioned workflow (WorkflowDefinition pinned per Contract)** ✓
- [x] **Admin workflow designer UI (per-type, per-step approvers)** ✓
- [x] **Nested sidebar menu per ContractType (fe-user) + menu split admin/user** ✓
- [x] **PermissionsPage 3-panel layout** ✓
- [ ] Email outbox for Notification (blocked — SMTP config)

## 📊 Thông số cumulative

| | P0 | P1f | P1.2 | P2 | P3 | P4 | P5prep | Tier3 | +Toolkit | +RolesPg+Demo | +PE module | +PE polish | +Budget+30 users | **+Session 5** |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | ~3300 | ~4800 | ~7800 | ~8800 | ~11100 | ~11400 | ~11750 | **~13050** (+1300 PE WF Designer + Opinion + Budget integration) |
| DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | 24 | 36 | 36 | 46 | 47 | 51 | **52** (+1 PEDepartmentOpinions) |
| API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | 35 | ~50 | ~80 | ~93 | ~110 | ~113 | ~124 | **~128** (+2 PE WF + 2 Opinion) |
| Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | 8 | 11 | 11 | 12 | 13 | 14 | **15** (`AddPEDepartmentOpinions`) |
| FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | ~20 | ~22 | ~23 | ~26 | ~26 | ~26 | **~31** (+5 Budget × 2 app + PeWorkflowsPage) |
| FE components | — | — | — | — | — | — | — | many | many+ | +EditRowDialog | +PE 5-tab | +Compare section | — | **+Budget tabs/panel + PE OpinionBox + PE 4-section restructure** |
| Scripts PS | 0 | 0 | 0 | 1 | 1 | 1 | 3 | 4 | 4 | 5 | 5 | 6 | 6 | 6 |
| CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | **1+test gate+path filter+manual checkout** |
| **Tests** | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | **77** (54 Domain + 17 Infra + 6 PE WF Application) |
| Docs | 10 | 13 | 14 | 24 | 26 | 30 | 35 | ~40 | ~42 | ~44 | ~46 | ~48 | ~50 | **~52** (+session log + Test plan) |
| Demo data | 0 | 0 | empty | 0 | 0 | 0 | 0 | 0 | 5+3 | 15+8+7+13+4 | +PE 4 phiếu | +rebrand email | 30 user | 30 user |
| Commits | 1 | 2 | 3 | 5 | 6 | 7 | 8 | ~25 | ~47 | ~52 | ~63 | ~70 | ~75 | **~82** (+6 session 5) |

## 🚨 Blockers / risks

- ⚠️ **Email SMTP chưa có** — blocker cho notification outbound
- ⚠️ **UAT real user chưa chạy** — risk phát sinh bug edge-case quan trọng
- ⚠️ **Credentials leaked trong chat** — cần rotate trước go-live thật
- ⚠️ **SQL backup không auto** — risk data loss nếu VPS crash
- ⚠️ **Permission `Workflows.Read` cho non-admin** — cần grant để họ thấy menu Wf_* (hiện chỉ admin thấy)
- ⚠️ **User-kind approver chưa enable runtime** — designer cho chọn User nhưng guard fall back DeptManager

## Credentials + URLs

```
admin@solutionerp.local / Admin@123456
```

- API prod: https://api.solutions.com.vn — Health `/health/live` + `/health/ready`
- API dev: http://localhost:5443 — Swagger `/swagger`
- Admin FE prod: https://admin.solutions.com.vn · dev `http://localhost:8082`
- User FE prod: https://eoffice.solutions.com.vn · dev `http://localhost:8080`
- SQL prod: `.\SQLEXPRESS` / `SolutionErp` / `vrapp`
- SQL dev: `(localdb)\MSSQLLocalDB` / `SolutionErp_Dev`
