[CLAUDE] Docs: S58 closeout — lock fix prod-verified Run #382 + S57bis flush + gotcha #59/#60 + harvest on-behalf

- STATUS/HANDOFF: thêm S57bis + S58 (2-session gap S57bis đóng vội), counts
  re-ground (Mig 49 · test 240 · gotcha 60 · menu 57 · bundle CP4CB1ym/BmZ3VHnm
  curl-verified · RAG 2420). Ops S56 "gán user IT" RESOLVED (nv.cao/nv.truong
  sống lại nhờ password fix).
- gotchas: #59 (PS5.1 git commit -F, residual S57bis) + #60 NEW (Identity seed
  CreateAsync silent-fail vs prod RequiredLength=12 — population Dev ≠ prod,
  dump data thật trước lock/seed-by-email) + checklist 31/32.
- agent-memory: cicd Run #381 (residual) + #382 · 4 spawn-record on-behalf
  (database-agent/impl-backend/impl-frontend/reviewer — H2 Coverage 4-MISS đóng)
  · investigator-codebase recon · 2 monitor RE-REPORT entries.
- skills: ef-core +row Mig 49 (49 mig ×5 chỗ) · README + dep-audit count sync.
- CLAUDE.md root: Mig 49 + test 240 + gotcha 60 + schema-ref 32-49.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-11 13:09:29 +07:00
parent 5998163642
commit 2aefb3134d
15 changed files with 102 additions and 23 deletions

View File

@ -2,7 +2,34 @@
> **Tiering rule (S40):** giữ **2-3 session gần nhất**. Cũ hơn → `docs/changelog/sessions/`. Full brief history pre-S40 → `docs/_archive/HANDOFF-preS40-fullhistory.md`.
**Last updated:** 2026-06-09 (Session 56 — **Pre-golive verify sweep + golive-harden 4 fix — Run #379 PASS, code golive-ready**. WF1 `pre-golive-verify` 7-stream + adversarial → 6 PASS/1 CONCERN/0 blocker = GO (key finds = ops not code). WF2 `golive-harden` fix 4: #3 LeaveBalance lost-updateatomic ExecuteUpdate+Serializable tx (NO mig) · #5 ItTicket authz Forbidden-trước-NotFound · #6 DocxRenderer null-guard · #4 Travel/Vehicle ApproveV2 tests. Test 216→**228**. Bundle FROZEN `4SUwDLD8`/`XdKzt9LL`. `sys.tables` re-ground 92→**93**. gotcha **#58** NEW. reviewer StructuredOutput-fail→em main đỡ. **2 ops VPS pending** (gán user IT + tzutil UTC+7). FE Phase 2 redesign **deferred** (recon ready). Commit `a20cde8`. Prev S55 — **Nạp master data thật từ Excel (62 dự án + 71 hạng mục + 3 NCC) + Project +4 cột (Mig 48) — prod-verified**. HMW-mode ON. Commit `69cb393` Run #377 PASS ~4m33s. Test 216 (compile-fix only). Bundle admin `B-d6893W`/user `XdKzt9LL`. `SeedRealMasterDataAsync` ungated idempotentcoexist demo. 2 agent return truncated (BE+reviewer) → em main disk/runtime-recover. Prev S54 — IT staff tự reassign ticket (cross-stack authz) — prod-verified. 1 code commit `ca4b602` Run #376 PASS ~4m18s. Test 203→**216**. Bundle admin `DfCfHUE9``DmjI8Cmn`/user `_3S0BPJ2``YxL_MljK` (cả 2 rotate). NO migration. Task 1 Phase 9 Ops anh dừng. ⚠️ residual: 3 agent ghi MEMORY nhầm `src/Backend/.claude` → em main reconcile. Prev S53: gotcha #57 EXT Master Mig 47 + P11-D/E + database-agent verified-runtime.)
**Last updated:** 2026-06-11 (Session 58 — **Fix lock-demo-user prod NO-OP — Run #382 PASS, việc sếp deadline 15:00 ĐÓNG TRỌN**. Root cause 2 tầng: lock-list = population Dev-only + `DemoUserPassword` 11 ký tự < prod RequiredLength=12 CreateAsync silent-fail từ trước tới giờ (= "helpdesk inert" S56). Fix union 20 UAT email + password 12 tự prod 55 user/34 locked, nv.cao+nv.truong sống, 5 real staff tạo. gotcha #59+#60. Commit `5998163`. Prev S57bis **PE gắn Hạng mục (Mig 49) + Pe all-role + menu Cá nhân + Harness-4 runtime-VERIFIED**. Test 228→**240**. Bundle `CP4CB1ym`/`BmZ3VHnm`. Commit `17b23a4`+`dd117b7` Run #381 PASS+1PARTIAL (lock NO-OP RESOLVED S58). Prev S56 **Pre-golive verify sweep + golive-harden 4 fix — Run #379 PASS, code golive-ready**. WF1 `pre-golive-verify` 7-stream + adversarial 6 PASS/1 CONCERN/0 blocker = GO (key finds = ops not code). WF2 `golive-harden` fix 4: #3 LeaveBalance lost-updateatomic ExecuteUpdate+Serializable tx (NO mig) · #5 ItTicket authz Forbidden-trước-NotFound · #6 DocxRenderer null-guard · #4 Travel/Vehicle ApproveV2 tests. Test 216→**228**. Bundle FROZEN `4SUwDLD8`/`XdKzt9LL`. `sys.tables` re-ground 92→**93**. gotcha **#58** NEW. reviewer StructuredOutput-failem main đỡ. **2 ops VPS pending** (gán user IT + tzutil UTC+7). FE Phase 2 redesign **deferred** (recon ready). Commit `a20cde8`. Prev S55 **Nạp master data thật từ Excel (62 dự án + 71 hạng mục + 3 NCC) + Project +4 cột (Mig 48) — prod-verified**. HMW-mode ON. Commit `69cb393` Run #377 PASS ~4m33s. Test 216 (compile-fix only). Bundle admin `B-d6893W`/user `XdKzt9LL`. `SeedRealMasterDataAsync` ungated idempotent coexist demo. 2 agent return truncated (BE+reviewer) em main disk/runtime-recover. Prev S54 IT staff tự reassign ticket (cross-stack authz) prod-verified. 1 code commit `ca4b602` Run #376 PASS ~4m18s. Test 203→**216**. Bundle admin `DfCfHUE9``DmjI8Cmn`/user `_3S0BPJ2``YxL_MljK` (cả 2 rotate). NO migration. Task 1 Phase 9 Ops anh dừng. residual: 3 agent ghi MEMORY nhầm `src/Backend/.claude` em main reconcile. Prev S53: gotcha #57 EXT Master Mig 47 + P11-D/E + database-agent verified-runtime.)
---
## S58 (2026-06-11) — Fix lock-demo-user prod NO-OP + password-seed root-cause (1 code commit prod-verified Run #382)
**Anh: `/session-start` → bootstrap bắt Run #381 PARTIAL + 2 dirty S57bis → recon → anh chốt 3 quyết định (union+password-fix · giữ chuong.phan-typo · giữ nv.test) → ship 13:00, prod-verified 13:05 (deadline 15:00 dư ~2h).**
**Done (commit `5998163` → Run #382 PASS ~3m31s):**
- **Fix `DbInitializer.cs` 2 chỗ:** lock list union 20 email UAT-matrix prod thật (`{act,equ,fin,hra,pm,qs}.{nv,pp,tp}@` + `bod.{1,2}@` tạo TAY 05-13, exact-email KHÔNG pattern) + `DemoUserPassword` `User@123456``User@1234567` (1112 tự, thỏa prod `RequiredLength=12` root cause CreateAsync silent-fail mọi user seed trên prod từ trước, luôn cả nv.cao/nv.truong IT pool + 5 real staff).
- **🟩 cicd Run #382:** prod Users **55/21 active/34 locked** · nv.cao+nv.truong CREATED+ACTIVE (**ops S56 "gán user IT" RESOLVED** helpdesk round-robin sống) · 5 real staff created+active · guard 6/6 (admin/catalog.manager/nv.test/chuong.phan-typo/binh.le/binh.lethanh) · nv.test login+authed 200 · bundle FROZEN `CP4CB1ym`/`BmZ3VHnm` · Mig giữ 49 · 93 tables · custom Identity table = `Users` (không phải `AspNetUsers`).
- **Closeout S57bis residual:** commit 2 dirty (gotcha #59 + cicd Run #381 entry) · gotcha **#60** NEW · 4 spawn-record on-behalf (H2 Coverage 4-MISS đóng) · H1 5-patch (ef-core +Mig 49 row · skills/README · dep-audit · CLAUDE.md root) · STATUS/HANDOFF flush S57bis+S58 · menu keys re-ground **57** · RAG 2420.
**🔴 NEXT SESSION (anh pick):**
- **Ops của anh:** (1) `ssh vietreport-vps "tzutil /g"` confirm `SE Asia Standard Time` · (2) hỏi anh Chương dùng email nào dọn `chuong.phan@solution.com.vn` typo (đang active chủ đích) · (3) báo 5 real staff mới (`thanh.lethanh`, `anh.nguyen`, `tring.le`, `truong.le`, `long.nguyen`) password mặc định `User@1234567` + yêu cầu đổi · (4) khi gán người thật vào CNTT thêm nv.cao/nv.truong vào lock list.
- **test-specialist guard test** cho `LockDemoSampleUsersAsync` (test-after deadline trade-off S58, IdentityFixture sẵn).
- **FE redesign Phase 2** (recon ready) · **Phase 9 Ops** (SMTP/backup/creds/UAT) · **monthly audit 2026-07-01** (kèm schema-diagram §16+ Mig 32-49 ERD debt + L1 cap curate cicd-monitor 32.2KB/investigator-codebase 32.1KB + STATUS/HANDOFF re-tier).
- **Cert** `api.solutions.com.vn` expire ~2026-07-23 (auto-renew ~06-23).
---
## S57bis (2026-06-11 sáng) — PE gắn Hạng mục công việc (Mig 49) + Pe all-role + menu "Cá nhân" + Harness-4 runtime-VERIFIED (Run #381 PASS+1PARTIAL)
**Sếp Zalo 11:02-11:17 deadline 15:00: mapping master data + phân quyền PE all-user + flow tạo phiếu Dự án→Hạng mục→NCC + clear data cũ. Anh chốt: khóa CHỈ user sample · quyền Xem+Tạo · 1 phiếu 1 hạng mục header. 2 commit `17b23a4` (Harness-4) + `dd117b7` (product 26 file) → Run #381 PASS ~4m25s.**
**Done:**
- **Mig 49 `AddWorkItemToPurchaseEvaluation`** (🔵 database-agent design): PE.WorkItemId `Guid?` loose-Guid KHÔNG FK vật (convention PE) + IX + validator NotEmpty create-only + FK-guard `AnyAsync(IsActive)`Conflict + UpdateDraft null-safe (chống null-hóa S42). WorkItems = catalog GLOBAL 2 dropdown độc lập, "Dự án (năm) Hạng mục" = chuỗi ghép. FE ×2 (PeHeaderForm SHA256 IDENTICAL). **Pe_* all-role 130 rows/13 role** (Pe_* leaf KHÔNG trong `MenuKeys.All` factory; PeWf_* GIỮ Admin). Menu Personal root@30 + re-parent + Master write-lock ×3 controller. Excel (3) = NO-CHANGE vs S55. Test 228→**240** (+12). **Harness-4 runtime-VERIFIED** (spawn-test 2 chiều) + email-back AI_INFRA.
- **Lessons:** 2 builder truncated #53 + reviewer **die-0-byte ×2** em main solo + self-gate. Đóng VỘI 2 file dirty trôi S58 (đã commit S58). `LockDemoSampleUsersAsync` 14 email = prod NO-OP (population Dev-only cicd #381 bắt, **RESOLVED S58**). session log `2026-06-11-S57bis-pe-workitem-perm-golive-prep.md`.
---

File diff suppressed because one or more lines are too long

View File

@ -1070,6 +1070,30 @@ for h in resp.points: # ← .points không phải iterable trực tiếp
**References:** `LeaveOtApprovalFeatures.cs:354-405` (ApproveLeaveRequestHandler terminal DaDuyet) · `LeaveBalanceTests.cs` (TwoSeparateRequests accumulate test) · database-agent design S56 (DB11) · surfaced bởi `pre-golive-verify` workflow.
### 59. PowerShell 5.1 vỡ `git commit -m` khi message chứa `"` — dùng `git commit -F <file>` (Session 57bis)
**Triệu chứng:** `git commit -m @'...here-string có "quote kép"...'@` qua PowerShell 5.1 → git báo `error: pathspec 'án' did not match any file(s) known to git` — message bị CẮT tại dấu `"` đầu tiên, phần sau git hiểu thành pathspec args. Commit KHÔNG được tạo. Dễ tưởng nhầm lỗi Unicode tiếng Việt (không phải — tiếng Việt OK nếu không có `"`).
**Root cause:** here-string single-quote giữ literal ĐÚNG ở tầng PowerShell, nhưng khi gọi native exe (git.exe), PS 5.1 rebuild command-line và escape `"` không chuẩn (legacy native-arg passing) → `"` trong arg phá vỡ arg boundary.
**Fix (proven S57bis):** message dài / nhiều dòng / chứa quote → Write tool ghi file UTF-8 (vd `%TEMP%\commit_msg.txt`) → `git commit -F <file>`. Tránh hẳn native-arg escaping. Message 1 dòng không quote thì `-m` vẫn OK. Cùng họ bài thuốc "file payload" của #8 (Unicode CLI).
**References:** S57bis commit `dd117b7` (lần 1 `-m` fail pathspec — commit 1 cùng batch KHÔNG có `"` nên pass; lần 2 `-F` PASS) · họ hàng #30/#37 (PS 5.1 encoding class).
### 60. Identity seed `CreateAsync` silent-fail vs prod password policy — population Dev ≠ prod, lock/seed-by-email phải dump data thật (Session 58)
**Triệu chứng:** `LockDemoSampleUsersAsync` (S57bis) ship + chạy trên prod nhưng locked=0 — NO-OP hoàn toàn. 14 email hardcode (`bod.huynh@`...) không tồn tại trên prod; demo user thật trên prod là 20 account UAT-matrix scheme khác (`bod.1@`, `pm.nv@`... tạo TAY qua admin UI 05-13, chưa từng nằm trong code). Test xanh + deploy PASS + health 200 — không gì báo lỗi.
**Root cause (2 tầng):**
1. **Seed silent-fail:** `DemoUserPassword = "User@123456"` (11 ký tự) < prod `Identity:Password:RequiredLength=12` (appsettings.Production.json; Dev fallback 8) `userManager.CreateAsync` trả `IdentityResult.Failed` seed code chỉ `LogWarning` + `continue` (by-design 1-fail-không-abort) **named-person user CHƯA BAO GIỜ được tạo trên prod**, luôn cả `nv.cao`/`nv.truong` (IT pool chính root cause "helpdesk inert phòng IT 0 user" S56) + 5 real staff.
2. **Lock-by-email viết theo population Dev:** author đọc seed code (Dev truth) thay dump prod Users list lệch hoàn toàn.
**Fix (S58 `5998163`):** (a) `DemoUserPassword` `"User@1234567"` (12 tự, thỏa policy mọi env); (b) lock list = union 14 Dev-population + 20 prod-population (exact-email, KHÔNG pattern `binh.le@` người thật sát scheme demo).
**Phòng tái diễn:** (1) Mọi thao tác theo-email trên user (lock/deactivate/migrate) **dump bảng Users env đích TRƯỚC** khi viết list; assertion trả 0/`-1` nghi data-mismatch trước khi nghi code. (2) Seed tạo user password const phải thỏa policy NGHIÊM NHẤT mọi env (prod 12). (3) `IdentityResult` không throw grep `LogWarning` sau deploy user-seed mới.
**References:** `DbInitializer.cs` `DemoUserPassword` + `LockDemoSampleUsersAsync` · `DependencyInjection.cs:67` (RequiredLength fallback 8) · `appsettings.Production.json:18` (12) · cicd-monitor Run #381 entry (phát hiện PARTIAL) · investigator-codebase recon S58.
---
## Checklist debug bug mới
@ -1105,3 +1129,5 @@ for h in resp.points: # ← .points không phải iterable trực tiếp
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)
29. Nếu spawn sub-agent trả `API Error: 529 Overloaded` + `tokens=0` → Anthropic API transient overload, agent KHÔNG chạy. KHÔNG retry loop → em main solo fallback reliable (#54). Phân biệt với #53 truncation (agent chạy đủ token nhưng cut output)
30. Nếu sub-agent WRITE truncate NGAY ĐẦU exploration phase (chưa write file, đọc > 4 reference) → heavy spec ~10K + context bloat. Mitigation: brief ≤ 8K + pre-supply reference snippet trong brief HOẶC em main solo nếu cần đọc > 4 reference file (#55)
31. Nếu `git commit -m` qua PS 5.1 báo `error: pathspec 'xxx' did not match` với message tiếng Việt có `"` → native-arg escaping vỡ tại quote kép → Write message ra file UTF-8 + `git commit -F <file>` (#59)
32. Nếu thao tác theo-email/code trên data prod (lock/seed/migrate) trả 0 row affected → DUMP bảng env đích trước khi nghi code — population Dev ≠ prod (seed silent-fail `IdentityResult` không throw) (#60)