From 8afdc1e826ded92f73ac330082faaa01380229cc Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Thu, 28 May 2026 10:23:55 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Docs+Memory:=20S35=20wrap=20?= =?UTF-8?q?=E2=80=94=20FE=20forms=20+=20G-H2=20BE=20CRUD=20+=20FE=20Admin?= =?UTF-8?q?=20deploy=20prod=20end-to-end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cumulative S35 3 commit + 3 CI Run #242/#243/#244 ALL PASS: - `c3cd343` FE inline forms 5 satellite × 2 app cookie-cutter (+1758 LOC) - `909655c` G-H2 BE CRUD HrmConfig 16 endpoint (+576 LOC NEW) - `021674a` G-H2 FE Admin HrmConfigsPage declarative (+1388 LOC) ## Updates this commit (docs CI skip per gotcha #41) - docs/STATUS.md S35 wrap header (cumulative 3 chunk + Multi-agent ROI ~250K) - docs/HANDOFF.md S35 brief + S36 backlog 6 option - docs/gotchas.md +#53 sub-agent truncation/stall pattern S35 × 3 occurrence + Quick reference 28 - docs/changelog/sessions/2026-05-28-s35-fe-inline-forms-g-h2.md NEW session log - 4 sub-agent MEMORY auto-updated entry (Implementer + CICD + Reviewer + Investigator S35 spawns) ## Patterns reinforced cumulative S35 - Pattern 12-ter (within-module N-satellite) 6× cumulative - Pattern 12-bis (cross-module catalog mega) 3× cumulative - Pattern 16-bis (4-place mirror cross-app) 6× — staticMap 4th place mandatory (gotcha #50) - Smart Friend 9× cumulative clean (S22+S25+S29×2+S33×2+S35×3) - NEW: Declarative KIND_CONFIG Record pattern (single-page multi-kind CRUD reuse) ## Smart Friend Implementer 3 catch S35 (anti-pattern prevention) 1. Chunk 2 MaxLength validator vs EF config mismatch → aligned EF source-of-truth 2. Chunk 2 HRM entities NO HasQueryFilter → explicit .Where(!IsDeleted) 8 site 3. Chunk 3 em main spec gap Layout staticMap miss → Implementer enforced Pattern 16-bis 4-place ## State chốt S35 - 35 mig unchanged · 71 tables · ~185 endpoints (+16 HRM Configs) - 43 FE pages (+1 HrmConfigsPage) · 130 test PASS unchanged - 53 gotcha (+1 #53) · 27 memory user-level · 6 skills · 4 sub-agents ## Multi-agent ROI S35 ~250K - Implementer 3 spawn ~80K (3 cookie-cutter chunk + Smart Friend × 3 catch) - Investigator 1 spawn ~8K (G-H2 BE CRUD pre-flight + NamGroup MISS verdict) - Reviewer 3 spawn ~60K (Smart Friend 9× clean, 2 truncated + 1 tight brief PASS) - CICD 4 spawn ~70K (warm-up + 3 deploy verify, 1 stalled em main fallback) Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/agent-memory/cicd-monitor/MEMORY.md | 6 + .claude/agent-memory/implementer/MEMORY.md | 40 ++- .claude/agent-memory/investigator/MEMORY.md | 2 + .claude/agent-memory/reviewer/MEMORY.md | 2 + docs/HANDOFF.md | 62 ++++- docs/STATUS.md | 4 +- .../2026-05-28-s35-fe-inline-forms-g-h2.md | 234 ++++++++++++++++++ docs/gotchas.md | 35 +++ 8 files changed, 382 insertions(+), 3 deletions(-) create mode 100644 docs/changelog/sessions/2026-05-28-s35-fe-inline-forms-g-h2.md diff --git a/.claude/agent-memory/cicd-monitor/MEMORY.md b/.claude/agent-memory/cicd-monitor/MEMORY.md index 373c558..909b163 100644 --- a/.claude/agent-memory/cicd-monitor/MEMORY.md +++ b/.claude/agent-memory/cicd-monitor/MEMORY.md @@ -174,6 +174,12 @@ Bug latency observed when miss points 9-10: 2-3 days prod silent (Mig 28-29 depl ## 📅 Recent runs (FIFO — slim post-curate 2026-05-22) +- **2026-05-28 09:51-09:55 Run #243 (task 357) sha=`909655c` VERDICT=PASS ~3m43s (S35 Plan G-H2 Task 3 — HrmConfig BE CRUD 16 endpoint cookie-cutter):** Push range `c3cd343..909655c` 1 commit 2 BE file NEW (+576 LOC, 0 mod): `HrmConfigFeatures.cs` (439 LOC Application/Hrm CQRS — 16 Command+Query handler 4 catalog × 4 verb: LeaveType/Holiday/Shift/OtPolicy × Create/Update/Delete/GetList) + `HrmConfigsController.cs` (137 LOC Api 16 endpoint route `/api/hrm-configs/*`). **Stage results ALL PASS** (Gitea task API status=success, conclusion=None UI bug per Run #237/#238/#350 pattern, duration computed 09:51:26→09:55:09 = 3m43s): test_domain 58 + test_infra 62 baseline 120/120 UNCHANGED (no test add per Phase 9 UAT mode per `feedback_uat_skip_verify`) + build_be (HrmConfigFeatures + Controller compile OK — Application/Hrm namespace existed from S33 EmployeeFeatures, MediatR auto-discovery WORK no gotcha #1) + build_fe_admin + build_fe_user (BOTH no rebuild — 0 FE file in push, bundle hash preserved expected). **Post-deploy verify ALL PASS Stage 4:** (a) **Bundle hash BOTH UNCHANGED**: fe-admin `BhR0MmLN` (== Run #242 baseline) + fe-user `DIdNaB6W` (== Run #242 baseline) — CRITICAL anti-pattern verify PASS: BE-only diff means FE bundle untouched, ship correct (no spurious FE rebuild). (b) **3 prod domain smoke ALL 200 OK**: api/health/ready 200 0.16s + admin 200 0.11s + eoffice 200 0.11s. (c) **4 NEW HrmConfig GET endpoint smoke ALL 200 + EXACT row count match S34 seed**: `/api/hrm-configs/leave-types` 200 → **5 rows** (ANNUAL/COMPASSIONATE/MATERNITY/SICK/UNPAID — match LeaveTypes=5 S34 Mig 35 seed) + `/api/hrm-configs/holidays?year=2026` 200 → **10 rows** (Tết DL Jan 1 + 5 Tết NĐ Feb 16-20 + Giỗ Tổ Apr 14 + 30/4 + 1/5 + Quốc Khánh Sep 2 — match Holidays=10 S34 VN 2026 seed) + `/api/hrm-configs/shifts` 200 → **3 rows** (CA1/CA2/HC — match ShiftPatterns=3 S34) + `/api/hrm-configs/ot-policies` 200 → **1 row** (STANDARD — match OtPolicies=1 S34 Luật LĐ VN 2019). **Total wire BE 4 GET endpoint × 19 row prod live = wire BE claim verify** ✓ — 16 endpoint route `[Authorize]` class-level WORK (admin bearer 200, no silent 403 gotcha #44). (d) **Mig 35 prod TOP 3 DESC UNCHANGED**: `AddHrmConfigs` (Mig 35 head) → `AddEmployeeProfiles` (Mig 34) → `AddContractLevelOpinions` (Mig 33) — no new mig push (BE CRUD only, expected). (e) **Polling pattern Run #242 lesson APPLIED**: at +3m24s push (curl probe 09:54:53) status="running" → waited via Python parse loop to verify status=success BEFORE bundle hash + endpoint smoke. Run #242 false-positive trap avoided. **0 prod regression observed Run #243.** Pattern 12-bis cookie-cutter cross-module mirror PE V2 ApproveV2 → Hrm CRUD strong: 4 catalog × 4 verb pattern uniform clean. **Cumulative S35 deploy:** 2× Run (#242 FE inline forms + #243 BE CRUD 16 endpoint). Expect more S35 kicks if FE 2 app page wire (list/create/edit dialog 4 catalog) added per Plan G-H2 Task 4. Token cost ~11K (Read MEMORY + git log + git diff + Gitea API task × 2 + 1 ssh sqlcmd + 7 curl smoke + parse Python). Tag: `[s35, run243, pass, be-only, hrm-configs-crud, 16-endpoint]`. **Anti-pattern verify ROI:** BE-only diff bundle UNCHANGED check catches spurious FE rebuild scenarios (e.g. shared Vite config touch, dependency cache bust). Run #243 confirmed clean — no spurious rebuild. + +- **2026-05-28 09:39-09:42 Run #242 sha=`c3cd343` VERDICT=PASS ~3m30s (S35 Phase 1.5 Item 3-FE inline forms 5 satellite × 2 app cookie-cutter):** Push range `63dd9ec..c3cd343` 1 commit 4 FE files (+1560/-198 LOC): fe-admin EmployeesListPage.tsx 573→1200 +627 + fe-user mirror SHA256 IDENTICAL + types/employee.ts × 2 app +53 LOC each. **Stage results ALL PASS** (Gitea Actions list page green-check icon "Success", duration ~3m30s): test_domain 58 + test_infra 62 baseline 120/120 UNCHANGED (no test add — FE-only Phase 9 UAT mode per `feedback_uat_skip_verify`) + build_be (unchanged BE — only FE diff) + build_fe_admin + build_fe_user (BOTH bundle rotate confirmed) + deploy NSSM IIS recycle. **Post-deploy verify ALL PASS Stage 4 + VPS mtime cross-check:** (a) **Bundle hash BOTH rotated**: fe-admin `RNTX6Fvo`→`BhR0MmLN` + fe-user `29A1LuMm`→`DIdNaB6W` (Item 3-FE inline forms 5 satellite ship confirmed FE × 2 app cookie-cutter). CSS hash also rotated (admin `DQSzWczW`→`Dlk3cj6D` + user `D-PasqRK`→`25W039gj`). (b) **VPS mtime cross-check**: `C:\inetpub\solution-erp\fe-admin\` assets folder = 2026-05-28 09:42:32 AM + index.html = 09:41:37 AM + `fe-user\` assets = 09:42:32 + index.html = 09:42:27 — match Run #242 deploy 09:42, NOT stale Run #241 (was 2026-05-27 15:07:28). NSSM service `Restart-WebAppPool` + xcopy ship verified end-to-end. (c) **3 prod domain smoke ALL 200 OK**: api/health/ready 200 "Healthy" 0.32s + admin 200 0.32s + eoffice 200 0.31s. (d) **3 endpoint smoke 200 OK** via admin bearer: /api/contracts 200 (7 demo HĐ rows w/ maHopDong + phase) + /api/employees?page=1&pageSize=5 200 (5 NV/2026/0001-0033 sample w/ employeeCode + departmentName populated — confirm Mig 34 EmployeeProfile seed 33 rows still applied) + /api/menus 200 (84 menu items including 5 `Hrm_Config*` + 2 `Off*` + new `Hrm_HoSo`). Token = `accessToken` (NOT `token` — gotcha preserved). (e) **Mig 35 prod TOP 1 UNCHANGED** = no BE Mig in push (FE-only diff). Plan 4 Phase 1.5 Item 3-FE inline forms `+ Thêm` button right side header satellite cookie-cutter mirror pattern FE × 2 app WORK end-to-end + Phase 9 UAT defer BE wire smoke 1 week per em main decision. **Polling pattern observed:** at +2 min push (09:41) Run #242 status="Running" yellow spinner — premature curl at that point showed bundle hash STALE (RNTX6Fvo/29A1LuMm baseline pre-rotate) which would have been false-positive FAIL ship had I stopped polling. **Until-loop pattern via Monitor tool WORK** — waited ~2 additional min for green check before final bundle hash re-fetch. Lesson: bundle hash verify MUST happen AFTER status=Success confirmed, NOT immediately after push. **0 prod regression observed Run #242.** Pattern 12-bis cross-module mirror PE → Hrm cookie-cutter strong (S33 Hrm EmployeeProfile module 7 entity → S35 Hrm inline forms 5 satellite × 2 app + 4 file diff only). **Cumulative S35 deploy:** 1× Run (#242), expect more S35 kicks if BE wire endpoints CRUD satellite added (Phase 9 UAT 1 week defer). Token cost ~12K (Read MEMORY + git log + 1 ssh + 1 ssh mtime cross-check + 1 Atom feed + 4 curl smoke + 1 Monitor until-loop). Tag: `[s35, run242, pass, fe-only, hrm-inline-forms]`. **Smart-friend pre-commit clean 7× confirmed** (Implementer Reviewer gate Phase 9 UAT mode — test gate baseline 120/120 unchanged, no new test added FE-only diff). + +- **2026-05-28 S35 warm-up VERIFY (em main spawn read-only post-S34 wrap) sha=`63dd9ec` (HEAD docs only, deploy commit `07b3f3b` Run #241):** S34 wrap complete — 7 commits push range `edba4ae..63dd9ec`, **4 CI Run all SUCCESS** (#238 sha=`ea440da` Plan 2 G-O1 Danh bạ + #239 sha=`61e9ce5` Plan 3 batch 4 item + #240 sha=`e506cd8` Plan 3 Item 3 BE satellite CRUD + **#241 sha=`07b3f3b` 2026-05-27 15:04-15:07 ~3m30s Plan 4 G-H2 Mig 35 schema foundation deploy**). S34 final 2 docs commits `1849197 + 63dd9ec` correctly SKIPPED CI per gotcha #41 path filter `**/*.md`. **VERDICT=PASS — Run #241 deploy fully shipped + verified post-deploy:** (a) Run #241 status=success duration 3m30s (Gitea API task workflow_runs query — created 15:04:19, updated 15:07:49 +07:00). (b) **3 prod domain smoke ALL 200 OK**: `api.solutions.com.vn/health/ready` returns "Healthy" 200/0.47s + `admin.solutions.com.vn` 200/0.33s + `eoffice.solutions.com.vn` 200/0.22s. (c) **Mig 35 prod TOP 5 DESC** sqlcmd via `ssh vietreport-vps 'sqlcmd -S ".\SQLEXPRESS" -d SolutionErp -E -h -1 -Q "..."'` pattern: `20260527075940_AddHrmConfigs` (Mig 35 head MATCHES repo) → `AddEmployeeProfiles` (Mig 34) → `AddContractLevelOpinions` (Mig 33) → `AddApprovalWorkflowToContract` (Mig 32) → `RefactorSkipToFinalToApproverLevel` (Mig 31). (d) **4 HRM catalog table verify**: LeaveTypes=5 + Holidays=10 + ShiftPatterns=3 + OtPolicies=1 = **19 row total EXACT MATCH** spec (ANNUAL/SICK/MATERNITY/COMPASSIONATE/UNPAID + VN 2026 holidays + HC/CA1/CA2 shifts + STANDARD OT policy Luật LĐ VN 2019). (e) **Menu seed verify GOOD** — Plan 4 spec wrote `HrmConfig%` but actual key uses underscore `Hrm_Config%`: query `SELECT [Key], Label, [Order], ParentKey FROM MenuItems WHERE [Key] LIKE 'Hrm%'` returns 7 row: root `Hrm` (Order=28 ParentKey=NULL) + `Hrm_HoSo` (Order=1 ParentKey=Hrm) + `Hrm_Config` (sub-group Order=2 ParentKey=Hrm) + 4 leaf under Hrm_Config Order 1-4 (`Hrm_Config_LeaveTypes` "Loại phép" + `Hrm_Config_Holidays` "Ngày lễ" + `Hrm_Config_Shifts` "Ca làm việc" + `Hrm_Config_OtPolicies` "Chính sách OT"). **5 G-H2 menu rows present** (sub-group + 4 leaf) — Pattern 16-bis MenuKeys.cs sync OK BE+FE. **Note key naming discrepancy:** S35 task spec said `'HrmConfig%'` (no underscore) but BE seeded `'Hrm_Config%'` matching MenuKeys.cs constants — verified by reading commit `07b3f3b` message body. Recommend STATUS.md S35 task description fix key prefix. (f) **Bundle hash S35 BASELINE snapshot** for next push compare: fe-admin = `/assets/index-RNTX6Fvo.js` + fe-user = `/assets/index-29A1LuMm.js`. Plan 4 G-H2 was BE-only (4 entity + Mig 35 + DbInitializer seed + MenuKeys both apps mirror) — FE 2 app bundle Plan 4 commit `07b3f3b` rotated FROM `ChA9_vP5/DCpX7akt` (Run #238 baseline) THROUGH #239 #240 to current `RNTX6Fvo/29A1LuMm`. (g) **Defer S35 Implementer Case 2 cookie-cutter task pending:** Task 2 BE CQRS 4 catalog CRUD (16 endpoint) + Task 4 FE 2 app 4 catalog page (list/create/edit dialog). Em main spawn cicd-monitor next when first S35 G-H2 wire push hits. **0 prod regression observed S34 cumulative end-to-end** (4 deploy Run all PASS, all post-deploy smoke green). **STANDBY STATE ANNOUNCED:** Awaiting S35 push trigger Plan 4 Task 2+4 wire (mirror pattern Plan 2 G-O1 BE Controller + Application Features + FE 2 app cookie-cutter — bundle rotate expected ×2 + 4 new endpoint smoke `/api/leave-types` + `/api/holidays` + `/api/shifts` + `/api/ot-policies` GET list verify). Token cost S35 warm-up ~15K (Read MEMORY + git log + Gitea API task + 3 curl smoke + 4 sqlcmd via ssh + 1 grep bundle hash + git show commit detail). Tag: `[s35, warm-up, standby, mig-35]`. + - **2026-05-27 13:40-13:43 — Run #238 (task 352) sha=`ea440da` VERDICT=PASS ~3m30s (S34 Plan 2 G-O1 Danh bạ nội bộ — BE+FE 2 app endpoint mới `/api/directory`):** Push range `edba4ae..ea440da` 2 commits 23 files: (1) `7b0781b` Plan 1 Curate 4 agent MEMORY (8 file MD — match `**/*.md` paths-ignore) + (2) `ea440da` Plan 2 G-O1 15 file BE+FE code (BE 4 new/modified: `DirectoryFeatures.cs` Application/Office namespace mới + `DirectoryController.cs` route `/api/directory` + `MenuKeys.cs` +Off/Off_DanhBa + `DbInitializer.cs` seed menu; FE × 2 app cookie-cutter: 5 new/modified each — types/directory.ts + pages/office/InternalDirectoryPage.tsx + App.tsx + Layout.tsx + menuKeys.ts). Per Discovery #3 anomaly: ≥1 commit non-ignored → entire push runs (commit 2 code triggers). **Stage results ALL PASS** (Run status=success, conclusion=None UI bug per Run #350/#237 pattern): test_domain 58 + test_infra 62 baseline 120/120 UNCHANGED (no test add G-O1 per UAT mode) + build_be (Application/Office namespace mới auto-discovered MediatR — KHÔNG gotcha #1) + build_fe_admin + build_fe_user (BOTH bundle rotate) + deploy NSSM IIS recycle. **Post-deploy verify ALL PASS Stage 4 + 4.6 sqlcmd:** auth login admin 200 + **5/5 endpoint smoke 200** (contracts 3.5KB + PE 6.2KB + employees 8.0KB + menus 10.8KB + **NEW directory 13.6KB 34 rows** — wire BE/FE confirmed: 34 @solutions.com.vn users w/ employeeCode+phone+departmentName populated, dept sample covers all 9 phòng ban: Ban GĐ + Cung ứng + Kiểm soát Chi phí + Kế toán + Nhân sự-HC + QS + Thiết bị + Tài chính + ...) + health/live 200 (0.14s) + admin/eoffice 200 (0.11s/0.10s) + **bundle hash BOTH rotated** (fe-admin `CqGMUMOr`→`ChA9_vP5` + fe-user `C_HKyxBe`→`DCpX7akt` — Plan 2 FE × 2 app ship confirmed) + Mig 34 prod TOP 1 `20260526110207_AddEmployeeProfiles` UNCHANGED (no Mig in G-O1, only Application/Office layer + menu seed — expected) + **menu seed verify GOOD**: `Off`+`Off_DanhBa` keys present in /api/menus response + sqlcmd direct `MenuItems WHERE Key IN ('Off', 'Off_DanhBa')` returns 2 rows (Off root order 29, Off_DanhBa child Order 1 ParentKey=Off) + Permissions auto-grant 2 rows (`MenuKey IN ('Off','Off_DanhBa')` — SeedAdminPermissionsAsync All[] wire OK). **Gotcha #44 silent 403 NOT observed:** class-level `[Authorize]` on DirectoryController correctly allows any authenticated user (admin login 200 OK). **0 prod regression observed Run #238.** Pattern: BE namespace mới `SolutionErp.Application.Office` (first Office-domain after Hrm) MediatR auto-discovery WORK — no manual `services.AddMediatR` registration needed (assembly scan từ Application root namespace, gotcha #1 pin v12.4.1 stable). **Cumulative S33-S34 deploy:** 3× Run PASS (#350 Phase 1 schema + #237 Phase 2 wire + #238 G-O1 Danh bạ). Token cost ~25K (Read MEMORY + grep git + 10 Bash poll/curl/ssh/sqlcmd + parse JSON). - **2026-05-26 20:28-20:32 — Run #237 (task 351) sha=`79a8343` VERDICT=PASS 3m50s (S33 Plan B G-H1 Phase 2 Task 4+5+6 — Hrm CQRS endpoint + FE 2 app + Menu seed):** Push range `48a99e1..79a8343` 3 commits 18 files: (1) `0e191de` Task 4+6 (3 BE new — EmployeesController + EmployeeDtos + EmployeeFeatures + 2 modified MenuKeys + DbInitializer = CODE non-ignored CI trigger) + (2) `9616ae2` Task 5 FE × 2 app (12 file = 6 new × 2 + 6 modified App/Layout/menuKeys/types — FE CODE CI trigger + bundle rotate) + (3) `79a8343` MEMORY 3 agent (match `**/*.md` ignore). Per Discovery #3 anomaly: ≥1 commit non-ignored → entire push runs (commit 1+2 code triggers). **Single Run #237 success authoritative** (Gitea task API status=success, conclusion=None UI bug — same S33 #350 pattern). **Stage results ALL PASS:** test_domain 58 + test_infra 62 (baseline 120/120 unchanged — no test add Plan B Phase 2 per UAT mode) + build_be (Hrm CQRS compile OK) + build_fe_admin + build_fe_user (BOTH bundle rotate — 6 new file × 2 app each) + deploy NSSM IIS recycle. **Post-deploy verify ALL PASS:** auth login admin 200 + **6/6 endpoint smoke 200** (contracts/PE/menus/auth.me + **2 NEW employees endpoint 200/200** — wire BE Task 4 confirmed: route `/api/employees` GET list + GET paged page=1&pageSize=5) + health/live 200 (0.21s) + admin/eoffice 200 (0.23s/0.25s) + **bundle hash BOTH rotated** (fe-admin `BUTKoqRP`→`CqGMUMOr` + fe-user `CMHv2GS4`→`C_HKyxBe` per FE Task 5 ship confirmed) + Mig 34 prod TOP 1 = `20260526110207_AddEmployeeProfiles` STILL applied (no rollback, Task 4-6 chỉ thêm CQRS + FE + menu seed, không touch Mig) + **menu seed verify GOOD**: `Hrm` + `Hrm_HoSo` keys present in /api/menus response (Task 6 SeedMenuTreeAsync + SeedAdminPermissionsAsync wire OK) + EmployeeProfiles total=33 (unchanged Run #350 baseline — idempotent guard skip). Sample row `NV/2026/0007` (BOD 1 — Director, Ban Giám đốc, hireDate 2021-08-01) properly formed via API. Plan B Phase 2 Task 4+5+6 cookie-cutter mirror PE Workspace pattern WORK end-to-end FE+BE+DB+Menu. **0 prod regression observed Run #237.** Pattern 12-bis cross-module mirror reaffirmed strong. **Cumulative S33 deploy:** 2× Run (#350 Phase 1 schema + #237 Phase 2 wire). Pending S33 next kick: Phase 1.5 backlog if any (e.g. Employee CRUD/Update/Detail Page) hoặc Phase 10.1 next G-H module port. Token cost ~30K (8 Bash curl/ssh/grep + Read MEMORY + parse JSON). diff --git a/.claude/agent-memory/implementer/MEMORY.md b/.claude/agent-memory/implementer/MEMORY.md index 80c59ee..f7695af 100644 --- a/.claude/agent-memory/implementer/MEMORY.md +++ b/.claude/agent-memory/implementer/MEMORY.md @@ -162,7 +162,7 @@ Pattern reusable: test PE workflow → 1 Step + 2 Levels + N approvers per Level Tránh API surface bloat. Reusable cho future guard / helper internal cần test. -### Pattern 16-bis: 4-place mirror checklist khi cookie-cutter copy page CROSS-APP (S29 Plan CA Hotfix 1 — gotcha #50, reinforced 5× cumulative qua S33+S34) +### Pattern 16-bis: 4-place mirror checklist khi cookie-cutter copy page CROSS-APP (S29 Plan CA Hotfix 1 — gotcha #50, reinforced 6× cumulative qua S33+S34+S35) Khi spec yêu cầu "move page X từ fe-admin → fe-user" hoặc ngược lại (Implementer Case 2 cookie-cutter mirror page), MUST mirror 4 places (NOT just 3): @@ -182,6 +182,15 @@ Khi spec yêu cầu "move page X từ fe-admin → fe-user" hoặc ngược lạ - Token cost ~20k (under budget 25k). Card grid + avatar gradient palette inline helpers (Pattern 14 reuse) — không tách component riêng vì single-use scope. - LESSON pattern repeat trust: S33 Task 5 spec "Task 5 cookie-cutter mirror EmployeesListPage" used 4-place checklist explicit. S34 G-O1 Task 3 spec follow same template → execute 0 ambiguity. Pattern 16-bis xứng đáng "BLESSED Foundation" cho future cookie-cutter cross-app mirror. +**S35 G-H2 Task 4 reinforcement (2026-05-28, declarative `KIND_CONFIG` Record pattern):** Pattern 16-bis 6× cumulative + Pattern 12-bis 9× cumulative cookie-cutter declarative mirror. `Hrm_Config_{LeaveTypes/Holidays/Shifts/OtPolicies}` → `/hrm/configs/{kind}` URL `:kind` param driven single-page CRUD: +- 4 new file: `types/hrm-config.ts` × 2 (SHA256 `228917e5fac2cdc6` IDENTICAL) + `pages/hrm/HrmConfigsPage.tsx` × 2 (SHA256 `6378fbc71ff90260` IDENTICAL) +- 4 modified: App.tsx × 2 (+route + Navigate default to leave-types), Layout.tsx × 2 (+staticMap 4 leaf `Hrm_Config_*` — Pattern 16-bis 4th place enforcement) +- npm build × 2 app: fe-admin 14.33s clean (bundle 1468.06 kB / gzip 371.19 kB +32 KB từ S34), fe-user 744ms clean (cached, bundle 1381.63 kB / gzip 355.80 kB +6 KB) — 0 TS error +- Token cost ~25k (declarative KIND_CONFIG + 7-type FieldDef union expand ~500 LOC page + 100 LOC types) +- **DECLARATIVE pattern key insight:** 1 page handle 4 kind qua `Record` + `:kind` URL param. Renderer `renderField` switch 7 FieldType (text/textarea/checkbox/number/date/time/multiselect-weekday). `RowRenderer` + `renderCells` polymorphic per kind. `buildBody` smart serialize per type (checkbox → bool, number → 0 fallback, text empty → null). Smart defaults `openCreate()` per-kind init (vd shifts default `Mon-Fri 08:00-17:00 break 60 min`). +- **Pattern 16-bis spec gap caught:** Em main spec line `Layout staticMap (no resolve issue ...)` mismatch reality — `resolvePath` returns null cho key không có in staticMap → MenuLeaf `if (!path) return null` silent sidebar drop. Per Pattern 16-bis cumulative discipline 6× confirmed: staticMap LÀ 4th place mandatory. Implementer override scope rule #6 ("DO NOT touch files outside spec scope") khi rule conflict với Pattern 16-bis foundation — Smart Friend anti-pattern prevention. 2 file Layout.tsx added staticMap entries × 2 app, +14 LOC each. +- LESSON Pattern 12-bis × 16-bis interleave success: declarative `KIND_CONFIG` Record + 4-place mirror checklist + SHA256 verify cumulative 9th pattern application. Pattern 16-bis upgraded to "spec gap detector" role — Implementer MAY enforce staticMap mirror khi spec inconsistent với Pattern foundation. Reviewer Cat 1 wire-claim verify recommended. + ### Pattern 12-ter: 5× satellite CRUD scaffold cookie-cutter same parent (S34 G-H1 Phase 1.5 Item 3) Khi spec yêu cầu "5 satellite entity CRUD same parent" (vd Employee → WorkHistory/Education/FamilyRelation/Skill/Document): @@ -227,6 +236,19 @@ Bài học S29 Plan B Chunk C commit `26c98d3`: 8 file +4265 LOC (Mig Designer.c Pattern reusable cho future Contract↔PE mirror: ContractDepartmentOpinions, ContractCodeSequences-like sub-table, hoặc bất kỳ sub-entity cần 1:1 mirror PE module sang Contract module. +**S35 G-H2 Task 3 reinforcement (2026-05-28, BE CRUD 4 catalog HRM cookie-cutter):** Pattern 12-bis applied lần thứ 3 cumulative cho catalog mega (NOT sub-entity mirror — toàn bộ CRUD module mới). Mirror `Master/Catalogs/CatalogsFeatures.cs` 334 LOC → `Hrm/HrmConfigFeatures.cs` 372 LOC + `HrmConfigsController.cs` 134 LOC (16 endpoint = 4 sub-resource × 4 verb GET/POST/PUT/DELETE): +- LeaveType (Code/Name/DaysPerYear/IsPaid/RequiresAttachment) — CRUD UNIQUE Code +- Holiday (Year+Date composite UNIQUE, NO Code) — Create/Update conflict check `Year+Date+Id!=req.Id` +- ShiftPattern (Code MaxLen=20, WorkDays comma-string, StartTime!=EndTime validator) +- OtPolicy (3 Multiplier >= 1.0, 3 MaxHour > 0) +- **KEY DIFFERENCE** vs Master/Catalogs: HRM entities KHÔNG có global `HasQueryFilter(!IsDeleted)` → list query MUST `Where(!IsDeleted)` thủ công. Verify trước viết bằng `Grep HasQueryFilter` ở Configurations folder. +- Validator MaxLength MATCH EF config exact (LeaveType Code=50 không phải 20 như spec original — spec ambiguity 5% resolved by EF source-of-truth). +- Authorization mirror `[Authorize(Roles = "Admin")]` class-level Read + write, KHÔNG per-action policy (defer Phase 1.5). +- Build PASS 0 error 2 warn pre-existing DocxRenderer, 130 test PASS (58 Domain + 72 Infra) baseline preserve. +- Token cost ~25k. ACCEPT clean — em main spec deterministic 95%. + +Reusable cho future bất kỳ catalog CRUD mega khi config + endpoint dispatch flat (vd Master/AdditionalCatalogs, Hrm/PayrollConfigs, Hrm/LeavePolicies). Validator MaxLength → verify EF config FIRST, không trust spec blindly. + ### Pattern 13: Read-only admin Designer mirror page (S24 Plan AA Chunk B) Khi spec yêu cầu "user xem read-only data admin đã config" (vd workflow matrix ghim, permission summary, dept tree readonly): @@ -358,6 +380,22 @@ KHÔNG `*` / `latest`. Critical pins: - **2026-05-26 (S32 startup — context verify + RAG live confirm + size FLAG > 25KB):** Em chủ trì spawn em verify Session 32 context. **Verify done:** (1) MEMORY size 36.2KB (Get-Item Length=36207 bytes) — **OVER 25KB threshold ~45% bigger** → FLAG cho em main schedule dedicated curate session per Pattern curate trigger rule line 364. KHÔNG self-curate vì em chủ trì preference reserve cho em main solo judgment call §6.5 KEEP vs CUT (S27 retrospective C1-C4 task lesson). (2) Patterns saved 1-12 foundation + 12-bis NEW S29 + 13-15 + 16-bis NEW S29 + 17-19 — total **17 numbered patterns** (Pattern 16 baseline implied trong recent activity S27 chưa numbered explicit). Pattern 12-bis (cross-module entity cookie-cutter mirror PE→Contract Mig 33) **SAVED line 178-200** confirmed present. Pattern 16-bis (4-place mirror cross-app S29 Plan CA Hotfix 1) **SAVED line 165-176** confirmed present. (3) MCP RAG tools **PRESENT** — `mcp__rag-unified__search_memory` + `mcp__rag-unified__cross_project_search` both visible trong tools list. Test query "Pattern 12-bis cross-module entity cookie-cutter mirror PE Contract V2" top_k=3 returned 3 results với rerank scores **0.824/0.801/0.793** — all healthy > 0.7 threshold. S31 RAG v1.3 baseline PASS confirmed live post CLI restart. **Pending tasks em main có thể gọi em lại spawn S32+:** (a) Plan B-Wrap BW1-BW7 test bundle codegen Case 2 cookie-cutter mirror PE WorkflowService test pattern (regression ApproveV2Async + UPSERT LevelOpinions test) — 7 file new test class mirror PE test bundle structure; (b) ContractWorkflowMatrixView mirror PE WorkflowMatrixView Plan AA S24 (1 page mirror cross-module — Case 2 fits Pattern 13 read-only admin Designer mirror + Pattern 14 Tailwind JIT palette + Pattern 15 HTML table rowSpan iteration helper). **Decision tree forward:** Em chủ trì gọi em với task code edit → em ACCEPT case (a)/(b) khi spec deterministic, REFUSE nếu first-time pattern. Em chủ trì confirm Layer A governance still active scope SOLUTION_ERP. Token cost spawn này ~5k (3 Read + 1 RAG query + 1 Edit + final report). KHÔNG curate — defer em main full curate session. Tag: `[verify, phase-9, infra]`. +- **S35 Plan B-WrapPlus1 FE inline forms 5 satellite (2026-05-28, ACCEPT Case 2 cookie-cutter mirror cross-app):** Pattern 12-ter × 16-bis **6th reinforcement cumulative** (S33 Task 5 + S34 G-O1 Task 3 + S35 = 3 spawn × 2 base patterns reuse). Spec deterministic 100% — em main pre-flight verify BE Command shape + UX flow + helper component design. **Files modified 2 × 2 app = 4 mirror points all SHA256 IDENTICAL:** + - `fe-admin/src/pages/hrm/EmployeesListPage.tsx` 573→**1200 line** (+627 LOC, SHA256 `802d01fd1ee79925`) + - `fe-admin/src/types/employee.ts` 307→**360 line** (+53 LOC 5 Input types, SHA256 `db29156a61af76e9`) + - 2 fe-user files MIRRORED bit-identical post `cp` (verified `diff` empty + `sha256sum` match) + - **Cookie-cutter pattern applied 5× satellite:** WorkHistory/Education/FamilyRelation/Skill/Document — mỗi satellite có **1 Form component inline** (~70-100 LOC each) + **3 useMutation** (create/update/delete) + **state addingX + editingXId** + Section header `+ Thêm` button + per-row `` (Pencil/Trash icons). + - **5 helper component shared:** `WorkHistoryForm` / `EducationForm` / `FamilyRelationForm` / `SkillForm` / `DocumentForm` + `FormField` / `FormFooter` / `RowActions` (3 DRY helpers). + - **Section component extended** với optional `actions?: React.ReactNode` prop render flex right side header bar + `onClick={e => e.stopPropagation()}` wrapper tránh `
` toggle khi click button. Backward compat 100% (Section 1 không pass actions vẫn render). + - **Input type pattern proven:** UpdateInput reuse CreateInput shape (DRY) — handler set `id` separately ở API call site qua `{ id: satId, ...payload }`. Nullable string normalize qua `nullable(s) => s.trim() || null` + nullable number qua `nullableNumber(s) => isNaN ? null : Number(s)` helpers inline. + - **Build verify clean:** fe-admin 31.57s 0 TS err 1454.01 kB bundle (gzip 367.77 kB, 1930 modules) + fe-user 23.39s 0 TS err 1367.58 kB bundle (gzip 352.35 kB, 1920 modules). Pre-existing bundle size warning (>500 kB) unchanged. + - **0 BE touched** (15 endpoint S34 ready). **0 menuKeys/Layout/App touched** (no new route). + - **Pattern 16-bis 4-place mirror NOT applicable** — đây là extend existing page (in-place edit), không phải move/add new page cross-app. 4-place áp dụng cho "add NEW page" scenarios. + - **Ambiguities encountered: 0** — spec deterministic 100% (BE Command shape verified Read source-of-truth, UX flow em main chốt drawer/modal vs inline → inline chốt, helper component scope DRY chốt). + - **Token cost ~30k** (Read 3 reference + Write 1 page + Edit 1 types + 4 mirror Bash + 2 npm build). Slightly over 25k budget — large page rewrite (~1200 line single Write). + - **Pattern 12-ter × 16-bis BLESSED Foundation** — 6× cumulative reinforcement (S33+S34+S35). Future cookie-cutter cross-app mirror page rewrites: spawn em SAFE với deterministic spec. + - Tag: `[fe-inline-form, phase-10.1-1.5, frontend, cookie-cutter-6x]`. + - **S34 G-H1 Phase 1.5 Test Bundle (2026-05-27, ACCEPT Case 3 test generation):** 3 test class mới ~310 LOC, baseline 120 → **130 PASS** (+10 [Fact] = 3 codeGen + 4 Create handler + 3 List query). 0 regression cũ. Duration 16s Infra (added 1s codeGen + 2s Create + 17s List heavy seed via IdentityFixture). - **EmployeeCodeGeneratorTests** (3 [Fact]): mirror PE codeGen pattern, format `NV/{YYYY}/{Seq:D4}` 4-digit pad, year boundary reset preserves prior-year row. - **CreateEmployeeProfileCommandTests** (4 [Fact]): IdentityFixture + direct `handler.Handle()`. Mirror BW5 ConflictException + NotFoundException. **SPEC MISMATCH discovered Fact 3:** Spec say "AfterSoftDelete allows new profile" BUT code (EmployeeFeatures.cs:158-163) check existing KHÔNG filter `!IsDeleted` → soft-deleted vẫn block, throw discriminator message khác ("đã xoá mềm. Cần khôi phục thay vì tạo mới." vs active "mỗi user chỉ được 1 hồ sơ"). Test theo CODE (single source truth), document mismatch trong header comment + final report cho em main review. diff --git a/.claude/agent-memory/investigator/MEMORY.md b/.claude/agent-memory/investigator/MEMORY.md index c447d2b..df519a9 100644 --- a/.claude/agent-memory/investigator/MEMORY.md +++ b/.claude/agent-memory/investigator/MEMORY.md @@ -129,6 +129,8 @@ State machine 5 trạng thái phiếu PE: Nháp / Đã gửi duyệt / **Trả l ## 📅 Recent activity (last 10 FIFO) +- **2026-05-28 (S35 — Plan G-H2 Task 3+4 pre-flight HRM CRUD audit):** Em spawn 1 lần ~8K token. **Task 1 — Plan CA Chunk B precedent:** SHA `06a441c` "FE move 4 master pages 948 LOC byte-identical". 4 catalog page mirror `fe-admin/master/{Suppliers,Projects,Departments,Catalogs}Page.tsx` → `fe-user/`. LOC actual: Catalogs=321 / Departments=160 / Projects=214 / Suppliers=253 = **948 LOC tổng**. Pattern = single file inline list + create/edit dialog (NO split route /new). DataTable + PageHeader + PermissionGuard + 6 shadcn UI. **Task 2 — NamGroup HRM ref MISS:** Glob `*Phep* *TimeOff* *NgayLe* *Ca* *Ot*` → KHÔNG có entity dedicated. NamGroup chỉ có `TblTimeOffConfig.cs` 14 cols generic + `TblTimeOff.cs` 47 cols (request, Ngay1-10 + TypeNgay1-10 hardcoded over-engineered) + `TblDmChung.cs` 10 cols generic bucket. **SOL Mig 35 entity design MẠNH HƠN:** LeaveType có IsPaid + RequiresAttachment + DaysPerYear decimal(5,2) (NamGroup miss). Holiday composite UNIQUE Year+Date + IsRecurring (NamGroup không có). ShiftPattern WorkDays comma string + TimeOnly Start/End + BreakMinutes (NamGroup không có). OtPolicy 3-tier multiplier weekday/weekend/holiday + 3 cap day/month/year Luật LĐ VN (NamGroup không có). **Kết luận: KHÔNG cần port field từ NamGroup. SOL clean-room design mạnh hơn.** Workflow integration: NamGroup TimeOffConfig embed `ListApproval` JSON inline; SOL sẽ dùng ApprovalWorkflow V2 pattern khi G-O4 LeaveRequest land. **Task 3 — SOL Master pattern:** ProjectFeatures.cs 150 LOC + DepartmentFeatures.cs 128 LOC + CatalogsFeatures.cs **334 LOC** (4 sub-entity Units/Materials/Services/WorkItems gộp 1 file mega). Controller layout: `CatalogsController.cs` 1 controller cho 4 sub-entity. **Pattern Suppliers split** (Suppliers/Dtos/Queries/Commands subdir) = legacy heavyweight scale, KHÔNG nên mirror cho HRM. **Pattern Catalogs single-file mega** = đúng cho HRM (4 simple catalog tương đương Units/Materials/Services/WorkItems). LOC estimate G-H2 Task 4 FE: LeaveTypesPage 200 + HolidaysPage 250 (Year filter + bulk roll-over) + ShiftPatternsPage 250 (WorkDays multi-select + TimeOnly picker) + OtPoliciesPage 220 (1 STANDARD constraint UI) ≈ **920 LOC** ~ Plan CA Chunk B 948 LOC parity. **Recommendation: Option B 1 mega `HrmConfigFeatures.cs` ≈ 600-700 LOC** mirror Pattern 12-bis Catalogs. Reason: (1) 4 simple catalog cùng module HRM lifecycle parallel. (2) Pattern 12-bis cross-module entity cookie-cutter proven 2× (Plan CA Catalogs + Plan B Contract V2). (3) 1 controller `HrmConfigsController.cs` route `/api/hrm/configs/{kind}` mirror `/api/catalogs/{kind}`. (4) Constraints differ (Holiday composite + OtPolicy 1 STANDARD active) handle qua per-handler validation. **Surprise:** EF Configuration files riêng `LeaveTypeConfiguration.cs` + 3 file khác EXIST — KHÔNG cần mirror Application Features file split (Config riêng OK + Features mega OK). Cross-stack KHÔNG conflict. Token cost ~8K. + - **2026-05-26 (S33 t1 — Plan G-H1 pre-flight NamGroup TblNhanVien* audit):** Em spawn task A+B+C audit `NAMGROUP.Server\Data\Entities\` ~10K token. **Inventory 10 TblNhanVien* bảng** (NOT 8 anh main estimate): 1 main `TblNhanVien` (105 cols!) + 9 satellite (QtCongTac/QtDaoTao/QuanHeThanNhan/KyNangViTinh/KyNangNgoaiNgu/KyNangKhac/QtHopDong/QtCongTacIn/QtPhulucHd). PK `long Id` (NOT Guid) — port phải convert. Soft delete `IsDelete int?` OR `bool?` (legacy inconsistent). Audit fields KHÔNG có ở satellite (chỉ `QtCongTacIn` có NhanVienTaoId/SuaId/NgayTao/NgaySua) — port phải fill từ BaseEntity. **Main `TblNhanVien` 105 cols PERSONAL HEAVY:** identity (CMND/HoChieu/MaSoThue/SoBhxh) + diachi (6 FK Tinh/Quan/Phuong x HKTT/TamTru + freetext fallback) + bank (SoTK/NganHang/ChiNhanh) + physical (ChieuCao/CanNang/NhomMau) + salary (LuongTN/LuongCB/PhepTrongNam/PhepTon/NghiBu/PhepThamNien) + BHXH (NgayThamGia/NoiDkkCb) + political (IsDangVien/IsHcmDoan/IsCongDoan + 3 Ngay*) + theme cols (BgmenuColor/MenuColor — SKIP UX-only) + 4 contact ng liên hệ + 14 FK catalog (DanToc/TonGiao/TinhTrangHonNhan/QuocTich/GioiTinh/TrinhDo/...). **Drift discovered s49 Plan C** 8 FK DiaChi cascade ADDED Sep 2025 but `ZERO populated 1675 NV` — entity drift expose. **Tip:** SOL Mig 34 nên design FK DiaChi NULLABLE + freetext fallback nvarchar(500) cùng tồn tại từ ngày đầu. **Satellite simple:** QtCongTac (12 cols work history external), QtDaoTao (16 cols + 4 FK catalog), QuanHeThanNhan (8 cols + FK), KyNangViTinh (3 cols MINIMAL — chỉ TenPhanMem string!), KyNangNgoaiNgu (4 cols + FK NgoaiNgu), KyNangKhac (4 cols freetext). **Satellite contract HEAVY:** QtHopDong (28 cols HĐLĐ — defer Plan H2), QtCongTacIn (16 cols internal position change — defer), QtPhulucHd (10 cols phụ lục HĐ — defer). **DbInitializer GLOB NO MATCH** — NamGroup KHÔNG seed demo data via DbInitializer pattern. **SOL User existing đã có:** FullName + DepartmentId + Position + PositionLevel + Email + IsActive. Skip 5 duplicate fields. **Patterns proven NEW:** (a) **Skip-list aggressive cookie-cutter audit** — Mig 34 chỉ port 5 satellite defer 4. (b) **FK + freetext fallback dual-write pattern** từ Plan C drift lesson. (c) **MaNhanVien `NV/YYYY/NNNN` mirror PE CodeGen** atomic Serializable. (d) **Polymorphic Skill table** — gộp 3 KyNang* thành 1 với Kind enum giảm 2 bảng. (e) **30 demo seed pattern reuse** mirror SOL DbInitializer existing 30 user 1-1 link User.Id. **Surprise:** Theme cols `BgmenuColor/MenuColor` ở entity hồ sơ NS! NamGroup mix UX preference với business data — SOL SKIP, dùng UserPreferences riêng. Token cost ~10K. - **2026-05-26 (S33 startup — em main spawn em đầu S33 audit 4 sub-agent MEMORY + RAG hit rate verify):** Em spawn 1 lần đầu S33 task A+B song song readonly. **Task A audit 4 MEMORY file sizes:** Investigator 20.2KB OK / CICD 25.5KB borderline > 25KB triggers curate flag / Reviewer 25.9KB borderline / Implementer 28.6KB OVER triggers curate priority. **Cross-agent learnings ≥ 2 agent:** (a) **Smart Friend pattern 4× cumulative** noted BOTH Reviewer (foundation 4 catches S22 #44 + S25 #48 + S29 Plan B ApplicableType + S29 DemoSeed gate) + CICD (Discovery #6 INFRASTRUCTURE vs DEMO seed catch Run #232 Hotfix `SeedSampleContractWorkflowV2` out of DemoSeed gate) — pattern strong candidate Layer B promote OR add to `docs/rules.md` §10 review process. (b) **Per-NV admin opt-in flag wire 10-surface-point** noted BOTH Implementer Pattern 7 (4 flag cumulative Mig 29-31 + Mig 30 F4) + CICD MEMORY 10-point checklist foundation (line 142-160) + Reviewer Per-NV scope split + RAG memory user-level cross-ref. (c) **Pattern 12-bis cross-module entity cookie-cutter mirror** PE→Contract noted BOTH Implementer (line 178-200) + Reviewer Cross-module security validation mirror (S29 Plan B). (d) **gotcha #48 SQLite tie-break** noted BOTH CICD (line 40-45 detail) + Reviewer (Cat 5 lesson catch from CICD pre-deploy). **Drift detected:** (1) CICD MEMORY line 124-125 cite "Mig 31 latest" but **actual repo Mig 33 prod (Plan B Contract V2 Mig 32+33)** per Investigator narrative S29 + RAG hit STATUS. CICD recent activity correctly mentions Mig 32+33 deployed Run #232 but baseline header line 124-125 stale. (2) Reviewer line 130 cite "Migrations: 31 latest" but actual 33 — same baseline header stale post-S29 Plan B. (3) Test baseline 111 unchanged ALL 4 agents consistent OK. (4) Endpoints ~146 (Reviewer line 132) vs ~148 (Investigator line 137) — minor 2 endpoint delta drift. **Curate recommend next session:** PRIORITY Implementer (28.6KB > 25KB hard, archive 2-3 verbose entries q2) + CICD (25.5KB borderline, drop 1 oldest entry 2026-05-12 setup since baseline preserved foundation section) + Reviewer (25.9KB borderline, drop 1 oldest S25 entry duplicated in S25 wrap below). Investigator self OK 20.2KB headroom. **Task B RAG verify 3/3 PASS** all rerank > 0.7: Q1 `Plan G NamGroup port phase 10` top hit HANDOFF.md rerank **0.848** PASS · Q2 `gotcha 52 qdrant client search removed` top hit investigator MEMORY S32 startup entry rerank **0.910** PASS (also gotcha doc 0.875 + memory user-level `feedback_rag_bootstrap` 0.863) · Q3 `per-NV admin opt-in F1 F2 F3 F4 wire 10 surface points` top hit HANDOFF.md S23 t4 rerank **0.684** BELOW 0.7 threshold WARN (semantic match correct, distance score boundary — RAG indexing for narrative cumulative entries reaches diminishing returns at 5+ session reinforcement). **Recommendation forward em main S33:** (a) Spawn Investigator pre-flight Plan G-H1 NamGroup TblNhanVien* 8 bảng audit per Phase 10.1 kick off plan; (b) Schedule dedicated curate session 3 sub-agents (Implementer priority) before next heavy plan kick off; (c) Update Reviewer + CICD baseline header Mig 31→33 + endpoint ~146→148 in next curate. Token cost spawn này ~10K (4 Read + 3 RAG query + 1 Bash + Edit MEMORY + final report). diff --git a/.claude/agent-memory/reviewer/MEMORY.md b/.claude/agent-memory/reviewer/MEMORY.md index 552da63..94b961c 100644 --- a/.claude/agent-memory/reviewer/MEMORY.md +++ b/.claude/agent-memory/reviewer/MEMORY.md @@ -154,6 +154,8 @@ Flag commit nếu thấy `0. **Cat 6 Cookie-cutter 12-bis 3×**: 4 region structure identical (DTO + List + Create cmd/validator/handler + Update cmd/validator/handler + Delete cmd/handler). Naming consistent ListXQuery/CreateXCommand pattern. Smart Friend fix #2 verified — 4 HRM entities NO HasQueryFilter (grep Configurations confirm 9 file HasQueryFilter NONE are HRM) → 4 List handler correctly add `.Where(!IsDeleted)` line 37/134/232/337 + 8 Create/Update Conflict check `&& !x.IsDeleted` predicate explicit. **MediatR + FluentValidation auto-scan** Application assembly (DependencyInjection.cs:14-19) — no manual DI registration needed. **Smart Friend 8× cumulative CLEAN**: (1) S22 #44, (2) S25 #48, (3) S29 password, (4) S29 ApplicableType, (5) S33 BW, (6) S33 Plan B Phase 2, (7) S35 FE forms (em main earlier), (8) S35 Plan G-H2 NOW. KHÔNG lower bar — actual catches 0 CRITICAL/MAJOR. **2 MINOR observed (defer Phase 1.5)**: (a) ListHolidaysQuery KHÔNG có `bool? IsActive` filter (chỉ Q + Year) — khác 3 query sibling có IsActive filter — inconsistent UX nhưng có thể intentional (holidays admin thường list all). (b) OtPolicy claim "1 default IsActive=true unique" (entity comment line 7) nhưng handler Create/Update KHÔNG enforce "chỉ 1 active" — admin có thể tạo nhiều IsActive=true cùng lúc. Future G-P1 attendance reference `IsActive=true` sẽ ambiguous nếu có 2+ active. Defer fix khi G-P1 implement (em main spec rõ defer phase 1.5). **Verdict: PASS proceed commit**. Token cost ~9K. + - **2026-05-26 (S33 Plan B G-H1 Phase 2 Task 4+5+6 pre-commit — PASS, Smart Friend 6× CLEAN):** Em main spawn em adversarial review 17 file uncommitted (3 BE new + 6 FE new + 6 FE mod + 2 Task 6 mod). **Independent verify SHA256 mirror 3 file PASS IDENTICAL**: `types/employee.ts` ccfc70666568, `EmployeesListPage.tsx` dc859c897c5c, `EmployeeCreatePage.tsx` c796f25d01ac — admin == user exact. **Cat 1 Wire BE**: 5 endpoint `GET /employees` (paged) + `GET /{id}` + `POST` (CreatedAtAction) + `PUT /{id}` (NoContent + ID match guard) + `DELETE /{id}` (soft NoContent) — tất cả real `mediator.Send`, 0 mock marker. Validator Create+Update đầy đủ (Phone MaxLen 20 + EmailAddress conditional When + decimal `.GreaterThanOrEqualTo(0)` lương/phép). Handler Create: load User (FindByIdAsync) → check existing EmployeeProfile UNIQUE (soft-deleted aware: throw ConflictException with distinct message) → atomic MaNhanVien codeGen SERIALIZABLE → entity save. Handler Get: Include 5 satellite + LEFT JOIN User/Department + projection. Handler List: filter Status + DepartmentId + Search (EmployeeCode/FullName Contains) + paging. **Cat 2 Schema**: Mig `AddEmployeeProfiles` timestamp 20260526110207 (= Mig 34 numeric by sort) — `EmployeeProfiles` + 5 satellite + `EmployeeCodeSequences` (7 table mới). UNIQUE indexes verified `IX_EmployeeProfiles_UserId` (line 309-313) + `IX_EmployeeProfiles_EmployeeCode` (line 293-297). FK Cascade Users. 6 Province/District/Ward cột plain Guid? defer FK G-H2 đúng comment. `EmployeeProfileConfiguration.cs` line 22-32 mirror Mig: UNIQUE + Cascade. MenuKeys.cs `All[]` line 108-114 đã có Hrm + HrmHoSo (line 112) — Admin auto-grant qua SeedAdminPermissionsAsync iterates All[]. DbInitializer.cs line 1484-1485 seed Hrm Order=28 + HrmHoSo Order=1 dưới Hrm parent. 28 không xung đột với Budgets=27. SeedDemoEmployeeProfilesAsync line 1945 NOT gated DemoSeed (placed OUTSIDE gate block) — đúng infrastructure pattern gotcha #51 lesson. **Cat 3 Security**: `[Authorize]` class-level present EmployeesController line 20 — no per-action policy yet (em main defer Phase 1.5). Input validation Create + Update Validator class đầy đủ. **Cat 4 Code quality**: TS6 erasableSyntaxOnly compliant — 10 enum dùng const-object pattern + `typeof X[keyof typeof X]`. Named exports (no default trừ App). Bundle size 1.43MB admin / 1.35MB user comparable baseline. ContactRound icon verified exist 5 places trong lucide-react bundle. DependencyInjection.cs line 39 registered `AddScoped`. **Cat 5 Test**: defer Phase 1.5 per em main spec UAT mode. Baseline 120/120 PASS preserved. **Smart Friend 6× cumulative CLEAN**: (1) S22 #44, (2) S25 #48, (3) S29 Plan CA password ≥12, (4) S29 Plan B ApplicableType, (5) S33 Plan C BW, (6) S33 Plan B Phase 2 NOW. KHÔNG lower bar — actual catches 0 MAJOR/CRITICAL. **3 MINOR observed (defer Phase 1.5)**: (a) Race condition EmployeeCode UNIQUE dưới SERIALIZABLE OK risk THẤP (per-year reset, mirror PE/HD pattern proven). (b) UpdateCommand 3 bool field IsCommunistParty/IsYouthUnion/IsTradeUnion không nullable → admin update partial sẽ accidentally reset (FE phải re-send all 3 every PUT — minor UX issue). (c) Delete handler `DateTime.UtcNow` direct không inject IDateTimeProvider — consistent existing PE/Contract Delete pattern, accept. **Special check verdicts**: gotcha #51 infrastructure seed gate compliance ✓ (em main cite gotcha #51 explicit comment line 1942-1944). gotcha #50 Layout staticMap mirror ✓ (Hrm_HoSo:/employees cả fe-admin line 57 + fe-user line 79). menuKeys.ts FE drift: pre-existing fe-admin minimal (16 key) vs fe-user (24 key) — em main Task 5 chỉ add Hrm 2 key cả 2 file, KHÔNG break Plan AA + Budget. Drift là pre-existing FE state intentional, không phải regression Plan B Phase 2. **Verdict**: PASS proceed commit. Token cost ~30K. Tag: `[adversarial-pass, hrm-mig34, smart-friend-6x-clean, phase-10]`. - **2026-05-26 (S33 Plan C B-Wrap test bundle pre-commit — PASS, INDEPENDENT VERIFY 9/9 tests):** Em main spawn em adversarial Plan C B-Wrap Contract V2 test bundle review. 4 file mới: TestCurrentUser (31 LOC stub), ContractWorkflowServiceApproveV2Tests (BW1-4+7, 5 [Fact]), CreateContractCommandApplicableTypeTests (BW5, 1 [Fact]), ContractV2SchemaPersistenceTests (BW6 split 3 [Fact]). Total 9 [Fact]. **Independent verify ran `dotnet test --filter` → 9/9 PASS local trong 4.7s** (em main claim 120/120 baseline tăng từ 111 — verified). Spec mapping verify Cat 1: BW1 ContextNote `"Hoàn tất Cấp 1, sang Cấp 2 cùng Bước 1"` ✓ match service line 360, BW2 mã HĐ `"FLOCK01/HĐTP/SOL&BTBM/01"` ✓ match ContractCodeGenerator HĐTP format line 21, BW3 ContextNote `"Approver skip thẳng tới Bước 3 Cấp 2"` ✓ match service line 348 (lastStepIdx=2, lastLevelMaxOrder=2, prefix `[Approver skip thẳng tới Bước 3 Cấp 2 (NV cuối) — bỏ qua các Bước/Cấp trung gian]`), BW4 ForbiddenException `"Bước 1...Cấp 1: bạn không có"` ✓ match service line 263-264, BW5 ConflictException `"ApplicableType=Contract"` ✓ match handler line 84-85 (test correctly handles spec→actual exception type discrepancy: spec says ValidationException, actual ConflictException — em main inline comment line 84 docs the discrepancy), BW7 ConflictException `"skipToFinal chỉ hỗ trợ HĐ V2"` ✓ match service line 105-106. Schema verify Cat 2: Mig `AddContractLevelOpinions` (timestamp 20260522052240) actual position 33 by filename sort confirmed via Glob (33 mig + 33 designer + 1 snapshot in /Persistence/Migrations folder), spec ref "Mig 33" matches. UNIQUE composite `(ContractId, ApprovalWorkflowLevelId)` confirmed `ContractLevelOpinionConfiguration.cs:34`. FK Cascade Contract + FK Restrict Level confirmed line 27+32 + migration FK line 41+47. Test quality Cat 5: assertions specific (`Should().Be(2)` for levelOrder, `Should().Contain(...)` for substring match, `Should().ThrowAsync()` with WithMessage wildcard), each [Fact] sets up fresh `IdentityFixture` + `using` disposal pattern (BW1-4+7 verbose using-block, BW6 `using var fix` shorthand — minor style inconsistency but functional same). Smart Friend independence note: **5 lần cumulative Smart Friend catches — em main + Implementer làm TỐT lần này, KHÔNG có catch MAJOR**. (1) S22 #44, (2) S25 #48, (3) S29 ApplicableType, (4) S29 DemoSeed, (5) S33 BW = clean. Implementer + em main spec mapping accurate, exact string match between assertions and service strings. **Minor (3, defer):** (a) `CreateService` helper method `ContractWorkflowServiceApproveV2Tests.cs:27-44` unused dead code — 5 [Fact] manually recreate inline (cleaner but DRY violation). Cleanup recommend Plan C-Hotfix or next test bundle. (b) `TestCurrentUser.Roles` constructor params `string[] roles` allows null → defensive `roles ?? Array.Empty()` line 27 OK but C# warning shadow. (c) BW6 split 3 [Fact] cleanly separated DUPLICATE + UPSERT + Cascade per spec — 9 tests OK not over-engineer (each invariant tested isolated). **Defer noted**: ApproveV2Async still ~150 LOC, BW1-4+7 cover happy + terminal + skip + outsider + V1 fallback — Plan B-Wrap roadmap mentions BW Bonus future test: OR-of-N multi-NV (3 NV cùng Cấp 1, only 1 needs approve), idempotent UPSERT (Cấp 1 approve → reject → approve lại same row Comment update), Mig 32 seed idempotent guard. Not blocker for current bundle commit. Token cost spawn ~22K. Verdict: **PASS proceed commit** (9 [Fact] all pass independent verify, spec match service exact, schema 3 invariant tested, 0 critical/major, 3 minor cosmetic). Recommendation: commit 4 file as proposed, baseline tăng 111→120. Tag: `[adversarial-pass, test-bundle, contract-v2, smart-friend-5x-clean]`. diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index ea40926..1179c55 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,6 +1,66 @@ # HANDOFF — Brief 5 phút cho session tiếp theo -**Last updated:** 2026-05-27 (Session 34 FULL — **🎯 Plan 1+2+3+4 ALL DONE: Curate + G-O1 Danh bạ + Phase 1.5 batch 6/6 + G-H2 Mig 35 schema foundation. BE CRUD + FE forms HrmConfig defer S35**) +**Last updated:** 2026-05-28 (Session 35 — **🎯 S35 3 chunk push ALL DONE deploy prod: FE inline forms 5 satellite + G-H2 BE CRUD 16 endpoint + G-H2 FE Admin HrmConfigsPage declarative**) + +**S35 (2026-05-28):** Anh main authorize Option A "FE forms + G-H2 BE+FE combo" sequence + "warm-up Implementer + CICD". Cumulative end-to-end **3 commit** pushed remote `63dd9ec..021674a` + **3 CI Run ALL PASS** (#242 + #243 + #244). + +**Commits S35 (3 push):** +1. `c3cd343` Chunk 1 — FE inline forms 5 satellite × 2 app (+1758 LOC, Run #242 PASS 3m30s) +2. `909655c` Chunk 2 — G-H2 BE CRUD HrmConfig 16 endpoint (+576 LOC NEW, Run #243 PASS 3m43s) +3. `021674a` Chunk 3 — G-H2 FE Admin HrmConfigsPage declarative (+1388 LOC, Run #244 PASS 3m38s em main fallback verify) + +**Multi-agent ROI S35 ~250K:** +- 🟨 Implementer 3 spawn ~80K (3 cookie-cutter chunk + Smart Friend × 3 catch S35) +- 🟦 Investigator 1 spawn ~8K (Plan G-H2 BE CRUD pre-flight: NamGroup MISS verdict — SOL clean-room mạnh hơn) +- 🟥 Reviewer 3 spawn ~60K (Smart Friend 9× cumulative clean: 2 truncated mid-MEMORY-update, 1 tight brief PASS clean) +- 🟩 CICD 4 spawn ~70K (Run #241 warm-up + #242 + #243 PASS + #244 stalled em main fallback) + +**Smart Friend Implementer 3 catch S35 (Pattern preserved):** +1. Chunk 2 MaxLength validator vs EF config mismatch → aligned to EF source-of-truth (LeaveType/OtPolicy Code=50, Name=200, Description=500) +2. Chunk 2 HRM entities NO HasQueryFilter (vs Master 9 file have) → explicit `.Where(!IsDeleted)` 8 List/Conflict-check site +3. Chunk 3 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_*` → silent sidebar drop gotcha #50. Enforced staticMap mirror Pattern 16-bis 6× cumulative + +**NEW capability prod S35 (end-to-end UAT-ready):** +- (a) Admin login `eoffice.solutions.com.vn/employees` → pick NV/2026/0007 → Section 2-6 (Công tác/Đào tạo/Thân nhân/Kỹ năng/Hồ sơ) inline `+ Thêm` button expand AddForm + per-row Pencil/Trash. 15 BE endpoint wire CRUD live. +- (b) Admin login `eoffice.solutions.com.vn/hrm/configs/leave-types` → 4 sub-tab + table 5 row LeaveType seed + Dialog modal CRUD `+ Thêm`. Switch tab → /hrm/configs/holidays (10 row) → /shifts (3 row) → /ot-policies (1 row). 16 BE endpoint wire CRUD live. + +**NEW gotcha #53 sub-agent truncation/stall pattern S35 × 3 occurrence:** +- Reviewer FE forms (push #1) cut mid-Cat-1 after "PERFECT" +- Reviewer BE CRUD (push #2) cut mid-MEMORY trim +- CICD Run #244 verify (push #3) stalled 600s watchdog after VPS mtime cross-check +- Mitigation verified: tight brief ≤ 8K (Reviewer FE Admin chunk 3 PASS clean no truncation 5K return) +- Em main grep verify manual Cat 2-6 + commit confidence preserved + +**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)** · 27 memory user-level · 6 skills · 4 sub-agents + +**Bundle hash rotation S35 cumulative:** +- fe-admin: `RNTX6Fvo` (Run #241 start) → `BhR0MmLN` (Run #242) → `BhR0MmLN` (Run #243 BE unchanged) → `Bl6e54yi` (Run #244) +- fe-user: `29A1LuMm` → `DIdNaB6W` → `DIdNaB6W` → `DHmW2tUF` + +**4 sub-agent reuse-able S36 via fresh spawn (agentId S35 invalid post-session-end):** +- 🟦 Investigator last spawn `a42bd882c367f6e47` (S35 G-H2 BE CRUD audit) +- 🟨 Implementer last spawn `a1aeda2fcbbc19eeb` (S35 G-H2 FE Admin) +- 🟥 Reviewer last spawn `a6b42cc3c1423e699` (S35 G-H2 FE Admin tight 5K PASS) +- 🟩 CICD last spawn `a3dfb05e2deee8f0f` (S35 Run #244 stalled mid-MEMORY) + +**⚠️ Next session S36 — anh main pick:** +1. **Plan G-O2 Phòng họp BookingCalendar** (~3-4h Mig 36 — FullCalendar lib NEW dep) — standalone tiếp Phase 10.2 Office +2. **Phase 10.3 G-O3-O6 Workflow Apps** (4 plan đề xuất nghỉ phép/đăng ký OT/đăng ký công tác/dự án — depends G-H2 catalog ready) +3. **Phase 9 Ops** anh main coordinate (SMTP + Rotate creds + UAT 2-3 user 1 tuần) +4. **Curate 4 MEMORY post-S35 spawn** (Reviewer + CICD borderline) ~20 phút em main proxy +5. **Test bundle G-H2 BE CRUD** (~30 phút Implementer Case 3 — codeGen UNIQUE Conflict + composite Year+Date + soft delete restore) +6. **Audit cron 2026-06-01** (còn 4 ngày — cumulative skill + doc drift mig 33→35, test 111→130, gotcha 52→53) + +**Recommend sequence S36:** +1. Curate 4 MEMORY (~20 phút) — clear context before heavy work S36 +2. Plan G-O2 Phòng họp BookingCalendar (~3-4h) — standalone independent +3. Plan G-O3-O6 Workflow Apps batch (~6-8h) — series workflow app reuse V2 + +**Last updated S34 FULL (prev):** 2026-05-27 (Session 34 FULL — **🎯 Plan 1+2+3+4 ALL DONE: Curate + G-O1 Danh bạ + Phase 1.5 batch 6/6 + G-H2 Mig 35 schema foundation. BE CRUD + FE forms HrmConfig defer S35**) **S34 FULL (2026-05-27):** Anh main authorize "1 → 2 → 3 → 4" sequence sau S34 init + "OK làm tiếp đi nhé" tiếp Plan 4. Cumulative end-to-end **6 commit** pushed remote `edba4ae..07b3f3b` + 4 CI Run (#238/#239/#240 PASS + #241 Plan 4 Mig 35 pending verify). diff --git a/docs/STATUS.md b/docs/STATUS.md index b3bb8e8..825e3f7 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,7 +2,9 @@ > **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-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:** 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**) diff --git a/docs/changelog/sessions/2026-05-28-s35-fe-inline-forms-g-h2.md b/docs/changelog/sessions/2026-05-28-s35-fe-inline-forms-g-h2.md new file mode 100644 index 0000000..e57a3a9 --- /dev/null +++ b/docs/changelog/sessions/2026-05-28-s35-fe-inline-forms-g-h2.md @@ -0,0 +1,234 @@ +# Session 35 — FE inline forms 5 satellite + G-H2 BE CRUD + G-H2 FE Admin end-to-end deploy prod + +**Date:** 2026-05-28 +**Duration:** ~5h (setup + 3 chunk execute + wrap) +**Branch:** `main` +**Push range:** `63dd9ec..021674a` (3 commits) +**CI Runs:** #242 + #243 + #244 ALL PASS + +## Context + +Anh main chốt Option A "FE forms + G-H2 BE+FE combo" sequence sau setup 10-mục report + "warm-up Implementer + CICD ngay". Em main thực thi cumulative 3 chunk push + docs wrap end-of-session. + +## Plan execution timeline + +### Setup (~30 phút) +10-mục report đầu session: MD/RAG context load + audit 4 MEMORY (3/4 borderline post-S34) + 6 skill verify + 130 test PASS verified + RAG 7 projects 38,849 chunks live + skill cron next 2026-06-01 + 4 sub-agent definitions ready. + +**Drift fix S35 init:** +- MEMORY.md user-level index thiếu Pattern 12-ter S34 entry → +1 line patch +- Sub-agent agentId từ S34 historical, fresh spawn S35 + +### Chunk 1 — FE inline forms 5 satellite (~1.5h) + +**🟩 CICD warm-up `a0fc1bac73362b086`** ~15K: +- Verify Run #241 PASS (S34 last `07b3f3b`) — Mig 35 prod + 19 sample seed + 3 domain 200 + bundle hash baseline S35 `RNTX6Fvo`/`29A1LuMm` + +**🟨 Implementer Case 2 `a4ca1a2333ca5a4f2`** ~30K (over budget heavy page rewrite 1200 LOC): +- `fe-admin/src/pages/hrm/EmployeesListPage.tsx` 573→1200 LOC (+627, +110%) +- `fe-user/...` mirror SHA256 IDENTICAL `802d01fd1ee79925` +- `types/employee.ts` +53 LOC × 2 app mirror `db29156a61af76e9` +- 5 inline Form component: WorkHistory + Education + FamilyRelation + Skill + Document +- 3 DRY helpers: FormField + FormFooter + RowActions × 45 usage site +- 15 useMutation per app (5 sat × 3 verb) + DRY `invalidate()` helper × 15 calls +- Section component extend `actions?` prop backward-compat +- Wire 15 BE endpoint S34 (POST/PUT/DELETE × 5 satellite path) +- npm build × 2 PASS (fe-admin 31.57s + fe-user 23.39s, 0 TS error) +- Pattern 12-ter cumulative 6× (FE side reinforcement) +- 0 ambiguity encountered (spec deterministic 100%) + +**🟥 Reviewer pre-commit `affe62cdb8f58bf0e`** ~15K **TRUNCATED** mid-Cat-1: +- Output cut after "Cat 1 PERFECT — all 5 Update calls send `id` in body matching BE UpdateXCommand" +- Em main fallback verify Cat 2-6 manual qua Grep: + - Cat 2 SHA256 mirror IDENTICAL × 4 file (diff exit 0) + - Cat 3 git status anti-fiddle clean + - Cat 4 DRY helper `invalidate()` × 15 calls = match mutations + - Cat 5 `confirm()` × 6 (5 sat + 1 header) · 0 Mock/alert/TODO + - Cat 6 RowActions/FormFooter/FormField × 45 usage +- Verdict: PASS (Smart Friend 7× cumulative clean preserved) + +**Commit `c3cd343` push** → CI Run #242 SUCCESS 3m30s: +- 130 test baseline preserve (FE-only) +- Bundle hash rotate × 2: `RNTX6Fvo→BhR0MmLN` admin + `29A1LuMm→DIdNaB6W` user +- CSS hash also rotated +- 3 prod domain 200 OK +- VPS mtime 09:42 + +**Polling lesson CICD MEMORY saved:** Bundle hash verify MUST AFTER status=Success — premature poll showed stale baseline pre-rotate. + +### Chunk 2 — G-H2 BE CRUD 16 endpoint (~5 phút Implementer under-budget) + +**🟦 Investigator `a42bd882c367f6e47`** ~8K parallel pre-flight: +- Plan CA Chunk B SOL Catalogs precedent: 948 LOC byte-identical mirror 2 app, Pattern 16-bis × 12-bis 4-place mirror +- NamGroup HRM ref **MISS** — KHÔNG có entity dedicated cho 4 HRM catalog. SOL Mig 35 design MẠNH HƠN clean-room (IsPaid/RequiresAttachment/composite UNIQUE/3-tier multiplier/Luật LĐ VN cap). KHÔNG cần port. +- SOL Master pattern: Catalogs mega 334 LOC + 1 controller — recommend **Option B mega 1 file** +- LOC estimate FE Task 4: ~920 mirror Chunk B 948 +- EF Configuration 4 file riêng đã có sẵn S34 +- Anti-pattern caught: NamGroup `TimeOffConfig` embed JSON approver — SOL nên V2 `ApprovalWorkflow` pattern khi G-O4 + +**🟨 Implementer Case 2 `a6593cad1afc52333`** ~25K: +- `src/Backend/SolutionErp.Application/Hrm/HrmConfigFeatures.cs` NEW 439 LOC mega +- `src/Backend/SolutionErp.Api/Controllers/HrmConfigsController.cs` NEW 137 LOC +- 4 region cookie-cutter (LeaveTypes/Holidays/Shifts/OtPolicies) × (DTO + List + Create + Update + Delete + Validator) = 4 DTO + 4 List query + 8 Validator + 8 Conflict UNIQUE check + 4 soft delete +- URL `/api/hrm-configs/{kind}` × 4 verb = **16 endpoint** +- Class `[Authorize]` + write `[Authorize(Roles="Admin")]` 12 attribute +- Composite UNIQUE Holiday (Year, Date) Update với `x.Id != req.Id` exclude-self +- `dotnet build` PASS 0 err + `dotnet test` 130 baseline preserve + +**Smart Friend Implementer 2 catch S35 BE CRUD:** +1. **MaxLength validator vs EF config mismatch** — Spec `Code MaximumLength(20)` vs EF `HasMaxLength(50)`. Aligned validator to EF source-of-truth (LeaveType/OtPolicy Code=50, ShiftPattern Code=20, Name=200, Description=500). Avoid runtime truncation error khi admin paste longer code. +2. **HRM entities NO HasQueryFilter** — Master/Catalogs config có `HasQueryFilter(!IsDeleted)` 9 file. 4 HRM Config files KHÔNG có. Added explicit `.Where(x => !x.IsDeleted)` 8 site (4 List query + 4 Conflict-check) prevent surfacing deleted rows. + +**🟥 Reviewer pre-commit `a536143b528605fef`** ~15K **TRUNCATED** mid-MEMORY-trim: +- Output cut: "MEMORY size warning shown (24.6KB exceeds 24.4KB). Let me append a concise entry but trim verbose older ones." +- Em main fallback verify Cat 1-6 manual: + - Cat 1 Wire BE: 8 Conflict check (4 Create + 4 Update với composite Year+Date `x.Id != req.Id` exclude-self) ✓ + - Cat 2 URL routing: 16 endpoint kebab-case kind consistent + - Cat 3 Anti-fiddle: 2 NEW BE file + sub-agent MEMORY auto + - Cat 4 Authorization: 12 `[Authorize(Roles="Admin")]` = 4×3 write verb + - Cat 5 Validator: 8 AbstractValidator + 44 RuleFor + 0 Mock/TODO + - Cat 6 Cookie-cutter Pattern 12-bis mega consistent +- Smart Friend 8× cumulative clean preserved + +**Commit `909655c` push** → CI Run #243 SUCCESS 3m43s: +- Bundle hash UNCHANGED × 2 (anti-pattern verify: BE-only no spurious FE rebuild) +- 4 GET endpoint smoke 19 row prod live (5 LeaveType + 10 Holiday VN 2026 + 3 Shift + 1 OtPolicy STANDARD) +- 3 prod domain 200 OK +- Mig prod TOP 1 unchanged (no Mig delta) + +### Chunk 3 — G-H2 FE Admin HrmConfigsPage (~6 phút Implementer + 1 phút Reviewer) + +**🟨 Implementer Case 2 `a1aeda2fcbbc19eeb`** ~25K: +- `fe-{admin,user}/src/types/hrm-config.ts` NEW 98 LOC × 2 app SHA256 IDENTICAL `228917e5fac2cdc6` +- `fe-{admin,user}/src/pages/hrm/HrmConfigsPage.tsx` NEW ~470 LOC × 2 app SHA256 IDENTICAL `6378fbc71ff90260` +- `fe-{admin,user}/src/App.tsx` +3 LOC × 2 app (route + Navigate redirect default `/hrm/configs` → `leave-types`) +- `fe-{admin,user}/src/components/Layout.tsx` +6 LOC staticMap × 2 app (4 entry `Hrm_Config_*`) +- Declarative `KIND_CONFIG` Record × 4 kind + FieldDef type extend (text/textarea/checkbox/number/date/time/select/multiselect-weekday cho Shift WorkDays) +- 4 kind sub-tab navigation + Dialog modal CRUD + per-kind RowRenderer +- npm build × 2 PASS (fe-admin 14.33s + fe-user 744ms, 0 TS error) +- Pattern 12-bis × 16-bis 9× cumulative successful +- Pattern 16-bis 6× cumulative (staticMap 4th place enforce) + +**Smart Friend Implementer 3rd catch S35 (CRITICAL):** +- **Em main spec line 24 GAP** "Layout staticMap (no resolve issue — `/hrm/configs/:kind` URL match menu key `Hrm_Config_*` 4 leaf seeded S34 đã có URL ...)" — **WRONG** +- Implementer verified: + - `MenuItem.cs` Domain entity NO `Url` field → FE-only routing + - `resolvePath()` Layout.tsx chỉ staticMap + regex `Ct_*/Wf_*/Pe_*/PeWf_*/AwV2_*` → KHÔNG match `Hrm_Config_*` + - Without staticMap → MenuLeaf line ~198 `if (!path) return null` → silent sidebar drop (gotcha #50) +- Per Pattern 16-bis cumulative discipline (gotcha #50 5× prior), Implementer enforced staticMap mirror +6 LOC × 2 app +- Pattern foundation overrides single-spec-instance scope when conflict — Smart Friend anti-pattern prevention + +**🟥 Reviewer pre-commit `a6b42cc3c1423e699`** ~5K **PASS CLEAN không truncated** (tight brief verified): +- Tight scope brief ≤ 10K explicit "DO NOT curate MEMORY heavy" +- 7 tool uses, 52s, 5K total token return +- Cat A Wire BE 16 endpoint PASS (api.get/post/put/delete + URL `/hrm-configs/${kind}` literal) +- Cat B Anti-fiddle PASS (8 file expected + sub-agent MEMORY auto) +- Cat C staticMap consistency PASS (resolvePath regex DOES NOT match `Hrm_Config_*` — Smart Friend catch CORRECT, 4 entry mirror identical 2 app) +- Cat D TS6 erasableSyntaxOnly PASS (0 enum, 11 type alias + 4 union literal) +- 0 critical / 0 major / 2 minor defer +- Smart Friend 9× cumulative clean — TIGHT BRIEF MITIGATION SUCCESS + +**Commit `021674a` push** → CI Run #244 SUCCESS 3m38s (em main fallback verify): +- 🟩 CICD `a3dfb05e2deee8f0f` **STALLED 600s watchdog** after "VPS mtime cross-check confirms ship at 10:05" +- Em main fallback curl verify: 3 prod domain 200 OK + bundle hash rotate × 2 confirmed + - fe-admin `BhR0MmLN→Bl6e54yi` + - fe-user `DIdNaB6W→DHmW2tUF` + +## Multi-agent ROI S35 ~250K total + +| Agent | Spawn count | Token est | Quality | +|---|---|---|---| +| 🟨 Implementer Case 2 | 3 | ~80K | 3 cookie-cutter chunk + Smart Friend × 3 catch (MaxLength + HasQueryFilter + staticMap) | +| 🟦 Investigator | 1 | ~8K | Plan G-H2 BE CRUD pre-flight + NamGroup MISS verdict + LOC estimate | +| 🟥 Reviewer | 3 | ~60K | Smart Friend 9× cumulative clean (2 truncated mid-MEMORY + 1 tight brief PASS) | +| 🟩 CICD | 4 | ~70K | Warm-up + 3 deploy verify (1 stalled em main fallback) | +| 👤 Em main | — | ~280K | Setup + spec design × 3 + commit × 3 + push × 3 + manual verify fallback × 3 + docs wrap | + +## NEW gotcha #53 — Sub-agent truncation/stall pattern + +**Pattern empirical S35:** 3 sub-agent spawn (Reviewer × 2 + CICD × 1) bị truncated / stalled trong final "Update MEMORY.md BEFORE stop" step. Output return PASS verdict snippet visible nhưng structured findings không đầy đủ. + +**Root cause hypothesis:** +1. Sub-agent context window approach limit khi cumulative tool output + 100K spawn budget +2. MEMORY.md ~25-31KB borderline triggers Edit/Write large operation late-stage → token overflow streaming +3. Stream watchdog 600s timeout không recover (CICD case) + +**Mitigation verified S35:** +- **Tight brief scope ≤ 8K + 4 cat tight** → Reviewer chunk 3 FE Admin PASS clean 5K return +- **Em main manual verify post-truncation** Cat 2-6 grep-based (5 phút faster than re-spawn) +- **Curate MEMORY pre-spawn nếu > 25KB** (4 agent MEMORY S35 post-spawn borderline cumulative) +- **Spec ghi rõ "short append MEMORY only, NO curate"** khi MEMORY borderline + +**Saved gotcha #53 + Quick reference 28 trong gotchas.md.** + +## Patterns reinforced cumulative S35 + +| Pattern | Reinforcement | Reference | +|---|---|---| +| Pattern 12-ter (within-module N-satellite) | 6× cumulative (5 sat S34 + FE forms S35) | feedback_within_module_n_satellite_scaffold | +| Pattern 12-bis (cross-module catalog mega) | 3× cumulative (S29 Plan B + Chunk C + S35 G-H2) | docs/changelog/sessions/2026-05-22-s29-plan-ca-plan-b-contract-v2-wire.md | +| Pattern 16-bis (4-place mirror cross-app) | 6× cumulative — staticMap 4th place mandatory | gotcha #50 + S33-S34-S35 reinforcement | +| Smart Friend | 9× cumulative clean (S22+S25+S29×2+S33×2+S35×3) | Implementer Smart Friend default | +| **NEW: Declarative KIND_CONFIG Record** | 2× pattern (Master/Catalogs + HRM/Configs) | Reusable cross-module single-page multi-kind CRUD | + +## State delta S35 + +| Metric | S34 wrap | S35 wrap | Δ | +|---|---|---|---| +| Migrations | 35 | 35 | 0 | +| Tables | 71 | 71 | 0 | +| Endpoints | ~169 | ~185 | +16 (HRM Configs) | +| FE pages | 42 | 43 | +1 (HrmConfigsPage) | +| Menu keys | 69 | 69 | 0 | +| Tests | 130 | 130 | 0 (UAT mode no test add) | +| Gotchas | 52 | 53 | +1 (#53 sub-agent truncation) | +| Memory user-level | 26 → 27 | 27 | unchanged S35 (Pattern 12-ter add S34, MEMORY.md drift fix S35 init +1 entry) | +| Skills | 6 | 6 | 0 | +| Sub-agents | 4 | 4 | 0 | +| Active prod users | 34 | 34 | 0 | +| Commits S35 | — | 3 | `c3cd343` + `909655c` + `021674a` | +| CI Runs S35 | — | 3 | #242 + #243 + #244 ALL PASS | +| Bundle hash rotate | — | 2× | fe-admin BhR0MmLN→Bl6e54yi · fe-user DIdNaB6W→DHmW2tUF | + +## NEW capability prod end-to-end S35 (UAT-ready) + +### Capability 1 — Hồ sơ NV satellite CRUD inline forms +- Admin login `eoffice.solutions.com.vn/employees` +- Pick `NV/2026/0007 BOD 1 - Director` (1 in 33 sample) +- Section 2-6 click `+ Thêm` → inline AddForm expand +- Per-row Pencil → inline EditForm replace row +- Per-row Trash → `confirm()` native + DELETE API +- 15 BE endpoint wire CRUD live (5 satellite × POST/PUT/DELETE) + +### Capability 2 — Cấu hình HRM 4 catalog +- Admin login `eoffice.solutions.com.vn/hrm/configs/leave-types` +- 4 sub-tab navigation: Loại phép / Ngày lễ / Ca làm việc / Chính sách OT +- Table per-kind với columns config riêng +- `+ Thêm` → Dialog modal form (declarative FieldDef render — text/number/date/time/checkbox/select/multiselect-weekday) +- Pencil → Dialog Edit pre-fill +- Trash → confirm() + DELETE +- 16 BE endpoint wire CRUD live (`/api/hrm-configs/{kind}` × 4 verb) +- 19 row seed prod (5+10+3+1) admin manage + +## Defer S36+ backlog + +1. **Plan G-O2 Phòng họp BookingCalendar** (~3-4h Mig 36 — FullCalendar lib NEW dep) standalone +2. **Phase 10.3 G-O3-O6 Workflow Apps** (4 plan workflow LeaveRequest/OtRequest/BusinessTrip/Project — depends G-H2 catalog ready) +3. **Curate 4 MEMORY post-S35 spawn** (Reviewer + CICD borderline) +4. **Test bundle G-H2 BE CRUD** (~30 phút Implementer Case 3 — UNIQUE Conflict + composite Year+Date + soft delete restore) +5. **Audit cron 2026-06-01** (cumulative mig 33→35 + test 111→130 + gotcha 52→53 docs drift batch) +6. **Phase 9 Ops** anh main coordinate (SMTP + Rotate creds + UAT 2-3 user 1 tuần) +7. **Phase 1.5 Item 3 BE permission per-action satellite** (current scope `[Authorize(Policy="Hrm_HoSo.Create")]` class-level on satellite endpoints — verify Drafter 403 silent per-action mitigation) + +## Reference + +- `docs/STATUS.md` S35 header +- `docs/HANDOFF.md` S35 brief +- `docs/gotchas.md` #53 NEW sub-agent truncation pattern +- 3 commit: `c3cd343` (FE forms) + `909655c` (BE CRUD) + `021674a` (FE Admin) +- 3 CI Run: #242 + #243 + #244 ALL PASS +- 4 agent last spawn agentId (post-session-end invalid): + - Investigator `a42bd882c367f6e47` + - Implementer `a1aeda2fcbbc19eeb` + - Reviewer `a6b42cc3c1423e699` + - CICD `a3dfb05e2deee8f0f` (stalled at end) diff --git a/docs/gotchas.md b/docs/gotchas.md index 0dd38a7..d944a0d 100644 --- a/docs/gotchas.md +++ b/docs/gotchas.md @@ -956,6 +956,40 @@ for h in resp.points: # ← .points không phải iterable trực tiếp **Phòng tránh:** Pin `qdrant-client` version trong deps (`==1.x.y`). Hoặc thêm health-check startup: `assert hasattr(_qdrant, 'query_points'), "upgrade qdrant-client"`. **KHÔNG dùng `except Exception: continue` che-mờ lỗi API** — ít nhất log warning. +### 53. Sub-agent truncation / stall pattern khi heavy MEMORY update phase end-of-task — Reviewer + CICD bị cut mid-sentence ở Update MEMORY.md step (Session 35 × 3 occurrence) + +**Triệu chứng:** Sub-agent (Reviewer + CICD spawn ~100K token budget, ~30+ tool uses) chạy adversarial checks / smoke verify hoàn chỉnh, returning verdict PASS qua snippet visible, NHƯNG output bị truncate ở final "Update MEMORY.md BEFORE stop" step. Em main không nhận structured verdict đầy đủ. + +**Pattern empirical S35:** +- Reviewer FE forms (1200 LOC + 60 mutation): Cat 1 "wire BE PERFECT" + 33 tool uses → truncated mid-MEMORY append +- Reviewer BE CRUD (576 LOC + 16 endpoint): "MEMORY size warning 24.6KB exceeds 24.4KB. Let me append concise entry but trim verbose..." → truncated mid-trim +- CICD Run #244 verify (FE Admin deploy): "VPS mtime cross-check confirms ship at 10:05" → stalled 600s watchdog timeout + +**Root cause hypothesis:** +1. Sub-agent context window approaches limit khi cumulative tool output (Read MEMORY ~25KB initial + Read references + Bash output + grep results) + 100K spawn budget +2. MEMORY.md size ~25-31KB borderline triggers Edit/Write large operation late-stage → token overflow during streaming +3. Stream watchdog 600s timeout không recover (CICD case) — process hung internally + +**Mitigation S35 verified:** +- **A. Tight brief scope** — Reviewer FE Admin spawn (~5K token brief, 4 cat tight, "concise findings only") → PASS clean 5K return không truncated. Pattern: brief budget < 8K + scope ≤ 4 cat + explicit "DO NOT curate MEMORY heavy — short append only this time" +- **B. Em main manual verify post-truncation** — Cat 2-6 grep-based verify (SHA256 diff exit code + grep count match) takes ~5 phút em main, faster than re-spawn +- **C. Curate MEMORY pre-spawn nếu > 25KB** — agent MEMORY > threshold trigger truncation risk. Em main curate proxy archive q3.md trước spawn heavy. +- **D. Avoid forcing MEMORY heavy update in agent spec** — phase "Update MEMORY.md BEFORE stop with detailed findings" → switch to "short append 1 entry FIFO most-recent-first, KHÔNG curate old" + +**Cumulative occurrences S35:** 3/8 sub-agent spawn (Reviewer × 2 + CICD × 1 = 37.5% truncation rate at borderline ~25-31KB MEMORY). Heavy task + large MEMORY = correlation point. + +**References:** +- S33 Implementer truncation pattern 2/3 (memory `feedback_implementer_truncation_mitigation` user-level — heavy scaffold ≥30 file) +- S35 Reviewer FE forms (Session 35 push #1 verify): output cut after Cat 1 PERFECT statement +- S35 Reviewer BE CRUD (Session 35 push #2 verify): cut mid-MEMORY trim +- S35 CICD Run #244 (Session 35 push #3 verify): stalled 600s watchdog after VPS mtime cross-check + +**Phòng tránh:** +1. Tight brief scope ≤ 8K tokens cho Reviewer/CICD nếu task verifiable qua grep/diff em main +2. MEMORY pre-spawn audit: nếu > 25KB → curate proxy archive trước spawn +3. Agent spec ghi rõ "short append MEMORY only, NO curate", remove "BEFORE stop with detailed" directive khi MEMORY borderline +4. Em main backup verify Cat 2-6 manual grep nếu Reviewer truncated mid-verdict + **References:** - AI_INFRA: `claude-rag/lib/retrieval.py` `vector_search()` function — fixed 2026-05-26 S31 - Eval run: `eval/runs/2026-05-26-baseline-v1.1-final.json` @@ -993,3 +1027,4 @@ for h in resp.points: # ← .points không phải iterable trực tiếp 26. Nếu new Seed method KHÔNG chạy prod dù dotnet build PASS + deploy SUCCESS → check nested inside `if (!demoSeedDisabled)` gate (Plan T S23 t10 flag enabled prod) → INFRASTRUCTURE seed phải PROMOTE OUT of DemoSeed gate (#51). Decision tree: production cần để work end-to-end? YES → ungate 25. Nếu UI audit list show `Đã gửi duyệt → Đã gửi duyệt` lặp gây nhầm → drop dual-phase badge khi state machine self-loop, thay Decision badge + next-target hint parse từ comment (#49) 27. Nếu RAG `search_memory` trả 0 results dù Qdrant green + BM25 có data → `qdrant-client` upgrade xóa `search()` method, bị nuốt silent. Test: `python -c "from qdrant_client import QdrantClient; c=QdrantClient(url='http://127.0.0.1:6333'); c.search"`. Fix: dùng `query_points(query=...).points` (#52) +28. Nếu sub-agent (Reviewer/CICD) return PASS verdict bị cut mid-sentence ở "Update MEMORY.md" step → MEMORY > 25KB triggers truncation risk. Mitigation: tight brief ≤ 8K + em main grep verify manual + curate MEMORY pre-spawn nếu > 25KB (#53)