Files
solution-erp/docs/changelog/sessions/2026-06-08-S52-phase11-def-close-database-agent.md
pqhuy1987 f440c194a8 [CLAUDE] Docs: S52 closeout — Phase 11 D+E+F deployed + database-agent + session-limit recovery
STATUS/HANDOFF S52 (Phase 11 product COMPLETE, test 200, Mig 46, roster 11, bundle DYfjnpY0/_3S0BPJ2). Session log. Proxy-append implementer-backend + test-specialist diaries (Wave 2 agent killed by session-limit truoc MEMORY step).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:38:12 +07:00

67 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# S52 (2026-06-08) — Phase 11 product backlog ĐÓNG TRỌN (P11-D+E+F) + database-agent adopt
> HMW-mode ON · 3 commit deployed prod · session-limit recovery · em main + multi-agent fan-out.
> **User flow:** `/session-start` → chọn "Cả 3 (D+E+F)" → pivot "Adopt database-agent" → "để em chạy tiếp".
## TL;DR
- **Phase 11 product backlog ĐÓNG TRỌN**: P11-D (ItTicket assign+SLA) + P11-E (AttendanceReport+Excel+OtPolicy) + P11-F (MaTicket codegen) — **deployed prod**.
- **database-agent adopt** (AI_INFRA broadcast) — roster 10→11, nấc executed-file, chờ CLI restart.
- Test **186 → 200 PASS**. Mig **45 → 46**. Bundle admin `DYfjnpY0` / user `_3S0BPJ2`.
- **⚠️ Session-limit hit giữa Wave 2** → recovery: verify-on-disk + em main solo FE + curl-self-verify.
## 3 commit (deployed prod)
| Commit | Scope | CI |
|---|---|---|
| `e9ee97f` | database-agent governance (.md) | skip (docs-only) |
| `6a66429` | Wave 1 — P11-E AttendanceReport + P11-F MaTicket codegen | run + deploy |
| `dcf76f8` | Wave 2 — P11-D ItTicket round-robin + SLA timer (Mig 46) | run + deploy |
## database-agent adopt (`e9ee97f`)
- AI_INFRA broadcast `2026-06-08-Agent-database-codebase-agents` (reviewer_gate PASS_WITH_FIXES, targets all-fit). Via `/adap-apply`.
- **database-agent** = floor DB1DB11 (schema/query/migration-review/perf/concurrency). **Tailored READ-advisory tier** (SE `implementer-backend` vẫn author entity+config+migration cohesive 3-file → database-agent design/review/advise, KHÔNG author file). Skill `sql-database-assistant` + `ef-core-migration`. `color` OMIT (8 standard hết — mirror monitor precedent, tránh gotcha #37). `store_memory` strip. DB11 RowVersion = tie-in vá **S43 LeaveBalance lost-update gap**.
- **codebase-agent = SKIP n-a** (investigator-codebase cover grep/audit + `csharp-lsp` Windows no-op).
- Files: `.claude/agents/database-agent.md` + `agent-memory/database-agent/MEMORY.md` seed + `agents/README.md` roster 10→11 (5-điểm sync) + `adap-reports/2026-06-08-...md` (5-trường LOCK).
- **Nấc executed-file → 🔴 CHỜ CLI restart** verified-runtime (agent .md no hot-reload).
## Wave 1 — P11-E + P11-F (migration-free, `6a66429`)
- **P11-F MaTicket:** `CreateItTicketHandler` set `e.MaTicket = WorkflowAppCodeGen.GenerateMaDonTuAsync(db,"IT",clock.Now.Year,clock,ct)` gen-on-**Create** (ItTicket = kanban no-workflow, khác Leave/OT gen-on-Submit). `IT/2026/NNN` Serializable atomic.
- **P11-E AttendanceReport:** `GetAttendanceReportQuery(Year,Month,DeptId?)` monthly aggregate. Day-type (weekday/weekend/holiday) classify **IN-MEMORY** (`.AsEnumerable()`, KHÔNG EF-translate `.DayOfWeek`). OtWeighted = OtWeekday×mWd + OtWeekend×mWe + OtHoliday×mHol (OtPolicy active, fallback 1.5/2.0/3.0). `Holiday.Date`=**DateOnly** (implementer verify source-of-truth, em spec ghi DateTime nhầm → agent tự sửa). `AttendanceReportExcelExporter` ClosedXML sync no-DB. 2 endpoint `[Authorize(Roles=Admin)]`. fe-admin `AttendanceReportPage` (download authed `api.get(blob)` qua interceptor + refresh-retry).
- **reviewer PASS** (independent re-verify build/test/tsc). **gotcha #44 disarmed:** `AppRoles.Admin="Admin"` khớp `[Authorize(Roles="Admin")]` + seeded role; decoy = `"QTV"` (DbInitializer display-code, KHÔNG phải role-name). FE `user.roles.includes('Admin')` khớp.
- +5 test (186→191).
## Wave 2 — P11-D ItTicket assign + SLA (Mig 46, `dcf76f8`)
- **Mig 46** `AddSlaFieldsToItTicket` — 3 AddColumn (SlaDueAt/SlaWarnedSent/SlaBreached) vào ItTicket, **no new table** (tables stay 92).
- **Pool = department "IT"** (user chọn dept thay role): DbInitializer +dept thứ 10 + `SeedItDepartmentStaffAsync` gán nv.cao/nv.truong. **KEY ordering: PHẢI chạy SAU `SeedDemoUsersAsync`** (method đó reconcile 2 user dept về PRO/CCM mỗi boot → override về IT sau → end-state deterministic).
- **Round-robin least-loaded:** `Users.Where(DepartmentId==itDept && IsActive).OrderBy(open-ticket-count).ThenBy(Id).First()`. No IT-staff → unassigned.
- **SlaDueAt** = CreatedAt + `SlaWindow[priority]` (Urgent4/High8/Medium24/Low72h) — `SlaWindow` static map **shared** với job (single-source).
- **`ItTicketSlaJob`** BackgroundService mirror SlaExpiryJob NHƯNG **KHÔNG auto-transition** (ticket chỉ breach-flag + warning-notify assignee, idempotent qua guard). Khác Contract SLA (auto-approve transition).
- **PUT `/{id}/assign`** `[Authorize(Roles=Admin)]` admin override. FE ItTicketsPage +MaTicket+assignee+SLA badge (2 app SHA256 mirror, gỡ banner skeleton). Reassign-UI defer (endpoint sẵn).
- +9 test (191→**200**).
## ⚠️ Session-limit recovery (multi-agent resilience case study)
- Giữa Wave 2, session-limit hit ("resets 1:10pm") → **3 background agent killed mid-task**: Wave 2 FE (26 tool-use, 0 file ghi), Wave 2 test (10 tool-use, file ghi xong), cicd Run A (6 tool-use, verdict mất). Wave 2 BE trước đó return TRUNCATED (gotcha #53) nhưng work xong.
- **Recovery (git/disk/prod = source-of-truth, KHÔNG agent return-message):**
1. Wave 2 BE — verify-on-disk (git status + build 0-err + đọc handler/job/seed) → complete.
2. Wave 2 test — file `ItTicketAssignSlaTests.cs` đã ghi → `dotnet test` = **200 PASS** → complete.
3. Wave 1 deploy — cicd verdict mất → **curl prod độc lập**: api 200 + /attendances/report 401 + admin bundle rotate `CJcApLsI` + user unchanged → confirmed live.
4. Wave 2 FE — 0 file ghi → **em main solo redo** (gotcha #53-class fallback): types ×2 + ItTicketsPage ×2 (copy SHA256) + build ×2 pass.
5. Wave 2 review — **em main self-review** (limit pressure, no reviewer-spawn): seed↔query dept-code cross-check + nv.cao/nv.truong tồn tại + ItTicketSlaJob idempotent → PASS.
6. Wave 2 deploy — **curl-self-verify**: api 200 (Mig 46) + /assign 401 + 2 bundle rotate.
## Deploy verification (curl độc lập, no cicd-spawn)
- Wave 1: api 200 · /attendances/report 401 · admin `CJcApLsI` (rotate) · user `YgqDvsqr` (unchanged — đúng).
- Wave 2: api 200 (Mig 46 applied) · /it-tickets 401 · /assign 401 (new endpoint) · admin `DYfjnpY0` · user `_3S0BPJ2` (cả 2 rotate — đúng, cả 2 app đổi).
## Lessons
- **Source-of-truth = git/disk/prod, KHÔNG agent return-message** — truncation/kill recovery dựa vào on-disk verify (`feedback_implementer_truncation_mitigation` reinforced).
- **Multi-agent resilience:** killed agents để lại work-on-disk recoverable; em main solo fallback cho phần dở (boundary cho phép gotcha #53-class).
- **Agent verify-source-of-truth > spec-mù:** implementer bắt `Holiday.Date`=DateOnly + exporter-sync = deviation đúng (em spec sai → agent tự sửa, tránh build-break).
- **reviewer decoy-hunting:** gotcha #44 role-string verify ground-truth (decoy "QTV") = giá trị reviewer độc lập.
- **Migration coordination:** worktree session "đang chạy" (S51 HANDOFF) thực tế KHÔNG active (git worktree list = main only) → P11-D tự do dùng Mig 46; gotcha #57 EXT Master = Mig 47 (rebase sau).
## 🔴 NEXT SESSION
1. **RESTART CLI** → activate database-agent → spawn-test → verified-runtime.
2. H1/H2 monitor closeout SKIPPED (limit) → next /session-start re-report.
3. Follow-up minor: ItTicket reassign-UI · P11-E menu-key promote · gotcha #57 EXT Master Mig 47 · RAG re-index S42-S52 (AI_INFRA op).
4. Product: Phase 11 DONE → Phase 9 Ops (anh main coordinate).