[CLAUDE] Docs: S67 session-end closeout — Hồ sơ NS visual + fe-admin mirror + PE Link file:// + research auto-open (6 deploy #297->#302) + harvest 4 agent-memory
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -50,7 +50,7 @@ Read-only CI/CD + post-deploy verifier SOLUTION_ERP. Polls Gitea Actions API, ve
|
|||||||
- **Tests baseline:** **263 PASS** (S62 Run #286 sha 7926c21 spec; 45 Domain + 218 Infra — em-main supplied; supersedes prev 228/240/256). CI gate runs both test projects BEFORE build/deploy → status=success ⟹ test gate passed (`tasks` endpoint reports terminal as `status:success`, `conclusion` field NOT populated). Local grep undercounts (Theory/InlineData) — trust CI conclusion. Phase 9 UAT mode skip per chunk OK.
|
- **Tests baseline:** **263 PASS** (S62 Run #286 sha 7926c21 spec; 45 Domain + 218 Infra — em-main supplied; supersedes prev 228/240/256). CI gate runs both test projects BEFORE build/deploy → status=success ⟹ test gate passed (`tasks` endpoint reports terminal as `status:success`, `conclusion` field NOT populated). Local grep undercounts (Theory/InlineData) — trust CI conclusion. Phase 9 UAT mode skip per chunk OK.
|
||||||
- **Mig latest repo:** **Mig 52 `20260616035929_AddHoSoLinkToPurchaseEvaluation`** (S65; PE +HoSoLink hyperlink-NAS, AddColumn-only no new table). Prev Mig 51 `AddDepartmentParentId` (S65 Department.ParentId loose-Guid org-tree, AddColumn-only) + Mig 50 `ReplaceBudgetModuleWithPeWorkItemBudgets` (S61 Budget→PeWorkItemBudgets net-reduce). Path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/` (52 mig .cs non-designer total). Prod check `sqlcmd __EFMigrationsHistory ORDER BY MigrationId DESC TOP 5`. ⚠️ Table-count: `sys.tables` (is_ms_shipped=0, excl mighist) = **88** (S62 Run #286 verified — S61 Budget-replace DROPPED tables 93→88). Narrative-93 is STALE pre-S61 — when commit touches no schema, 88 is correct, don't FAIL on 88↔93. Always cross-ref COMMIT scope vs ambient count.
|
- **Mig latest repo:** **Mig 52 `20260616035929_AddHoSoLinkToPurchaseEvaluation`** (S65; PE +HoSoLink hyperlink-NAS, AddColumn-only no new table). Prev Mig 51 `AddDepartmentParentId` (S65 Department.ParentId loose-Guid org-tree, AddColumn-only) + Mig 50 `ReplaceBudgetModuleWithPeWorkItemBudgets` (S61 Budget→PeWorkItemBudgets net-reduce). Path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/` (52 mig .cs non-designer total). Prod check `sqlcmd __EFMigrationsHistory ORDER BY MigrationId DESC TOP 5`. ⚠️ Table-count: `sys.tables` (is_ms_shipped=0, excl mighist) = **88** (S62 Run #286 verified — S61 Budget-replace DROPPED tables 93→88). Narrative-93 is STALE pre-S61 — when commit touches no schema, 88 is correct, don't FAIL on 88↔93. Always cross-ref COMMIT scope vs ambient count.
|
||||||
- **Bearer:** admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM, gotcha #44 check)
|
- **Bearer:** admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM, gotcha #44 check)
|
||||||
- **Bundle hash live S70:** admin `BDwV5d0X` (FROZEN since S68 Run #293 — fe-admin untouched S69-S70) · user `DbVv6rsf` (Run #295 sha 456c7a7 — ROTATED from `CZfo_PFZ`, FE-user-only EmployeesListPage layout-2col + tô-màu 1 file). ⚠️ ASYMMETRIC-deploy lesson (S66): FE-one-app commit → that app's bundle MUST rotate + OTHER app MUST stay frozen; admin-rotate-when-only-fe-user-changed = anomaly → flag. S50 mid-deploy transient lesson: pre-success snapshot can show intermediate FE copy in-flight — re-confirm hash AFTER status=success ALWAYS (anti-pattern #3). FROZEN-expectation runs (BE-only or other-app): hash MUST stay = live pre-deploy value; rotate w/o relevant FE change = anomaly.
|
- **Bundle hash live S72:** admin `xkSz9BfE` (Run #298 sha 292d64d — ROTATED from `BDwV5d0X`, broke S68→S71 frozen-streak; FE-admin mirror EmployeesListPage + index.css accent 2 files) · user `BumgrwCJ` (Run #297 sha ab4e681 S71 — FROZEN through S72 deploy-2 since fe-user untouched). ⚠️ ASYMMETRIC-deploy lesson (S66): FE-one-app commit → that app's bundle MUST rotate + OTHER app MUST stay frozen; admin-rotate-when-only-fe-user-changed = anomaly → flag. S50 mid-deploy transient lesson: pre-success snapshot can show intermediate FE copy in-flight — re-confirm hash AFTER status=success ALWAYS (anti-pattern #3). FROZEN-expectation runs (BE-only or other-app): hash MUST stay = live pre-deploy value; rotate w/o relevant FE change = anomaly.
|
||||||
- **DB pw (S42, when `$PROD_DB_PASSWORD` empty):** `vrapp/buKL3TGBkD0wDDbYVw65QeX9` read from `C:\inetpub\solution-erp\api\appsettings.Production.json`→`ConnectionStrings.Default`. ⚠️ Skill-doc path `C:\inetpub\apps\SolutionErp\Api` is STALE → real path `C:\inetpub\solution-erp\api`. sqlcmd over SSH works direct (no UTF-16 encode needed). ⚠️ sys-catalog string-concat queries hit collation conflict (`Latin1_General_CI_AS_KS_WS` vs `SQL_Latin1_General_CP1_CI_AS`) → add `COLLATE DATABASE_DEFAULT` per concatenated column.
|
- **DB pw (S42, when `$PROD_DB_PASSWORD` empty):** `vrapp/buKL3TGBkD0wDDbYVw65QeX9` read from `C:\inetpub\solution-erp\api\appsettings.Production.json`→`ConnectionStrings.Default`. ⚠️ Skill-doc path `C:\inetpub\apps\SolutionErp\Api` is STALE → real path `C:\inetpub\solution-erp\api`. sqlcmd over SSH works direct (no UTF-16 encode needed). ⚠️ sys-catalog string-concat queries hit collation conflict (`Latin1_General_CI_AS_KS_WS` vs `SQL_Latin1_General_CP1_CI_AS`) → add `COLLATE DATABASE_DEFAULT` per concatenated column.
|
||||||
|
|
||||||
## 🔑 Critical config (flag commit nếu tái xuất)
|
## 🔑 Critical config (flag commit nếu tái xuất)
|
||||||
@ -68,14 +68,16 @@ BE (test+build) ~90s · FE × 2 ~60s/app · deploy ~30s · **total ~3min code /
|
|||||||
|
|
||||||
## 📅 Recent runs (FIFO — older → archive/git)
|
## 📅 Recent runs (FIFO — older → archive/git)
|
||||||
|
|
||||||
|
- **2026-06-16 S76 Run #302 (run_number 302, id416) sha=`536dd6b` PASS ~4m (FE BOTH-APP additive: PE "Link hồ sơ ổ mạng" render upgrade — đường-dẫn-ổ-mạng từ chữ+Copy → `<a href=file://…>` bấm-thử mở Explorer + GIỮ nút Copy dự phòng. 2 file `PeDetailTabs.tsx` fe-user+fe-admin SHA256-IDENTICAL `b415023b…`, +46/−14 mỗi file, NO BE/mig/index.css/Employee-page; deploy 6/6 session after #297/#298/#299/#300/#301 all PASS):** Push 2 files `{fe-admin,fe-user}/src/components/pe/PeDetailTabs.tsx`. `.tsx` → not in paths-ignore → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default`. Run IN-PROGRESS first 6 polls (running 14:54:20→14:56:57) — correctly did NOT verify-bundle-mid-flight (anti#3); pre-deploy baseline captured BEFORE poll-loop: admin `I1fpLeYw` (S75 #301 live) + user `DrQYkzh0` (S75 #301 live) — both == spec baseline. Polled iter7 status=success (started ~14:53 → success 14:57:13 ≈4m). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **286** baseline (45D+241I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — `tasks` endpoint terminal=`status:success` doesn't populate `conclusion`, trust success). **★ BUNDLE BOTH ROTATE (the change-point — FE-BOTH-app, both PeDetailTabs changed ⟹ both bundles MUST rotate; verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient — anti#3): admin ROTATE `I1fpLeYw→CcrZqfht`** ✓ (file:// link shipped) **+ user ROTATE `DrQYkzh0→DniDFUB_`** ✓ (same component shipped). BOTH required per spec → BOTH did (mirror S74/S75 pure-FE-both-app pattern — both same-SHA256 file ⟹ both rotate; frozen sibling here = ship-fail flag). Smoke **4×200**: api `/health/ready`+`/health/live` + admin root + eoffice root. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (`git diff --name-only 536dd6b~1 536dd6b -- '*Migrations*'` = EMPTY; FE cannot alter schema → top did NOT advance; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). **sys.tables=88 verified** (sqlcmd COUNT excl mighist — unchanged, no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "link file:// bấm mở Explorer / nút Copy" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged+tables88; SHA256-identical-between-2-apps is a SOURCE-claim (git), not runtime DOM-equality (file:// scheme browsers thường block từ https-origin → click có thể no-op tùy browser, đó là lý do GIỮ Copy dự phòng — không kiểm chứng được qua curl). **LESSON: pure-FE-BOTH-app additive verify (6th consecutive deploy this session, both apps same component SHA256-identical) = both bundles MUST ROTATE (≠ asymmetric one-app where sibling frozen; ≠ BE-only where both frozen). Migration top + sys.tables MUST stay = prev (FE-only). No BE call-site/DTO/endpoint smoke (no API surface — render-only). TOOLING (re-confirmed S75): Bash tool EATS inline `$var`/`$env:` in `powershell -Command` → write PowerShell to `.ps1` + run `-File`; `certutil -hashfile … SHA256` for SHA256 (NOT findstr-pipe — quoting breaks); parse Gitea `tasks` via `Invoke-RestMethod`+native object (match `head_sha -eq sha`, `limit=N` ignored); SSH→sqlcmd base64 `EncodedCommand` (UTF-16LE, no `$` in B64 passes bash clean), CLIXML progress-stream stdout harmless; read DB pw from prod appsettings when PROD_DB_PW empty (path `C:\inetpub\solution-erp\api`, key `ConnectionStrings.Default`). NEVER fixed code (READ-only).** Tag `[s76, run302, pass, fe-both-app-pe-link-hoso-file-scheme, fe-both-2files-sha256-identical-b415023b, bundle-BOTH-rotate-CcrZqfht-DniDFUB_, no-mig-top-stays-mig52, tables88-verified, deploy6of6, no-regression, test286]`.
|
||||||
|
- **2026-06-16 S75 Run #301 (run_number 301, id415) sha=`6df1b2d` PASS ~2.5m (FE BOTH-APP additive: PE "Link hồ sơ" auto-detect render — `http(s)`→hyperlink bấm-mở (giữ nguyên) / đường dẫn ổ mạng `O:\...`→chữ+nút Copy. 2 file `PeDetailTabs.tsx` fe-user+fe-admin SHA256-IDENTICAL `da0884a5…`, NO BE/mig/index.css/Employee-page; deploy 5/5 session after #297/#298/#299/#300 all PASS):** Push 2 files `{fe-admin,fe-user}/src/components/pe/PeDetailTabs.tsx`. `.tsx` → not in paths-ignore → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default`. Run IN-PROGRESS first poll (running 14:31) — correctly did NOT verify-bundle-mid-flight (anti#3); pre-deploy baseline captured BEFORE poll-loop: admin `PxiZQkaw` (S74 #300 live) + user `B36hGoKd` (S74 #300 live) — both == spec baseline. Polled iter4 status=success (started ~14:31 → success 14:33:21 ≈2.5m — fastest streak, FE-only no big BE build). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **286** baseline (45D+241I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — `tasks` endpoint terminal=`status:success` doesn't populate `conclusion`, trust success). **★ BUNDLE BOTH ROTATE (the change-point — FE-BOTH-app, both PeDetailTabs changed ⟹ both bundles MUST rotate; verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient — anti#3): admin ROTATE `PxiZQkaw→I1fpLeYw`** ✓ (Link-hồ-sơ auto-detect shipped) **+ user ROTATE `B36hGoKd→DrQYkzh0`** ✓ (same component shipped). BOTH required per spec → BOTH did (mirror S74 pure-FE-both-app pattern — both same-SHA256 file ⟹ both rotate; frozen sibling here = ship-fail flag). Smoke **3×200**: api `/health/ready` + admin root + eoffice root. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (`git diff --name-only 6df1b2d~1 6df1b2d -- '*Migrations*'` = EMPTY; FE cannot alter schema → top did NOT advance; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). **sys.tables=88 verified** (sqlcmd COUNT excl mighist — unchanged, no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "hyperlink bấm-mở / nút Copy hiện đúng" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged+tables88; SHA256-identical-between-2-apps is a SOURCE-claim (git), not runtime DOM-equality (auto-detect http-vs-O:\ branching is component logic, not provable by curling bundle). **LESSON: pure-FE-BOTH-app additive verify (5th consecutive deploy this session, both apps same component SHA256-identical) = both bundles MUST ROTATE (≠ asymmetric one-app where sibling frozen; ≠ BE-only where both frozen). Migration top + sys.tables MUST stay = prev (FE-only). No BE call-site/DTO/endpoint smoke (no API surface — render-only change). TOOLING (re-confirmed S74): Bash tool EATS inline `$var`/`$env:` in `powershell -Command` → write PowerShell to `.ps1` + run `-File`; parse Gitea `tasks` via `Invoke-RestMethod`+native object (match `head_sha -eq sha`, `limit=N` ignored); SSH→sqlcmd base64 `EncodedCommand` (UTF-16LE, no `$` in B64 passes bash clean), CLIXML progress-stream stdout harmless; read DB pw from prod appsettings when PROD_DB_PW empty (path `C:\inetpub\solution-erp\api`). NEVER fixed code (READ-only).** Tag `[s75, run301, pass, fe-both-app-pe-link-hoso-autodetect, fe-both-2files-sha256-identical, bundle-BOTH-rotate-I1fpLeYw-DrQYkzh0, no-mig-top-stays-mig52, tables88-verified, deploy5of5, fastest-2.5m, ps1-file-not-inline-dollar, no-regression, test286]`.
|
||||||
|
- **2026-06-16 S74 Run #300 (id414) sha=`91aaf05` PASS ~5m (FE BOTH-APP list-redesign: bảng list 3-cột → flex-row gọn hết-tràn-ngang-rail + đồng nhất cỡ chữ (header text-xl→lg, list name 13px) — 2 file `EmployeesListPage.tsx` fe-user+fe-admin SHA256-IDENTICAL `37d7cc6c…`, NO BE/mig/index.css; deploy 4/4 session after #297/#298/#299 all PASS):** Push 2 files `{fe-admin,fe-user}/src/pages/hrm/EmployeesListPage.tsx`. `.tsx` → not in paths-ignore → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...buKL3TGBkD0wDDbYVw65QeX9`). Run IN-PROGRESS first poll (running 14:22) — correctly did NOT verify-bundle-mid-flight (anti#3); pre-deploy baseline snapshot captured BEFORE poll-loop: admin `xkSz9BfE` (S72 #298 live) + user `BumgrwCJ` (S71 #297 live, FROZEN-streak through S73 BE-only) — both == spec baseline. Polled iter5 status=success (started ~14:20 → success ~14:25 ≈5m). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **286** baseline (45D+241I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — `tasks` endpoint terminal=`status:success` doesn't populate `conclusion`, trust success). **★ BUNDLE BOTH ROTATE (the change-point — FE-BOTH-app, both pages changed ⟹ both bundles MUST rotate; verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient — anti#3): admin ROTATE `xkSz9BfE→PxiZQkaw`** ✓ (EmployeesListPage flex-row shipped) **+ user ROTATE `BumgrwCJ→B36hGoKd`** ✓ (same page shipped — user un-froze from S71-S73 frozen-streak, correct now fe-user finally changed). BOTH required per spec → BOTH did. ⚠️ Distinct from S68 (cross-stack BE+FE both-rotate) — this is PURE-FE-both-app both-rotate (no BE/mig). Smoke **3×200**: api `/health/ready` + admin root + eoffice root. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (commit 0 mig files; FE cannot alter schema → top did NOT advance; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). **sys.tables=88 verified** (sqlcmd COUNT excl mighist — unchanged, no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "flex-row gọn/hết-tràn-rail/đồng nhất cỡ chữ" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged+tables88; SHA256-identical-between-2-apps is a SOURCE-claim (git), not runtime DOM-equality. **LESSON: pure-FE-BOTH-app verify (both apps same file, SHA256-identical) = both bundles MUST ROTATE (≠ asymmetric S70/S71 one-app where sibling stays frozen; ≠ S73 BE-only where both stay frozen) — a frozen sibling here would = ship-fail flag; user un-froze from multi-session frozen-streak = EXPECTED when fe-user finally changes (streak-break normal). Migration top + sys.tables MUST stay = prev (FE-only). No BE call-site/DTO/endpoint smoke (no API surface). **TOOLING (re-confirmed S73): Bash tool wrapper EATS inline `$var`/`$matches[1]`→`[1]` in `powershell -Command` strings AND `$env:`→mangled — MUST write PowerShell to a `.ps1` file + run `-File` (no inline `$` survives bash eval); python3 broken on box. Parse Gitea `tasks` via `Invoke-RestMethod`+native object (match by `head_sha -like sha*`); `limit=N` ignored. SSH→sqlcmd: base64-encode (UTF-16LE via `[Convert]::ToBase64String([Text.Encoding]::Unicode...)`) the query `.ps1` → `ssh vps "powershell -EncodedCommand $B64"` (B64 has no `$` so passes bash clean); CLIXML progress-stream on stdout harmless, data lines clean. Read DB pw via `ssh→appsettings.Production.json ConvertFrom-Json .ConnectionStrings.Default` when PROD_DB_PW empty (path `C:\inetpub\solution-erp\api`). NEVER fixed code (READ-only).** Tag `[s74, run300, pass, fe-both-app-list-redesign-flexrow, fe-both-2files-sha256-identical, bundle-BOTH-rotate-PxiZQkaw-B36hGoKd, user-unfroze-from-s71streak, no-mig-top-stays-mig52, tables88-verified, deploy4of4, ps1-file-not-inline-dollar-eaten, no-regression, test286]`.
|
||||||
|
- **2026-06-16 S73 Run #299 (id413) sha=`bcd619d` PASS ~3m (TESTS-ONLY BE: +3 files `tests/SolutionErp.Infrastructure.Tests/Application/{DepartmentTreeTests,PeHoSoLinkTests,HrmProfilePermissionSeedTests}.cs` = +23→286 total (45D+241I). NO prod code, NO FE, NO migration; deploy 3/3 session after #297/#298 both success):** `.cs` not in paths-ignore → full pipeline RAN. Run IN-PROGRESS first poll (running 14:06) → polled iter4 status=`success` (~14:09 ≈3m); `conclusion` empty (terminal=success, trust). **CI test gate = the focus: gate runs BOTH test projects BEFORE build ⟹ status=success ⟹ 23 new tests passed on CI (not just local 286).** Could NOT extract exact CI count — Gitea `runs/413/logs`+`jobs` endpoints all **404 anon** (logs web-UI-only without auth token; GITEA_TOKEN empty). Inferred 286 from success (gate-passes-pre-build invariant) — NOT log-confirmed numerically. **★ BUNDLE BOTH-FROZEN (BE-only ⟹ neither app may rotate), verified AFTER status=success +2nd-fetch STABLE no transient (anti#3): admin `xkSz9BfE` FROZEN ✓ + user `BumgrwCJ` FROZEN ✓** (==pre-deploy baseline both; rotate-on-BE-only = anomaly→none). Smoke **4×200**: api `/health/ready`+`/health/live`+admin root+eoffice root. **NO migration** — prod `__EFMigrationsHistory` top=`AddHoSoLinkToPurchaseEvaluation`(Mig52)==repo HEAD GIỮ NGUYÊN ✓ (prev-2 Mig51 `AddDepartmentParentId`+Mig50 `ReplaceBudgetModule…` chain intact; commit 0 mig files). **sys.tables=88** ✓ (sqlcmd excl mighist, unchanged). 0 regression, NO prod-data mutation (read curls+SELECT-only). **TOOLING LESSON (supersedes S72 #298): `python3`/`py -3` on this box = BROKEN ZKBioTime embed (`AssertionError: SRE module mismatch` on `import re`/`json`) — version banner works but stdlib import dies. USE PowerShell `Invoke-RestMethod`+native object access (NOT ConvertFrom-Json on cached temp file — temp got stale snapshot once) to parse Gitea tasks; `limit=N` param IGNORED (returns full 299, match by id anyway). SSH→sqlcmd: nested bash→ssh→PS ate `$var` (S42) → use `iconv UTF-16LE|base64`→`powershell -EncodedCommand`; CLIXML progress-stream noise on stdout is harmless, data lines clean. Read DB pw from prod `appsettings.Production.json`→`ConnectionStrings.Default` when PROD_DB_PW empty (path `C:\inetpub\solution-erp\api`). NEVER fixed code (READ-only).** Tag `[s73, run299, pass, tests-only-be, +23-test-286-CI-gate-inferred-not-logcount, bundle-both-frozen-xkSz9BfE-BumgrwCJ, no-mig-top-mig52, tables88, deploy3of3, python3-broken-use-powershell-IRM, no-regression]`.
|
||||||
|
- **2026-06-16 S72 Run #298 (run_number 298, id412) sha=`292d64d` PASS ~4m20s (FE-Admin MIRROR "Hồ sơ Nhân sự" master-detail từ fe-user: overwrite EmployeesListPage.tsx cũ 1200→1602 dòng SHA256-IDENTICAL với fe-user + index.css +4 accent palette teal/amberx/violet/greenx + utility `.icon-chip`/`.app-gradient-brand`/`.card-accent`/`.stat-value` — FE-ADMIN-ONLY 2 files, NO BE, NO migration, NO fe-user; ASYMMETRIC NGƯỢC deploy-1 S71 #297 (đó fe-user-rotate/admin-frozen, đây admin-rotate/user-frozen)):** Deploy 2/2 trong session (deploy-1 = `ab4e681` #297 PASS fe-user `BumgrwCJ`; #297=success TRƯỚC push này nên KHÔNG bị cancel — confirmed in tasks list). Push 2 files `fe-admin/src/index.css`(+81) + `fe-admin/src/pages/hrm/EmployeesListPage.tsx`(1020+/537−, 1476-line overwrite). `.tsx`+`.css` → not in paths-ignore → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...buKL3TGBkD0wDDbYVw65QeX9`). Run IN-PROGRESS first poll (running 13:52) — correctly did NOT verify-bundle-mid-flight (anti#3); pre-deploy baseline snapshot captured BEFORE poll: admin `BDwV5d0X` (S68 frozen-since, must rotate) + user `BumgrwCJ` (S71 deploy-1 live, must stay frozen). ⚠️ POLL-PARSER BUG: my `tr ','|grep -A4 '"id":412'` returned empty status ×10 iter (false negative — grep -A on tr-newlined JSON misanchors) → re-queried with `python3 json.load` → status=`success` (started 13:51:27 → updated 13:55:47 ≈4m20s). LESSON-tooling: parse Gitea tasks JSON via python3 NOT tr/grep -A (multi-field-per-object splits wrong); always cross-check with a clean parser before trusting empty-status. CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC NGƯỢC-deploy-1 (the change-point — FE-one-app verify) ALL PASS, verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient (anti#3): admin ROTATE `BDwV5d0X→xkSz9BfE`** ✓ (EmployeesListPage mirror + accent index.css shipped — admin un-froze from S68's BDwV5d0X frozen-streak S68→S71, now rotated correctly cho fe-admin change) **+ user FROZEN `BumgrwCJ`==deploy-1-baseline** ✓ (fe-user 0 files touched deploy-2 → MUST NOT rotate = correct; rotate-when-untouched = anomaly→flag). Health api live+ready **200/200** (real endpoints `/health/ready`+`/health/live`, NOT `/health`) + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact; commit 0 mig files — FE cannot alter schema → top did NOT advance). **sys.tables=88 verified** (sqlcmd COUNT excl mighist — unchanged, no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "mirror identical / chữ xanh đậm brand-800 / accent đẹp" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged+tables88; SHA256-identical-with-fe-user is a SOURCE-claim (git diff), not runtime-verified by me (can't compare rendered DOM cross-app). **LESSON: deploy-2 of same-session asymmetric-NGƯỢC = (a) verify prior deploy (#297) NOT cancelled by this push (it was success first — confirmed in tasks); (b) status=success ⟹ deploy ran; (c) THIS-app bundle ROTATE + OTHER-app FROZEN — direction FLIPS vs deploy-1 (deploy-1 fe-user-rotate/admin-frozen → deploy-2 admin-rotate/user-frozen); admin un-froze from multi-session frozen-streak = EXPECTED when fe-admin finally changes (frozen-streak break is normal, not anomaly); (d) migration top + sys.tables MUST stay = prev (FE-only). Re-query Gitea JSON with python3 when tr/grep parse yields empty — parser bug ≠ run-stuck. No BE call-site/DTO/endpoint smoke (no API surface). SHA256-source-identical = git-level claim, runtime-mirror-equality not provable by curl. NEVER fixed code (READ-only).** Tag `[s72, run298, pass, fe-admin-mirror-hoso-from-feuser, fe-admin-only-2files, bundle-asymmetric-NGUOC-admin-rotate-user-frozen, admin-unfroze-from-s68-streak, no-mig-top-stays-mig52, tables88-verified, deploy2of2-prior297-not-cancelled, poll-parser-bug-use-python3, no-regression, test263]`.
|
||||||
|
- **2026-06-16 S71 Run #297 (run_number 297, id411) sha=`ab4e681` PASS ~4m21s (FE-User "Hồ sơ NS" cosmetic: đồng nhất font/size + chữ đen `text-slate-900/800`→xanh-đậm `text-brand-800` cho value/tên + bỏ `text-xs` nhánh mono — FE-USER-ONLY 1 file, NO BE, NO migration; 4th consecutive same-page S68→S71):** Push 1 file `fe-user/src/pages/hrm/EmployeesListPage.tsx` (className màu chữ + size, KHÔNG đụng BE/Mig/dep/fe-admin). `.tsx` → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (len24). Run IN-PROGRESS first poll (running 13:43) — correctly did NOT verify-bundle-mid-flight (anti#3), pre-deploy baseline snapshot captured BEFORE poll iter0: user `DbVv6rsf` (S70 baseline) + admin `BDwV5d0X`. Polled iter5 status=success (started ~13:42 → success ~13:46:48 ≈4m21s). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC (the change-point — FE-one-app verify) ALL PASS, verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient (anti#3): user ROTATE `DbVv6rsf→BumgrwCJ`** ✓ (EmployeesListPage cosmetic shipped — re-rotated from S70's DbVv6rsf, 4th consecutive same-page FE-user deploy = new content-hash each, normal) **+ admin FROZEN `BDwV5d0X`==baseline** ✓ (fe-admin 0 files touched → MUST NOT rotate = correct; rotate-when-untouched = anomaly→flag). Health api live+ready **200/200** (⚠️ `/health` spec'd → 404, real endpoint `/health/ready`+`/health/live` per iis-deploy-runbook skill — both 200, API healthy) + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (commit 0 mig files — `git diff --name-only | grep Migrations/` = NONE; FE-only cannot alter schema → top did NOT advance; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). **sys.tables=88 verified** (sqlcmd COUNT excl mighist — unchanged, no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "chữ xanh đậm/đồng nhất size" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged+tables88. **LESSON: pure-FE-one-app cosmetic verify (4th consecutive same-page) = (a) status=success ⟹ deploy ran; (b) target-app bundle ROTATE + sibling-app FROZEN (re-rotate of same page across sessions = NORMAL, each deploy=new hash; rotate-sibling-when-untouched = anomaly); (c) migration top + sys.tables MUST stay = prev (FE cannot alter schema — advancing = bug); (d) health 200×2 (/ready+/live, NOT /health). ⚠️ `/health` 404 ≠ unhealthy — SOL uses `/health/ready`+`/health/live` (skill-doc), spec literal `/health` is wrong-path; cross-check skill before flagging. No BE call-site/DTO/endpoint smoke needed (no API surface). Tokens empty: anon Gitea + prod-appsettings DB pw works. NEVER fixed code (READ-only).** Tag `[s71, run297, pass, fe-user-hoso-cosmetic-brand800, fe-only-1file, bundle-asymmetric-user-rotate-admin-frozen, no-mig-top-stays-mig52, tables88-verified, health-ready-not-health, no-regression, test263]`.
|
||||||
- **2026-06-16 S70 Run #295 (run_number 295, id409) sha=`456c7a7` PASS ~4m21s (FE-User "Hồ sơ Nhân sự" layout 2-cột: cây tổ chức + list chồng cột trái, detail cột phải + tô màu panel chi tiết — FE-USER-ONLY 1 file, NO BE, NO migration; follow-up S69 Run #294 same page):** Push `ec517f7..456c7a7` 1 file `fe-user/src/pages/hrm/EmployeesListPage.tsx` (309+/262−, 571-line layout rewrite). `.tsx` → full pipeline RAN. Both tokens SET this run (GITEA_TOKEN+PROD_DB_PW present — unlike S65-S69 empty; DB pw still works via prod `appsettings.Production.json`→`ConnectionStrings.Default` `buKL3...` len24). Run IN-PROGRESS first poll (running 11:36) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter6 status=success (started ~11:36 → success 11:40:46 ≈4m21s). Pre-deploy baseline snapshot iter0: user `CZfo_PFZ` (S69 baseline) + admin `BDwV5d0X` — captured BEFORE poll, correct timing. CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC (the change-point — FE-one-app verify) ALL PASS, verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient (anti#3): user ROTATE `CZfo_PFZ→DbVv6rsf`** ✓ (EmployeesListPage layout-2col shipped — re-rotated from S69's CZfo_PFZ, consecutive FE-user deploys on SAME page = new content-hash each, normal) **+ admin FROZEN `BDwV5d0X`==baseline** ✓ (fe-admin 0 files touched → MUST NOT rotate = correct; rotate-when-untouched = anomaly→flag). Health api live+ready **200/200** + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (commit 0 mig files — `git diff --name-only | grep Migrations/` = NONE; FE-only cannot alter schema → top did NOT advance past S68's Mig 52; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). sys.tables stays 88 by construction (no schema touch — skipped explicit count, FE-only). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "2-cột đẹp/tô-màu" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged. **LESSON: pure-FE-one-app verify (3rd consecutive same-page FE-user S68→S69→S70) = (a) status=success ⟹ deploy ran; (b) target-app bundle ROTATE + sibling-app FROZEN (asymmetric — re-rotate of already-rotated page across sessions is NORMAL, each deploy=new hash; rotate-sibling-when-untouched = anomaly); (c) migration top MUST stay = prev (FE cannot alter schema — advancing top on FE-only commit = bug); (d) health 200×3. No BE call-site/DTO/endpoint smoke needed (no API surface). Tokens-present vs empty: both paths work — when GITEA_TOKEN set use `token` header, but anon also fine for public repo. NEVER fixed code (READ-only).** Tag `[s70, run295, pass, fe-user-hoso-2col-layout, fe-only-1file, bundle-asymmetric-user-rotate-admin-frozen, no-mig-top-stays-mig52, tables88, no-regression, test263, tokens-present]`.
|
- **2026-06-16 S70 Run #295 (run_number 295, id409) sha=`456c7a7` PASS ~4m21s (FE-User "Hồ sơ Nhân sự" layout 2-cột: cây tổ chức + list chồng cột trái, detail cột phải + tô màu panel chi tiết — FE-USER-ONLY 1 file, NO BE, NO migration; follow-up S69 Run #294 same page):** Push `ec517f7..456c7a7` 1 file `fe-user/src/pages/hrm/EmployeesListPage.tsx` (309+/262−, 571-line layout rewrite). `.tsx` → full pipeline RAN. Both tokens SET this run (GITEA_TOKEN+PROD_DB_PW present — unlike S65-S69 empty; DB pw still works via prod `appsettings.Production.json`→`ConnectionStrings.Default` `buKL3...` len24). Run IN-PROGRESS first poll (running 11:36) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter6 status=success (started ~11:36 → success 11:40:46 ≈4m21s). Pre-deploy baseline snapshot iter0: user `CZfo_PFZ` (S69 baseline) + admin `BDwV5d0X` — captured BEFORE poll, correct timing. CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC (the change-point — FE-one-app verify) ALL PASS, verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient (anti#3): user ROTATE `CZfo_PFZ→DbVv6rsf`** ✓ (EmployeesListPage layout-2col shipped — re-rotated from S69's CZfo_PFZ, consecutive FE-user deploys on SAME page = new content-hash each, normal) **+ admin FROZEN `BDwV5d0X`==baseline** ✓ (fe-admin 0 files touched → MUST NOT rotate = correct; rotate-when-untouched = anomaly→flag). Health api live+ready **200/200** + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (commit 0 mig files — `git diff --name-only | grep Migrations/` = NONE; FE-only cannot alter schema → top did NOT advance past S68's Mig 52; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 chain intact). sys.tables stays 88 by construction (no schema touch — skipped explicit count, FE-only). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "2-cột đẹp/tô-màu" NOT verified (anh xem mắt) — only ship+rotate+health+mig-unchanged. **LESSON: pure-FE-one-app verify (3rd consecutive same-page FE-user S68→S69→S70) = (a) status=success ⟹ deploy ran; (b) target-app bundle ROTATE + sibling-app FROZEN (asymmetric — re-rotate of already-rotated page across sessions is NORMAL, each deploy=new hash; rotate-sibling-when-untouched = anomaly); (c) migration top MUST stay = prev (FE cannot alter schema — advancing top on FE-only commit = bug); (d) health 200×3. No BE call-site/DTO/endpoint smoke needed (no API surface). Tokens-present vs empty: both paths work — when GITEA_TOKEN set use `token` header, but anon also fine for public repo. NEVER fixed code (READ-only).** Tag `[s70, run295, pass, fe-user-hoso-2col-layout, fe-only-1file, bundle-asymmetric-user-rotate-admin-frozen, no-mig-top-stays-mig52, tables88, no-regression, test263, tokens-present]`.
|
||||||
- **2026-06-16 S69 Run #294 (run_number 294, id408) sha=`ec517f7` PASS ~4m18s (FE-User cây tổ chức gốc "SOLUTION COMPANY" toả xuống phòng ban — gộp nút "Tất cả"+list-phẳng → 1 node gốc công ty; FE-USER-ONLY 1 file, NO BE, NO migration):** Push `5a0aaa4..ec517f7` 1 file `fe-user/src/pages/hrm/EmployeesListPage.tsx`. `.tsx` → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...` len24). Run IN-PROGRESS first poll (running 11:24:05) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter5 status=success (started 11:24:05 → success ~11:28:23 ≈4m18s). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; FE-only ⟹ 0 BE call-site risk) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC (the change-point — FE-one-app verify) ALL PASS, verified AFTER status=success +re-confirm STABLE 2nd-fetch identical no transient (anti#3): user ROTATE `DXkyUjtQ→CZfo_PFZ`** ✓ (EmployeesListPage shipped — was rotated S68, now re-rotated) **+ admin FROZEN `BDwV5d0X`==baseline** ✓ (fe-admin 0 files touched → MUST NOT rotate = correct; rotate-when-untouched = anomaly→flag). Health api live+ready **200/200** + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation` (Mig 52) == repo HEAD GIỮ NGUYÊN ✓ (commit 0 mig files; FE-only cannot alter schema — top did NOT advance past S68's Mig 52; prev-2 = `AddDepartmentParentId` Mig51 + `ReplaceBudgetModuleWithPeWorkItemBudgets` Mig50 confirm chain intact). sys.tables stays 88 by construction (no schema touch). 0 regression. NO prod-data mutation (read-only curls + sqlcmd SELECT-only). Visual "đẹp/cây-gốc-công-ty" NOT verified (anh xem mắt) — only ship+rotate+health. **LESSON: pure-FE-one-app verify = (a) status=success ⟹ deploy ran; (b) target-app bundle ROTATE + sibling-app FROZEN (asymmetric — rotate-sibling-when-untouched = anomaly); (c) migration top MUST stay = prev (FE cannot alter schema — advancing top on a FE-only commit would be a bug); (d) health 200×3. No BE call-site risk, no DTO/endpoint smoke needed (no API surface changed). Re-rotate of an already-rotated app across consecutive sessions is normal (each FE deploy = new content-hash). Tokens empty: anon Gitea + prod-appsettings DB pw works (Bash tool POSIX — read pw via ssh→appsettings ConnectionStrings.Default len24).** Tag `[s69, run294, pass, fe-user-org-tree-root-company, fe-only-1file, bundle-asymmetric-user-rotate-admin-frozen, no-mig-top-stays-mig52, tables88, no-regression, test263]`.
|
|
||||||
- **2026-06-16 S68 Run #293 (run_number 293, id407) sha=`5a0aaa4` PASS ~5m00s (FE-User "Hồ sơ Nhân sự" 3-panel master-detail 5-tab rewrite + PE "Link hồ sơ" hyperlink NAS + rename "Dự trù PRO"→"Ngân sách PRO" — CROSS-STACK BE Mig 52 + FE×2; 2-commit `318860a`(FE-User EmployeesListPage) + `5a0aaa4`(PE cross-stack)):** Push `6ce5803..5a0aaa4` 15 files: BE `PurchaseEvaluation.cs`(+HoSoLink) + `PurchaseEvaluationConfiguration.cs` + `PurchaseEvaluationFeatures.cs`(Create/Update cmd +trailing optional `HoSoLink=null`) + `PurchaseEvaluationDtos.cs`(Detail DTO +hoSoLink) + Mig 52 `20260616035929_AddHoSoLinkToPurchaseEvaluation`(3-file) + FE `EmployeesListPage.tsx`(fe-user, 3-panel rewrite cây-tổ-chức+list+5-tab) + PE×2 (`PeDetailTabs.tsx`+`PeWorkspaceCreateView.tsx`+`types/purchaseEvaluation.ts` both apps, mục E hyperlink + label rename). `.cs`+`.tsx`+Mig → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...`). Run IN-PROGRESS first poll (running 11:15) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter5 status=success (started 11:13:57 → success 11:18:57 ≈5m). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; BE Create/Update +trailing optional param=null ⟹ call-sites UNBROKEN) passed; `conclusion` empty — trust success). **★ MIGRATION APPLIED (the KEY): prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation`** ✓ (Mig 52; ADVANCED from prev top Mig 51 `AddDepartmentParentId`; DbInitializer auto-migrate on startup ran — api ready=200 confirms boot OK post-mig). Mig content = AddColumn `HoSoLink nvarchar(1000) maxLength=1000 NULL` (AddColumn-only, NO new table → **sys.tables stays 88** verified). DB-level: `sys.columns WHERE object_id=OBJECT_ID('PurchaseEvaluations') AND name='HoSoLink'` = 1 row ✓ (column physically present prod). **★ BUNDLE BOTH ROTATE (verified AFTER status=success +re-confirm STABLE 2nd-fetch no transient — anti#3): admin `Df06fmpq→BDwV5d0X`** ✓ (PE files shipped — was FROZEN since S67, now correctly rotated) **+ user `DxK3fCfh→DXkyUjtQ`** ✓ (EmployeesListPage + PE files shipped). Both required to rotate per spec → BOTH did. Health api live+ready **200/200** + admin/eoffice root 200. **★ NEW-FIELD live smoke (admin bearer, route `/api/auth/login` field `accessToken` len468):** `GET /api/purchase-evaluations/{48154149...}` (phiếu thật `PE/2026/A/015`) = **200** ✓ JSON detail carries `"hoSoLink":null` (key PRESENT, null cho phiếu cũ = backward-compat ✓ — Detail DTO wired AND Create/Update signature-change did NOT break GET path) · `GET /api/departments/tree` = **200** ✓ (Phase B dependency from Mig 51, still live). 0 regression. NO prod-data mutation (read-only GETs + sqlcmd SELECT-only). **LESSON: nullable-AddColumn cross-stack verify = (a) `__EFMigrationsHistory` top ADVANCED to new Mig (Mig 52) + api ready=200 (auto-migrate boot OK); (b) `sys.tables`=88 unchanged (AddColumn ≠ new table) + `sys.columns` confirms col present; (c) Detail DTO field-presence via authed GET on a REAL phiếu — `"hoSoLink":null` for old rows proves both DTO-wiring AND backward-compat (trailing-optional Create/Update param won't break GET — confirmed 200); (d) cross-stack BE+FE×2 = BOTH bundles rotate (admin un-froze from S67). Tokens empty: anon Gitea + prod-appsettings DB pw works (Bash tool is POSIX bash NOT PS despite shell=PowerShell env — `$env:`/`jq`/`python3` unavailable; parse via `tr ','|grep` + read pw via `ssh→appsettings`).** Tag `[s68, run293, pass, pe-hosolink-mig52-applied, fe-user-hoso-3panel-rewrite, pe-link-hoso-hyperlink, rename-dutru-to-ngansach, bundle-both-rotate-admin-unfroze, hosolink-null-in-dto-backward-compat, no-new-table-88, test263]`.
|
- **2026-06-16 S68 Run #293 (run_number 293, id407) sha=`5a0aaa4` PASS ~5m00s (FE-User "Hồ sơ Nhân sự" 3-panel master-detail 5-tab rewrite + PE "Link hồ sơ" hyperlink NAS + rename "Dự trù PRO"→"Ngân sách PRO" — CROSS-STACK BE Mig 52 + FE×2; 2-commit `318860a`(FE-User EmployeesListPage) + `5a0aaa4`(PE cross-stack)):** Push `6ce5803..5a0aaa4` 15 files: BE `PurchaseEvaluation.cs`(+HoSoLink) + `PurchaseEvaluationConfiguration.cs` + `PurchaseEvaluationFeatures.cs`(Create/Update cmd +trailing optional `HoSoLink=null`) + `PurchaseEvaluationDtos.cs`(Detail DTO +hoSoLink) + Mig 52 `20260616035929_AddHoSoLinkToPurchaseEvaluation`(3-file) + FE `EmployeesListPage.tsx`(fe-user, 3-panel rewrite cây-tổ-chức+list+5-tab) + PE×2 (`PeDetailTabs.tsx`+`PeWorkspaceCreateView.tsx`+`types/purchaseEvaluation.ts` both apps, mục E hyperlink + label rename). `.cs`+`.tsx`+Mig → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...`). Run IN-PROGRESS first poll (running 11:15) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter5 status=success (started 11:13:57 → success 11:18:57 ≈5m). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45D+218I; BE Create/Update +trailing optional param=null ⟹ call-sites UNBROKEN) passed; `conclusion` empty — trust success). **★ MIGRATION APPLIED (the KEY): prod `__EFMigrationsHistory` top = `20260616035929_AddHoSoLinkToPurchaseEvaluation`** ✓ (Mig 52; ADVANCED from prev top Mig 51 `AddDepartmentParentId`; DbInitializer auto-migrate on startup ran — api ready=200 confirms boot OK post-mig). Mig content = AddColumn `HoSoLink nvarchar(1000) maxLength=1000 NULL` (AddColumn-only, NO new table → **sys.tables stays 88** verified). DB-level: `sys.columns WHERE object_id=OBJECT_ID('PurchaseEvaluations') AND name='HoSoLink'` = 1 row ✓ (column physically present prod). **★ BUNDLE BOTH ROTATE (verified AFTER status=success +re-confirm STABLE 2nd-fetch no transient — anti#3): admin `Df06fmpq→BDwV5d0X`** ✓ (PE files shipped — was FROZEN since S67, now correctly rotated) **+ user `DxK3fCfh→DXkyUjtQ`** ✓ (EmployeesListPage + PE files shipped). Both required to rotate per spec → BOTH did. Health api live+ready **200/200** + admin/eoffice root 200. **★ NEW-FIELD live smoke (admin bearer, route `/api/auth/login` field `accessToken` len468):** `GET /api/purchase-evaluations/{48154149...}` (phiếu thật `PE/2026/A/015`) = **200** ✓ JSON detail carries `"hoSoLink":null` (key PRESENT, null cho phiếu cũ = backward-compat ✓ — Detail DTO wired AND Create/Update signature-change did NOT break GET path) · `GET /api/departments/tree` = **200** ✓ (Phase B dependency from Mig 51, still live). 0 regression. NO prod-data mutation (read-only GETs + sqlcmd SELECT-only). **LESSON: nullable-AddColumn cross-stack verify = (a) `__EFMigrationsHistory` top ADVANCED to new Mig (Mig 52) + api ready=200 (auto-migrate boot OK); (b) `sys.tables`=88 unchanged (AddColumn ≠ new table) + `sys.columns` confirms col present; (c) Detail DTO field-presence via authed GET on a REAL phiếu — `"hoSoLink":null` for old rows proves both DTO-wiring AND backward-compat (trailing-optional Create/Update param won't break GET — confirmed 200); (d) cross-stack BE+FE×2 = BOTH bundles rotate (admin un-froze from S67). Tokens empty: anon Gitea + prod-appsettings DB pw works (Bash tool is POSIX bash NOT PS despite shell=PowerShell env — `$env:`/`jq`/`python3` unavailable; parse via `tr ','|grep` + read pw via `ssh→appsettings`).** Tag `[s68, run293, pass, pe-hosolink-mig52-applied, fe-user-hoso-3panel-rewrite, pe-link-hoso-hyperlink, rename-dutru-to-ngansach, bundle-both-rotate-admin-unfroze, hosolink-null-in-dto-backward-compat, no-new-table-88, test263]`.
|
||||||
- **2026-06-16 S67 Run #292 (run_number 292, id406) sha=`6ce5803` PASS ~4m06s (phân cấp phòng ban Department.ParentId + /tree + FE-admin "Phòng cha" picker — CROSS-STACK BE+FE-admin+Mig 51, RETRY của Run #291 FAIL):** Push 3-commit chain `0f44d97`(BE Department.ParentId + DepartmentFeatures + /tree + Config + Mig 51) → `8c8179c`(FE-admin DepartmentsPage picker + types/master.ts) → `6ce5803`(Tests fix `MasterCatalogFilteredUniqueTests.cs` +ParentId 5th arg CreateDepartmentCommand call-site). **★ Run #291 (id405) sha=`8c8179c` = `failure` @10:42:18 (test-gate CS7036 — CreateDepartmentCommand thêm ParentId param nhưng test call-site chưa update → build_test FAIL → deploy GATED → Mig NOT applied).** `6ce5803` = the fix → Run #292 status=success @10:50:16→10:54:22. Files full-range (8 src incl `.cs`+`.tsx`+Mig 3-file) → full pipeline RAN. Tokens empty → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...`). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** (45D+218I, +1 fixed call-site) passed; `conclusion` empty — trust success). **★ MIGRATION APPLIED (the KEY — last time gated, this time landed): prod `__EFMigrationsHistory` top = `20260616032402_AddDepartmentParentId`** ✓ (Mig 51; prev top Mig 50 `ReplaceBudgetModuleWithPeWorkItemBudgets`; DbInitializer auto-migrate on startup ran — api ready=200 confirms boot OK post-mig). Mig content = AddColumn `ParentId uniqueidentifier NULL` + `IX_Departments_ParentId` (loose-Guid NO physical FK — convention Master; AddColumn-only, NO new table → sys.tables stays 88). **★ BUNDLE ASYMMETRIC (verified AFTER status=success, terminal not mid-flight): admin ROTATE `DRob3iVl→Df06fmpq`** ✓ (fe-admin picker shipped — was FROZEN since S65, now rotated correctly) **+ user FROZEN `DxK3fCfh`==baseline** ✓ (fe-user 0 files touched → MUST NOT rotate = correct). Health api live+ready **200/200** + admin/eoffice root 200. **★ NEW-ENDPOINT live smoke (admin bearer, route `/api/auth/login` field `accessToken` len468):** `GET /api/departments/tree` = **200** ✓ JSON array nodes each w/ `parentId`+`directEmployeeCount`+`totalEmployeeCount`+`children[]` (e.g. CCM direct=10/total=10, BOD 1/1, ACT 0/0; all `parentId:null` currently — no parent assigned yet in prod, but col+endpoint live) · `GET /api/departments?page=1&pageSize=5` list = **200** ✓ DTO includes `parentId` (IT/PM both null). 0 regression. **LESSON: FAIL→retry chain — when commit N fails test-gate (CS7036 call-site mismatch from a signature change) the deploy is GATED so prod Mig stays at N-1; the FIX commit N+1 must re-trigger a NEW run (here #292) whose success ⟹ Mig finally applies. KEY verify on retry = confirm `__EFMigrationsHistory` top ADVANCED to the new Mig (not stuck at prev) + api ready=200 (no startup crash from the auto-migrate). Cross-stack BE+FE-one-app = asymmetric bundle: changed-app rotates (admin un-froze from S65), untouched-app stays frozen. New endpoint = curl 200 + structural-key presence proof; FK-less ParentId is convention (PE/Master loose-Guid) not a defect. Tokens empty: anon Gitea + prod-appsettings DB pw works (PS `$env:` syntax in spec N/A — Bash tool is POSIX, read pw via ssh→appsettings).** Tag `[s67, run292, pass, dept-parentid-hierarchy, mig51-applied-after-291-fail, retry-chain-cs7036-fix, bundle-asymmetric-admin-rotate-user-frozen, tree-endpoint-200, no-new-table-88, test263]`.
|
- _(S67 Run #292 [dept-parentid Mig51-applied-after-#291-fail, retry-chain CS7036-fix, bundle-asymmetric, tree-endpoint-200] + S65 #289 [hrm-hoso public-readonly seed-only, asymmetric read200/write403] → FIFO-trimmed, full verbatim git `d2f52ba` + `archive/2026-06.md`)_
|
||||||
- **2026-06-16 S66 Run #290 (run_number 290, id404) sha=`c98030f` PASS ~4m24s (redesign foundation màu fe-user "nâng màu giữ brand" — FE-USER-ONLY 14 files, NO BE, NO migration):** Push `4004481..c98030f` 14 files all `fe-user/src/**` (index.css + 6 ui primitives Button/Dialog/Input/Label/Select/Textarea + 4 shell DataTable/Layout/PageHeader/TopBar + UserDashboardPage + 2 color-map types contracts/purchaseEvaluation). `.tsx`+`.css` → full pipeline RAN. GITEA_TOKEN+PROD_DB_PW empty → anon Gitea API + (DB pw read deferred, FE-only no DB touch). Run IN-PROGRESS first poll (running 10:15) — correctly did NOT verify-bundle-mid-flight (anti#3), polled iter3 status=success (10:13:04→10:17:28 ≈4m24s). CI gate (both test proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45 Domain + 218 Infra) passed; `conclusion` empty — trust success). **★ BUNDLE ASYMMETRIC (the change-point — one-app-FE verify) ALL PASS, verified AFTER status=success +re-confirm STABLE no transient: user ROTATE `Cpion_xQ→DxK3fCfh`** ✓ (fe-user 14 files shipped) **+ admin FROZEN `DRob3iVl`==baseline** ✓ (fe-admin 0 files touched → MUST NOT rotate = correct). Health api live+ready **200/200** + admin/eoffice root 200. **★ CSS-REDESIGN-SHIPPED PROOF (live-vs-source diff, defeats stale-bundle false-pass):** fetch live eoffice CSS `index-DZ-56qoN.css` (71740 B) → grep brand `#1F7DC1` PRESENT + NEW accent tokens `--color-teal-{50..800}` + `app-gradient-brand` + `card-accent` (×5) + `--color-accent-{500,600}` ALL PRESENT ✓. Cross-check: these tokens = **0 occurrences in HEAD~1 index.css**, **added in c98030f** (git show source: teal×6, app-gradient-brand×1, card-accent×5, 1F7DC1×1) → live CSS IS new redesign NOT stale. **NO migration** — repo HEAD top = Mig 50 `ReplaceBudgetModuleWithPeWorkItemBudgets` GIỮ ✓ (commit 0 mig files; FE-only cannot alter schema → prod `__EFMigrationsHistory` top stays Mig 50 by construction, fe-user site static no .NET runtime — DB check skipped per FE-only scope). 0 regression. **LESSON: ASYMMETRIC FE-one-app verify = (a) status=success ⟹ deploy ran; (b) target-app bundle ROTATE + sibling-app FROZEN (rotate-sibling-when-untouched = anomaly→flag); (c) for visual/CSS redesign — fetch live CSS asset + grep claimed tokens, AND diff-prove tokens were 0-in-HEAD~1 / added-in-commit (live-token-present alone could be coincidental stale; the 0→N delta defeats stale-bundle false-pass). Visual "đẹp" NOT verified (anh xem mắt) — only ship+rotate+CSS-token-present. Tokens empty: anon Gitea works; FE-only ⟹ no DB pw needed.** Tag `[s66, run290, pass, fe-user-redesign-foundation, fe-only-14files, bundle-asymmetric-user-rotate-admin-frozen, css-tokens-shipped-0to-N-delta, teal-accent-gradient-brand, no-mig, test263]`.
|
- **Older runs (S66 #290 ← S62 #286 06-13 ← … → S29 #232) full verbatim archived → git `d2f52ba` + `archive/2026-06.md`** (incl #291 06-16 FAIL forensic [lesson=gotcha #65 + #292-inline] + #383 ex-VITRILAC); pre-S38 → `archive/2026-05-{runs,q2,q3,q4}.md`.
|
||||||
|
|
||||||
- **2026-06-16 S65 Run #289 (run_number 289, id403) sha=`4004481` PASS ~4m41s (mở quyền XEM "Hồ sơ Nhân sự" read-only cho MỌI role eoffice — BE-ONLY 1 file DbInitializer SEED, NO migration, NO FE):** Push `cfed3d0..4004481` 1 file `DbInitializer.cs` (+66, new `SeedAllRolesHrmProfileReadPermissionsAsync` grant CanRead `Hrm`+`Hrm_HoSo` 13 role, upgrade-only mirror PE :2107, chạy SAU `RevokeTemporarilyHiddenModulesAsync` S58 để THẮNG revoke; Create/Update/Delete giữ false). `.cs` → full pipeline RAN. **GITEA_TOKEN+PROD_DB_PW empty** → anon Gitea API + DB pw từ prod `appsettings.Production.json`→`ConnectionStrings.Default` (`buKL3...`). Run IN-PROGRESS first poll (running 09:53) — correctly did NOT FAIL/verify-bundle-mid-flight (anti#3), polled iter5 status=success (09:52:03→09:56:44 ≈4m41s). CI gate (both proj pre-deploy ⟹ status=success ⟹ test gate **263** baseline (45 Domain + 218 Infra) passed; `conclusion` empty — trust success). **Bundle FROZEN (BE-only, NO FE change → MUST NOT rotate = correct): admin `DRob3iVl` + user `Cpion_xQ`** ✓ both unchanged pre==post (live advanced from S62 `0xKYGhhf`/`C81ZdG9G` via intervening S63/S64 FE deploys — narrative-Run#286 hash now 3 deploys stale; current live = baseline). Health live+ready **200/200** + admin/eoffice root 200. **NO migration** — prod `__EFMigrationsHistory` top = `20260612173224_ReplaceBudgetModuleWithPeWorkItemBudgets` (Mig 50) == repo HEAD GIỮ ✓ (commit 0 mig files). **★ SEED-EFFECT 7-CHECK reviewer ALL PASS (the change-point — asymmetric read-open/write-locked, non-admin `nv.test`=Drafter + admin):** (1) menus/me non-admin tree = exactly `['Hrm','Hrm_HoSo']` present ✓ + (4) `Hrm_Dashboard`+`Hrm_Config*` ABSENT ✓ (revoke still che); (2) non-admin GET /api/employees?page=1&pageSize=20 = **200** ✓ (was 403 — MẤU CHỐT, seed áp đúng + `Hrm_HoSo.Read` resolve qua permission matrix); (3) non-admin GET /api/employees/{id} = **200** ✓; (5) non-admin POST = **403** ✓; (6) non-admin PUT+DELETE = **403/403** ✓ (read-only giữ); (7) admin GET = **200** ✓ no regression. **DB-level ground-truth (sqlcmd via SSH):** `Permissions WHERE MenuKey IN ('Hrm','Hrm_HoSo')` = 13 rows EACH, all CanRead=1, AnyWrite=1 (=Admin only, full CRUD legit — upgrade-only KHÔNG hạ write existing) ✓. EmployeeProfiles=33 INTACT + ZZCICD-PROBE=0 (403 POST tạo 0 rows, no leak) ✓. ⚠️ **CRED NOTE: reviewer spec ghi non-admin pw `User@1234567` SAI** → 401 "Email/mật khẩu không đúng"; pw THẬT = memory-baseline `TestUser@123456` ✓. 0 regression. **LESSON: SEED-change verify (DbInitializer, no-mig) = (a) status=success ⟹ app restarted ⟹ seed ran; (b) prove EFFECT not schema — curl asymmetric probe (read 200 / write 403 / admin 200) + sqlcmd Permission-row count==role-count w/ CanRead=1 & write-row=Admin-only; (c) "seed NO-OP" failure-class (S58) caught iff check#2 still 403 post-restart — here 200 ⟹ revoke-then-grant ordering correct. BE-only ⟹ bundle FROZEN = pass-signal (rotate w/o FE = anomaly). Tokens empty: anon Gitea + prod-appsettings DB pw works. Spec creds may be illustrative — fall back to memory-baseline on 401.** Tag `[s65, run289, pass, hrm-hoso-public-readonly, seed-only-no-mig, bundle-frozen, asymmetric-read200-write403, permrows-13-canread, no-leak, spec-cred-wrong-fallback-baseline]`.
|
|
||||||
- **Older runs (S62 #286 06-13 <- ... -> S29 #232) full verbatim archived S66 -> `archive/2026-06.md`** (incl #291 06-16 FAIL forensic [lesson=gotcha #65 + #292-inline] + #383 ex-VITRILAC); pre-S38 -> `archive/2026-05-{runs,q2,q3,q4}.md` + git `d2f52ba`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,9 @@ Read-only EXTERNAL research specialist. WebFetch/WebSearch official docs + NuGet
|
|||||||
|
|
||||||
- **2026-05-29 (S39 agent split setup):** NEW agent created từ split investigator. Seeded external-research half. Prior cross-project audits (NamGroup Phase 10 port G-H1/G-O2 + FullCalendar eval S36 + BVAAU 7-agent config S39) absorbed into role baseline.
|
- **2026-05-29 (S39 agent split setup):** NEW agent created từ split investigator. Seeded external-research half. Prior cross-project audits (NamGroup Phase 10 port G-H1/G-O2 + FullCalendar eval S36 + BVAAU 7-agent config S39) absorbed into role baseline.
|
||||||
- **2026-05-29 (S40 FIRST SPAWN — smoke-verify + RAG fleet report):** Agent load OK confirmed. `list_projects` → 7 project, total **39,798 chunks**. Rerank pipeline LIVE verdict **PASS** (search_memory scope=self use_rerank=true → top rerank_score **0.8789**, 3 results all carry rerank_score). Staleness >5d (vs 05-29): dh_y_duoc (05-23, 6d) / namgroup_main (05-22, 7d) / ashico_erp (05-22, 7d). solution_erp 05-28 fresh-ish but missing S37-S39 content. `shared_global` = 0 chunks (chưa promote pattern nào). MINOR drift: namgroup_main actual 11306 (brief said 11305). vipix_ai_infra (1652) = AI_INFRA hub root `D:\...\AI_INFRA`. No re-ingest performed (report-only).
|
- **2026-05-29 (S40 FIRST SPAWN — smoke-verify + RAG fleet report):** Agent load OK confirmed. `list_projects` → 7 project, total **39,798 chunks**. Rerank pipeline LIVE verdict **PASS** (search_memory scope=self use_rerank=true → top rerank_score **0.8789**, 3 results all carry rerank_score). Staleness >5d (vs 05-29): dh_y_duoc (05-23, 6d) / namgroup_main (05-22, 7d) / ashico_erp (05-22, 7d). solution_erp 05-28 fresh-ish but missing S37-S39 content. `shared_global` = 0 chunks (chưa promote pattern nào). MINOR drift: namgroup_main actual 11306 (brief said 11305). vipix_ai_infra (1652) = AI_INFRA hub root `D:\...\AI_INFRA`. No re-ingest performed (report-only).
|
||||||
|
- **2026-06-16 (Góc 1 — FOUNDATIONAL: HTTPS `<a href=file://>` click có mở Explorer/local/UNC?):** Dứt khoát = **KHÔNG** trên browser mặc định. Chrome/Edge **76+** chặn navigate file:// từ trang non-file:// → click = "nothing visibly happens", console `"Not allowed to load local resource: file://host/page"` (textslashplain 2019 + MS Learn xác nhận verbatim). Firefox cũng chặn cross-origin file://. **NGOẠI LỆ CHÍNH THỨC duy nhất** = Edge GPO **`IntranetFileLinksEnabled`** — confirmed **Windows ≥95** (MS Learn dedicated page DEFINITIVE; "77+" trên trang chỉ là article-applies boilerplate, ĐỪNG nhầm). Behavior: intranet-zone HTTPS → file:// link → Explorer parent-dir + select file (dir-link mở folder no-select). Reg `HKLM\SOFTWARE\Policies\Microsoft\Edge\IntranetFileLinksEnabled=1` REG_DWORD, ADMX `Content settings`. `https://localhost/` block exception; loopback 127.x/[::1]=internet-zone. **URLAllowlist KHÔNG giải**: MS Learn quote verbatim "doesn't work as expected with file://* wildcards" + chỉ exception URLBlocklist, KHÔNG lift nav-block. **Chrome KHÔNG có equivalent** ("No option to disable this navigation blocking is available in Chrome"). Ext "Enable Local File Links"/Local Explorer = workaround nhưng cần install per-machine + "will not help if page uses JS to navigate" (chỉ bắt click listener). one-click+zero-install thuần-web = **FALSE**; chỉ path = Edge GPO 100% fleet (Góc 3). Sources: textslashplain.com/2019/10/09/navigating-to-file-urls; learn.microsoft.com/deployedge intranetfilelinksenabled + urlallowlist.
|
||||||
|
- **2026-06-16 (Góc 2 — ZERO-install mở Explorer tới O:\ từ web, complements Góc 3 below):** Ruled OUT the no-server-policy tricks: (a) **File System Access `showDirectoryPicker` KHÔNG mở path cho-sẵn** — `startIn` chỉ nhận well-known dir (downloads/desktop/...) HOẶC FileSystemHandle đã-pick, KHÔNG raw `O:\`; BẮT BUỘC user gesture + tự navigate (MDN). (b) **.url download = 2-BƯỚC** (download→double-click), KHÔNG one-click; nhưng `.url [InternetShortcut] URL=file:///O:/...` dispatch qua shell nên folder/UNC CÓ mở Explorer — `.lnk` thì dính MoTW/SmartScreen (chính vector LNK-stomping CVE-2024-38217, IT flag). (c) **ms-explorer/shell: KHÔNG web-callable** = custom-protocol anh đã reject. Kết: KHÔNG có true one-click+zero-install thuần web; chỉ-server-side path duy nhất = Edge GPO `IntranetFileLinksEnabled` (xem Góc 3 entry kế). Sources: MDN showDirectoryPicker; learn.microsoft win32 internet-shortcuts; textslashplain navigating-to-file-urls.
|
||||||
|
- **2026-06-16 (eoffice "open mapped O: drive folder from web app" — Góc 3 setup-light research):** WINNER = native Edge policy **`IntranetFileLinksEnabled`** (Edge ≥95, REG_DWORD `HKLM\SOFTWARE\Policies\Microsoft\Edge\IntranetFileLinksEnabled=1`, ADMX `Admin Templates/Microsoft Edge/Content settings`). Behavior: intranet-zone HTTPS page → file:// link → opens Explorer to parent dir + selects file (dir-link opens folder). **ZERO per-machine install** (1 GPO setting). HARD reqs: (1) app served HTTPS, (2) eoffice host in **IE Intranet Zone** (push via SiteToZoneAssignmentList GPO), (3) Edge only — **Chrome has NO equivalent** (confirmed MS+textslashplain: Chrome 76+ blocks file:// nav, only fix=Local Explorer ext). Caveat: first-click shows external-protocol prompt unless ExternalProtocolDialogShowAlwaysOpenCheckbox lets user tick "always". URLAllowlist does NOT solve nav-block + "doesn't work with file://* wildcards" (MS Learn). Ext route = ExtensionInstallForcelist (force-install, but 3rd-party Local Explorer = paid + needs native helper.exe install = NOT zero-install). .reg custom-protocol = anh đã reject. Verdict: oneClick+zeroInstall TRUE **only if 100% Edge fleet**; mixed-Chrome → must add extension (loses zero-install). Sources: learn.microsoft.com/deployedge intranetfilelinksenabled + urlallowlist + extensioninstallforcelist; chromeenterprise.google/policies/url-patterns; textslashplain.com navigating-to-file-urls.
|
||||||
- **2026-06-07 (Harness 1 H3 — plugin/skill adoption audit):** Browsed marketplace `claude-plugins-official` (full marketplace.json ~200+ plugin; local folder 35). Enabled user-global (`~/.claude/settings.json`) = **15 plugin**. **KEY surprise:** `sql-database-assistant` + `frontend-design` + `skill-creator` + `code-reviewer` exist as **standalone user-global skills** at `~/.claude/skills/` (auto-available every project — NO plugin enable needed). `~/.claude/skills/` has 23 standalone skills. Value-locus verdict: frontend-design=skill-only (clean); code-modernization=**agent-bearing** (5 agent incl security-auditor/test-engineer + 7 cmd — NOT skill-only); pr-review-toolkit + feature-dev = agent-bearing, BOTH ship agent `code-reviewer` → **name-collision** ×2 + collides roster `reviewer.md`. csharp-lsp = **Windows no-op** (`csharp-ls` NOT on PATH, needs `dotnet tool install`). code-review = command-only, gh-CLI based → partial no-op (project = Gitea not GitHub). session-report = node `.mjs` (Win-OK, Node 20). Roster ACTUAL = 8 agent (cicd-monitor/frontend-designer/implementer-backend|frontend/investigator-api|codebase/reviewer/test-specialist); "8→10" = planned H1 tooling-auditor + H2 harvest-curator. Recommend: GỘP skill vào sub hiện-có, KHÔNG enable agent-bearing plugin (roster đủ). Report-only.
|
- **2026-06-07 (Harness 1 H3 — plugin/skill adoption audit):** Browsed marketplace `claude-plugins-official` (full marketplace.json ~200+ plugin; local folder 35). Enabled user-global (`~/.claude/settings.json`) = **15 plugin**. **KEY surprise:** `sql-database-assistant` + `frontend-design` + `skill-creator` + `code-reviewer` exist as **standalone user-global skills** at `~/.claude/skills/` (auto-available every project — NO plugin enable needed). `~/.claude/skills/` has 23 standalone skills. Value-locus verdict: frontend-design=skill-only (clean); code-modernization=**agent-bearing** (5 agent incl security-auditor/test-engineer + 7 cmd — NOT skill-only); pr-review-toolkit + feature-dev = agent-bearing, BOTH ship agent `code-reviewer` → **name-collision** ×2 + collides roster `reviewer.md`. csharp-lsp = **Windows no-op** (`csharp-ls` NOT on PATH, needs `dotnet tool install`). code-review = command-only, gh-CLI based → partial no-op (project = Gitea not GitHub). session-report = node `.mjs` (Win-OK, Node 20). Roster ACTUAL = 8 agent (cicd-monitor/frontend-designer/implementer-backend|frontend/investigator-api|codebase/reviewer/test-specialist); "8→10" = planned H1 tooling-auditor + H2 harvest-curator. Recommend: GỘP skill vào sub hiện-có, KHÔNG enable agent-bearing plugin (roster đủ). Report-only.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -92,6 +92,7 @@ Bearer từ `POST api.solutions.com.vn/api/auth/login` → status matrix expecte
|
|||||||
|
|
||||||
- **2026-06-16 (S65bis recon — Employee profile master-detail vs NamGroup, on-disk):** ⭐ **STALE-PREMISE CORRECTION:** fe-user `/employees` KHÔNG list-only — `hrm/EmployeesListPage.tsx` (1201 LOC) ĐÃ master-detail 2-panel (filter sidebar :117 + list table :197 + inline detail :234) với **6 collapsible section** (`<details>` :1157, KHÔNG tab) + 5 satellite inline CRUD (WorkHistory/Education/FamilyRelation/Skill/Document, `setEditing{X}Id`+`adding{X}` mutex pattern 12-ter S35). **fe-admin == fe-user `diff -q` IDENTICAL** (SHA256 same). **Entity gần đủ screenshot:** `Domain/Hrm/EmployeeProfile.cs` (137 LOC) CÓ: DOB/Gender/Ethnicity/Religion/Nationality/Height/Weight(:98-99)/IdCard(số+ngàycấp+nơicấp :52-54)/permanent+temporary addr/phone/personalEmail/code/hireDate/qualification/salary(Base+Total)/bank/4×leave-days. **THIẾU vs screenshot:** (a) BloodType CÓ nhưng "sức khỏe loại" (health-grade A/B/C) KHÔNG; (b) thâm niên = DERIVED từ HireDate (no column); (c) chức danh = `User.Position`/`PositionLevel` (Identity, KHÔNG ở EmployeeProfile) — list/detail JOIN Users (`EmployeeFeatures.cs:467`); (d) "lương BHXH/phụ cấp" tách riêng KHÔNG có (chỉ Base+Total); đơn vị=DepartmentName JOIN. **5 satellite entity + 15 endpoint FULL** (`EmployeesController.cs:75-233` 5 region×Create/Update/Delete; GET detail Include cả 5 :455-459). Skill polymorphic gộp 3 NamGroup table (Computer/Language/Other Kind :69). **GAP THẬT:** (1) **NO org-tree** — `Department.cs` FLAT (Code/Name/ManagerUserId/Note, KHÔNG ParentId), `DepartmentsController` chỉ GET list+byId (NO /tree), KHÔNG endpoint count-per-dept → cây trái + badge phải build CLIENT-side group-by departmentId từ list; (2) **5-tab layout** screenshot = 6-section `<details>` hiện tại (re-skin UI, data đủ); (3) "Hợp đồng lao động" tab = chỉ có `EmployeeDocument` type=LaborContract(5), KHÔNG entity HĐLĐ riêng (3 HĐLĐ table DEFER Plan H2 per `EmployeeProfile.cs:10`). **NamGroup source:** `D:\...\NAMGROUP\SOURCECODE_CÔNG_TY\` find .tsx/.razor = 0 hit (KHÔNG phải React/archived) — RAG `proj_namgroup_main` 0 component; tham khảo layout = screenshot anh gửi, KHÔNG có code mirror trực tiếp. ⇒ **Wire-lại-là-xong:** data + API + satellite CRUD 100% sẵn. **Build mới:** Department.ParentId migration + /tree + count endpoint (nếu muốn org-tree thật thay client-group). **Re-skin:** 6-section→5-tab + avatar header. **No new field bắt buộc** trừ health-grade nếu anh cần. Tag `[s65bis, employee-profile, master-detail-EXISTS, dept-flat-no-tree, stale-list-only-corrected]`.
|
- **2026-06-16 (S65bis recon — Employee profile master-detail vs NamGroup, on-disk):** ⭐ **STALE-PREMISE CORRECTION:** fe-user `/employees` KHÔNG list-only — `hrm/EmployeesListPage.tsx` (1201 LOC) ĐÃ master-detail 2-panel (filter sidebar :117 + list table :197 + inline detail :234) với **6 collapsible section** (`<details>` :1157, KHÔNG tab) + 5 satellite inline CRUD (WorkHistory/Education/FamilyRelation/Skill/Document, `setEditing{X}Id`+`adding{X}` mutex pattern 12-ter S35). **fe-admin == fe-user `diff -q` IDENTICAL** (SHA256 same). **Entity gần đủ screenshot:** `Domain/Hrm/EmployeeProfile.cs` (137 LOC) CÓ: DOB/Gender/Ethnicity/Religion/Nationality/Height/Weight(:98-99)/IdCard(số+ngàycấp+nơicấp :52-54)/permanent+temporary addr/phone/personalEmail/code/hireDate/qualification/salary(Base+Total)/bank/4×leave-days. **THIẾU vs screenshot:** (a) BloodType CÓ nhưng "sức khỏe loại" (health-grade A/B/C) KHÔNG; (b) thâm niên = DERIVED từ HireDate (no column); (c) chức danh = `User.Position`/`PositionLevel` (Identity, KHÔNG ở EmployeeProfile) — list/detail JOIN Users (`EmployeeFeatures.cs:467`); (d) "lương BHXH/phụ cấp" tách riêng KHÔNG có (chỉ Base+Total); đơn vị=DepartmentName JOIN. **5 satellite entity + 15 endpoint FULL** (`EmployeesController.cs:75-233` 5 region×Create/Update/Delete; GET detail Include cả 5 :455-459). Skill polymorphic gộp 3 NamGroup table (Computer/Language/Other Kind :69). **GAP THẬT:** (1) **NO org-tree** — `Department.cs` FLAT (Code/Name/ManagerUserId/Note, KHÔNG ParentId), `DepartmentsController` chỉ GET list+byId (NO /tree), KHÔNG endpoint count-per-dept → cây trái + badge phải build CLIENT-side group-by departmentId từ list; (2) **5-tab layout** screenshot = 6-section `<details>` hiện tại (re-skin UI, data đủ); (3) "Hợp đồng lao động" tab = chỉ có `EmployeeDocument` type=LaborContract(5), KHÔNG entity HĐLĐ riêng (3 HĐLĐ table DEFER Plan H2 per `EmployeeProfile.cs:10`). **NamGroup source:** `D:\...\NAMGROUP\SOURCECODE_CÔNG_TY\` find .tsx/.razor = 0 hit (KHÔNG phải React/archived) — RAG `proj_namgroup_main` 0 component; tham khảo layout = screenshot anh gửi, KHÔNG có code mirror trực tiếp. ⇒ **Wire-lại-là-xong:** data + API + satellite CRUD 100% sẵn. **Build mới:** Department.ParentId migration + /tree + count endpoint (nếu muốn org-tree thật thay client-group). **Re-skin:** 6-section→5-tab + avatar header. **No new field bắt buộc** trừ health-grade nếu anh cần. Tag `[s65bis, employee-profile, master-detail-EXISTS, dept-flat-no-tree, stale-list-only-corrected]`.
|
||||||
|
|
||||||
|
- **2026-06-16 (S66 recon — mirror Hồ sơ NS fe-user→fe-admin, on-disk):** ⭐ **VERDICT (B): vá `fe-admin/src/index.css` TRƯỚC rồi cookie-cutter SẠCH.** Copy page thuần = VỠ MÀU. **fe-admin index.css = 86 dòng (chốt `7feb53e`, TRƯỚC redesign S58 `e959f72`/`c98030f`) → THIẾU:** 4 accent palette `teal/amberx/violet/greenx` (mỗi cái 50/100/500/600/700) + 3 utility `.icon-chip`/`.app-gradient-brand`/`.card-accent`/`.stat-value`. **CÓ SẴN:** `--color-brand-50..900` (hex y hệt fe-user, incl brand-800 #175685 :15), `.label-eyebrow` :54, font Be Vietnam Pro :22. ⚠️ heading-weight CẦN CHECK (fe-user S66 `h1-h4 font-weight:700 color:#0b1220`; fe-admin có thể còn 600). **Page fe-user phụ thuộc THẬT:** text-brand-800 ×9, teal/amberx/violet/greenx-50/500/700 ×4 mỗi, icon-chip ×3, app-gradient-brand ×1. **Wiring fe-admin ĐỦ SẴN (0 đụng):** route `/employees`+`/new` `App.tsx:82-83` · `EmployeeCreatePage.tsx` **identical** (diff rỗng) · menu `Hrm_HoSo` `menuKeys.ts:33`+staticMap `Layout.tsx:53`. **Lib parity ✅:** ui/{Input,Select,Textarea,Button} prop-sig **identical** (HTMLAttributes passthrough, content khác chỉ className=chủ ý non-breaking) · EmptyState/cn/api/apiError ✅ · `types/employee.ts` **identical** · Paged `types/master` ✅ · `DepartmentTreeNode` định nghĩa INLINE trong page (:65 mirror BE DepartmentTreeNodeDto, đi theo copy — không cần type file). **KHÔNG khác chủ ý admin/user** — mirror y hệt như S35 (`9616ae2`/`c3cd343` cùng commit 2 app); write Admin-gated ở BE controller. **Cấu trúc:** admin=1200 dòng (S35 cũ, 2-panel + 5 `<details>` + 5 satellite mutex); user=1602 dòng (redesign: cây "SOLUTION COMPANY" đệ quy + list cột trái dọc · detail phải 5 tab accent + avatar gradient). **Scope: 3 file** = index.css (chèn ~40 dòng token+class block từ fe-user :29-51+:100-160) + overwrite EmployeesListPage.tsx (import path KHÔNG chỉnh, đều `@/`) + (tùy chọn heading-700). KHÔNG đụng route/menu/types/primitives/CreatePage. Tag `[s66, mirror-employee-page, accent-token-missing-fe-admin, verdict-B, cookie-cutter-after-css]`.
|
||||||
- **2026-06-16 (S65ter recon — Mục E "Link hồ sơ" phiếu PE, on-disk):** ⭐ Anh Kiệt: chèn mục E "Link hồ sơ" NGAY DƯỚI mục D "Bản so sánh". **Render 4 file** (SHA256-identical 2 app): `components/pe/PeDetailTabs.tsx` (detail+edit, 2770 LOC) + `PeWorkspaceCreateView.tsx` (create) × {fe-user,fe-admin}. KHÔNG tabs — 5 `<Section>` dọc, tiêu đề "1./2./3./4." + sub-item chữ thường "a./b./c./d." (label cột trái w-44). **Mục D ∈ Section "3. Đơn vị NCC/TP" = `ChonNccSection`** (`PeDetailTabs.tsx:1302-1375`): a.NCC(:1321) · b.Tổng hợp NS trình ký(:1324 `PeBudgetSummaryTable` — S61 thay Budget) · c.Giá chào thầu(:1326 auto) · **d.Bản so sánh(:1337-1348)** = `GeneralAttachmentsSection`(:2613) upload N FILE filter `supplierId===null` purpose=ComparisonTable(4). **INSERT E: `PeDetailTabs.tsx:1348`** (sau `</div>` mục D, trước paymentTerms :1350); mẫu = block :1337-1348. Create: `PeWorkspaceCreateView.tsx:277` (sau FormRow d). **BE: `PurchaseEvaluation.cs`(:1-72) KHÔNG có field URL** — DiaDiem/MoTa/PaymentTerms semantic khác. 1 link → `string? HoSoLink`(1000)+Mig AddColumn+cmd+DTO+validator; nhiều link → entity con `PurchaseEvaluationLink`+CREATE TABLE+CRUD (nặng). **Attachment KHÔNG reuse URL** — `PurchaseEvaluationAttachmentFeatures.cs:18-55` IFormFile thuần (FileSize>0+ContentType whitelist+IFileStorage). Mục D multi-row → E nên multi-row đối xứng. ⚠️ Surprise: comment :1314 nói "purpose=ComparisonTable hoặc supplier-row null" SAI — filter thực :1315-17 CHỈ `supplierId===null`. Tag `[s65ter, pe-section-e-link, attachment-file-only, insert-1348]`.
|
- **2026-06-16 (S65ter recon — Mục E "Link hồ sơ" phiếu PE, on-disk):** ⭐ Anh Kiệt: chèn mục E "Link hồ sơ" NGAY DƯỚI mục D "Bản so sánh". **Render 4 file** (SHA256-identical 2 app): `components/pe/PeDetailTabs.tsx` (detail+edit, 2770 LOC) + `PeWorkspaceCreateView.tsx` (create) × {fe-user,fe-admin}. KHÔNG tabs — 5 `<Section>` dọc, tiêu đề "1./2./3./4." + sub-item chữ thường "a./b./c./d." (label cột trái w-44). **Mục D ∈ Section "3. Đơn vị NCC/TP" = `ChonNccSection`** (`PeDetailTabs.tsx:1302-1375`): a.NCC(:1321) · b.Tổng hợp NS trình ký(:1324 `PeBudgetSummaryTable` — S61 thay Budget) · c.Giá chào thầu(:1326 auto) · **d.Bản so sánh(:1337-1348)** = `GeneralAttachmentsSection`(:2613) upload N FILE filter `supplierId===null` purpose=ComparisonTable(4). **INSERT E: `PeDetailTabs.tsx:1348`** (sau `</div>` mục D, trước paymentTerms :1350); mẫu = block :1337-1348. Create: `PeWorkspaceCreateView.tsx:277` (sau FormRow d). **BE: `PurchaseEvaluation.cs`(:1-72) KHÔNG có field URL** — DiaDiem/MoTa/PaymentTerms semantic khác. 1 link → `string? HoSoLink`(1000)+Mig AddColumn+cmd+DTO+validator; nhiều link → entity con `PurchaseEvaluationLink`+CREATE TABLE+CRUD (nặng). **Attachment KHÔNG reuse URL** — `PurchaseEvaluationAttachmentFeatures.cs:18-55` IFormFile thuần (FileSize>0+ContentType whitelist+IFileStorage). Mục D multi-row → E nên multi-row đối xứng. ⚠️ Surprise: comment :1314 nói "purpose=ComparisonTable hoặc supplier-row null" SAI — filter thực :1315-17 CHỈ `supplierId===null`. Tag `[s65ter, pe-section-e-link, attachment-file-only, insert-1348]`.
|
||||||
- **2026-06-16 (S65 recon — public HRM module for all-role, on-disk):** ⭐ **Mục 6 CRITICAL (gotcha #44 family) RESOLVED-FAVORABLE:** `EmployeesController.cs:23-25` = class `[Authorize(Policy="Hrm_HoSo.Read")]` (NOT `Roles="Admin"`) + per-action `Hrm_HoSo.{Create/Update/Delete}` (:45/:54). Policy resolves THROUGH permission matrix (`MenuPermissionHandler.cs:40-52` baseQuery role×menuKey CanRead; Admin-bypass :27) → seed CanRead row = API ALSO unlocked, NO 403. `HrDashboardController.cs:8-11` = `[Authorize]` any-auth only (`/api/hr/dashboard`). GET list = `/api/employees` (:28). ⇒ **seed BE permission ĐỦ, không cần đụng controller.** **Menu keys dưới `Hrm` (prefix THẬT = `Hrm_`):** root `Hrm`="Nhân sự" parent=null Order=28 (`DbInitializer.cs:1805`); `Hrm_Dashboard`="Dashboard NS" parent=Hrm Order=1 (:1850); `Hrm_HoSo`="Hồ sơ Nhân sự" parent=Hrm Order=2 (:1806). Hrm_Config* (6 leaf: LeaveTypes/Holidays/Shifts/OtPolicies/Vehicles/Drivers) parent=**Master** Order=25 (S57 re-parent :1812 — KHÔNG dưới Hrm). **Revoke (Mục 2):** `RevokeTemporarilyHiddenModulesAsync` :2151 — match `StartsWith("Hrm")||StartsWith("Off")||==Personal` AND role!=Admin AND any-flag-true (:2162-67) → set 4 cờ CRUD=false. ⚠️ **THỨ TỰ: gọi CUỐI CÙNG `:2040` trong SeedAsync, SAU grant `:2033`** → revoke THẮNG mọi grant trước nó. Mở Hrm = phải (a) sửa revoke loại trừ Hrm_HoSo/Hrm_Dashboard HOẶC (b) thêm grant SAU :2040. **Pe pattern (Mục 3):** `SeedAllRolesReviewReadPermissionsAsync:2055` — `roleManager.Roles.ToListAsync():2090` loop ALL role × reviewKeys, upsert CanRead (+CanCreate cho Pe_*), additive idempotent (skip-existing non-Pe :2115). **Seed entity (Mục 4):** `Permission`(RoleId,MenuKey,4 CRUD); idempotent = app-level skip per (RoleId,MenuKey); **13 role** `AppRoles.All` (Admin/Drafter/DeptManager/ProjectManager/Procurement/CostControl/Finance/Accounting/Equipment/Director/AuthorizedSigner/HrAdmin/CatalogManager). `Hrm_HoSo`+`Hrm_Dashboard` ĐỀU ∈ `MenuKeys.All:153,160` (khác Pe_* leaf NOT in All). **FE (Mục 5):** menu-tree-API-driven via `GetMyMenuTreeQuery.cs` (`/api/menus/me`); Hrm NOT inherit-root (chỉ 4: Contracts/Workflows/Pe/PeWf :51-59) → MỖI leaf cần CanRead row riêng, NHƯNG root `Hrm` auto-hiện nếu child có access (`HasAccess:96` CanRead OR child). `Layout.tsx:145 USER_HIDDEN_KEYS`={System,Users,Roles,Permissions,Forms,Reports} — KHÔNG chứa Hrm → fe-user auto-render; `staticMap Hrm_HoSo→/employees :75`, `Hrm_Dashboard→/hr/dashboard :104`. NO PermissionGuard per-route fe-user. ⇒ **chỉ seed BE, FE tự hiện.** Tag `[s65-recon, public-hrm, policy-based-authz-not-roles, revoke-runs-last]`.
|
- **2026-06-16 (S65 recon — public HRM module for all-role, on-disk):** ⭐ **Mục 6 CRITICAL (gotcha #44 family) RESOLVED-FAVORABLE:** `EmployeesController.cs:23-25` = class `[Authorize(Policy="Hrm_HoSo.Read")]` (NOT `Roles="Admin"`) + per-action `Hrm_HoSo.{Create/Update/Delete}` (:45/:54). Policy resolves THROUGH permission matrix (`MenuPermissionHandler.cs:40-52` baseQuery role×menuKey CanRead; Admin-bypass :27) → seed CanRead row = API ALSO unlocked, NO 403. `HrDashboardController.cs:8-11` = `[Authorize]` any-auth only (`/api/hr/dashboard`). GET list = `/api/employees` (:28). ⇒ **seed BE permission ĐỦ, không cần đụng controller.** **Menu keys dưới `Hrm` (prefix THẬT = `Hrm_`):** root `Hrm`="Nhân sự" parent=null Order=28 (`DbInitializer.cs:1805`); `Hrm_Dashboard`="Dashboard NS" parent=Hrm Order=1 (:1850); `Hrm_HoSo`="Hồ sơ Nhân sự" parent=Hrm Order=2 (:1806). Hrm_Config* (6 leaf: LeaveTypes/Holidays/Shifts/OtPolicies/Vehicles/Drivers) parent=**Master** Order=25 (S57 re-parent :1812 — KHÔNG dưới Hrm). **Revoke (Mục 2):** `RevokeTemporarilyHiddenModulesAsync` :2151 — match `StartsWith("Hrm")||StartsWith("Off")||==Personal` AND role!=Admin AND any-flag-true (:2162-67) → set 4 cờ CRUD=false. ⚠️ **THỨ TỰ: gọi CUỐI CÙNG `:2040` trong SeedAsync, SAU grant `:2033`** → revoke THẮNG mọi grant trước nó. Mở Hrm = phải (a) sửa revoke loại trừ Hrm_HoSo/Hrm_Dashboard HOẶC (b) thêm grant SAU :2040. **Pe pattern (Mục 3):** `SeedAllRolesReviewReadPermissionsAsync:2055` — `roleManager.Roles.ToListAsync():2090` loop ALL role × reviewKeys, upsert CanRead (+CanCreate cho Pe_*), additive idempotent (skip-existing non-Pe :2115). **Seed entity (Mục 4):** `Permission`(RoleId,MenuKey,4 CRUD); idempotent = app-level skip per (RoleId,MenuKey); **13 role** `AppRoles.All` (Admin/Drafter/DeptManager/ProjectManager/Procurement/CostControl/Finance/Accounting/Equipment/Director/AuthorizedSigner/HrAdmin/CatalogManager). `Hrm_HoSo`+`Hrm_Dashboard` ĐỀU ∈ `MenuKeys.All:153,160` (khác Pe_* leaf NOT in All). **FE (Mục 5):** menu-tree-API-driven via `GetMyMenuTreeQuery.cs` (`/api/menus/me`); Hrm NOT inherit-root (chỉ 4: Contracts/Workflows/Pe/PeWf :51-59) → MỖI leaf cần CanRead row riêng, NHƯNG root `Hrm` auto-hiện nếu child có access (`HasAccess:96` CanRead OR child). `Layout.tsx:145 USER_HIDDEN_KEYS`={System,Users,Roles,Permissions,Forms,Reports} — KHÔNG chứa Hrm → fe-user auto-render; `staticMap Hrm_HoSo→/employees :75`, `Hrm_Dashboard→/hr/dashboard :104`. NO PermissionGuard per-route fe-user. ⇒ **chỉ seed BE, FE tự hiện.** Tag `[s65-recon, public-hrm, policy-based-authz-not-roles, revoke-runs-last]`.
|
||||||
- **[→ archive/2026-06.md + git]** S52 P11-D/E/F 6-gap recon (IT-pool absent → S56 corrected: dept IT exists 0 user · SlaExpiryJob HostedService DI:46 pattern · OtPolicy 3-multiplier · ClosedXML exporter reuse · Attendance API cá nhân-only · FE skeleton state — full text git pre-S60) · S50 P11-C HrmConfigs add-kind 11-chỗ pattern · S50 wave h2-verify B6 gitignore ordering + POSIX-not-pwsh (curated S57bis) · S51 gotcha #57 EXT reachability 3-Master-fix/3-skip global-filter-makes-bug (curated S59).
|
- **[→ archive/2026-06.md + git]** S52 P11-D/E/F 6-gap recon (IT-pool absent → S56 corrected: dept IT exists 0 user · SlaExpiryJob HostedService DI:46 pattern · OtPolicy 3-multiplier · ClosedXML exporter reuse · Attendance API cá nhân-only · FE skeleton state — full text git pre-S60) · S50 P11-C HrmConfigs add-kind 11-chỗ pattern · S50 wave h2-verify B6 gitignore ordering + POSIX-not-pwsh (curated S57bis) · S51 gotcha #57 EXT reachability 3-Master-fix/3-skip global-filter-makes-bug (curated S59).
|
||||||
|
|||||||
@ -15,7 +15,8 @@ WRITE specialist độc quyền `tests/**`. xUnit + FluentAssertions 7.2 + EF SQ
|
|||||||
- ❌ NOT: production code `src/Backend/**` + `fe-*/**` → test reveal bug → REPORT em main, KHÔNG fix
|
- ❌ NOT: production code `src/Backend/**` + `fe-*/**` → test reveal bug → REPORT em main, KHÔNG fix
|
||||||
- ❌ NOT: decide WHAT to test (test plan) → em main + reviewer chốt priority
|
- ❌ NOT: decide WHAT to test (test plan) → em main + reviewer chốt priority
|
||||||
|
|
||||||
## 📊 Baseline 254 tests = 254 PASS (58 Domain + 196 Infra) ← S60 +14 (PeSubmitGuardAndBypassTests: 8 Section-3 guard + 6 drafter-bypass). Pre = 240 (S57bis).
|
## 📊 Baseline 286 tests = 286 PASS (45 Domain + 241 Infra) ← S67 +23 HRM test-after [DepartmentTreeTests 8 cycle-guard/rollup/orphan + PeHoSoLinkTests 9 absolute-set (⚠️spec-drift: HoSoLink gửi null=CLEAR, KHÔNG null-safe như Budget*/WorkItemId) + HrmProfilePermissionSeedTests 6 reflection private-static revoke→seed chain]. **em main PROXY-RECORD** — return truncated #53 (chết lúc update MEMORY), 3 file delivered + `dotnet test` 286 PASS verify-on-disk. Prev 263 (S61 +22 PeWorkItemBudget −14 BudgetPolicy; Domain 58→45 drop Budget module). Pre = 254 (S60).
|
||||||
|
> Pattern S67: private-static seed/init → invoke qua REFLECTION (`GetMethod(name, NonPublic|Static)` + `Invoke(null, [db, roleManager, NullLogger.Instance])`); seed MenuItem rows TRƯỚC Permission (FK MenuKey→MenuItem.Key Cascade, SQLite Error 19 nếu thiếu). Cycle-guard test: SqliteDbFixture đủ (no User); rollup-count test cần IdentityFixture (đếm User.DepartmentId active).
|
||||||
Run: `dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1` (MSBuild OOM → serialize build)
|
Run: `dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1` (MSBuild OOM → serialize build)
|
||||||
|
|
||||||
### ⚠️ Pattern: deduction hook FK → seed LeaveType cho terminal test (S43)
|
### ⚠️ Pattern: deduction hook FK → seed LeaveType cho terminal test (S43)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,42 @@
|
|||||||
|
# S67 (2026-06-16) — Hồ sơ NS visual polish + fe-admin mirror + PE Link hồ sơ auto-detect/file-link + research auto-open
|
||||||
|
|
||||||
|
**Mode:** HMW-ON · lead Opus 4.8 1M (Fable down H5) · 6 deploy prod-verified Run #297→#302 · anh + anh Kiệt FDC UAT realtime.
|
||||||
|
|
||||||
|
## Dòng việc (anh chỉ đạo realtime)
|
||||||
|
`/session-start` → "đồng nhất font + chữ đen→xanh đậm" (Hồ sơ NS fe-user) → deploy → `/ultra-on` "làm nhanh hết sức" → "list còn đen + chữ to tràn sliderbar, đồng nhất cỡ" → chat anh Kiệt vụ HoSoLink (`O:\` ổ mạng) → "cho link đi" → "auto direct sang đc ko? cho workflow research" → "file:// đc mà cu" (screenshot Chrome mở `file://D:/`) → "cho link file://" → "registry phức tạp thôi khỏi" → `/session-end`.
|
||||||
|
|
||||||
|
## 6 deploy
|
||||||
|
|
||||||
|
| Run | Commit | Việc | Bundle |
|
||||||
|
|---|---|---|---|
|
||||||
|
| #297 | `ab4e681` | fe-user Hồ sơ NS: đồng nhất font/size (mono value 12→14px) + chữ value/tên đen `slate-900`→**`brand-800`** (#175685, WCAG-AA ~7.4:1) qua `Field` dùng-chung (1 sửa = ~40 ô) + 9 vị trí tên/heading/inline | user `BumgrwCJ` |
|
||||||
|
| #298 | `292d64d` | **fe-admin mirror master-detail**: vá `index.css` (+4 accent palette + 4 utility class) TRƯỚC → `cp` page (1602 dòng SHA256 identical). Đóng pending lớn nhất HRM go-live | admin `xkSz9BfE` |
|
||||||
|
| #299 | `bcd619d` | **+23 test-after HRM → 286** (DepartmentTree 8 + PeHoSoLink 9 + HrmProfilePermissionSeed 6) | both frozen (BE-only) |
|
||||||
|
| #300 | `91aaf05` | **list flex-row gọn**: bảng 3-cột (tràn ngang rail 22rem) → flex-row 1-ô/dòng truncate + `overflow-x-hidden`. Cỡ chữ 18/14/13/11px ×2 | admin `PxiZQkaw`/user `B36hGoKd` |
|
||||||
|
| #301 | `6df1b2d` | **PE Link hồ sơ auto-detect**: `http(s)`→hyperlink bấm-mở / `O:\`→chữ+nút Copy | admin `I1fpLeYw`/user `DrQYkzh0` |
|
||||||
|
| #302 | `536dd6b` | **Link `O:\` render file://** bấm-thử + Copy dự phòng (`toFileUrl`) | admin `CcrZqfht`/user `DniDFUB_` |
|
||||||
|
|
||||||
|
## Workflow research — auto-mở `O:\` từ web (3 investigator-api song song)
|
||||||
|
**Verdict:** KHÔNG có cách one-click + zero-install thuần web. **CÁCH DUY NHẤT** bấm-mở-thẳng không-cài-per-máy = **Edge GPO `IntranetFileLinksEnabled`**:
|
||||||
|
- `HKLM\SOFTWARE\Policies\Microsoft\Edge\IntranetFileLinksEnabled=1` + `eoffice` trong IE Intranet Zone (SiteToZoneAssignmentList) — 1 GPO domain, không đụng từng máy.
|
||||||
|
- Điều kiện: **Edge-only** (Chrome KHÔNG có policy tương đương → buộc extension per-máy), HTTPS, lần đầu prompt external-protocol.
|
||||||
|
- Default browser (Chrome/Edge/FF 76+): click `file://` từ https = **CHẶN HOÀN TOÀN** ("Not allowed to load local resource", no-op).
|
||||||
|
- `.url` download = zero-install nhưng **2-click** + SmartScreen/MoTW. `.lnk` tệ hơn (CVE-2024-38217 AV chặn). File System Access API không mở path cho-sẵn. → đều thua.
|
||||||
|
- Nguồn: textslashplain.com/2019/10/09 · learn.microsoft.com/.../intranetfilelinksenabled · .../urlallowlist (file://* không work).
|
||||||
|
|
||||||
|
## §L closeout
|
||||||
|
- **§L.a:** 0 RCA mới. #53 truncate (test-specialist return cut) = class đã có guard (recover-from-disk). cwd-after-build git-add fail (build `cd ../fe-admin` → cwd kẹt) = minor shell-hygiene, recover ngay (quay root). Không nâng RCA.
|
||||||
|
- **§L.b(d) harvest:** 3 sub self-record on-return (cicd-monitor 6 run · investigator-codebase recon · investigator-api 3 research). **test-specialist PROXY-RECORD** (return truncated #53 → chưa tự ghi MEMORY → em main append baseline 254→286 + pattern reflection-seed).
|
||||||
|
- **§L.b(c) chore-flag:** ⚠️ cicd-monitor MEMORY **39.8KB** + investigator-codebase **39.4KB** over ~30KB cap (re-inflated S67: 6 cicd-run verbose + recon). Curate next session (move runs cũ → `archive/2026-06.md`).
|
||||||
|
- **§L.b(f) harvest GATE:** Coverage 4 sub (3 self + 1 proxy) · Completeness OK · Placement đúng `agent-memory/X` · Corruption 0-byte=0 (test-specialist intact 74L, không phải 0-byte — chỉ thiếu session entry) · Fidelity: test-specialist proxy honest-marked. PASS.
|
||||||
|
- **§L.b(g) tooling:** roster 11 unchanged · 0 skill/plugin mới · gotcha 65 (không phát sinh) · Workflow tool dùng lần đầu cho research (3 investigator-api qua schema StructuredOutput → return reliable 3/3, đối lập FE/reviewer empty-return S65 — data-point: research-fan-out tin được, write/verify-stage không).
|
||||||
|
|
||||||
|
## Lessons
|
||||||
|
- **Mirror cross-app cần vá `index.css` TRƯỚC khi `cp` page** nếu trang dùng accent token mới (Tailwind v4: token thiếu → class emit-RỖNG = "vỡ màu im lặng", build vẫn PASS). recon token-parity = bắt buộc trước mirror.
|
||||||
|
- **Workflow research-fan-out (investigator-api read-only + schema) RELIABLE** trong harness này (3/3 return) — khác write/reviewer-stage hay empty-return (#53). → chọn Workflow tool cho research/audit fan-out OK; verify-heavy write vẫn cân nhắc em-main self-gate.
|
||||||
|
- **Browser file:// block** = recurring "mở file local từ web" question → đã lưu memory `project_hosolink_open_from_web_browser_block`.
|
||||||
|
|
||||||
|
## 🔴 NEXT
|
||||||
|
- anh test link `O:\` (mở/no-op) → quyết IT-guide Edge GPO · visual list+màu ưng chưa (đổi `brand-700` nếu nhạt hơn).
|
||||||
|
- em: curate cicd-monitor + inv-codebase over-cap · doc-flush docs/CLAUDE.md count.
|
||||||
|
- Ops anh giữ S58/S59. Cert ~07-23. Monthly audit 2026-07-01.
|
||||||
Reference in New Issue
Block a user