Files
solution-erp/.claude/agent-memory/implementer-backend/MEMORY.md

19 KiB
Raw Blame History

Implementer-Backend Agent — Persistent Memory

  • S187 (2026-08-10) lane W1-GREEN — gỡ 2 bom per-type cho type-3 HĐ [31/31 xanh · build 0/0 · 0-mig; artifact runs/2026-08-10-S187-duyet-hd-tu-khkk/sub-implementer-backend-w1green.md]: Nghề ăn tiền = ĐỌC ASSERT ĐỂ CHỌN HÌNH VÁ, đừng nhận hình từ đề bài: đề (và test-doc) gợi hình (a) "thêm trường tập hợp chứa MỌI bản active cạnh Active" — nhưng test đo kênh-đương-nhiệm bằng REFLECTION duyệt MỌI property ≠ History ⇒ hình đó ĐỎ VÌ ĐÔI (BeEquivalentTo = song ánh 7↔7; ContainSingle cho type-1 thành 2). Chọn phân hoạch: Active giữ ≡ giá trị cũ từng byte (versions.FirstOrDefault(IsActive)actives.FirstOrDefault()) + ActiveOthers = phần CÒN LẠI (Skip(1)) ⇒ xanh cả 2 ca 0 rủi ro FE. Bác hình "để Active=null khi >1 active": FE đọc thẳng t.active (ApprovalWorkflowsV2Page.tsx:381-389/455-479) mà type-10 KHKK HÔM NAY đã 8 active ⇒ đó là đổi hành vi ĐANG CHẠY, không phải vá. Vá bom-2 CỐ Ý không hỏi type (đếm actives) ⇒ tự đúng cho family sau này, và control xanh vì dữ liệu thật (type-1 chỉ 1 active) chứ không vì khai riêng cho nó. Bom-1: ternary 1-type → mảng TYPE tường minh PerCodeDeactivationTypes (R-6 cấm regex trên Code). Comment tự-khai "1 active/type là bất biến" hỏng vì neo con số ⇒ viết lại neo TẬP TYPE + ghi vết vì sao câu cũ hỏng. Đa-lane: KHÔNG git stash để đối chứng (thao tác toàn-cây, nuốt việc lane khác) — chuỗi nhân-quả dựng bằng RED-đã-ghi + file chưa ai chạm + chỉ tôi sửa; số ĐO SAU byte cuối. Tag [s187, w1-green, reflection-assert-chon-hinh-va, phan-hoach-thay-tap-hop, neo-tap-type-khong-neo-so, khong-stash-da-lane]

  • S180 (2026-08-07) lane W3 — nghi thức 2 đầu: 4 nhãn + vòng hỏi ngược + tiền-kiểm 9/19 + gói-B persona [#53 vai thứ 20; cứu TRỌN nhờ ghi-đĩa-từng-phần — lead resume, xong nốt]: Nghề ăn tiền = KHAI ĐÚNG NẤC CƯỠNG CHẾ: ký 4/4 nhãn thành văn nhưng đo lại thì 1 có máy đủ · 2 nửa · 1 (bị chặn) CHƯA CÓ MÁY — vị từ (3) cho cùng một số với trỏ đặc tảtrỏ nỗ lực gỡ, không phân biệt được ⇒ khai thẳng thay vì để nó trông như đã cưỡng chế (LỚP-9). 🔴 Bác đề bài 1 chỗ, đứng: khung "chỉ bỏ-qua-KHÔNG-khai mới là lỗi" ⊥ chữ hub (phu-luc:189 tính cả ca CÓ KHAI mà điều kiện đánh-giá-lại ra SAItự ý bỏ) ⇒ nhận khung đó thì một dòng khai là tự tha được; ký theo hub + luật không-xác-định rơi về nhãn NẶNG (mặc-định-vô-tội = thưởng cho đặc tả mơ hồ). 🔴 Bác lane F: check-email bị đếm là 1 trong "6 cửa gọi nhip-no-probe" — đĩa nói 2 hit đều là NHẮC TÊN, 0 lời gọi ⇒ tập đúng = 5. Sửa lane C 4/19→5/19 (snapshot:69 đóng từ 🟡 sang CÓ). 🔴 Fault-inject lượt ĐẦU chết vì HARNESS: viết inline qua bash ⇒ bash nuốt $/backtick của chuỗi PS ⇒ WAL "lành" không bao giờ ghi đúng ⇒ chiều B kêu trông y hệt script hỏng; dựng harness thành .ps1 riêng ⇒ 5/5. Tự bắt citation-trap vòng 1 (ghi chú vá trích nguyên cụm số cũ ⇒ grep vẫn =1), vòng 2 diễn-giải ⇒ 0, re-grep bằng lệnh KHÁC. Wall-clock ĐO TRƯỚC khi cắm (luật check-email.md:41): ròng 194ms < 281ms đã-chấp-nhận ⇒ vẫn KHÔNG cắm vào /pause·/tiep (đã có probe). Tag [s180, w3-nghi-thuc, khai-dung-nac-cuong-che, khai-khong-tu-mien-tru, use-vs-mention-lane-f, harness-hong-trong-nhu-script-hong, do-truoc-roi-noi-khong]

  • S180 (2026-08-07) lane W2 — dựng máy điểm danh vật chứng (4 vị từ · fault-inject 3 chiều · ca-N1 BẮT) [#53 vai thứ 19; cứu TRỌN nhờ ghi-đĩa-từng-phần — lead resume, xong nốt]: Nghề ăn tiền = ĐO PHÂN BỐ TRƯỚC KHI CHỌN NGƯỠNG: K của vị-từ-tỉ-lệ lấy = phân vị 5 đo thật trên 446 tệp họ sub-* (K=3,00), KHÔNG chỉnh cho vừa ca đã biết — ca N1 rơi ở phân vị 3,6, lọt lưới sát nút ⇒ khai thẳng "vị từ này là lưới PHỤ" thay vì hạ K xuống 2,7 (= Goodhart). Vị từ CHÍNH = nhãn treo NEO VÀO HEADING (tách dùngnhắc đến): thô cho 1 dương-giả trên chính bản đã xong (câu định nghĩa nhãn) — neo heading ⇒ 6/0. 🔴 Bẫy thước tự bắt: grep '[^\x00-\x7F]' Git-Bash cho 268 hit trên tệp biết-là-sạchcontrol âm sai = hỏng THƯỚC, phải đọc byte bằng .NET. 🔴 Bác lệnh lead 1 chỗ, đúng: spec bảo git show HEAD~1:<file> — hook wal: chèn commit giữa ⇒ HEAD~1 không phải bản trước CỦA TỆP, phép so thành so bản mới với chính nótrông y hệt phép đo hợp lệ; dùng git log -2 -- <file>. Quét toàn kho lộ 2 lớp dương-giả (294→31 cờ): con-trỏ CHÉO giữa lượt chạy (README bắt trỏ input spec: sang lượt trước) = lỗi MÁY không phải nợ kho ⇒ phân giải toàn cây; KHONG-KHAI 245/720 = cờ cho luật chưa từng tồn tạihạ xuống hạng-mục-đếm-riêng NHƯNG GIỮ SỐ + mẫu số (phép thử "cái mất đi là dương-giả hay CHỨNG-NHÂN?"). Vá đến SAU test ⇒ chạy lại trọn 3 chiều. Tag [s180, w2-artifact-integrity, do-phan-bo-truoc-chon-nguong, neo-heading-use-vs-mention, control-am-sai-la-hong-thuoc, headn-khong-phai-ban-truoc, giu-so-bo-co]

  • S180 (2026-08-07) lane W1-b — ký chuẩn đặt tên + dựng máy soi (11/11 ràng buộc · 3/3 vá · fault-inject 4 lượt/3 chiều) [#53 vai thứ 18/phiên; cứu TRỌN nhờ ghi-đĩa-từng-phần — artifact 21KB đủ ruột TRƯỚC khi return chết; lead resume, xong nốt]: Nghề mới ăn tiền = LUẬT NẤC: "một nhóm tên sạch CHÍNH XÁC tới độ sâu máy của nó KIỂM, không sâu hơn một nấc" ⇒ mỗi mục chuẩn PHẢI khai nấc + trỏ máy ép đúng nấc đó; nhóm không máy ⇒ ghi CHƯA CÓ MÁY, CẤM ký luật hình dạng (ký sâu hơn máy = ký ra thứ tự nó trôi). Hệ quả 2: máy chỉ-ĐỌC (detectors:1109 liệt-không-cờ) hoặc THA (:1660 -or chấp 2 tên) ⇒ tên vẫn trôi — nhưng KHÔNG cần STOP-HARD: :1639 chỉ in INFORM mà nhóm sạch 12/12. 🔴 Tự bắt mình tái phạm citation-trap:hmw.js:33 bỏ số "11 class", bản vá ĐẦU trích nguyên văn cụm cũ ⇒ grep vẫn =1 ⇒ bài học lời-giải-thích nằm TRONG tập đo; vòng 2 mới =0 (control-dương 2 chuỗi cùng tệp). Bác 3 chỗ, 3/3 đứng: (a) lane a "23 lệch" → tôi đo 8/233 (16 script s<n>-/plan-một-lần HỢP LỆ, gọi lệch = dương-giả, mà dương-giả ngày đầu là cách nhanh nhất để người ta tắt máy soi; +1 vật lane a sót resume-S146); (b) lead tả bản vá S159 = (sub|harness)-* → đĩa thật ^(sub-.+|.+-return)\.md$ (bộ ba lọt qua nhánh -return, KHÔNG qua tiền tố) — mirror theo diễn giải sẽ đẻ bản sao thứ 3 lệch nhau; (c) wave-plan:85 kê W3 sửa "5 class"→6 = đúng LỚP-5 vừa gỡ, phải BỎ SỐ không đổi số. Bẫy đơn-vị cắn thật: scripts/+docs/governance/ đếm theo MỤC (gồm thư mục) ≠ TỆP ⇒ lệch 4; và tự mình đẻ 2 vật giữa lượt ⇒ 231→233, phải KHAI. Phát hiện mới ngoài lane a: settings.json:2 autoMemoryDirectory = đường dẫn TUYỆT ĐỐI neo cả tên thư mục lẫn gốc kho (lane a chỉ liệt :9). Tag [s180, w1b-naming-standard, luat-nac, citation-trap-tu-bat, duong-gia-vs-chung-nhan, muc-vs-tep, inform-only-exit0]

  • S133+S134 (07-17) PE budget-freeze BE (Mig 67) + lũy kế TẠM TÍNH BE📦 verbatim dời archive/2026-07.md (@S161 curate, moved-not-cut). Giữ hook: insertion-only-diff = proof thân-bất-động · backfill Sql() plain KHÔNG provider-guard (Mig 61/65/67 khuôn) · TransitionAsync KHÔNG SaveChanges nội bộ :537 · Dev drift committed-chưa-apply → catch-up. Tag [s133, s134, mig67, computepending, moved-l2]

Persistent diary cross-session. Auto-injected first ~200 lines at spawn (L1 HOT). Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 archive/ on-demand · L3 RAG search_memory just-in-time. Keep entry ≤ 1.5K chars (gotcha #53). Full verbatim history pre-S40 → git d2f52ba + archive/2026-05-q1..q4.md + archive/2026-06.md. 🗺️ Lookup map (Harness-9 S70): archive/_INDEX.md — 1 dòng/bản-ghi + con-trỏ substring (sha-keyed, Ctrl-F fallback); đọc verbatim + 2026-0{5,6}.gist.md (nén 4-field) theo nhu cầu. Renamed S39: implementer → implementer-backend (.NET half). FE patterns → implementer-frontend MEMORY. Test patterns → test-specialist MEMORY.


🎯 Role baseline

WRITE specialist .NET backend SOLUTION_ERP (Domain+Application+Infrastructure+Api). Case 1+2+3+5 only. Tools: Read, Edit, Write, Bash, Skill, Grep, Glob + 5 RAG MCP. Skills: ef-core-migration + permission-matrix + contract-workflow + form-engine. Output: commits + verify report.

🚫 Split boundary (S39) + auto-refuse

  • MINE: src/Backend/SolutionErp.{Domain,Application,Infrastructure,Api}/**
  • NOT: fe-*/**implementer-frontend · tests/**test-specialist · schema/UX/architecture decision → em main
  • REFUSE if ANY: 1 schema design (FK/nullable/discriminator) · 2 UX flow · 3 cross-stack >2 layer · 4 bug fix reasoning chain · 5 integration multi-component · 6 <30min trivial · 7 first-time no precedent · 8 spec ambiguity >20%

📋 BE Patterns proven (apply confidently)

Pattern 1: Per-chunk discipline A-E

A Domain+Mig (3-file) · B Application CQRS (Command/Query/Validator) · C Service (workflow logic) · D Api Controller · E commit. Build+test pass mỗi chunk. Commit [CLAUDE] <scope>: Chunk X — ... + Co-Authored-By Claude Opus 4.8 (1M context).

Pattern 2: EF migration 3-file rule (gotcha #17 — BẮT BUỘC commit đủ)

{TS}_{Name}.cs + .Designer.cs + ApplicationDbContextModelSnapshot.cs. Path src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/.

dotnet ef migrations add <Name> --project src/Backend/SolutionErp.Infrastructure --startup-project src/Backend/SolutionErp.Api
# Apply Dev (runtime): --connection "Server=(localdb)\MSSQLLocalDB;Database=SolutionErp_Dev;Trusted_Connection=True;TrustServerCertificate=true"
# Apply Design (ef default): không cần --connection

Apply BOTH DB per feedback_designtime_runtime_db.

Pattern 3: Audit reuse trước khi clone (feedback_audit_reuse_before_clone)

"Clone X→Y": grep discriminator (ApplicableType/Type/Kind) → check Service/Handler hardcode → check FE route dynamic → check menu key (BE const + FE menuKeys.ts thường thiếu) → default reuse 80%, chỉ thêm menu key + sample seed.

Pattern 4: Service hook vs CRUD endpoint cho derived state (feedback_service_hook_vs_endpoint)

State X derived của action Y → UPSERT trong handler Y, KHÔNG endpoint /X riêng. VD ApproveV2Async UPSERT LevelOpinion qua match ApproverUserId==actorUserId (fallback first khi Admin override). 0 endpoint mới.

Pattern 7: Per-NV admin opt-in flag (Mig 29/30/31)

ApprovalWorkflowLevel +1 bool DEFAULT 0 (opt-in). EF HasDefaultValue(false). DTO extend. FE Designer checkbox inline. Scope role-context → table mapping (Approver→Level table carry ApproverUserId FK, Drafter→User table direct, feedback_per_nv_permission_scope). Reusable F5/F6.

Pattern 8: Tách endpoint riêng cho narrow scope

1 action 2 scope theo role → tách endpoint (guard tự nhiên + audit). VD Drafter UpdatePeDraft (Section 1 rộng, phase Nháp/Trả lại) vs Approver AdjustBudget (Budget rows hẹp, phase Đang duyệt + per-NV flag). KHÔNG default expand Drafter scope cho Approver.

Pattern 9: Defense-in-depth FE+BE guard pair

UI disabled={!canX} + BE helper EnsureCanXAsync(id, userId) throw 403 (NOT inline handler) — tránh forge qua DevTools. Bất kỳ action sensitive (approve/reject/adjust).

"Mirror entity X từ module A→B": 6 file MAX — (1) new entity Domain/<Mod>/<Entity>.cs rename FK+nav · (2) parent +nav collection · (3) IApplicationDbContext +DbSet · (4) ApplicationDbContext +Set<X>() · (5) new <Entity>Configuration.cs (separate file mirror PE, NOT inline) · (6) dotnet ef migrations add 3-file. AuditableEntity inherit. FK: parent Cascade + 3rd-party Restrict + User skip-nav (denorm <Type>ByFullName). Apply 2 DB. ⚠️ Catalog-mega variant (S35 HrmConfig): HRM entities KHÔNG có global HasQueryFilter(!IsDeleted) (vs Master) → list query MUST .Where(!IsDeleted) thủ công (verify Grep HasQueryFilter Configurations FIRST). Validator MaxLength MATCH EF config (verify source-of-truth, KHÔNG trust spec blind).

Pattern 12-ter: N≤7 satellite CRUD scaffold same parent (S34, feedback_within_module_n_satellite_scaffold)

"N satellite cùng parent" → 1 mega file <Parent>SatelliteFeatures.cs N region cookie-cutter (Create verify parent AnyAsync → Update FirstOrDefault !IsDeleted → Delete soft IsDeleted+DeletedAt+DeletedBy ICurrentUser) + 1 Controller extend (3 verb × N). Endpoint verify parentId==cmd.ParentId BadRequest mismatch. Per-action policy override class-level Read.

Patterns moved (split S39)

  • FE patterns (5 mirror 2-app · 6 VND helpers · 13 read-only Designer · 14 Tailwind JIT palette · 15 rowSpan builder · 16-bis 4-place mirror) → implementer-frontend MEMORY (seeded).
  • Test patterns (10 reflection authz · 11 test infra helper · 12 InternalsVisibleTo) → test-specialist MEMORY (seeded).

⚠️ Anti-patterns (DO NOT)

  1. Skip MEMORY · 2. --no-verify · 3. git add -A/git add . (specific files) · 4. Touch outside spec scope · 5. Push remote autonomous (em main pushes) · 6. Modify SolutionErp.slnx autonomous · 7. Lower bar match em main (Smart Friend) · 8. Proceed khi ambiguity >20% → REFUSE

🧠 SOLUTION_ERP BE conventions (S40)

  • BE .NET 10: PascalCase entities + DTO records + command names. CQRS+MediatR+FluentValidation+AutoMapper. Repository qua IApplicationDbContext. GlobalExceptionMiddleware → ProblemDetails (NO try-catch controllers).
  • State S53: 47 mig (last FilterMasterCatalogUniqueIndexesByIsDeleted Mig 47, index-only) · 93 SQL tables · ~224 endpoints · 203 test (58 Domain + 145 Infra, test-specialist owns). Phase 9 UAT skip per chunk (feedback_uat_skip_verify).
  • Build: dotnet build SolutionErp.slnx clean 0 err. Commit [CLAUDE] <scope>: <msg> + Co-Authored-By Claude Opus 4.8 (1M context).
  • Pin (KHÔNG */latest): MediatR 12.4.1 (14 fail DI) · Swashbuckle 6.9.0 · Node CI 20.x · LibreOffice 25.8.6 · @microsoft/signalr 8.0.7.

📅 Recent activity (FIFO — older → archive/git)

  • (Mục FIFO này hiện RỖNG — 4 entry cuối [2026-07-12/13: S116 PE giá ÂM · S113 Supplier import v2 Mig 64 · S112 PE sign-off · S112 Supplier Excel-import Mig 63] dời verbatim → archive/2026-07.md @S167. Trước đó: 2026-06-25→19 [S88 frozen-relocation · PE Section-B Mig 59 · PE chuông approver] → archive/2026-06.md @S116; S77→S56 [7 entries] @S112. Việc gần đây SỐNG nằm ở khối L1 HOT đầu file (S167/S166/S161/S139). Recall verbatim: archive tương ứng / archive/_INDEX.md / RAG search_memory.)

🔄 Curate trigger

  • ~30KB → archive recent → L2 archive/<period>.md. Stale >3mo → remove.

  • Last curate: 2026-08-01 S167 (self-FIFO, hook read-limit-guard bắn @22.4KB) (22.4→15.4KB, dưới ngưỡng 17.1KB hook đòi): moved verbatim 4 entry Recent-activity 2026-07-12/13 (S116/S113/S112×2) → archive/2026-07.md (2.8→10.3KB). Mục Recent-activity nay rỗng có chủ đích — việc SỐNG ở khối L1 HOT đầu file. Prev S116 (21.5→~15KB): moved 3 oldest Recent-activity (2026-06-19/24/25: PE chuông · PE Section-B Mig 59 · S88 frozen-relocation) verbatim → archive/2026-06.md, kept 4 newest (S116/S113/S112×2). Prev S112 (25.6→~16KB): S77→S56 7-entry → 2026-06.md. Prev S70 Harness-9 (33.2→17.4KB): L2 dark-matter recovery + _INDEX + gists. Prev: S40 dedup-split · S34 · S22.

S182→S185 (08-08→08-09) — entries mới-nhất (heading cũ "S152" đổi @S185 refine-A1: span≠nhãn — ruột span này chứa S182+S185; bullet S152 verbatim → archive/2026-07.md)

  • (S152 R1 retention-note → archive/2026-07.md @S185 — moved-not-cut, 430B)

  • S182 YC-013 (lead-seed, C2 /pause — lane đứt limit giữa W1, lane 1bis nối TỪ ĐĨA): W0 trọn — phát hiện local có BA DB (lượt đầu trỏ nhầm base, TỰ KHAI "nhìn lượt đầu mà tuyên xong = PASS giả" rồi chạy lại đúng _Dev+_Design lên Mig 72) + baseline 645 đo độc lập + seed 8 row local ĐỦ roster. W1 5-fix land: ContractSigningPlanWorkflowGuards.cs public-static (Submit ở Infrastructure không thấy internal — 3 lối đã cân nhắc ghi doc-comment) · per-Code deactivate + normalize Trim().ToUpperInvariant() @:348 (MAJOR-2 collation SQLite khác SQL-Server) · pin-check D6 2 message tách · changelog type-10 · DELETE-guard 8-module + IgnoreQueryFilters + D5+ApplicableType. Suite 660/0. → runs/2026-08-08-S182-khkk-awf-mirror-ncc/sub-implementer-backend-0.md

  • S185 (08-09) 3 lane Opus MAX run YC-017 (lane1-detector · lane2-tienkiem · lane7-machine) [LEAD PLACEMENT (a) @S185 — nguồn .claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/sub-opus-lane{1,2,7}*.md 27.465+19.289+17.662 B]: lane1 cắm 4 detector (+438 dòng ASCII-sạch, TOTAL 49=baseline, fault-inject 14/14 CÂY TẠM -RepoRoot + positive-control) — tự bắt thước hỏng: mảng pattern PS thiếu ngoặc ⇒ + chạy xuyên dấu phẩy ⇒ 0-hit vĩnh viễn = SẠCH-GIẢ. lane2 DỪNG ĐÚNG LỆNH C-1: soak PHẦN Q vế-2 đòi rider-jump đã soak ≥1 phiên mà rider-jump CHƯA TỒN TẠI (5 phép + control OVERDUE 6-hit ⟂ OVERDUE:jump 0-hit) ⇒ soak thật = 0, không cắm mã thoát, chỉ flip 2 dòng stale; tự bắt thước: git show | Select-String PS 5.1 mojibake ⇒ 0-hit giả, đo lại bằng bash grep UTF-8. lane7 dựng scripts/loi-hua-may-scan.ps1 (759ms, self-test 11/11, mẫu-số chấm tay 30 dòng KHÔNG phải 19 — đo lại trước khi tin số cũ). Tag [s185, fault-inject-cay-tam, dung-dung-lenh-soak, thuoc-hong-tu-bat-x2]