[CLAUDE] Docs: S45 session-end — test-gap + Mig 43 sync
STATUS/HANDOFF S45 (154->181 test, Mig 43) + gotcha #57 (soft-delete UNIQUE must filter [IsDeleted]=0) + session log + root CLAUDE counts + ef-core skill Mig 43 row + flush 3 agent MEMORY (test-specialist proxy after #53 truncation + cicd Run #368 + investigator P11-C recon). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,48 @@
|
||||
# Session 45 — HRM test-gap stabilization + Holiday drift fix (Mig 43)
|
||||
|
||||
**Date:** 2026-06-01
|
||||
**Scope:** Tests + Infra (schema)
|
||||
**Commits:** `051b62b` (Tests) → `0c5a014` (Mig 43) → docs (this session-end)
|
||||
**CI:** Gitea Run #368 (run_number 254) PASS ~4m20s — verified prod
|
||||
**Test:** 154 → **181 PASS** (58 Domain + 123 Infra, 0 fail / 0 skip)
|
||||
|
||||
---
|
||||
|
||||
## Bối cảnh + quyết định
|
||||
|
||||
Anh giao quyền chọn thứ tự việc. Em main chọn **"stabilize before extend"**: đóng 3 test-gap deferred từ S35-S38 TRƯỚC khi chồng schema Phase 11 mới (P11-C). Lý do: 1 gap CRITICAL-flagged, nhỏ + low-risk, deferred nhiều session; làm xong baseline vững rồi mới thêm Mig.
|
||||
|
||||
## Việc done
|
||||
|
||||
### 1. Đóng 3 test-gap (commit `051b62b`, +27 test)
|
||||
🟪 **test-specialist** viết (em main chốt test plan sau recon 8 file):
|
||||
|
||||
- **Gap1 (CRITICAL) — `HrmConfigHolidayTests.cs` (7 test):** Holiday composite UNIQUE (Year, Date). Create duplicate → Conflict; same-date-diff-year → OK; Update→occupied-slot → Conflict; ⭐ **self-update giữ (Year,Date) đổi Name → KHÔNG false-positive** (guard short-circuit `entity.Year!=req.Year || entity.Date!=req.Date`); Update→empty-slot OK; Update non-existent → NotFound; soft-delete exclusion.
|
||||
- **Gap2 (MAJOR) — `EmployeeSatelliteTests.cs` (10 test):** 5× FK-invariant (mọi Create satellite guard parent `AnyAsync(Id && !IsDeleted)` → NotFound); soft-deleted parent → NotFound; happy path FK đúng; Delete soft + DeletedBy + re-operate NotFound; **DeleteEmployeeProfile soft KHÔNG cascade satellite** (behavior hiện tại — handler chỉ soft-delete parent); EF model `DeleteBehavior.Cascade` config assertion (lock schema intent).
|
||||
- **Gap3 (MAJOR) — extend `AuthorizePolicyRegressionTests.cs` (10 test):** 2 controller shape KHÁC nhau lock đúng intent — `HrmConfigsController` (class `[Authorize]` trần Policy/Roles null + writes `Roles="Admin"`) vs `EmployeesController` (class `Policy="Hrm_HoSo.Read"` + per-action Create/Update/Delete + 1 satellite representative).
|
||||
|
||||
⚠️ **gotcha #53 recurrence:** test-specialist return truncated mid-MEMORY-update ("let me read it first"). → em main verify-on-disk (glob + git status + đọc 3 file line-by-line + dotnet test) thay vì tin output cụt. MEMORY proxy-updated bởi em main.
|
||||
|
||||
### 2. Holiday drift fix (commit `0c5a014`, Mig 43)
|
||||
👤 **em main solo** (bug-fix reasoning chain + schema decision tightly coupled → tránh spawn-truncation cho change nhỏ).
|
||||
|
||||
- **Bug Gap1 lòi ra:** `HolidayConfiguration` DB UNIQUE `(Year,Date)` plain `.IsUnique()` KHÔNG filter, trong khi handler check `!IsDeleted` → admin xoá (soft) 1 ngày lễ rồi tạo lại cùng (Year,Date) → app-check PASS nhưng DB UNIQUE reject → `DbUpdateException` **500 reachable**.
|
||||
- **Fix:** `.HasFilter("[IsDeleted] = 0")` — khớp pattern **13× sẵn có** (Catalogs ×4, Contract/PE/Proposal/Budget/WorkflowApps code-unique). **Mig 43 `FilterHolidayUniqueIndexByIsDeleted`** (DropIndex + CreateIndex filter; Down reverse sạch). Applied Dev + Design LocalDB.
|
||||
- **Test flip:** Case 7 từ assert `DbUpdateException` → assert SUCCESS (reuse slot, 1 active + 1 soft-deleted). Spec-change → update test cùng commit.
|
||||
- Table count vẫn **91** (index-only mig, no CREATE TABLE).
|
||||
|
||||
### 3. cicd verify (🟩 Run #368 PASS)
|
||||
test gate 181 · Mig 43 applied prod (`__EFMigrationsHistory` top) · `IX_Holidays_Year_Date` `filter_definition = ([IsDeleted]=(0))` live (was NULL) · FE bundle UNCHANGED `Krjvg_3j`/`6sNStgxa` (đúng — BE-only push, KHÔNG flag ship-fail) · health 200 · 0 regression.
|
||||
|
||||
### 4. P11-C pre-flight (🟦 investigator-codebase)
|
||||
Vehicle+Driver catalog: chưa có master entity (chỉ VehicleBooking free-text Mig 39). **Recommend:** extend HrmConfigs +2 kind (`vehicles`+`drivers`) declarative KIND_CONFIG, Mig 44, giữ VehicleBooking free-text (FK link defer). Caught gotcha #57 backlog (LeaveType/Shift unfiltered).
|
||||
|
||||
## Learnings
|
||||
|
||||
- **gotcha #57 NEW:** soft-delete + UNIQUE → MUST `.HasFilter("[IsDeleted]=0")`. Backlog: LeaveType.Code + ShiftPattern.Code vẫn unfiltered.
|
||||
- **`feedback_background_spawn_visibility`:** spawn agent foreground = im lặng vài phút = "looks frozen" (anh phản hồi). → đẩy long work background + report "đã launch X" ngay. Cũng có 1 dead turn ("No response requested") = hiccup thật, em main nhận.
|
||||
- **Test theo CODE = single source of truth** → test lòi drift thật (Holiday) → REPORT → fix proper. Closed loop: gap test → bug surfaced → fixed + verified prod cùng session.
|
||||
- **EF model-metadata assertion** (`db.Model.FindEntityType(...).GetForeignKeys()...DeleteBehavior`) = cách lock schema intent (cascade) không cần DB round-trip — Pattern-10-style cho EF model.
|
||||
|
||||
## Next (S46, anh pick)
|
||||
P11-C Vehicle+Driver (Mig 44, recon ready) · gotcha #57 fix LeaveType/Shift filtered-unique (gộp P11-C) · P11-D ItTicket SLA / P11-E AttendanceReport / P11-F MaTicket · Phase 9 Ops.
|
||||
Reference in New Issue
Block a user