Files
solution-erp/.claude/agent-memory/database-agent/MEMORY.md
pqhuy1987 4263d63e74 [CLAUDE] Docs: S98 harness backlog — Fable-restore gỡ caveat H5.6 (runtime-verified spawn-test ×2) + monthly→2026-08-01 + skill Mig 60/61 + re-tier mega-line S93/S94→archive-S98 + cicd L1 curate + 3 orphan-append H2 + ledger mode-A note + email AI_INFRA
Verify: V1 conservation PASS (arithmetic full-accounting 0-byte-unaccounted) · V2 cross-doc PASS (detector 28→25, còn lại false-positive class) · V3 moved-not-cut PASS (sha-match + byte-arithmetic đóng vòng).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 10:57:33 +07:00

7.2 KiB
Raw Blame History

database-agent — MEMORY (L1 HOT)

READ-advisory DB specialist SOLUTION_ERP (.NET 10 EF Core 10 + SQL Server, single ApplicationDbContext dbo). Adopt AI_INFRA broadcast 2026-06-08-Agent-database-codebase-agents (floor DB1DB11), S52 2026-06-08. Seed = em main. Nấc hiện: executed-file — verified-runtime CHỜ anh restart CLI + spawn-test.

Vai trò (FORM tailored SE)

  • READ-advisory tier — DESIGN/REVIEW/PERF/CONCURRENCY-advise, KHÔNG author file. implementer-backend author entity+config+migration; em main solo quyết schema-design cuối. database-agent = deep-DB lens hỗ trợ + review.
  • Floor DB1DB11 (canonical, KHÔNG hạ) — chi tiết .claude/agents/database-agent.md.
  • Skill: sql-database-assistant (SQL Server raw, KHÔNG cover EF-Core) + ef-core-migration (EF Core 10 pin + 3-file rule). Verify present TRƯỚC wire.
  • store_memory STRIPPED → ghi finding vào FILE này; em main + re-index → RAG.

SE facts cốt lõi (DB10 evidence-based — re-ground khi cần)

  • 45 migration → 92 tables (S51). sys.tables = ground-truth (narrative count drift "incremented-per-session" → re-ground).
  • 2 DB instance: LocalDB SolutionErp_Dev (runtime) / SolutionErp_Design (design-time) — gotcha designtime-vs-runtime DB (apply migration cả 2 qua --connection override). Prod = .\SQLEXPRESS\SolutionErp.
  • Soft-delete UNIQUE index PHẢI .HasFilter("[IsDeleted]=0") (gotcha #57 — 13× pattern; S45 Holiday + S51 LeaveType/Shift/OtPolicy/Vehicle/Driver). EXT backlog: Department/Supplier/Project (Mig 46 worktree).
  • Codegen atomic = WorkflowAppCodeGen.GenerateMaDonTuAsync dùng IsolationLevel.Serializable tx (Prefix-keyed sequence) — pattern ĐÚNG tham chiếu cho concurrency.

🎯 DB11 gap đã biết (concurrency — vai trò chính)

  • S43/S56 LeaveBalance lost-update — FIX DESIGNED S56 (approach A, NO migration). ApproveLeaveRequestHandler terminal DaDuyet branch (LeaveOtApprovalFeatures.cs:355-386) đọc bal.UsedDays in-memory + += p.NumDays + bare SaveChanges → 2 concurrent terminal-approve cùng (User,Type,Year) lost-update. Fix: wrap terminal-branch trong explicit BeginTransactionAsync → (1) SaveChanges persist opinion-upsert + status=DaDuyet + ensure balance-row exists (insert UsedDays=0 nếu absent), (2) ExecuteUpdateAsync(SET UsedDays = UsedDays + n) atomic DB-side race-free, (3) Commit. Atomic-with-approval preserved (1 tx all-or-nothing). Exactly-once untouched (early Status != DaGuiDuyet guard :296). NO ambient TransactionBehavior (chỉ ValidationBehavior) → handler own tx boundary. Cast (DbContext)db để reach Database (IApplicationDbContext chỉ expose DbSet+SaveChangesAsync). Existing terminal test (Case 4 :226) assert Status/Level/opinion-count only — KHÔNG assert UsedDays-on-tracked → ExecuteUpdate (bypass tracker) WON'T break suite. Spec authoritative → implementer-backend author.
  • OtRequest terminal KHÔNG trừ phép (chỉ status) → no lost-update bên OT.
  • P11-D SLA flags (SlaWarnedSent/SlaBreached) + P11-F codegen = concurrency-sensitive → DB11 lens áp được.

Boundary (⟂)

  • vs implementer-backend: DESIGN/REVIEW vs AUTHOR (KHÔNG double-touch migration file).
  • vs investigator-codebase: deep DB-layer (introspection/query-plan/concurrency) vs broad grep/audit.
  • vs reviewer: DB-layer design-review (DB6/DB11/DB5) TRƯỚC author vs adversarial pre-commit cross-stack.
  • KHÔNG: FE · business-logic · deploy · session-lifecycle audit.

Accuracy (G-015)

  • DB7 scope-DB-only = PHÂN-VAI, KHÔNG "read-only enforced" (giữ Bash → write-channel shell mở; containment = em main single-writer + git-diff post-session).
  • Schema/perf-claim từ introspection THẬT (sqlcmd/dotnet ef), KHÔNG narrative.

Log

  • S52 (2026-06-08): Seeded (em main, adap-apply database-agent). Roster 10→11. Nấc executed-file. CHỜ restart + spawn-test → verified-runtime.
  • S56 (2026-06-09) — pre-golive verify (2nd real spawn, verified-runtime ✓): Schema/Mig integrity P11 + S55 master-data = SOLID. Mig 42-48 applied IDENTICALLY Dev+Design+prod .\SQLEXPRESS (48 mig / 92 tables, NO S53-style unapplied-local drift); 0 pending model-snapshot diff; 9 gotcha-#57 filtered-unique confirmed BOTH EF config (HasFilter×13) AND DB (filter_definition=([IsDeleted]=(0))) incl Vehicle/Driver day-1; FK đúng (LeaveBalance→LeaveType Restrict + UNIQUE(User,Type,Year); 4× LevelOpinions Cascade(parent)/Restrict(Level)+UNIQUE composite; ItTicket SLA nullable). DB11 FAIL (1 major, fast-follow KHÔNG blocker): LeaveBalance.UsedDays += NumDays @ LeaveOtApprovalFeatures.cs:361-386 chạy bare SaveChanges (no tx / no RowVersion / READ COMMITTED) → concurrent double-approve lost-update. S43 gap STILL OPEN. Fix-pattern sẵn repo: Serializable tx (codegen :34) HOẶC RowVersion+retry (1 mig). Low-prob ~30 user, recoverable Admin Adjustment. Tag [s56, pre-golive-verify, schema-pass, db11-lostupdate-open].
  • S57bis (2026-06-11) — PE gắn Hạng mục design (3rd real spawn, DELIVERED — on-behalf em main ghi hộ, H2-proposed): Introspect LocalDB → design PurchaseEvaluations.WorkItemId Guid? scalar loose-Guid + IX, KHÔNG FK vật lý — nhất quán convention PE (ProjectId/SelectedSupplierId đều loose; duy nhất ApprovalWorkflowId có FK). Guard = validator + handler mirror S43 FK-invariant. KHÔNG đụng CodeSequences (mã phiếu giữ PE/{YYYY}/{A|B}/{Seq}). LEARNED: PE FK-convention map (loose-Guid là norm module này — FK vật lý là exception). SURPRISE: WorkItems = catalog GLOBAL (KHÔNG ProjectId) → 2 dropdown độc lập; "Dự án (năm) Hạng mục" chỉ là chuỗi ghép hiển thị, không ràng buộc quan hệ. Ship: Mig 49 deploy Run #381 prod-applied. Tag [s57bis, mig49-design, on-behalf].
  • S97 (2026-07-01) — PE prod-điều-tra A/005 + deep-review lane (4th+5th real spawn, on-behalf em main ghi hộ, H2-proposed @S98): (4th) Điều tra prod (API+sqlcmd): A/005/A/008 Phase=7 endsBeforeCeo=False, lịch-sử 4 record dừng "[Bước 2 — Cấp 2]" KHÔNG có record CEO; đối chứng A/010 9-record có CEO. Chẩn đoán: A/005/A/008 finalize-CCM Cấp 2 (KHÔNG qua CEO) — lịch-sử ĐÚNG, sai là badge do EndedByLevelFinalize=0 → phát hiện Mig 60 backfill WRONG-TABLE (query Approvals.Comment nhưng marker do LogTransitionAsync:1073 ghi Changelogs.ContextNote) → dẫn tới Mig 61 + gotcha #79. (5th — wf_4951c347 lane prod-data-integrity) CLEAN: flag-vs-marker 3 phiếu DaDuyet khớp (A/005/A/008=1+marker · A/010=0+no-marker), 0 miss/0 over-reach, Mig 60/61 applied, NCC=21, 0 orphan changelog, DB11 pointer-NULL đúng. LEARNED: PE 2 bảng lịch-sử TÁCH VAIPurchaseEvaluationApprovals = per-approver record (:745) vs PurchaseEvaluationChangelogs.ContextNote = transition+marker (LogTransitionAsync:1073); backfill PHẢI xác định đúng bảng-writer + verify marker-count prod TRƯỚC. SURPRISE: backfill=0 rows @ cicd #482 lẽ ra là CỜ ĐỎ nhưng bị bỏ qua ("tưởng no-pre-Mig60 data"). Evidence: docs/changelog/sessions/2026-07-01-S97-pe-finalize-wording-default-flip.md:97-133. Tag [s97, mig60-wrongtable, gotcha79, prod-integrity-clean, on-behalf].