wal: flush 20260729T1236
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
# CI/CD Monitor Agent — Persistent Memory
|
||||
|
||||
- **07-29 verify `b5799fc` (FE-User: Tổng quan tất cả luồng duyệt — pipeline 4 GĐ) [S159 L8, FE-USER-ONLY 1 file-code, ghi-đĩa-suốt-lượt]:** **PASS 9/9** — Run **#422** (id=535) success **5m59s** (11:43:34→11:49:33+07); gate **562 EXACT** (45 D + **517** I, `Failed!`×0 toàn log). NO-Mig đúng kỳ vọng (diff `src/Backend/*`+`*Migrations*`=0 ⇒ KHÔNG query DB; Mig 68/89-table). Range **8 commit/37 file** (7 `wal:`) — chỉ `fe-user/src/pages/UserDashboardPage.tsx` thoát 7-glob ⇒ CI fire đúng. 🔑 **KỸ THUẬT MỚI — marker PHÂN-BIỆT-PHIÊN-BẢN (mạnh hơn marker-hiện-diện):** bản designer gốc ghi `Pipeline 4 giai đoạn`, bản sau review-fix ghi `Toàn trình 4 giai đoạn` ⇒ bundle prod có **`Toàn trình`=1 & `Pipeline`=0** ⟹ chứng prod chạy bản ĐÃ-FIX, không chỉ 'có nội dung mới'. Dùng khi review sửa CHỮ: chọn cặp chuỗi cũ/mới làm phép phân-biệt. ⚠️ **Bẫy comment-strip:** `grep -c` source ra 2 mà bundle=1 — occurrence dư nằm ở COMMENT đầu file (minifier strip) ⇒ so bundle với **occurrence-CODE**, đừng so grep-source thô. ⚠️ **Bẫy hình-dạng-truy-vấn (suýt hô cờ đỏ):** control `Pe` ra 182/182 vs kỳ vọng 197/185 — do tao dùng `LEFT(MenuKey,3)='Pe_'` còn gốc là `LIKE 'Pe%'` (+`Permissions`1/1+`Personal`13/1+`PeWorkflows`1/1=+15/+3). **LỆCH-số ⇒ truy PHẠM-VI-QUERY trước khi kết luận drift.** Bundle: user js `DptYR4wL`→**`0GO8mgrG`** css `BRCvEHvC`→`BARVqkP-` (1.584.514B, LM 11:49:05 in-window); admin js `8-QYcMOg`→`BHodkPNV` css `DiNJjaoo` FROZEN (#69 mode-A + REFINE). Control 2 tầng: fake-hash & **hash CŨ** đều `ct=text/html` 876B ⇒ bundle cũ biến mất = chứng ghi-đè. Smoke health live+ready 200 + 2 FE 200. **M7 menu-data (data-change NGOÀI CI, verify sống sót recycle): 3 root IsVisible=0 · 38-key grant min=max=13 · `Pe%` 197/185.** Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-b5799fc.md`. Tag `[run-422, pass-9-9, marker-phan-biet-phien-ban, comment-strip-trap, query-shape-not-drift, gate-562]`
|
||||
- **07-29 verify `1a47a61` ĐỢT-2 (tab strip 4 GĐ trên phiếu PE + menu 4-GĐ + đánh số 01-07 nhóm HĐ) [S159, 8 file code 190+/18−, FE×2 + seeder-only BE]:** **PARTIAL 8/9** — Run **#423** (id=536) success **5m44s**; gate **562 EXACT** (45+517). 0 migration (BE chỉ `MenuKeys.cs` const + `DbInitializer.cs` seeder). Bundle rotate **4/4** (admin js `BHodkPNV`→`D6Pz7nfV` css `DiNJjaoo`→`B1ErASuI` — admin-css rotate ĐÚNG vì fe-admin có sửa, khác đợt-1 frozen; user js `0GO8mgrG`→`Bpb8WEuY` css `BARVqkP-`→`7oAYFlzM`). Mirror `PePipelineStrip.tsx` 2 app **md5 IDENTICAL** `ef7b7824…`. 🔑 **Quy luật đếm marker (nối tiếp bài comment-strip): bundle-count = SỐ MODULE chứa chuỗi** (bundler pool hằng-số trong 1 module ⇒ nhiều occurrence cùng file gộp còn 1). USER=2 module→2 · ADMIN=1 module→1, đúng **6/6** (3 marker × 2 app) = 'đúng-BỘI-SỐ'. 2 control ÂM (`Đề xuất ký kết hợp đồng`, `Ký cứng & phát hành`) =0 cả 2 bundle + grep repo-wide 0-hit. Menu-data 5/5: **root=12 (0 double-insert) · DUPKEYS=0** · 2 root mới `KeHoachKyKet` ord26 / `HopDongCung` ord32 vis=1 (13 rows/13 canread mỗi key) · 3 root vẫn vis=0 · rename prefix `Duy…` ×2 · `Pe%` 197/185. 🔴 **FAIL #9 — BẮT ĐƯỢC REGRESSION NGOÀI CHECKLIST:** Serilog `Revoked 9 permission rows … Hợp đồng/Danh mục khỏi non-Admin` ⇒ đo lại grant-38-key của đợt-1: **47/494 canread, 0 key còn 13** (Admin=38 · Procurement=9 · 11 role còn lại=0, mất 447). Gốc = `DbInitializer.cs:2203-2236` **`RevokeTemporarilyHiddenModulesAsync` UNGATED chạy MỖI startup**, tập revoke TRÙNG KHỚP grant-set ⇒ **grant SQL tay không bao giờ bền, phải sửa CODE**. ⚠️⚠️ **BÀI HỌC LỚN NHẤT — bẫy ĐO-TRƯỚC-RECYCLE: pool restart nằm ở CUỐI deploy-window, nên đo DB lúc run còn `running` = đo trạng thái CŨ, KHÔNG chứng minh được 'sống sót recycle'. Mọi mục durability PHẢI đo SAU `status=success`.** (đợt-1 tao đo 11:46 vs restart 11:49 → kết luận sai). ⚠️ deploy `Remove-Item …pi\*` **xoá luôn `logs/`** ⇒ Serilog chỉ còn từ lần deploy cuối, không truy ngược được restart trước. ⚠️ prod Identity table = **`Roles`** không `AspNetRoles` (#472 tái xác nhận). Đợt-2 tự nó ship ĐÚNG — KHÔNG rollback. Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-1a47a61.md`. Tag `[run-423, partial-8-9, do-truoc-recycle-trap, revoker-ungated-durability, marker-count-per-module, gate-562]`
|
||||
|
||||
- **07-29 verify `b5799fc` (FE-User: Tổng quan tất cả luồng duyệt — pipeline 4 GĐ) [S159 L8, FE-USER-ONLY 1 file-code, ghi-đĩa-suốt-lượt]:** **PASS 9/9** — Run **#422** (id=535) success **5m59s** (11:43:34→11:49:33+07); gate **562 EXACT** (45 D + **517** I, `Failed!`×0 toàn log). NO-Mig đúng kỳ vọng (diff `src/Backend/*`+`*Migrations*`=0 ⇒ KHÔNG query DB; Mig 68/89-table). Range **8 commit/37 file** (7 `wal:`) — chỉ `fe-user/src/pages/UserDashboardPage.tsx` thoát 7-glob ⇒ CI fire đúng. 🔑 **KỸ THUẬT MỚI — marker PHÂN-BIỆT-PHIÊN-BẢN (mạnh hơn marker-hiện-diện):** bản designer gốc ghi `Pipeline 4 giai đoạn`, bản sau review-fix ghi `Toàn trình 4 giai đoạn` ⇒ bundle prod có **`Toàn trình`=1 & `Pipeline`=0** ⟹ chứng prod chạy bản ĐÃ-FIX, không chỉ 'có nội dung mới'. Dùng khi review sửa CHỮ: chọn cặp chuỗi cũ/mới làm phép phân-biệt. ⚠️ **Bẫy comment-strip:** `grep -c` source ra 2 mà bundle=1 — occurrence dư nằm ở COMMENT đầu file (minifier strip) ⇒ so bundle với **occurrence-CODE**, đừng so grep-source thô. ⚠️ **Bẫy hình-dạng-truy-vấn (suýt hô cờ đỏ):** control `Pe` ra 182/182 vs kỳ vọng 197/185 — do tao dùng `LEFT(MenuKey,3)='Pe_'` còn gốc là `LIKE 'Pe%'` (+`Permissions`1/1+`Personal`13/1+`PeWorkflows`1/1=+15/+3). **LỆCH-số ⇒ truy PHẠM-VI-QUERY trước khi kết luận drift.** Bundle: user js `DptYR4wL`→**`0GO8mgrG`** css `BRCvEHvC`→`BARVqkP-` (1.584.514B, LM 11:49:05 in-window); admin js `8-QYcMOg`→`BHodkPNV` css `DiNJjaoo` FROZEN (#69 mode-A + REFINE). Control 2 tầng: fake-hash & **hash CŨ** đều `ct=text/html` 876B ⇒ bundle cũ biến mất = chứng ghi-đè. Smoke health live+ready 200 + 2 FE 200. **M7 menu-data: 3 root IsVisible=0 · 38-key grant min=max=13 · `Pe%` 197/185 — ⚠️ ĐÍNH CHÍNH (đợt-2 bắt): đo lúc 11:46 tức TRƯỚC pool-restart ~11:49 ⇒ KHÔNG chứng minh được 'sống sót recycle'; phần 38-key sau đó ĐÃ MẤT (xem entry `1a47a61`).** Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-b5799fc.md`. Tag `[run-422, pass-9-9, marker-phan-biet-phien-ban, comment-strip-trap, query-shape-not-drift, gate-562]`
|
||||
|
||||
- _(**S157 #419 `a52a91e` PE cảnh-báo amber ô Địa-điểm (FE 2-app) GO 9/9** — gate 562 [45+517, khớp canonical STATUS cả tách-phần]; NO-Mig; 🔑 byte-marker **count=2/app = khớp SỐ FILE trong diff** ["đúng-BỘI-SỐ" > "tìm thấy ≥1"]; js-rotate ×2 css-FROZEN ×2; control âm 2 tầng [fake-hash + **hash CŨ** đều `ct=text/html` ⇒ bundle cũ biến mất = chứng ghi-đè]; self-correct on-disk "6 file"→13 commit/26 file · verbatim → `archive/2026-07.md` @S159-curate)_
|
||||
- _(**#416 S155 `b1bae77` Workflow duyệt-TẠI-CHỖ +Mig 68 APPLIED-PROD 6/6** [gate 551; FLAG 'mig rớt khỏi commit' loại-trừ 3 lớp — mạnh nhất `GET /approval-workflows-v2` trả cột ×54 **materialize qua EF từ DB thật**] · **#407 S135 `4510cea` mã-dự-án normalize 5/5** [gate 532] · **#399 S134 `6664a61` PE lũy-kế 0-mig 5/5** [gate 528; 🔑 `ct=text/html` discriminator SẠCH HƠN size-919B vì shell-size drift] · **#398 S133 `d4fbced` +Mig 67 budget-freeze 5/5** [gate 520; backfill 18/18; python text=True crash cp1252 → dùng bytes] · verbatim → `archive/2026-07.md` via `_INDEX`)_
|
||||
@ -33,6 +35,7 @@ cicd-lane đôi khi trả nhầm slice transcript (memory-curation) thay verdict
|
||||
- **Bundle hash unchanged = ship FAIL** — push+action success nhưng prod không đổi. Verify via INDEX.HTML ref (`curl -s https://admin.solutions.com.vn/ | grep -oE '/assets/index-[A-Za-z0-9_-]+\.(js|css)'`), NOT by GETting a hash-named asset directly. ⚠️ verify MUST sau status=success (Run #242 false-positive: check khi "running" → stale hash).
|
||||
- **🔴 #69 TWO-MODE (S72 #312 + S83 #333) — FE hash vừa có thể ROTATE vừa có thể FROZEN.** deploy.yml copy `dist\*` UNCONDITIONALLY mọi run (path-filter gate cả workflow, không per-step) ⇒ 0-FE-change vẫn rotate được (mode-A); ngược lại src y hệt ⇒ Vite ra byte-identical ⇒ hash FROZEN (mode-B). **Cả hai lành tính ⟹ hash-delta KHÔNG phải ship-proof.** Ship-proof THẬT = `Last-Modified` in deploy-window + real-size + byte-marker. Muốn biết FE có đổi thật → diff `fe-*/src` trong range.
|
||||
- **⚠️ SPA-fallback 200 trap (S72):** server rewrite `/*`→`index.html` ⇒ GET `/assets/index-<BỊA>.js` vẫn **200**. Discriminator sạch = **`Content-Type`** (`text/html` ~876-919B = trap · `application/javascript` ~1,6MB = thật); size drift per-build nên đừng neo số byte. **Hash CŨ rơi về text/html = bundle cũ biến mất khỏi đĩa = chứng ghi-đè (control âm tầng-2).**
|
||||
- **🔴 Durability: đo SAU recycle, không đo trước** — app-pool restart ở CUỐI deploy-window ⇒ query DB lúc `running` = trạng thái CŨ. Và `RevokeTemporarilyHiddenModulesAsync` (`DbInitializer.cs`) UNGATED mỗi startup revoke non-Admin trên `Contracts`/`Ct_*`/`Master`/`Suppliers`/`Projects`/`Departments`/`Catalog*`/`Hrm*`/`Off*`/`Personal` ⇒ **mọi grant SQL tay trên các key này CHẾT ở deploy kế** (S159 #423: 494→47 canread). Data-change ngoài CI phải re-verify SAU status=success.
|
||||
- **Migration drift prod vs repo** — compare `ls .../Persistence/Migrations/*.cs` vs `sqlcmd __EFMigrationsHistory`. Fix: check `Program.cs`/DbInitializer `app.MigrateDatabase()` + app pool recycle. Mig-applied proof = `__EFMigrationsHistory` top==repo-HEAD; stuck-old ⟹ pool didn't recycle ⟹ FAIL even if status=success+bundle-rotated.
|
||||
|
||||
---
|
||||
@ -61,10 +64,10 @@ cicd-lane đôi khi trả nhầm slice transcript (memory-curation) thay verdict
|
||||
- **Prod:** api/admin/eoffice `.solutions.com.vn` · SSH `ssh vietreport-vps` (Administrator, id_ed25519) · IIS phys paths: API `C:\inetpub\solution-erp\api` · admin `\fe-admin` · user `\fe-user`. DB `.\SQLEXPRESS`/`SolutionErp`/`vrapp` SQL-auth. **Conn key = `ConnectionStrings.Default` (NOT `DefaultConnection`)**. DB pw = `buKL3TGBkD0wDDbYVw65QeX9` (User Id=`vrapp`; ⚠️ Password field has NO `vrapp/` prefix — S89 login-failed when prefix included; read verbatim from prod `appsettings.Production.json` ConnectionStrings.Default when `$env:PROD_DB_PASSWORD` empty). ⚠️ skill-doc path `C:\inetpub\apps\SolutionErp\Api` STALE.
|
||||
- **SSH→PS quoting (S42):** nested bash→ssh→powershell mangles `$var`/`\"` → use `iconv UTF-16LE | base64` → `powershell -EncodedCommand $B64`; OR write ps1-file + `powershell -File $(cygpath -w)`. sqlcmd over SSH direct `-W -h -1` pw-inline. sys-catalog string-concat → `COLLATE DATABASE_DEFAULT` (collation conflict).
|
||||
- **Tests baseline:** **562 PASS** (45 Domain + 517 Infra · 0 fail/skip; run #422 `b5799fc` 07-29; khớp canonical `docs/STATUS.md`). 🔑 **Số cụ thể lấy ở web-UI log `https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/{run_number}/jobs/0/logs` (~18KB, KHÔNG có `/api/v1/` — api/v1 runs+tasks logs đều 404)** → mỗi project 1 dòng `Passed! - Failed: 0, Passed: N, Skipped: 0`; đối chiếu TÁCH-PHẦN (45/517) chứ đừng chỉ khớp tổng. Delta test mới = so run trước.
|
||||
- **Mig latest repo: Mig 68 `AddPeAllowApproverDelete`** (`20260727033522`, S155 `b1bae77` — AddColumn `AllowApproverDelete` bit NOT NULL def-0 trên **`ApprovalWorkflowLevels`**, no-new-table; VERIFIED-APPLIED-PROD history-top + col-present + sys.tables **89**). Prev Mig 67 `AddPeApprovedBudgetSnapshot` / 66 `AddPeApprovedPriceRange` / 65 backfill-invariant / 62 `ExpandSupplierFields` (full table → docs/CLAUDE.md). Path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/` (68 `.cs` excl Designer/Snapshot). Prod check `sqlcmd __EFMigrationsHistory ORDER BY MigrationId DESC`. ⚠️ **`sys.tables`(is_ms_shipped=0)=89** — AddColumn/data-only/enum-additive don't change count; no-new-table commit ⟹ 89 correct, don't FAIL. **NO-Mig proof = history NOT-advance + empty `git diff <base>..<head> -- '*Migrations*'`.**
|
||||
- **Bundle hash live:** ship-baseline = run #422 (07-29) admin js `BHodkPNV`/css `DiNJjaoo` · eoffice js `0GO8mgrG`/css `BARVqkP-` (user real-size 1.584.514B, LM 11:49:05+07). ⚠️ Đây là **SNAPSHOT-per-run, KHÔNG phải mốc ổn định** (#69 TWO-MODE) → LUÔN re-snapshot LIVE sau status=success; ship-proof = LM-in-window + real-size + marker, KHÔNG phải hash-delta. ⚠️ id ≠ run_number (key theo head_sha).
|
||||
- **Mig latest repo: Mig 68 `AddPeAllowApproverDelete`** (`20260727033522`, S155 — AddColumn bit trên `ApprovalWorkflowLevels`, no-new-table; VERIFIED-APPLIED-PROD). Path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/` (68 `.cs` excl Designer/Snapshot). Prod check `sqlcmd __EFMigrationsHistory ORDER BY MigrationId DESC`. ⚠️ **`sys.tables`(is_ms_shipped=0)=89** — AddColumn/data-only/enum-additive KHÔNG đổi số; no-new-table commit ⟹ 89 đúng, đừng FAIL. **NO-Mig proof = history NOT-advance + empty `git diff <base>..<head> -- '*Migrations*'`.** Bảng mig đầy đủ → skill `ef-core-migration` + `docs/STATUS.md`.
|
||||
- **Bundle hash live:** ship-baseline = run #423 (07-29 đợt-2) admin js `D6Pz7nfV`/css `B1ErASuI` · eoffice js `Bpb8WEuY`/css `7oAYFlzM`. ⚠️ **SNAPSHOT-per-run, KHÔNG phải mốc ổn định** (#69 TWO-MODE) → LUÔN re-snapshot LIVE sau status=success; ship-proof = LM-in-window + real-size + marker, KHÔNG phải hash-delta. ⚠️ id ≠ run_number (key theo head_sha).
|
||||
- **Bearer:** admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM, gotcha #44 check).
|
||||
- **API Serilog log (S118 correction):** real sink = `C:\inetpub\solution-erp\api\logs\solution-erp-YYYYMMDD.log` (lowercase `logs`, rolling daily). ⚠️ skill-runbook path `…\Logs\log-YYYYMMDD.txt` STALE → empty grep. MinimumLevel Default=Information (DbInitializer `LogInformation` seed/revoke lines DO persist) — Microsoft/System overridden Warning (no "Now listening" INFO). **Startup seed-race audit pattern (durability deploys):** grep this log for revoke-line THEN seeder-line same-second → "N added + M upgraded" proves seeder actively flipped rows revoke knocked down (0-upgraded = seeder no-op = FAIL flag).
|
||||
- **API Serilog log:** sink THẬT = `C:\inetpub\solution-erppi\logs\solution-erp-YYYYMMDD.log` (lowercase `logs`; skill-runbook path `…\Logs\log-*.txt` STALE → grep rỗng). Default=Information (DbInitializer seed/revoke lines CÓ ghi). ⚠️ **deploy `Remove-Item …pi\*` xoá luôn `logs/`** ⇒ chỉ còn từ lần deploy cuối, không truy ngược restart trước. Dùng grep revoke-line + seeder-line cùng-giây để audit seed-race.
|
||||
|
||||
## 🔑 Critical config (flag commit nếu tái xuất)
|
||||
Node CI `20.x` (`feedback_node_cicd`) · MediatR `12.4.1` (gotcha #1, flag `Version="14`) · Swashbuckle `6.9.0` (gotcha #2) · act_runner manual checkout (#39) · npm cache DISABLED (#40, flag `cache: npm`)
|
||||
@ -82,7 +85,7 @@ BE (test+build) ~90s · FE × 2 ~60s/app · deploy ~30s · **total ~3min code /
|
||||
## 📅 Recent runs (compressed — verbatim → archive via `_INDEX.md`)
|
||||
|
||||
- _(**S98-S132 #383-#397/#485-#496 — GOVERNANCE/FE/SECURITY streak, all GO** (gate leo 440→509): 🔑 bài-học còn dùng — **AS-6 #41 soi TỪNG file vs 7-glob** (`.ps1`/`.json` thoát `scripts/**.md` ⇒ governance non-.md VẪN trigger CI; memory-push thì HẾT trigger từ #495) · `conclusion:None` dù success ⇒ tin `status` · **411-refine**: endpoint MỚI bodyless-POST trả **411** (IIS Length-Required, pre-auth) KHÔNG phải 404 → re-probe CÓ body, 401/415 ⇒ đã wire · bare `/health`=404 UNMAPPED, thật là `/health/live`+`/ready` (đừng FAIL nhầm) · **LM mới hơn cửa-sổ đã verify = detector 'có run mình bỏ sót'** · Mig 63/64/65/66 + Mig 67 đều APPLIED-PROD, 89-table giữ · verbatim → `archive/2026-07.md` via `_INDEX`)_
|
||||
- _(**PASS-pattern library S69b→S104 #307-#494** all GO — 🔑 reusable verify-recipes: **SCHEMA-ADD+DATA-UN-CRAM** [#488 Supplier 9→27 Mig62: AddColumn×18-exact + 89-invariant + un-cram 4-NCC + DTO-live] · **DATA-FIX-BACKFILL** [#484 Mig61: Mig-top==HEAD + target-rows-flip-EXACT + control-untouched + derived-API-FLIP-live] · **DATA-SEED-PASS** [#477: pre/post-DB-row-delta + DLL-mtime + w3wp-recycle]; #482 Mig60 EF-ternary-SQL 200≠500; #472 PROD Identity NON-prefix `Roles`; #470 no-resurrect DB-count-diff; Mig54-62 applied-prod; #348 411→401 · verbatim → git + `2026-06/07.md`)_
|
||||
- _(**PASS-pattern library S69b→S104 #307-#494** all GO — recipe tái dùng: **SCHEMA-ADD+DATA-UN-CRAM** [#488 Supplier 9→27 Mig62: AddColumn×18-exact + 89-invariant + DTO-live] · **DATA-FIX-BACKFILL** [#484 Mig61: Mig-top==HEAD + target-rows-flip-EXACT + control-untouched + derived-API-FLIP-live] · **DATA-SEED-PASS** [#477: pre/post-DB-row-delta + DLL-mtime + w3wp-recycle]; #482 Mig60 EF-ternary-SQL 200≠500; **#472 PROD Identity table NON-prefix `Roles`** (không `AspNetRoles`); Mig54-62 applied-prod; #348 411→401 · verbatim → git + `2026-06/07.md`)_
|
||||
- **Older (S83 #325 ← S29 #232) → git `d2f52ba` + `archive/2026-06.md`** (incl #291 06-16 FAIL [gotcha #65]); pre-S38 → `archive/2026-05-*`.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user