Files
solution-erp/.claude/agent-memory/implementer/MEMORY.md
pqhuy1987 4dd6f9c013 [CLAUDE] Tests: Chunk M2 — Add F1 OneLevel/OneStep edge case tests Bước 1 reset ChoDuyet
Hai test mới cover edge case Plan M S23 t3 (em main M1 edit
PurchaseEvaluationWorkflowService.cs line 287-333):

- ApplyReturnMode_OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet
  PE init Step 0 Cấp 1 + actor=a1 + slot Cấp 1 tick AllowReturnOneLevel.
  Trước fallback Drafter Phase=TraLai → sau reset (0, 1) giữ Phase=ChoDuyet,
  SLA reset 7d, audit log ContextNote chứa "không lùi được".

- ApplyReturnMode_OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet
  PE init Step 0 Cấp 2 + actor=a2 + slot Cấp 2 tick AllowReturnOneStep.
  Service check curStepIdx > 0 → fallback ngay. Assert Phase=ChoDuyet,
  pointer (0, 1), SLA reset, audit log "không lùi được".

Extend helper SeedWorkflowAsync +2 params optional (allowReturnOneLevelL1
+ allowReturnOneStepL2) — default false, không phá compat 4 test ReturnMode
existing. Pattern 3 audit-reuse (extend helper KHÔNG clone).

Audit log assertion dùng ContextNote thay vì Summary: LogTransitionAsync set
Summary cố định "Chuyển phase {from} → {to}", summary từ ApplyReturnModeAsync
chèn vào comment qua line 96-99 service → ContextNote = comment.

K7 cascade NO regression: 3 ApproveV2_SkipToFinal_* tests still green (M1
edit chỉ F1 path, KHÔNG đụng F2 ApproveV2Async).

Verify:
- Build pass (0 error, 2 pre-existing DocxRenderer warning)
- 106/106 test pass (58 Domain + 48 Infra: +2 từ 46 baseline Plan L)
- 10 ReturnMode-class tests pass (4 ReturnMode + 3 ApproveV2_SkipToFinal
  + 1 Reject_NonApprover + 2 edge case mới)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:15:47 +07:00

24 KiB
Raw Blame History

Implementer Agent — Persistent Memory

Persistent diary cross-session. Auto-injected first 200 lines / 25KB at spawn. Update BEFORE every stop. Curate when > 25KB.


🎯 Role baseline

Code execution specialist for SOLUTION_ERP. Conditional WRITE (Case 1+2+3+5 ONLY). Tools: Read, Edit, Write, Bash, Skill, Grep, Glob. Output: commits + verification report.

🚨 STRICT scope auto-refuse criteria

REFUSE if ANY:

  1. Schema design decisions needed (FK strategy / nullable / discriminator)
  2. UX flow decisions needed (drawer vs tab vs modal)
  3. Cross-stack > 2 layers tight coupling
  4. Bug fix involving reasoning chain
  5. Integration testing involving multiple components
  6. < 30 min trivial task
  7. First time pattern (no prior precedent)
  8. Spec ambiguity > 20%

📋 Patterns proven (cross-session) — apply confidently

Pattern 1: Per-chunk discipline 5-chunk A-E (Anthropic Case 2 orchestrator-workers)

Memory feedback_per_chunk_commit chốt:

  • Chunk A: Domain entities + Migration (3-file rule)
  • Chunk B: Application handlers (CQRS Commands + Queries + Validators)
  • Chunk C: Service layer (workflow logic, business rules)
  • Chunk D: API controllers + endpoints
  • Chunk E: FE update (cả 2 app mirror) + Tests + Docs + commit final

Build + test pass mỗi chunk. Commit message format:

[CLAUDE] <scope>: Chunk <X> — <one-line summary>
<body>
Verify:
- Build pass (X warning, 0 error)
- N test pass (...)
Pending Chunk <Y+1>: <next>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

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

Memory + gotcha #17:

  • Migrations/{TS}_{Name}.cs (Up + Down)
  • Migrations/{TS}_{Name}.Designer.cs (snapshot at migration time)
  • Migrations/ApplicationDbContextModelSnapshot.cs (current snapshot)
dotnet ef migrations add <Name> \
  --project src/Backend/SolutionErp.Infrastructure \
  --startup-project src/Backend/SolutionErp.Api

# Apply lên DB Dev:
dotnet ef database update --project src/Backend/SolutionErp.Infrastructure \
  --startup-project src/Backend/SolutionErp.Api \
  --connection "Server=(localdb)\MSSQLLocalDB;Database=SolutionErp_Dev;Trusted_Connection=True;TrustServerCertificate=true"

# Apply lên DB Design (catchup nếu thiếu):
dotnet ef database update --project src/Backend/SolutionErp.Infrastructure \
  --startup-project src/Backend/SolutionErp.Api

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

Khi user nói "clone X sang Y":

  1. Grep discriminator field (ApplicableType, Type, Kind enum)
  2. Check Service / Handler / Controller có hardcode type cụ thể không
  3. Check FE pages có route dynamic typeCode hay hardcode
  4. Check menu key (BE const + FE menuKeys.ts) — thường thiếu chính ở đây
  5. Default reuse 80%, chỉ thêm menu key + sample seed (3 file ~60 LOC)

Bài học S17+ Clone B: 1 commit 937eb24, deploy 1 phát chạy.

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

State X = derived của action Y → UPSERT trong handler Y, KHÔNG endpoint /X riêng.

Bài học S19 Mig 26 PE LevelOpinions: Service ApproveV2Async UPSERT row qua match ApproverUserId == actorUserId (fallback first khi Admin override). 0 endpoint mới.

Pattern 5: FE mirror 2 app rule §3.9

Duplicate fe-admin/ + fe-user/ CÓ CHỦ ĐÍCH:

  • Sửa fe-admin xong → mirror fe-user (tay)
  • Khi breaking change rename prop → BẮT BUỘC npm run build × 2 app (memory feedback_uat_skip_verify exception)

Pattern 6: VND format helpers + Phone/Email validate (S20 turn 4)

Inline mỗi file FE PE:

const parseVnd = (s: string): number => Number(s.replace(/[^\d]/g, '')) || 0
const formatVndInput = (n: number): string => (n > 0 ? n.toLocaleString('vi-VN') : '')
const PHONE_RE = /^0\d{9,10}$/
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const isValidPhone = (s: string) => !s || PHONE_RE.test(s.replace(/[\s\-.]/g, ''))
const isValidEmail = (s: string) => !s || EMAIL_RE.test(s)

Pattern 7: Per-NV admin opt-in flag (S21 t5 Mig 29 + S22 Mig 30)

ApprovalWorkflowLevel +1 column bool DEFAULT 0 (opt-in admin set explicit). EF config HasDefaultValue(false). DTO extend field. FE Designer checkbox inline mỗi Level row.

Reusable cho future flag F5/F6 (vd AllowEarlyApprove, AllowDelegate): admin per-NV opt-in qua Level table thay vì global flag. Decision tree: flag scope role-context → table mapping natural (Approver → Level table carry ApproverUserId FK, Drafter → User table direct — memory feedback_per_nv_permission_scope).

Bài học S22: AllowApproverEditSection1 (Mig 30) follow same pattern Mig 29. 0 schema redesign cần.

Pattern 8: Tách endpoint riêng cho narrow scope (S22 AdjustBudget vs UpdatePeDraft)

Khi 1 action có 2 scope khác nhau theo role:

  • Drafter scope (rộng): UpdatePeDraft cover Section 1 (Tên/Địa điểm/Mô tả/Payment + Budget) — chỉ phase Nháp / Trả lại
  • Approver scope (hẹp): AdjustBudget chỉ Budget rows — phase Đang duyệt với per-NV flag

KHÔNG default expand Drafter scope cho Approver — tránh accidental edit Section 1. Endpoint tách riêng = guard tự nhiên + audit trail rõ.

Bài học S22: AllowApproverEditSection1 flag opt-in cụ thể PATCH /budget rows, KHÔNG /full-update.

Pattern 9: Defense-in-depth FE + BE guard pair (S22+1)

UI button disabled={!canReject} + BE helper EnsureCanRejectV2Async(peId, userId) throw 403 nếu non-approver. Tránh request forge non-approver gọi PATCH direct qua DevTools.

Pattern reusable: bất kỳ action sensitive (approve/reject/adjust) → FE disable + BE guard helper riêng (NOT inline trong handler).

Bài học S22+1: 3 button (Duyệt / Trả lại / Từ chối) — UI disable + BE helper. Tránh leak action qua API direct.

Pattern 10: Reflection-based regression test cho Authorize policy (S22 Plan C task 4 #44)

5 test lightweight ~50 LOC catch class-level [Authorize(Policy = "...")] regression:

var attr = typeof(ControllerXxx).GetCustomAttribute<AuthorizeAttribute>();
attr.Policy.Should().Be("CanDoSomething");

KHÔNG cần WebApplicationFactory heavy (slow + complex setup). Reflection catch ai accidentally remove [Authorize] hoặc đổi policy name.

Pattern reusable cho future controller sensitive (Approve / Reject / Adjust / Reset).

Trong PurchaseEvaluationWorkflowServiceReturnModeTests + PurchaseEvaluationDraftGuardTests:

private async Task<Guid> SeedWorkflowAsync(...) {
    // 1 Step (DepartmentId=null skip Dept FK) + 2 Levels
}

private async Task SeedApproversAsync(Guid levelId, ...) {
    // Multi user via fix.CreateUserAsync
}

Pattern reusable: test PE workflow → 1 Step + 2 Levels + N approvers per Level. DepartmentId=null skip Dept FK ràng buộc. Token cost ~80 LOC repeated cross 2 test class S22.

Pattern 12: InternalsVisibleTo csproj expose helper cho test (S22)

PurchaseEvaluationDraftGuard static helper internal — expose qua <InternalsVisibleTo Include="SolutionErp.Infrastructure.Tests" /> trong SolutionErp.Application.csproj thay vì rewrite public API.

Tránh API surface bloat. Reusable cho future guard / helper internal cần test.


⚠️ Anti-patterns observed (DO NOT)

  1. Skip MEMORY.md update — knowledge tài sản
  2. Bypass pre-commit hooks --no-verify (forbidden absolute)
  3. git add -A hoặc git add . — specific files only
  4. Touch files outside spec scope — anti-fiddle rule
  5. Push remote autonomously cho heavy change — em main pushes (UAT iteration: confirm với em trước push)
  6. Modify SolutionErp.slnx autonomously — em main updates khi thêm .cs/.csproj
  7. Lower bar to match em main quality — Smart Friend Cognition anti-pattern
  8. Proceed when spec ambiguous > 20% — return REFUSE với reason

🧠 SOLUTION_ERP conventions (auto-load via skills)

  • BE .NET 10: PascalCase tiếng Anh entities + DTO records + command names. CQRS + MediatR + FluentValidation + AutoMapper. Repository qua IApplicationDbContext. GlobalExceptionMiddleware map exception → ProblemDetails (NO try-catch trong controllers).
  • FE React 19 + Vite 8 + TS 6: Named export only (trừ App). TanStack Query. shadcn/ui copy-paste. TS6 erasableSyntaxOnly cấm enum → const-object pattern. UI 100% tiếng Việt. Mirror 2 app rule §3.9.
  • Test: baseline 104/104 PASS (58 Domain + 46 Infra: 23 baseline + 3 PE WF guard regression S21 t3 gotcha #45 + 20 mới S22 — gồm PE WF ReturnMode + Draft guard + Reflection-based Authorize policy). Phase 9 UAT skip per chunk theo memory feedback_uat_skip_verify. Stack xUnit + FluentAssertions 7.2 + EF SQLite 10 TestApplicationDbContext override nvarchar(max) → TEXT.
  • Build: dotnet build SolutionErp.slnx clean 0 err + npm run build × 2 app pass.
  • Commit: [CLAUDE] <scope>: <message> + Co-Authored-By Claude Opus 4.7 (1M context).

Scopes (pick 1)

Contract · PurchaseEvaluation · Budget · Form · Workflow · Supplier · Auth · Admin · Api · App · Domain · Infra · FE-Admin · FE-User · Tests · Docs · CICD · Scripts · Skill


🔑 Pin versions (package pinning §2.8)

KHÔNG * / latest. Critical pins:

  • MediatR 12.4.1 (14 fail DI)
  • Swashbuckle 6.9.0 (10 conflict OpenApi 2)
  • Node engines >= 20 + CI pin 20.x (bài học NamGroup, memory feedback_node_cicd)
  • LibreOffice 25.8.6
  • @microsoft/signalr 8.0.7

📅 Recent activity (last 10 FIFO)

  • 2026-05-15 (S24, Plan M Chunk M2 PASS): F1 edge case Bước 1 reset ChoDuyet tests (em main M1 service edit PurchaseEvaluationWorkflowService.cs line 287-333 đã DONE — fallback Drafter TraLai → reset (0, 1) giữ ChoDuyet + audit log "không lùi được"). Cookie-cutter 1 file test PurchaseEvaluationWorkflowServiceReturnModeTests.cs — 2 sub-tasks: (1) extend SeedWorkflowAsync helper +2 params optional allowReturnOneLevelL1 + allowReturnOneStepL2 (default false, không phá compat 4 test ReturnMode existing), set vào l1.AllowReturnOneLevel + l2.AllowReturnOneStep tương ứng — Pattern 3 audit-reuse EXTEND không clone helper; (2) add 2 [Fact] test ngay sau test admin bypass OneLevel (line 241) — ApplyReturnMode_OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet (PE init Step 0 Cấp 1 + actor=a1 + slot Cấp 1 tick AllowReturnOneLevel, build PE inline vì helper BuildPeAtLevel2 không phù hợp cho Cấp 1) + ApplyReturnMode_OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet (PE Step 0 Cấp 2 + actor=a2 + slot Cấp 2 tick AllowReturnOneStep, reuse BuildPeAtLevel2, OneStep service check curStepIdx > 0 → fallback ngay không quan tâm Cấp). Assert: Phase=ChoDuyet (KHÔNG TraLai như Drafter mode) + pointer (0, 1) + SLA NotNull + Changelog ContextNote chứa "không lùi được" (Summary field cố định "Chuyển phase {from} → {to}", summary từ ApplyReturnModeAsync chèn vào comment qua line 96-99 service → LogTransition ContextNote = comment). K7 cascade verify NO regression: 3 ApproveV2_SkipToFinal_* tests still green (M1 edit chỉ F1 OneLevel/OneStep edge case, KHÔNG đụng F2 path ApproveV2Async). Verify: dotnet test SolutionErp.slnx clean 0 err 2 warn pre-existing DocxRenderer, 106/106 PASS (58 Domain + 48 Infra: +2 từ 46 baseline post Plan L). 10 ReturnMode-class tests verified individually PASS (4 ReturnMode + 3 ApproveV2_SkipToFinal + 1 Reject_NonApprover + 2 edge case mới). Diff +94 LOC trên 1 test file (test add + helper signature 2 params). Token ~10k. Spec deterministic + 1 file independent + < 1h verified.

  • 2026-05-15 (S24, Plan M Chunk M3 PASS): FE rename Phase=TraLai (98) display label "Trả lại" → "Cần chỉnh sửa lại" cho UAT disconnect fix. Spec scope HẸP (display badge label + status reference) tuân thủ strict: 4 file FE × 2 app = 8 edit total. 2 file types/purchaseEvaluation.ts × 2 app: PurchaseEvaluationPhaseLabel[98] (raw phase badge) + PeDisplayStatusLabel.TraLai (display status badge — main user-facing). 2 file components/pe/PeWorkflowPanel.tsx × 2 app: rename 2 inline literal hardcode "Trả lại" trong F1 dialog tooltip (Phase → "...") + confirm message (Phiếu sẽ về "...") — đây là status display reference, KHÔNG phải action verb. Pattern 5 mirror 2 app strict applied. KHÔNG đụng: (1) action button label ← Trả lại (verb), (2) F1 mode picker label Trả về Người soạn thảo (4 mode action), (3) comments narrative line 62/71/etc giữ rationale dev (rule §6.5), (4) types/contracts.ts + types/budget.ts Phase 98 'Trả lại' — module Contract + Budget khác PE, ngoài scope M3. Verify: npm run build fe-admin PASS clean (0 TS err, 9.40s, 1395 KB bundle unchanged trivial) + npm run build fe-user PASS clean (0 TS err, 6.92s, 1275 KB). Diff +4/-4 LOC × 2 = 8 LOC tổng trên 4 file. Token ~9k. Decision tactical: 2 chỗ inline literal PeWorkflowPanel rename để giữ UX consistency với badge label sau rename — KHÔNG drift outside spec vì cùng "status display reference" semantics (badge + tooltip + confirm message phải mirror). Anti-fiddle threshold <20% LOC respected.

  • 2026-05-14 (S23 t1, K7 Chunk F PASS): Mig 31 Approver F2 service regression tests. Sub-task 1 fix broken Drafter F2 test reference K1 flagged: PurchaseEvaluationWorkflowServiceReturnModeTests.cs:253 drafter.AllowDrafterSkipToFinal = true (DELETE 3 deprecated Drafter F2 tests entire — SkipToFinal_DrafterAllowed_SetsPointerToFinalLevel + SkipToFinal_DrafterDenied_NonAdmin_Throws + SkipToFinal_AdminBypass_Succeeds, semantic deprecated no value). Sub-task 2 add 3 new Approver F2 tests: ApproveV2_SkipToFinal_AdminTickFlag_SetsPhaseDaDuyet (happy path — slot Cấp 1 Bước 1 admin tick → Phase=DaDuyet, pointer cleared, opinion + PEA + Changelog logged), ApproveV2_SkipToFinal_FlagOff_NonAdmin_ThrowsConflictException (denied — flag off non-admin slot user → throw "chưa được phép duyệt thẳng Cấp cuối"), ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck (admin bypass — flag off admin role → DaDuyet allowed). Pattern 11 SeedWorkflowAsync cookie-cutter REUSE — created SeedApproverF2WorkflowAsync helper (2 Steps × 2 Levels — multi-step verify skip thẳng terminal KHÔNG fallthrough advance pointer next Step), AllowApproverSkipToFinal per-slot param. PE init Phase=ChoDuyet + CurrentWorkflowStepIndex=0 + CurrentApprovalLevelOrder=1 (vs S22 happy path từ DangSoanThao). Add using Microsoft.EntityFrameworkCore cho .ToListAsync() PEL/PEA/Changelog query. File header narrative line 17-25 REWRITE để track Mig 31 refactor semantic Approver scope ChoDuyet vs Drafter-from-Nháp cũ. Verify: dotnet build clean 0 err 2 warn pre-existing DocxRenderer. dotnet test SolutionErp.slnx 104 PASS (58 Domain + 46 Infra, 3 deleted + 3 added cancel out, baseline preserved). 3 Approver F2 tests verified individually PASS. Diff +175/-92 LOC trên 1 file. Token ~14k.

  • 2026-05-14 (S23 t1, K5 Chunk D PASS): Cleanup zombie F2 endpoint + UsersPage column + DTO field + stale narrative comments (Reviewer Major #1 + Major #2 + Minor #3 + Minor #4). Pattern post-refactor full cleanup atomic 1 commit. BE 7 file (UsersController.cs DELETE PATCH /allow-skip-final endpoint + SetAllowDrafterSkipToFinalBody record; UserFeatures.cs DELETE UserDto field + SetUserAllowDrafterSkipToFinalCommand + Handler + sentinel-false mappings cleanup; ApprovalWorkflow.cs REWRITE stale narrative line 78-80 Mig 31 semantic + docstring line 108; PurchaseEvaluationFeatures.cs REWRITE Command DTO comment line 401; ApprovalWorkflowConfiguration.cs APPEND Mig 31 narrative line 22-24 + clean storage move comment line 87; ApprovalWorkflowV2AdminFeatures.cs clean DTO comment line 58; IPurchaseEvaluationWorkflowService.cs + PurchaseEvaluationDtos.cs clean stale "storage Users.AllowDrafterSkipToFinal" references) + FE Admin 2 file (UsersPage.tsx DELETE "Skip cuối" column TableHeader/TableCell + FastForward import + allowSkipMut mutation hook + FastForward toggle button; types/users.ts DELETE allowDrafterSkipToFinal field). fe-user KHÔNG đụng (no UsersPage admin-only + K6 sẽ handle Workspace Drafter checkbox), FE Designer page KHÔNG đụng (K3 done — 2 stale comment line 75 + 504 leftover deferred K6). Grep AllowDrafterSkipToFinal + allow-skip-final + allowDrafterSkipToFinal + Skip cuối + FastForward ZERO results across src/Backend (excl migrations) + fe-admin/src. Build BE production projects clean (0 err, 2 pre-existing DocxRenderer warn). Build fe-admin clean (0 TS err, 0 new warn). Diff +42/-94 LOC trên 9 file. Token ~12k. K6 Workspace Drafter checkbox cleanup next.

  • 2026-05-14 (S23 t1, K3 Chunk C PASS): FE Admin Designer 7th checkbox AllowApproverSkipToFinal + banner rewrite. Pattern Mig 29/30 admin opt-in per-slot mirror reinforced 3× cumulative (Mig 29 F1+F3 5 checkbox + Mig 30 F4 1 checkbox + Mig 31 F2-refactor 1 checkbox = 7 checkbox total per slot). Cookie-cutter 1 file fe-admin only (ApprovalWorkflowsV2Page.tsx, fe-user no Designer per Investigator K0 S1). 7 sub-items atomic: (1) LevelDto type +allowApproverSkipToFinal: boolean, (2) EditLevelEntry type +same, (3) makeDefaultLevelEntry default false, (4) copyFromDefinition propagate ?? false, (5) inline checkbox row position cuối list sau F4 AllowApproverEditBudget logical grouping (Edit Section 2 → Edit Budget → Skip to Final), (6) banner rewrite line ~623 từ "F2 cấu hình ở User Management" (Plan D S22 stale) → "Cấu hình quyền duyệt riêng cho từng NV trong slot Approver bên dưới (Trả lại / Edit Section 2 / Edit Budget / Duyệt thẳng Cấp cuối)", (7) POST/PATCH mutation body levels.map +allowApproverSkipToFinal. Verify: npm run build fe-admin PASS clean 0 TS error, 0 new warning. Bundle 1395.74 KB (unchanged trivial vs baseline). Diff +26/-7 LOC. Token ~6k. K5 next chunk cleanup zombie endpoint + UsersPage column.

  • 2026-05-14 (S23 t1, K1 Chunk A PASS): Mig 31 schema swap F2 storage Users → ApprovalWorkflowLevels. Pattern Mig 29 ADD-DROP no-BACKFILL Option A (accept lose 4 prod user value fin.pp + pm.nv + nv.test + truong.nguyen). Cookie-cutter 6 BE file (User.cs -1 prop + ApprovalWorkflow.cs +1 prop AllowApproverSkipToFinal per-Approver-slot + ApprovalWorkflowConfiguration.cs +HasDefaultValue + PurchaseEvaluationWorkflowService.cs surgical -37 LOC F2 Drafter SUBMIT branch line 121-157 stub + Mig 3-file). TransitionAsync bool skipToFinal 8th param KEPT cho K2 repurpose APPROVE STEP. 4 Application compile-break sites (UserFeatures.cs LIST + GET DTO mapping + SetUserAllowDrafterSkipToFinalCommandHandler NoOp + PurchaseEvaluationFeatures.cs drafter flag = false) patched với sentinel false + K2 marker comment (DTO/Command signature unchanged per spec — K2 sẽ refactor). Mig 31 Up() manual reorder ADD-DROP correct (no BACKFILL). Both DBs Dev + Design applied successful. Build production projects clean 0 err 0 warn. Test compile error PurchaseEvaluationWorkflowServiceReturnModeTests.cs:253 left for K7 chunk (spec exclude test scope). Pattern feedback_per_nv_permission_scope.md reinforced 3× cumulative (Mig 29 F1+F3 + Mig 30 F4 + Mig 31 F2-refactor). UserConfiguration.cs file không tồn tại — User entity configured inline ApplicationDbContext.OnModelCreating ~line 86, không có HasDefaultValue cho AllowDrafterSkipToFinal, EF picks prop change tự động.

  • 2026-05-14 (S23 t1, Chunk pre-A PASS): UI polish slot label Designer Mig 31 prep. File fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx line 873 replaced Quyền duyệt NV #{ei + 1}Quyền duyệt {usersList.data?.find(u => u.id === entry.approverUserId)?.fullName ?? 'Chưa chọn NV'}. Pattern: lookup user fullName từ usersList query (Option A — DTO EditLevelEntry không có approverFullName field, chỉ LevelDto BE response có approverUserName nhưng edit state dùng EditLevelEntry). usersList đã in scope ~line 500, pattern lookup .find(x => x.id === e.approverUserId) đã dùng tại line 535 cho validation. Cookie-cutter 1 file fe-admin only (fe-user KHÔNG có Designer per Investigator K0 S1). Tailwind classes preserved (mb-1 text-[10px] font-medium uppercase text-amber-700). Verify: npm run build fe-admin PASS clean 0 TS error, 0 new warning. Bundle 1395 KB (unchanged trivial). Token ~5k.

  • 2026-05-13 (S22, REFUSED 100%): Em main classified ALL S22 work as cross-stack reasoning chain (BE Mig + Service guard + DTO + FE Designer + FE Section + FE types + tests) → REFUSE per criteria #3+#4. Em main solo executed. State chốt S22: 30 migrations (+1 Mig 30 AllowApproverEditSection1 per-NV F4 flag), 104 test PASS (+20 từ 84 — gồm PE WF ReturnMode + Draft guard + Reflection-based Authorize policy regression), ~146 endpoints (+3), 46 gotchas unchanged, 33 active prod users (13 cũ + 20 mới S22+2). 7 patterns successfully applied throughout S22 (validated continued effectiveness): Pattern 7 per-NV admin opt-in flag (Mig 30 follow Mig 29), Pattern 2 EF migration 3-file rule, Pattern 8 tách endpoint narrow scope (AdjustBudget vs UpdatePeDraft), Pattern 9 defense-in-depth FE+BE guard pair (S22+1 disable 3 button), Pattern 10 Reflection-based regression test cho Authorize policy (Plan C task 4 #44, 5 test ~50 LOC), Pattern 11 test infra helper cookie-cutter (SeedWorkflowAsync + SeedApproversAsync), Pattern 12 InternalsVisibleTo csproj expose internal helper cho test. Mismatches discovered S22: (1) "Đang trong quá trình duyệt = người điều chỉnh cũng là người duyệt" — em first interpret default Approver scope always allowed → bro corrected per-NV admin opt-in flag (Mig 30). Lesson: clarify default behavior vs admin opt-in TRƯỚC khi default scope expansion. (2) PE.changelogs field KHÔNG có trong PeDetailBundle — em first design history display trong BudgetAdjustSection, build FAIL TS2339. Fix: removed history display (defer S23+ via separate fetch endpoint). (3) Dialog size="xl" NOT supported — only "sm" | "md" | "lg". Use "lg" cho preview iframe. (4) API auth field accessToken không phải token. Script seed-test-users-prod.ps1 lần đầu FAIL 401 sau auth — em fix $authResp.accessToken.

  • 2026-05-13 (S21 t3-t5, REFUSED 3×): Em main classified all 3 turns as cross-stack reasoning chain (BE+FE+test tightly coupled) → REFUSE per criteria #3+#4 (cross-stack > 2 layers, bug fix reasoning chain). Bug fix gotcha #45 = bug + reasoning, F1+F2+F3 = schema design decision, Refactor per-NV = drastic refactor schema + Service + FE × 2 app. All correct REFUSE — em main solo executed. Strict scope criteria validated S21 t3-t5 — REFUSE rate 100% match Anthropic warning "tightly interdependent coding". Cumulative: 84 test, 29 mig, 45 gotcha. Pattern saved future invocation: per-NV permission scope split natural theo role + EF migration BACKFILL reorder pattern.

  • 2026-05-11 (setup): Implementer agent initialized. Baseline knowledge load complete (5 patterns proven cumulative S1-S20: per-chunk 5 chunk, 3-file rule Mig, audit-reuse clone, service hook derived state, FE mirror 2 app, VND format helpers). No implementations performed yet. Awaiting first SendMessage from em main. Strict scope auto-refuse criteria active.


🔄 Curate trigger

  • Memory size > 25KB → archive recent entries to archive/<period>.md
  • Duplicate entries detected → merge
  • Stale > 3 months → remove

Last curate: 2026-05-11 (initial seed)