distill-gen: 1
# Gist — 2026-06 archive (S41-S55) · 4-field distillation

> **distill-gen: 1** — already-distilled; do NOT re-compress. Each block = VIỆC · KẾT-LUẬN(+Mig/file:line) · BÀI-HỌC · BẤT-NGỜ, ending `→ substring:"…"` grep-UNIQUE in `2026-06.md` (14 bullets moved byte-exact from MEMORY.md L87-L104, S? Harness-9 curate). Pointer-style = substring (Ctrl-F), Mig-name / phrase keyed. value tag: cao/vừa/thấp.
> The final subsection distills L1-HOT markers (S56/S57bis/S65) that REMAIN in MEMORY.md (not moved) — included here only so the coverage checklist resolves in one place; their verbatim lives in MEMORY.md, pointer notes say so.

---

## P11-A WorkflowApps wave (S41-S42) — schema + app + seed

**[cao] Mig 41 schema — 4 WorkflowApps ApproveV2 + LevelOpinions (S41 P11-A W1).** VIỆC: cookie-cutter mirror Proposal Mig 38 — 5 entity (4 {Leave,Ot,Travel,Vehicle}RequestLevelOpinion + shared WorkflowAppCodeSequence Prefix-PK) + 5 EF config (auto-discover ApplyConfigurationsFromAssembly) + 4 parent nav + enum TravelRequest=9 + 2 DbSet. KẾT-LUẬN: Mig 41 WireWorkflowAppsApprovalV2; diff CLEAN 5 CreateTable+4 AddColumn; FK Cascade parent + Restrict Level + UNIQUE composite; both DB. BÀI-HỌC: Pattern 12-bis 13× cumulative. BẤT-NGỜ: none (spec deterministic 100%). → substring:"S41 P11-A Wave 1 SCHEMA — wire ApproveV2+LevelOpinions"

**[cao] App-layer ApproveV2 CQRS (S42 Wave 2a LeaveOt stub + 2b Travel/Vehicle).** VIỆC: per-module DetailDto+LevelOpinionDto+GetById(JOIN Step/Level)+UpdateDraft+Submit+Approve(UPSERT+advance)+Reject+Return; shared internal CodeGen Serializable-tx. KẾT-LUẬN: TravelVehicleApprovalFeatures ~830 LOC; codes `{prefix}/{seq:D3}` (D3 NO year segment per spec) vs Leave/Ot `{prefix}/{year}/{seq:D3}`. BÀI-HỌC: **WorkflowAppCodeGen Serializable-tx Prefix-keyed**; **WorkflowAppStatus enum DIFFERS ProposalStatus int values (DaGuiDuyet=2 not 1, TraLai=3) → mirror by SEMANTIC enum member NOT literal**; Owner=RequesterUserId (not DrafterUserId); Submit verify wf.ApplicableType else Conflict. BẤT-NGỜ: 2a content absorbed (stub→git) into Pattern 4 + this 2b entry. → substring:"S42 P11-A Wave 2b APP — wire ApproveV2 CQRS Travel+Vehicle"

**[cao] Seed 4 sample workflow V2 (S42 P11-A) — gotcha #51.** VIỆC: DbInitializer mirror SeedSampleProposalWorkflowV2Async EXACT ×4 (Leave/Ot/Travel/Vehicle), each idempotent AnyAsync(ApplicableType) guard → 1 Workflow+1 Step+1 Level, codes QT-NP/OT/CT/XE-V2-001. KẾT-LUẬN: wired 4 calls; build 0 err 0 warn. BÀI-HỌC (marker #4): **gotcha #51 — infra seed NOT gated by DemoSeed:Disabled** (by-design reaches prod, like SeedDemoMasterData/Catalogs). BẤT-NGỜ: Bash tool runs bash NOT PowerShell despite env hint → use `cd && cmd | grep`. → substring:"S42 P11-A SEED — 4 sample ApprovalWorkflow V2"

## P11-B/C HRM business + catalogs (S43, S51)

**[cao] LeaveBalance deduct exactly-once (S43 P11-B W1) — Mig 42.** VIỆC: entity LeaveBalance:AuditableEntity (UserId/LeaveTypeId/Year + Entitled/Used/Adjustment decimal(5,2)); FK LeaveType Restrict + UNIQUE composite (UserId,LeaveTypeId,Year); deduction hook in ApproveLeaveRequestHandler terminal DaDuyet branch ONLY. KẾT-LUẬN: Mig 42 AddLeaveBalances; RemainingDays = Entitled+Adjustment−Used COMPUTED (not stored); GetMy/GetUser lazy-merge in-memory (no EF LEFT JOIN). BÀI-HỌC (marker #12): **deduct exactly-once GUARANTEED by early guard `Status != DaGuiDuyet throw`**; HRM admin convention `[Authorize(Roles="Admin")]` not menu policy. BẤT-NGỜ: OtRequest/Travel/Vehicle untouched — only Leave has balance. → substring:"S43 P11-B Wave 1 — LeaveBalance business logic"

**[cao] Vehicle+Driver catalogs (S51 P11-C W1) — Mig 44, gotcha #57.** VIỆC: 2 entity + 2 EF config (mirror filtered HolidayConfiguration NOT buggy bare LeaveType) + 2 DbSet + HrmConfigFeatures Region5/6 + Controller 8 endpoint (GET public, write Admin) + MenuKeys + DbInitializer seed. KẾT-LUẬN: Mig 44 AddVehicleAndDriverCatalogs; diff CLEAN 2 CreateTable+2 filtered IX. BÀI-HỌC (markers #57,#13,#14): **Code UNIQUE `.HasFilter("[IsDeleted]=0")`**; admin perm AUTO via MenuKeys.All (SeedAdminPermissions + Program.cs:78 both iterate); HRM no HasQueryFilter→`.Where(!IsDeleted)` manual. BẤT-NGỜ: RAG/Qdrant DOWN → all Read/Grep on-disk. → substring:"S51 P11-C HMW W1 — Vehicle+Driver catalogs HrmConfigs"

## P11-D/E/F WorkflowApps wave2 (S52)

**[cao] ItTicket round-robin + SLA (S52 P11-D W2) — Mig 46.** VIỆC: entity +SlaDueAt/SlaWarnedSent/SlaBreached; CreateItTicketHandler SlaWindow static map (Urgent4/High8/Medium24/Low72h) shared w/ ItTicketSlaJob; round-robin least-loaded assign (itDept=Departments.Code=="IT"); new ItTicketSlaJob:BackgroundService (breach+warn only, NO auto-transition). KẾT-LUẬN: Mig 46 AddSlaFieldsToItTicket 3 AddColumn no-table; AssignItTicketCommand PUT /{id}/assign [Authorize(Roles=Admin)]. BÀI-HỌC: **SeedItDepartmentStaffAsync MUST run AFTER SeedDemoUsersAsync** (that method reconciles 2 users to PRO/CCM each boot → override to IT after, end-state deterministic). BẤT-NGỜ: agent killed session-limit before MEMORY → proxy by em main. → substring:"S52 P11-D Wave2 BE — ItTicket round-robin + SLA"

**[cao] Attendance report + IT codegen (S52 P11-E+F) — NO mig.** VIỆC: P11-F MaTicket gen at Create (kanban no-workflow) `IT/2026/001`; P11-E AttendanceReportFeatures + IAttendanceReportExcelExporter (ClosedXML mirror ContractExcelExporter). KẾT-LUẬN: 2 endpoint [Authorize(Roles=Admin)] GET `/api/attendances/report` + `/report/excel`. BÀI-HỌC: **DayOfWeek+holidaySet NOT EF-translate → `.ToListAsync()` then group/classify IN-MEMORY C#**; **Holiday.Date = DateOnly NOT DateTime (spec wrote HashSet<DateTime> wrong) → HashSet<DateOnly>**; day-type prio holiday→weekend→weekday; OtWeighted=Σ(level×coef). BẤT-NGỜ: spec type-error caught (DateOnly). → substring:"S52 P11-E+F Wave1 BE migration-FREE"

## Master + cross-stack (S53, S54, S55)

**[cao] Filter 3 Master unique indexes (S53 gotcha #57 EXT) — Mig 47 + Mig 46 catch-up.** VIỆC: test-before RED→GREEN; edit 3 config Code unique `+.HasFilter("[IsDeleted] = 0")` (Department/Project/Supplier); Supplier ONLY Code filtered, Type index left untouched. KẾT-LUẬN: Mig 47 FilterMasterCatalogUniqueIndexesByIsDeleted; Mig 46 local catch-up closed LocalDB gap; 203 GREEN. BÀI-HỌC (markers #2,#57): **gotcha #57 — soft-delete UNIQUE must filter [IsDeleted]=0**; **copied filter string BYTE-FOR-BYTE from HolidayConfiguration:18 + LeaveTypeConfiguration:19** (spaces around `=`, not guessed) → snapshot+SQL consistent w/ 13 existing filtered idx. BẤT-NGỜ: Master HAS global HasQueryFilter (unlike HRM) → app-check passes but bare DB index counts soft-deleted → 500; filter aligns. → substring:"S53 gotcha #57 EXT BE — filter 3 Master Code unique indexes"

**[cao] ItTicket reassign capability + fail-closed authz (S54 cross-stack) — NO mig.** VIỆC: new GetAssignableItStaffQuery capability endpoint + AssignItTicketHandler authz Admin-OR-dept-IT→ForbiddenException, assignee-must-be-IT→ConflictException; controller /assign lowered Roles=Admin→[Authorize]. KẾT-LUẬN: 2 patterns saved (controller-lower-authorize-handler-finegrained + scoped-capability-endpoint-anti-silent-403); reviewer chain-verified role-string "Admin" real (AppRoles→SeedRoles→JWT→cu.Roles). BÀI-HỌC (marker #11): **fail-closed authz — Forbidden BEFORE NotFound** (avoid existence-oracle); ICurrentUser lacks DepartmentId → query db.Users. BẤT-NGỜ: em main reconciled 2 patterns from stray src/Backend/.claude (cwd-relative Write mishap). → substring:"S54 ItTicket reassign cross-stack — IT-staff self-service"

**[vừa] Menu leaf AttendanceReport (S54 Task D) — NO mig.** VIỆC: 3 insert — MenuKeys const Off_AttendanceReport + All[] + DbInitializer menu tuple (Order 8, parent Off). KẾT-LUẬN: admin perm auto via MenuKeys.All 2-point (SeedAdminPermissions :1916 + Program.cs:78). BÀI-HỌC: idempotent seed upsert (existing prod gets leaf on restart, existing rows only Order-reconciled). BẤT-NGỜ: none. → substring:"S54 Task D BE — promote AttendanceReport to sidebar menu leaf"

**[cao] Real master-data import (S55) — Mig 48 + ungated seed.** VIỆC: Project +4 prop (Year int?, Investor/Location/Package, maxlen 250/500/300); SeedRealMasterDataAsync 3 tuple-loop per-code idempotent, wired UNGATED after SeedCatalogsAsync. KẾT-LUẬN: Mig 48 AddProjectMasterFields 4 AddColumn no-table; seeds 62 Project+71 WorkItem+3 Supplier; runtime Dev proof landed. BÀI-HỌC: real-data import reaches prod by-design (DemoSeed:Disabled NOT gate); FLOCK01 collision demo↔real → per-code skip (demo wins). BẤT-NGỜ: WorkItem divider row "THIẾT BỊ" dropped; agent return truncated #53 → proxy by em main. → substring:"S55 master-data import (Mig 48 `AddProjectMasterFields`"

## [stub→git d2f52ba] older absorbed (S35/S40 trim)

**[thấp] S35 BE-CRUD-4-catalog + S29 Contract-V2-mirror.** KEY absorbed into L1 Pattern 12-bis foundation (catalog-mega + HRM `.Where(!IsDeleted)` manual + Validator MaxLength=EF). → substring:"Archived S35 G-H2 BE-CRUD-4-catalog + S29 Plan-B-Chunk-C Contract-V2-mirror"

**[thấp] S40 curate — FE/test + older BE → git d2f52ba.** S35 FE inline forms 5 satellite + S34 test +10 (130 PASS) + S33 EmployeesListPage + S32 wrap/startup. → substring:"Archived FE/test + older BE entries → `archive/2026-05-q4.md` + git d2f52ba (S40 curate)"

---

## L1-HOT markers (still in MEMORY.md — NOT moved; distilled here for coverage completeness)

> These live VERBATIM in MEMORY.md (kept hot). Pointers below target MEMORY.md, not 2026-06.md.

- **[cao] S56 GOLIVE-HARDEN — ExecuteUpdate atomic + fail-closed (markers #10,#11).** LeaveBalance lost-update → `ExecuteUpdateAsync` server-side row-lock inside tx (em-main post-review bumped to `IsolationLevel.Serializable`); AssignItTicket existence-oracle → Forbidden guard BEFORE NotFound (fail-closed). STALE-TRACKED caveat: ExecuteUpdate bypasses tracker → don't re-add `bal.UsedDays +=` (double-count). → substring(MEMORY.md):"S56 GOLIVE-HARDEN 3 BE fix"
- **[cao] S57bis/S65 loose-Guid FK guard (marker #13).** loose-Guid FK (WorkItemId S57bis, Department.ParentId S65) = NO physical FK; guard `AnyAsync(x.Id==id && x.IsActive)`→Conflict (mirror S43); UpdateDraft null-safe `if (request.WorkItemId is not null)` to avoid null-ing bug-class S42. → substring(MEMORY.md):"FK-guard loose-Guid"
- **[vừa] L1 Pattern foundation markers (#3,#5,#9b).** gotcha #17 = EF migration 3-file rule (Pattern 2, BẮT BUỘC commit `.cs`+`.Designer.cs`+snapshot); gotcha #65 = `dotnet build SolutionErp.slnx` includes 2 test projects; Mig 29/30/31 per-NV admin opt-in (Pattern 7, proven 4×). → substring(MEMORY.md):"EF migration 3-file rule (gotcha #17"

## CỤM BỔ SUNG [coverage-diff @S152 D2 — máy-trích nguyên-văn + lead-review; KHÔNG phải re-distill, distill-gen giữ]

> Token load-bearing có trong verbatim `2026-06.md` mà gist thiếu — mỗi dòng = token + TRÍCH NGUYÊN-VĂN dòng chứa nó (Ctrl-F token trong verbatim để đọc trọn). Chuẩn gate: gotcha#/Mig/file-ref/guard phải sống trong gist.

- gotcha **#73** · trích: "6 #5) + absolute-set null=clear (gotcha #73) + changelog Header (sibling-consistency; spec min=SaveChanges). (6) Controller `[HttpPatch('{id:guid}/bud"
- Mig **Mig 11** · trích: "field nằm trên **`User.DepartmentId`** (Mig 11) → GROUP BY `db.Users.Where(DepartmentId!=null && IsActive).GroupBy(DepartmentId).ToDictionary` = Direc"
- Mig **Mig 43** · trích: "#57 4th+5th+6th cumulative (S45 Holiday Mig 43, S51 HRM×3 Mig 45 → now Department/Project/Supplier). Edit 3 config Code unique: `b.HasIndex(x=>x.Code)"
- Mig **Mig 45** · trích: "mulative (S45 Holiday Mig 43, S51 HRM×3 Mig 45 → now Department/Project/Supplier). Edit 3 config Code unique: `b.HasIndex(x=>x.Code).IsUnique()` → `+."
- Mig **Mig 49** · trích: "proposed):** Return-truncated #53 TRƯỚC Mig 49 + projection-3 → em main solo hoàn tất (fix CS7036 + CS8019, Mig 49 `AddWorkItemToPurchaseEvaluation` 3"
- Mig **Mig 51** · trích: "- **2026-06-16 (S65b PE +HoSoLink BE — Mig 51 `AddHoSoLinkToPurchaseEvaluation` 3-file, 6 file edit + 0 new file, em-main CHỐT spec 100% → ACCEPT Case"
- Mig **Mig 52** · trích: "olumn, snapshot verified — clean mirror Mig 52. (4) DTO `PurchaseEvaluationDetailBundleDto` +`decimal? CcmBudgetPeriodAmount` sau ExpectedRemainingAmo"
- Mig **Mig 55** · trích: "mn, snapshot ×2 verified — clean mirror Mig 55. (4a) `UpdatePeSuggestedPriceProCommand` +trailing `string? Note=null` + validator `MaximumLength(1000)"
- Mig **Mig 57** · trích: "-19 (S77 PE +2 ghi-chú giá đề xuất BE — Mig 57 `AddPeSuggestedPriceNotes` 3-file, 6 edit/0 new file, COOKIE-CUTTER S73 suggested-price + S74 CcmNote,"
- Mig **Mig 58** · trích: "Suppliers.Where(s=>s.IsWinner)` (multi, Mig 58) → sửa CHỈ comment-text 'MỌI đơn vị IsWinner (multi-winner Mig 58)'. Field/code UNCHANGED. **LESSON:**"
- Mig **Mig 59** · trích: "vity 2026-06-25..19 (S88 · PE Section-B Mig 59 · PE chuông) -->"
- file-ref **AttendanceReportFeatures.cs** · trích: "/001`. **P11-E** report chấm công: NEW `AttendanceReportFeatures.cs` (DTO 3 record EXACT + GetAttendanceReportHandler) + NEW `IAttendanceReportExcelEx"
- file-ref **DbInitializer.cs** · trích: "Report` after OffChamCong:158-159 · (3) DbInitializer.cs menu tuple `(OffAttendanceReport, 'Báo cáo chấm công', Off, 8, 'FileBarChart')` after OffCham"
- file-ref **Department.cs** · trích: "y tổ chức nền trang Hồ sơ Nhân sự. (1) `Department.cs` +`Guid? ParentId` loose-Guid KHÔNG physical FK (convention PE.ProjectId/WorkItemId/SelectedSupp"
- file-ref **DepartmentConfiguration.cs** · trích: "Id/WorkItemId/SelectedSupplierId). (2) `DepartmentConfiguration.cs` +`HasIndex(x=>x.ParentId)` only — **KHÔNG `HasOne` self-FK** (em main chốt loose)."
- file-ref **DepartmentFeatures.cs** · trích: "e` self-FK** (em main chốt loose). (3) `DepartmentFeatures.cs` +`GetDepartmentTreeQuery`+`DepartmentTreeNodeDto`+Handler (append existing file, NO new"
- file-ref **DepartmentsController.cs** · trích: "e; slnx lists projects-not-files). (4) `DepartmentsController.cs` +`[HttpGet('tree')]`. **KEY recon finding (spec asked verify):** `EmployeeProfile` h"
- file-ref **MasterCatalogFilteredUniqueTests.cs** · trích: "real code+year only, OK). Compile-fix `MasterCatalogFilteredUniqueTests.cs` +4 null args CreateProjectCommand (necessary build-green). **Runtime Dev"
- file-ref **MenuKeys.cs** · trích: "potent seed (not schema). 3 insert: (1) MenuKeys.cs const `OffAttendanceReport = 'Off_AttendanceReport'` after OffChamCong:124 · (2) MenuKeys.cs All[]"
- file-ref **PEFeatures.cs** · trích: "ote` sau CcmSuggestedPrice + projection PEFeatures.cs positional-insert ĐÚNG order (DTO positional → order khít projection BẮT BUỘC). **Call-site grep"
- file-ref **PeSuggestedPriceFeatures.cs** · trích: "file → move về budget file. (a) REMOVE `PeSuggestedPriceFeatures.cs` lines 144-199 (blank + `===== CCM NS kỳ này =====` header → `SetPeCcmBudgetPeriod"
- file-ref **PeWorkItemBudgetFeatures.cs** · trích: "ce PRO/CCM trên giữ nguyên. (b) APPEND `PeWorkItemBudgetFeatures.cs` END sau line 200 (`UpdatePeBudgetCcmCommandHandler` `}`) → cạnh budget setters `U"
- file-ref **ProjectFeatures.cs** · trích: "len 250/500/300 ProjectConfiguration). `ProjectFeatures.cs` DTO+CreateCmd+UpdateCmd+validators+handlers+List/Get projections +4 (all nullable, appende"
- file-ref **PurchaseEvaluation.cs** · trích: "nullable, no table/index/backfill. (1) `PurchaseEvaluation.cs` +`string? ProSuggestedPriceNote`/`CcmSuggestedPriceNote` ngay sau CcmSuggestedPrice. (2"
- file-ref **PurchaseEvaluationConfiguration.cs** · trích: "eNote` ngay sau CcmSuggestedPrice. (2) `PurchaseEvaluationConfiguration.cs` +`HasMaxLength(1000)` ×2 sau ApprovedPriceSource (KHÔNG index — free-text)"
- file-ref **PurchaseEvaluationDtos.cs** · trích: "G đụng. **T2 stale-comment fix:** `Dtos/PurchaseEvaluationDtos.cs` ~250-254 comment trên `decimal WinnerQuoteTotal` ghi SUM 'của SelectedSupplierId' ("
- file-ref **PurchaseEvaluationFeatures.cs** · trích: "ngle-winner) → verified actual compute `PurchaseEvaluationFeatures.cs:1093-1099` = `Suppliers.Where(s=>s.IsWinner)` (multi, Mig 58) → sửa CHỈ comment-"
- file-ref **PurchaseEvaluationWorkflowService.cs** · trích: "= +1 block trong `LogTransitionAsync` (PurchaseEvaluationWorkflowService.cs ~line 1058) NGAY SAU drafter-notify, KHÔNG endpoint mới (Pattern 4 — noti"
- file-ref **TravelVehicleApprovalFeatures.cs** · trích: "— wire ApproveV2 CQRS Travel+Vehicle (`TravelVehicleApprovalFeatures.cs` ~830 LOC + 2 controller edit):** Cookie-cutter mirror Wave 2a / ProposalFeat"
- file-ref **WorkflowAppsFeatures.cs** · trích: "ullName)` capability endpoint (REGION 5 WorkflowAppsFeatures.cs) + MODIFIED `AssignItTicketHandler`: authz Admin-OR-dept-IT → `ForbiddenException`; as"
- file-ref **menuKeys.ts** · trích: "ing DocxRenderer warn). KHÔNG touch FE (menuKeys.ts/Layout = implementer-frontend) / tests / commit. Tag `[s54, task-d, menu-leaf, no-mig, admin-perm-"

### BỔ-SUNG-2 [F1/F2 sau Fidelity-gate @S152 — mở đuôi infra {yml,yaml,json,slnx,csproj,sql,config} + guard IsUnique/optimistic. N/A CỐ-Ý (F5): bundle-hash xoay #69 · tên-giả phép-thử ZZfakehash* · đuôi .md]

- file-ref **SolutionErp.Application.csproj** · trích: "mirror S35 EF-source-of-truth). Build `SolutionErp.Application.csproj -v q` **0 warn 0 err** (4s). KHÔNG test (test-specialist)/FE/mig/commit. Tag `["
