[CLAUDE] Docs: S51 P11-C Vehicle+Driver + gotcha #57 (3 HRM catalog) closeout

STATUS/HANDOFF S51 (Mig 43->45, tables 91->92, test 181->186, bundle Cg9mvltU/YgqDvsqr, P11-C DONE) + gotchas #57 ext (2->3 HRM catalog Mig 45 + Master ext backlog Mig 46 worktree) + session log 2026-06-08-S51. Agent-memory flush (impl-be/fe + test + cicd + investigator self-write; reviewer em-main proxy [return truncated gotcha #53]). CI-skip (docs/.md only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-08 10:52:25 +07:00
parent 30a99aa03f
commit 68c6bfea77
10 changed files with 106 additions and 34 deletions

View File

@ -2,7 +2,26 @@
> **Tiering rule (S40):** giữ **2-3 session gần nhất**. Cũ hơn → `docs/changelog/sessions/`. Full brief history pre-S40 → `docs/_archive/HANDOFF-preS40-fullhistory.md`.
**Last updated:** 2026-06-07 (Session 50**S49 Harness 1·2·3 verified-runtime closeout** (all 3 parts) · S49 adopt context: H1+H2 = 2 monitor sub TÁCH BIỆT (tooling-auditor + harvest-curator → roster 8→10) + wire session-start/end · H2 wave-folder isolation (hmw.js wave-mode + .gitignore B6) · H3 email channel `broadcasts/` (self=se). reviewer PASS all 3. **executed-file → S50 (2026-06-07) FULLY VERIFIED: (a) 2 monitor sub loaded+ran @session-start; (b) H2 wave-mode B6 isolation HELD (Run wf_b7e4d6ef-787); (c) H3 email send-path verified (AI_INFRA pull pending their step).** Prev: S48 adap verify closure; S47 adap channel install.)
**Last updated:** 2026-06-08 (Session 51**P11-C Vehicle+Driver catalogs (Mig 44) + gotcha #57 ext 3 HRM catalog (Mig 45)**, HMW-mode ON product feature, deployed prod Run #371. 7-agent fan-out, reviewer caught Driver FE↔BE required-field contract mismatch → fixed. test 181→186, tables 91→92, bundle admin `Cg9mvltU`/user `YgqDvsqr`. ⚠️ RAG/Qdrant DOWN cả session (file-based fallback). gotcha #57 EXT Master (Department/Supplier/Project, Mig 46) → separate worktree session. Prev S50: Harness 1·2·3 verified-runtime.)
---
## S51 (2026-06-08) — P11-C Vehicle+Driver catalogs + gotcha #57 ext (HMW-mode ON · product feature · deployed prod)
**User: `/session-start` → "P11-C Vehicle+Driver" → "làm đi / chạy luôn cho nhanh". HMW fan-out, ship to prod.**
**Done (commit `30a99aa` → Gitea Run #371 PASS ~4m18s, verified prod):**
- **Mig 44 `AddVehicleAndDriverCatalogs`** — extend HrmConfigs +2 declarative kind (Vehicle/Driver), 2 catalog table filtered-unique day-1. BE Region 5/6 CRUD + Controller +2 route (GET public/write Admin) + MenuKeys +All (auto perm) + DbInitializer idempotent seed. FE KIND_CONFIG +2 ×2 app SHA256 mirror + 4-place (`:kind`-driven, no new route). Tables 91→**92** (sys.tables ground-truth — narrative "93" was +1 drift).
- **Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted`** (bundled gotcha #57) — LeaveType+ShiftPattern+**OtPolicy** filtered (3 HRM catalog; OtPolicy missed in "2 catalog" backlog, caught via grep). +5 test-before (181→**186** RED→GREEN).
- **reviewer caught 1 MAJOR** → fixed: Driver FE↔BE required-field mismatch (root = inconsistent em-main brief BE-required vs FE-optional).
- **cicd Run #371:** bundle admin `Cg9mvltU`/user `YgqDvsqr`, 5 idx filtered `([IsDeleted]=(0))` live, smoke 200, /hrm-configs/{vehicles,drivers} wired.
**🔴 NEXT SESSION:**
- **gotcha #57 EXT (worktree session đang chạy):** Department/Supplier/Project (Master) → Mig 46 (3 idx, confirmed-reachable). Merge khi xong — nó tạo Mig 46; main KHÔNG tạo migration nào nữa → no conflict, chỉ cần sequence đúng.
- **RAG/Qdrant DOWN:** restart `rag-infra.ps1 -Action ensure` (AI_INFRA repo) → verify `list_projects`. RAG re-index S42-S51 stale (AI_INFRA op).
- **AI_INFRA-side carry-over:** `/check-email se` pull S50 handshake.
- **Product (anh pick):** P11-D ItTicket SLA / P11-E AttendanceReport+OtPolicy multiplier / P11-F MaTicket / Phase 9 Ops.
- **Doc backlog (low):** STATUS/HANDOFF over-tiering (re-tier) · schema-diagram §16+ Mig 27-45 gap · agent baselines stale (reviewer 130-test/investigator counts → monthly 2026-07-01).
---

View File

@ -3,7 +3,7 @@
> **Update rule:** trước khi bắt đầu 1 task → ghi row `🔥 In Progress`. Xong → `✅ Recently Done`.
> **Tiering rule (S40):** chỉ giữ **state hiện tại + 3 session gần nhất** ở file này. Session cũ hơn → `docs/changelog/sessions/`. Full history pre-S40 → `docs/_archive/STATUS-preS40-fullhistory.md`. (Tránh over-context — xóa double, không cắt nội dung.)
**Last updated:** 2026-06-07 (Session 49**AI_INFRA Harness 1·2·3 adopt** (HMW-mode ON — recon fan-out 4 read-only agent @P2 + em main single-writer WRITE ~25 file, governance/infra no product code): H1+H2 = **2 monitor sub TÁCH BIỆT** (tooling-auditor + harvest-curator → roster 8→10) + session-start/end wire · H2 **wave-folder isolation** (hmw.js wave-mode + .gitignore B6 VERIFIED git-check-ignore) · H3 **email channel** `broadcasts/` (self=se, 6+6 folder + 2 cmd). **S50 (2026-06-07) verified-runtime: 2 monitor sub (tooling-auditor H1 + harvest-curator H2) CONFIRMED loaded+ran @session-start RE-REPORT** (test gate 181 PASS). **H2 wave-mode VERIFIED** (Run wf_b7e4d6ef-787: 2-agent wave, B6 isolation HELD — git status 6-baseline/chunk 2415 unchanged, B4 both-paths exercised) + **H3 email send-path VERIFIED** (handshake → outbox/ai_infra, body-hash self-verified; AI_INFRA /check-email se pull = their step). Prev S48: adap verify closure; S47 adap channel install.)
**Last updated:** 2026-06-08 (Session 51**P11-C Vehicle+Driver catalogs + gotcha #57 ext**, HMW-mode ON, product feature): Mig 44 `AddVehicleAndDriverCatalogs` (2 catalog table, filtered-unique day-1) + Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted` (3 HRM catalog LeaveType/ShiftPattern/**OtPolicy** — OtPolicy missed in "2 catalog" backlog, caught via grep). 7-agent fan-out: investigator recon → BE∥FE parallel → test-before (RED→GREEN) → reviewer (caught Driver FE↔BE required-field contract mismatch → fixed) → cicd. **Commit `30a99aa` → Gitea Run #371 PASS, deployed prod** (test 181→186, tables 91→92, bundle admin `Cg9mvltU`/user `YgqDvsqr`, 5 idx filtered live). gotcha #57 EXT (Department/Supplier/Project Master, Mig 46) → separate worktree session. ⚠️ RAG/Qdrant DOWN cả session (file-based fallback). Prev S50: Harness 1·2·3 verified-runtime.)
---
@ -11,30 +11,30 @@
| Metric | Value | Note |
|---|---|---|
| Migrations | **43** | last `FilterHolidayUniqueIndexByIsDeleted` (20260601064128, S45) |
| SQL tables | **91** | +1 S43 LeaveBalances (verified prod, UNIQUE composite + FK LeaveTypes Restrict) |
| API endpoints | **~241** | +3 S43 (leave-balances my/admin/adjust) |
| FE pages | **67** | WorkflowAppDetailPage (admin+user SHA256 identical) |
| Menu keys | **~53** | BE `MenuKeys` const (FE menuKeys.ts mirror 54) |
| Tests | **181 PASS** | 58 Domain + 123 Infra · 0 fail / 0 skip · +27 HRM coverage S45 (Holiday/EmployeeSatellite/authz) |
| Gotchas | **57** | `docs/gotchas.md` (latest #57 soft-delete UNIQUE phải filter [IsDeleted]=0, S45) |
| User memory | **17** | +S50 monitor-residual-write-containment (E-006 lesson); H2 S50 cross-check 0 orphan/0 byte |
| Migrations | **45** | +S51 Mig 44 `AddVehicleAndDriverCatalogs` + Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted` |
| SQL tables | **92** | +2 S51 Vehicles + Drivers (cicd `sys.tables` ground-truth; narrative "91→93" = +1 drift, real 90+2=92) |
| API endpoints | **~249** | +8 S51 (hrm-configs vehicles/drivers × GET/POST/PUT/DELETE) |
| FE pages | **67** | HrmConfigsPage `:kind`-driven (P11-C +2 kind, no new page) |
| Menu keys | **~55** | +2 S51 `Hrm_Config_Vehicles`/`Drivers` (BE `MenuKeys` const + FE mirror) |
| Tests | **186 PASS** | 58 Domain + 128 Infra · 0 fail / 0 skip · +5 S51 `HrmConfigFilteredUniqueTests` (Vehicle/Driver/LeaveType/Shift/OtPolicy) |
| Gotchas | **57** | #57 soft-delete UNIQUE filter — S51 EXTENDED 3 HRM catalog (Mig 45) + ext backlog 3 Master (worktree) |
| User memory | **17** | (unchanged S51 — product feature session) |
| Skills | 6 | 3 domain + 3 ops |
| Sub-agents | **10** | Opus 4.8 1M · 8 product/quality (7 core + frontend-designer) + **2 monitor INFORM-only** (tooling-auditor H1 + harvest-curator H2, S49 2026-06-07 Harness 1 — **verified-runtime CONFIRMED S50** both spawned+ran clean) |
| RAG chunks | **2415** | live (S50 verified ×2 via `list_projects`) · S41 baseline 2406 (3080→2406 674 junk) +9 store_memory since · last_indexed 2026-05-29 stale ~9d (AI_INFRA re-index op) |
| Sub-agents | **10** | Opus 4.8 1M · 8 product/quality (7 core + frontend-designer) + 2 monitor INFORM-only (tooling-auditor H1 + harvest-curator H2) |
| RAG chunks | **DOWN S51** | Qdrant 127.0.0.1:6333 refused cả session (`search_memory` ConnectError; `rag-infra.ps1 -Action ensure` = AI_INFRA op). S50 baseline 2415. SE file-based fallback. |
**Bundle hash live (prod):** admin `DPPTx2Kw` · user `CjoUEsoV` (Gitea Run #369, S48 — rotated from `Krjvg_3j`/`6sNStgxa` by login a11y fix). cicd-monitor PASS: test 181 · Mig stays 43 · health/smoke 200 ×4.
**Phase:** ✅ Phase 10 COMPLETE · 🔄 **Phase 11 IN PROGRESS** — P11-A + P11-B DONE (deployed prod) · ⬜ P11-C..F pending (P11-C Vehicle+Driver recon ready S45) · 🧪 S45 test-gap stabilization + Mig 43 Holiday fix shipped · 🚫 Phase 9 Ops blocked (anh main coordinate).
**Bundle hash live (prod):** admin `Cg9mvltU` · user `YgqDvsqr` (Gitea Run #371, S51 — rotated from `DPPTx2Kw`/`CjoUEsoV` by P11-C). cicd-monitor PASS: test 186 · Mig 44+45 applied prod (5 `IX_*_Code` filtered `[IsDeleted]=0`) · health/smoke 200 ×4 · /hrm-configs/{vehicles,drivers} wired.
**Phase:** ✅ Phase 10 COMPLETE · 🔄 **Phase 11 IN PROGRESS** — P11-A/B/**C** DONE (deployed prod) · ⬜ P11-D/E/F pending · 🚫 Phase 9 Ops blocked (anh main coordinate).
> ⚠️ **Count drift fixed S40:** endpoints ~223→**211**, FE pages 53→**65**, menu keys 85→**~53**. Tables **84 confirmed correct** (DbSet 77 + Identity 7). 3 số "khó fake" (mig/gotcha/git) luôn đúng. Cause: số "incremented mỗi session" over/under-count optimistic — re-ground định kỳ.
---
## 🔥 In Progress (S50)
## 🔥 In Progress (S51)
| Task | Owner | Status |
|---|---|---|
| _(none — S50 closed S49 infra-finish: Harness 1·2·3 **verified-runtime** (2 monitor sub + wave-mode B6 isolation + email send-path). **NEXT product (anh pick):** P11-C Vehicle+Driver (Mig 44, recon ready) / gotcha #57 LeaveType+Shift filtered-unique (coords ready: LeaveTypeConfiguration.cs:19 + ShiftPatternConfiguration.cs:19) / P11-D-F / Phase 9 Ops)_ | 👤 | ✅ |
| _(none — S51 closed P11-C Vehicle+Driver (Mig 44) + gotcha #57 ext-to-3-HRM-catalog (Mig 45), deployed prod Run #371. **NEXT product (anh pick):** P11-D ItTicket SLA / P11-E AttendanceReport+OtPolicy multiplier / P11-F MaTicket / Phase 9 Ops. gotcha #57 EXT Master (Mig 46) running in worktree session.)_ | 👤 | ✅ |
**S40 done:** ✅ Consolidation (`d2f52ba`) · ✅ Curate 4 agent MEMORY >25KB→<8.4KB (`78c9de3`) · RAG catch-up chunk S37-S40 (rerank 0.867) · **AI_INFRA bulletin 2026-05-29 adopt 4/4** (MỤC2 Tiered Memory Policy v1 `6f08d1f` + MỤC3 /session-start+/session-end slash commands `c8ff5e1`). Full RAG re-index = AI_INFRA op (cần VOYAGE_API_KEY).
@ -44,6 +44,14 @@
## ✅ Recently Done (newest on top — 3 session; cũ hơn → session logs)
### S51 (2026-06-08) — ✅ P11-C Vehicle+Driver catalogs (Mig 44) + gotcha #57 ext 3 HRM catalog (Mig 45) — HMW fan-out, deployed prod
- **Commit `30a99aa` Gitea Run #371 PASS ~4m18s, verified prod.** HMW-mode ON, 7-agent fan-out: 🟦 recon 🟨 BE 🟧 FE (parallel file-disjoint) 🟪 test-before 🟥 reviewer 🟩 cicd. RAG/Qdrant DOWN cả session ground-truth on-disk (đáng tin hơn stale RAG index 05-29).
- **Mig 44 `AddVehicleAndDriverCatalogs`** 2 catalog table (Vehicles + Drivers, `AuditableEntity`), filtered-unique Code day-1 (gotcha #57 từ đầu). Extend HrmConfigs declarative: BE Region 5/6 CRUD (mirror LeaveType) + Controller +2 route-group (8 endpoint, GET public / write Roles=Admin) + MenuKeys +2 +All (auto Admin perm) + DbInitializer idempotent seed 2 veh/2 drv. FE KIND_CONFIG +2 kind ×2 app (SHA256 mirror) + 4-place (types/page/menuKeys/Layout staticMap), `:kind`-driven (no new App.tsx route). Tables 91→**92** (cicd `sys.tables` ground-truth).
- **Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted`** (bundled gotcha #57) LeaveType + ShiftPattern + **OtPolicy** bare `.IsUnique()` `.HasFilter("[IsDeleted]=0")`. **OtPolicy BỊ BỎ SÓT khỏi backlog "2 catalog" → em main bắt được khi grep toàn bộ config** (= 3 HRM catalog). test-before: +5 `HrmConfigFilteredUniqueTests` (181→**186**), REDGREEN observed.
- **🟥 reviewer caught 1 MAJOR** (pre-commit): Driver FEBE required-field mismatch (FE optional vs BE `NotEmpty`+NOT NULL) root = inconsistent em-main brief across BE/FE fixed (FE +`required:true`). Lesson: parallel fan-out shared-contract inconsistency chỉ lộ lúc integration; green tests correct contract.
- **🟩 cicd Run #371 PASS:** test 186 · Mig 44+45 prod · 5 `IX_*_Code` filtered `([IsDeleted]=(0))` live (3 HRM was NULL) · bundle rotate admin `Cg9mvltU`/user `YgqDvsqr` · health 200 · /hrm-configs/{vehicles,drivers} 401 unauth + 200 authed (2 seed each).
- **gotcha #57 EXT** (investigator audit complete): Department/Supplier/Project (Master, confirmed-reachable via global query-filter quirk) **worktree session** Mig 46 (3 idx). ContractClause/MeetingRoom/EmployeeProfile = SKIP (not reachable). session log `2026-06-08-S51-p11c-vehicle-driver-gotcha57.md`.
### S50 (2026-06-07) — ✅ S49 Harness 1·2·3 verified-runtime closeout (HMW-mode ON · infra-finish, no product code, CI-skip)
- **`/session-start` bootstrap** spawned **2 monitor sub** (tooling-auditor H1 + harvest-curator H2) RE-REPORT **verified-runtime CONFIRMED** (S49 milestone (a) closed). H1 caught 3 doc-freshness drifts em main patched (plugin 1518 · skill-index 3143 mig + 4957 gotcha · verified-runtime markers). H2 harvest 🟢 clean (0-byte/orphan/corruption=0). Test gate **181 PASS**, RAG 2415.
- **(b) H2 wave-mode VERIFIED** wave-run `h2-verify` (Workflow Run `wf_b7e4d6ef-787`, 2-agent: investigator-codebase read-only + test-specialist write-direct). **B6 isolation HELD**: git status = 6-baseline only (0 canonical/agent-memory leak), sub-MDs gitignored, **chunk 2415→2415** (0 rogue RAG write). B4 both-paths exercised. Bonus: gotcha #57 confirmed open + exact coords (`LeaveTypeConfiguration.cs:19` + `ShiftPatternConfiguration.cs:19` vs fixed `HolidayConfiguration.cs:18`).
@ -136,13 +144,14 @@
## 🎯 Next up
### 🔄 Phase 11 — Polish/wire skeleton (IN PROGRESS)
- **P11-A** wire ApproveV2 + LevelOpinions 4 module (Leave/OT/Travel/Vehicle) **DONE S42** (Run #250, deployed prod). CodeGen MaDonTu cho 4 module ĐÃ gộp luôn (WorkflowAppCodeSequences) P11-F phần ItTicket MaTicket còn lại.
- **P11-B** LeaveBalance business logic **DONE S43** (Mig 42, trừ phép terminal + số + FK guard, Gitea #367 prod).
- **P11-C** Vehicle+Driver catalog Mig 43 · **P11-D** ItTicket auto-assign + SLA timer · **P11-E** AttendanceReport + Excel + OtPolicy multiplier · **P11-F** CodeGen atomic MaTicket (MaDonTu xong S42)
- **P11-A** wire ApproveV2 + LevelOpinions 4 module **DONE S42** (Run #250, prod).
- **P11-B** LeaveBalance business logic **DONE S43** (Mig 42, prod).
- **P11-C** Vehicle+Driver catalog **DONE S51** (Mig 44, Run #371, prod). HrmConfigs +2 kind declarative; VehicleBooking giữ free-text (FK link defer).
- **P11-D** ItTicket auto-assign + SLA timer · **P11-E** AttendanceReport + Excel + OtPolicy multiplier · **P11-F** CodeGen atomic MaTicket (MaDonTu xong S42)
### 🔧 Maintenance backlog
- RAG re-ingest `solution_erp` S42-S43 content (store_memory stopgap live; full re-index = AI_INFRA op)
- **Test coverage gaps Gap1/2/3 DONE S45** (+27 test). NEW backlog (gotcha #57): **LeaveType.Code + ShiftPattern.Code UNIQUE chưa filter `[IsDeleted]=0`** (cùng class Holiday Mig 43 recreate-on-soft-deleted-slot 500; test-before khi fix). **Wave-verified S50 (exact coords):** `LeaveTypeConfiguration.cs:19` + `ShiftPatternConfiguration.cs:19` bare `.IsUnique()` vs fixed `HolidayConfiguration.cs:18 .HasFilter("[IsDeleted] = 0")`; test template = `HrmConfigHolidayTests.cs:180-197` (Case 7). Cân nhắc gộp vào P11-C khi đụng HrmConfigs.
- **gotcha #57 LeaveType+ShiftPattern+OtPolicy filtered-unique DONE S51** (Mig 45, **3 HRM catalog** OtPolicy bị bỏ sót khỏi backlog "2 catalog", bắt được via grep + test-before 5 case). **EXT (worktree session, Mig 46):** Department/Supplier/Project (Master, confirmed-reachable via global query-filter quirk); ContractClause/MeetingRoom/EmployeeProfile = SKIP (audit-verified not-reachable).
- Skill + doc drift audit cron **2026-06-01 DONE (S44)** 42 count-drift fixes + AI_INFRA bundle adopt; next **2026-07-01**
### 🚫 Phase 9 Ops (blocked — anh main coordinate)

View File

@ -0,0 +1,34 @@
# Session 51 (2026-06-08) — P11-C Vehicle+Driver catalogs + gotcha #57 ext
> HMW-mode ON · product feature · deployed prod. Commit `30a99aa` → Gitea Run #371 PASS ~4m18s.
## Bối cảnh
- `/session-start` bootstrap → **RAG/Qdrant DOWN** phát hiện ngay (search_memory `ConnectError 127.0.0.1:6333`; `rag-infra.ps1 -Action ensure` = AI_INFRA-repo op). Anh chọn "bỏ qua, làm product" → chạy file-based fallback cả session (ground-truth on-disk còn đáng tin hơn RAG index stale 05-29).
- Anh chọn task **P11-C Vehicle+Driver** + `/ultra-on` (HMW consent) + "làm đi / chạy luôn cho nhanh".
## Quy trình HMW (7-agent fan-out)
1. **Recon** — investigator background treo lâu → em main fallback tự recon on-disk: HrmConfigs = 4 catalog RIÊNG (LeaveType/Holiday/ShiftPattern/OtPolicy), KHÔNG discriminated; FE `:kind`-driven KIND_CONFIG Record. `TestApplicationDbContext` inherit `ApplicationDbContext` → +DbSet không cần sửa tests/. `VehicleBooking` free-text (VehicleLicense/VehicleName/DriverName), comment "defer catalog Phase 11".
2. **Schema chốt (em main solo)** — Mig 44: Vehicle {Code/Name/LicensePlate/SeatCount} + Driver {Code/Name/PhoneNumber/LicenseNumber/LicenseClass}, filtered-unique Code **từ đầu** (tránh gotcha #57).
3. **Wave 1 parallel (file-disjoint):** 🟨 implementer-backend (Mig 44 + 2 entity + 2 config + DbSet + HrmConfigFeatures Region 5/6 + Controller +2 route + MenuKeys + DbInitializer seed) ∥ 🟧 implementer-frontend (KIND_CONFIG +2 + 4-place mirror ×2 app, SHA256 identical). Build 0 err.
4. **gotcha #57 bundled (Mig 45):** test-specialist test-before → **2 RED observed** (LeaveType+ShiftPattern bare `.IsUnique()``SQLite Error 19`). Em main grep TOÀN BỘ config → **OtPolicy cũng bare** (bị bỏ sót khỏi backlog "2 catalog"!) → fix cả **3** config + Mig 45 + thêm OtPolicy test. 181→**186** all GREEN.
5. **🟥 reviewer (pre-commit) caught 1 MAJOR:** Driver FE↔BE required-field mismatch — FE render phoneNumber/licenseNumber/licenseClass OPTIONAL nhưng BE validator `NotEmpty()` + EF `.IsRequired()` NOT NULL → empty submit 400/500. Root = **inconsistent em-main brief** (BE "mirror Vehicle"=required vs FE spec quên required). Fix: FE +`required:true` (align all-required như Vehicle). Other cats clean.
6. **Commit `30a99aa` + push → 🟩 cicd Run #371 PASS.**
## Kết quả (verified prod)
- Mig 44+45 trong `__EFMigrationsHistory`; Vehicles+Drivers tables EXIST; tables 91→**92** (cicd `sys.tables` ground-truth — narrative "93" = +1 drift cũ).
- **gotcha #57 proof:** 5 `IX_*_Code` filtered `([IsDeleted]=(0))` (Vehicle/Driver/LeaveType/Shift/OtPolicy) — 3 HRM was NULL pre-Mig 45.
- Bundle rotate admin `DPPTx2Kw→Cg9mvltU` / user `CjoUEsoV→YgqDvsqr`. Smoke 200; /hrm-configs/{vehicles,drivers} 401 unauth + 200 authed (2 seed each).
- Test 186 (58 Domain + 128 Infra).
## gotcha #57 EXTENSION (→ worktree session)
Investigator audit (completed before kill, MEMORY line 73): **FIX 3 Master** (Department/Supplier/Project — confirmed-reachable: global `HasQueryFilter(!IsDeleted)` auto-ẩn soft-deleted khỏi Create check → check PASS → unfiltered index 500; nghịch lý global filter LÀM lộ bug). **SKIP 3**: ContractClause (no CRUD handler), MeetingRoom (Delete=IsActive not IsDeleted), EmployeeProfile (Create chặn reuse "Cần khôi phục"). **Mig 46 = 3 idx.** Anh click chip → spawn worktree session riêng (isolated) own task này; main session bỏ ext (tránh Mig 46 conflict).
## Lessons
- **Parallel fan-out contract risk:** BE∥FE file-disjoint chạy độc lập theo brief → bất kỳ inconsistency trong SHARED em-main contract chỉ lộ lúc integration. Green tests ≠ correct contract (no test chạm empty-optional path). reviewer = the net (caught it). Brief cross-stack PHẢI nhất quán required/optional 2 đầu.
- **Thoroughness grep > backlog trust:** backlog ghi "2 catalog" nhưng grep toàn bộ ra 3 (OtPolicy sót). Đừng tin count backlog — verify từ code.
- **Truncation recurrence (gotcha #53):** BE return + reviewer return + (audit) đều truncate cuối → em main ground-truth on-disk (git status/diff + read) + proxy reviewer MEMORY.
- **cicd anti-pattern #3:** transient mid-deploy bundle hash (CVbyotwa/BBlyMlJH) — KHÔNG trust tới status=success.
- **RAG MCP client reconnect ≠ Qdrant up:** client lên lại nhưng backend down → vẫn ConnectError.
## Tags
`[s51, p11-c, mig44, mig45, vehicle-driver, gotcha57, hmw-fanout, contract-mismatch-catch, rag-down]`

View File

@ -1044,7 +1044,7 @@ for h in resp.points: # ← .points không phải iterable trực tiếp
---
### 57. Soft-delete entity + UNIQUE index PHẢI filter `[IsDeleted] = 0` (Session 45)
### 57. Soft-delete entity + UNIQUE index PHẢI filter `[IsDeleted] = 0` (Session 45, ext S51)
**Triệu chứng:** Entity soft-delete (AuditableEntity) có UNIQUE index trên business key (Code / composite). Handler check trùng đã loại soft-deleted (`AnyAsync(x => x.Key == k && !x.IsDeleted)`) → định cho phép reuse slot. NHƯNG nếu DB UNIQUE index KHÔNG filter → xoá (soft) 1 row rồi tạo lại cùng key → handler PASS app-check nhưng `SaveChangesAsync` ném `DbUpdateException` (SQL Server 2627 / SQLite Error 19) → HTTP **500** (không phải Conflict sạch hay insert OK). Reachable thật: admin xoá nhầm 1 ngày lễ / mã catalog rồi nhập lại đúng.
@ -1052,7 +1052,9 @@ for h in resp.points: # ← .points không phải iterable trực tiếp
**Fix:** EF config filtered index — `e.HasIndex(x => x.Key).IsUnique().HasFilter("[IsDeleted] = 0")` (composite: `new { x.A, x.B }`). Migration DropIndex + CreateIndex(filter). SQL Server + SQLite test đều honor (bracket-quote + partial index OK).
**Đã áp 13× sẵn:** Catalogs ×4, Contract/PE/Proposal/Budget/WorkflowApps code-unique. **Fixed S45:** Holiday `(Year,Date)` Mig 43. ⚠️ **CÒN unfiltered (backlog test-before):** `LeaveTypeConfiguration.cs` Code + `ShiftPatternConfiguration.cs` Code — cùng bug class.
**Đã áp sẵn:** Catalogs ×4, Contract/PE/Proposal/Budget/WorkflowApps code-unique. **Fixed S45:** Holiday `(Year,Date)` Mig 43. **Fixed S51 (Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted`):** LeaveType + ShiftPattern + **OtPolicy** Code = **3 HRM catalog** (OtPolicy bị BỎ SÓT khỏi backlog "2 catalog" — bắt được khi grep TOÀN BỘ config). Vehicle/Driver (Mig 44) filtered day-1. ✅ test-before `HrmConfigFilteredUniqueTests.cs` (5 case, RED→GREEN).
⚠️ **EXT backlog (worktree session S51, Mig 46):** **FIX 3 (Master)** `Department`/`Supplier`/`Project` Code — CONFIRMED-reachable: AuditableEntity + GLOBAL `HasQueryFilter(!IsDeleted)` auto-ẩn soft-deleted khỏi Create check → check PASS → unfiltered index ném 500 (nghịch lý: global filter LÀM lộ bug, ngược HRM cần manual `!IsDeleted`). **SKIP 3** (audit-verified KHÔNG reachable): ContractClause (no CRUD handler — chỉ DbSet), MeetingRoom (Delete set `IsActive=false` NOT IsDeleted), EmployeeProfile (Create chặn reuse by-design — UserId ConflictException "Cần khôi phục" + EmployeeCode auto-gen atomic). Mọi bare-unique khác = composite junction / nullable-code đã `IS NOT NULL` filter / no-soft-delete.
**References:** Mig 43 `FilterHolidayUniqueIndexByIsDeleted` · `HolidayConfiguration.cs` · `HrmConfigHolidayTests.cs` Case 7 · surfaced bởi test-specialist Gap1 S45.