[CLAUDE] Docs: S40 curate 4 agent MEMORY >25KB + RAG catch-up chunk S37-S40
- investigator-codebase 35.7->7.6 · cicd-monitor 35.3->8.4 · implementer-backend 30.9->7.9 · reviewer 28.4->7.5 KB - Archived verbose FIFO -> git d2f52ba; refreshed stale counts (111->130 test, 33->40 mig, ~146->211 endpoints, 47->55 gotcha); dedup split (FE patterns -> implementer-frontend, test patterns -> test-specialist) - Foundation preserved: gotcha patterns + 5-stage/5-category checklist + Smart Friend guard + workflow schemas + sqlcmd/controller-audit + BE Patterns 1-12-ter - RAG: store_memory S37-S40 catch-up chunk (rerank 0.867 top hit); full re-index pending `python bootstrap.py --project solution_erp` (needs VOYAGE_API_KEY env) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -1,181 +1,69 @@
|
||||
# Reviewer Agent — Persistent Memory
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first 200 lines / 25KB at spawn.
|
||||
> Update BEFORE every stop. Curate when > 25KB.
|
||||
> Update BEFORE every stop. Curate when > 25KB. Keep entry ≤ 1.5K chars (gotcha #53).
|
||||
> Full verbatim history pre-S40 → git `d2f52ba` + `archive/2026-05-q1..q2.md`.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Role baseline
|
||||
|
||||
Adversarial pre-commit reviewer for SOLUTION_ERP. Read-only verification + live curl on prod UAT environment (`*.solutions.com.vn`). Tools: Read, Grep, Glob, Bash (curl + git diff + sqlcmd read). Output: PASS/FAIL verdict + concrete issues file:line.
|
||||
Adversarial pre-commit reviewer SOLUTION_ERP. Read-only verify + live curl prod UAT (`*.solutions.com.vn`). Tools: Read, Grep, Glob, Bash (curl + git diff + sqlcmd read) + 5 RAG MCP. Skills: `dependency-audit-erp` + `contract-workflow` + `permission-matrix`. Output: PASS/FAIL + concrete issues file:line. NEVER write code.
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Recurring SOLUTION_ERP bug patterns (catch with priority)
|
||||
## 🚨 Recurring bug patterns (catch priority)
|
||||
|
||||
### Gotcha #44 — Silent 403 class-level Authorize quá strict (S18 lesson)
|
||||
|
||||
- Symptom: Drafter dropdown V2 workflow empty silent (no error toast)
|
||||
- Root: `[Authorize(Policy = "Workflows.Read")]` class-level → non-admin 403, TanStack Query catch silent → UI empty
|
||||
- Verify: grep `\[Authorize\(Policy = .*\)\]` class-level vs action-level + curl với non-admin token expect 200
|
||||
- Fix pattern: class-level `[Authorize]` only (any authenticated). POST/PUT/DELETE giữ `[Authorize(Policy = "X.Create")]` admin-only
|
||||
|
||||
### Gotcha #43 — Step.Order ≠ index 0-based
|
||||
|
||||
- Symptom: EF query `Where(s => s.Order == i)` returns wrong row
|
||||
- Verify: grep `step.Order` arithmetic — array index 0-based vs Order field 1-based
|
||||
- Fix pattern: precompute candidates EF query → in-memory `OrderBy(s => s.Order).ToList()` → array index access
|
||||
|
||||
### Gotcha #42 — Dual schema workflow V1 vs V2 — Service phải branch
|
||||
|
||||
- Symptom: PE submit failed do Service không biết V1 hay V2 schema
|
||||
- Verify: grep `evaluation.ApprovalWorkflowId is Guid awId` — phải branch theo pin field
|
||||
- Fix pattern: `if (evaluation.ApprovalWorkflowId is Guid awId) ApproveV2Async(...) else ApproveV1LegacyAsync(...)`
|
||||
|
||||
### Wire BE claim recurring bug pattern
|
||||
|
||||
- Symptom: claim wire CRUD nhưng grep diff finds `// Mock` / `alert(...)` / no POST/PUT/DELETE call
|
||||
- Verify: grep diff mock markers + live curl POST/PUT/DELETE expect 2XX
|
||||
- Severity: CRITICAL — block commit
|
||||
|
||||
### Cross-module security validation mirror (NEW S29 — Smart Friend 4× cumulative)
|
||||
|
||||
- Symptom: khi mirror entity/Command/Handler cross-module (PE → Contract → Budget V2), em main solo focus data shape (DTO field, FK relation, projection) MISS security validation guards
|
||||
- Pattern: ApplicableType type guard cho V2 workflow pin entity — `aw.ApplicableType == ExpectedType` validate ON Create command BEFORE entity instantiation. Mirror PE pattern `PurchaseEvaluationFeatures.cs:62-77`: load workflow, assert ApplicableType=Contract(3) / PE(1) / Budget(2), throw `ConflictException` on mismatch
|
||||
- Attack vector example (S29 Plan B): Drafter forge POST `/api/contracts` với `approvalWorkflowId` của PE/Budget V2 workflow → FK Restrict allows (only checks Id existence, NOT ApplicableType) → Contract pins wrong-scope workflow → semantic policy violation
|
||||
- Password policy mirror (S29 Plan CA Hotfix D2): Identity ≥12 chars enforced — new seed user CreateAsync fail nếu reuse legacy 11-char `User@123456`. Verify per-user inline conditional override (e.g. `"CatalogMgr@2026"` 15 chars)
|
||||
- Verify: grep `CreateXCommand` handler — expect `aw.ApplicableType == ApprovalWorkflowApplicableType.X` check. Also re-verify `IsActive=true` + `IsUserSelectable=true` server-side (FE filters but BE trusts blindly = lower-risk gap)
|
||||
- Applicable cross-module forward: Contract V2 (S29 fixed), Budget V2 (future), Notification V2 (future), any new V2 workflow pin entity
|
||||
- Severity: MAJOR — block push pre-commit gate
|
||||
|
||||
### Gotcha #17 — EF migration 3-file rule
|
||||
|
||||
- Symptom: commit migration nhưng thiếu `.Designer.cs` hoặc `ApplicationDbContextModelSnapshot.cs` → next migration fail
|
||||
- Verify: `git diff --name-only | grep Migrations/` expect 3 files (target.cs + target.Designer.cs + Snapshot.cs)
|
||||
|
||||
### Gotcha #47 — `.claude/agent-memory/**` NOT in `paths-ignore` filter (S22 discovery, PENDING bro decide)
|
||||
|
||||
- Symptom: MEMORY.md drift patch commit (end-of-session flush) triggers full CI deploy ~3.5min waste
|
||||
- Verify: check `.gitea/workflows/deploy.yml` `paths-ignore` — currently `['docs/**', '**/*.md', '.claude/skills/**']` MISSING `.claude/agent-memory/**`
|
||||
- Discovery: S21 CICD Monitor Run #188 verify chốt initial — confirmed via path filter audit
|
||||
- Fix recommended: add `.claude/agent-memory/**` vào paths-ignore (em main KHÔNG tự edit — flag bro decide; pending add to `docs/gotchas.md` 47th entry)
|
||||
- Severity: minor (CI waste only, no functional impact)
|
||||
- **#44 Silent 403 class-level Authorize quá strict** — Drafter dropdown empty silent (TanStack catch silent → UI empty). Grep `\[Authorize\(Policy=.*\)\]` class-level + curl non-admin expect 200. Fix: class-level `[Authorize]` only (any authenticated); POST/PUT/DELETE giữ `[Authorize(Policy="X.Create")]`.
|
||||
- **#43 Step.Order ≠ index 0-based** — `Where(s=>s.Order==i)` wrong row. Fix: EF query → in-memory `OrderBy(Order).ToList()` → index.
|
||||
- **#42 Dual schema V1/V2 — Service phải branch** — `if (entity.ApprovalWorkflowId is Guid awId) ApproveV2Async else V1Legacy`.
|
||||
- **Wire BE claim** — grep diff `// Mock`/`alert(`/no POST-PUT-DELETE call + live curl expect 2XX. Severity CRITICAL block.
|
||||
- **Cross-module security mirror (S29 Smart Friend)** — khi mirror entity/Command cross-module (PE→Contract→Budget V2), em main solo focus data shape MISS security guard. Pattern: `aw.ApplicableType == ExpectedType` validate ON Create BEFORE instantiation (mirror `PurchaseEvaluationFeatures.cs:62-77`). Attack: Drafter forge POST `/api/contracts` với `approvalWorkflowId` của PE/Budget → FK Restrict chỉ check Id existence NOT ApplicableType → wrong-scope pin. Also re-verify `IsActive`+`IsUserSelectable` server-side. Password ≥12 chars (Identity reject 11-char legacy). Severity MAJOR block push.
|
||||
- **#17 EF migration 3-file** — `git diff --name-only | grep Migrations/` expect 3 (target + Designer + Snapshot).
|
||||
- **#47 `.claude/agent-memory/**` NOT in paths-ignore** (PENDING bro decide) — MEMORY flush commit triggers CI ~3.5min waste. paths-ignore hiện `['docs/**','**/*.md','.claude/skills/**']` missing agent-memory. Severity minor (CI waste). ⚠️ S40 note: agent-memory commits đang trigger — recommend bro add.
|
||||
|
||||
---
|
||||
|
||||
## 📋 5-category checklist (apply EVERY review)
|
||||
## 📋 5-category checklist (EVERY review)
|
||||
|
||||
### Category 1: Wire BE / feature claim verify
|
||||
- Grep mock markers in diff (`// Mock`, `alert(`, `setEditing(null) // close UI`, `TODO.*wire`)
|
||||
- Grep actual API call: `await api\.(post|put|delete|patch)\(` trong FE diff
|
||||
- Live curl POST/PUT/DELETE/PATCH if deploy claim (`https://api.solutions.com.vn/...`)
|
||||
- Status code matrix expected vs actual
|
||||
|
||||
### Category 2: Schema integrity (44 active gotchas)
|
||||
- Reference `docs/gotchas.md` + skill `dependency-audit-erp`
|
||||
- Check 3-file rule Mig
|
||||
- Check column types vs entity definition (Mig 27 lesson: `IsVisible bit NOT NULL DEFAULT 1` + `DisplayLabel nvarchar(200) NULL`)
|
||||
|
||||
### Category 3: Security
|
||||
- `[Authorize]` class-level on ALL new controllers
|
||||
- Per-action `[Authorize(Policy = "...")]` cho admin-scoped (gotcha #44 lesson)
|
||||
- Permission guard wrap new admin pages (FE)
|
||||
- Route permission map populate (`menuKeys.ts` mirror BE `MenuKeys.cs` + `All[]`)
|
||||
- Input validation FluentValidation Validator class
|
||||
- SQL parameterized (EF Core default OK) + XSS escape
|
||||
|
||||
### Category 4: Code quality
|
||||
- `dotnet build SolutionErp.slnx` clean 0 err
|
||||
- `npm run build` × fe-admin + fe-user clean (TS6 strict)
|
||||
- Tests baseline 81 PASS (Phase 9 UAT exception OK)
|
||||
- No `--no-verify` bypass (forbidden absolute)
|
||||
- Anti-fiddle audit (scope drift > 20% LOC outside spec = FAIL)
|
||||
- Mirror 2 FE app khi feature FE (rule §3.9)
|
||||
|
||||
### Category 5: Test coverage
|
||||
- New helper static → unit test (xUnit)
|
||||
- New Repository method → repo test
|
||||
- New endpoint API → integration test (WebApplicationFactory)
|
||||
- Bug recurring → regression test TDD-style (test BEFORE fix)
|
||||
- **Phase 9 UAT exception:** test-after default OK theo memory `feedback_uat_skip_verify`
|
||||
- Test count baseline 81 → tăng khi feature added theo §7
|
||||
- **Cat 1 Wire BE/feature claim:** grep mock markers diff + `await api\.(post|put|delete|patch)\(` + live curl POST/PUT/DELETE if deploy claim + status matrix.
|
||||
- **Cat 2 Schema integrity:** 3-file rule Mig + column types vs entity def. Reference `docs/gotchas.md` (55 active).
|
||||
- **Cat 3 Security:** `[Authorize]` class-level ALL new controllers + per-action policy admin-scoped (gotcha #44) + FE PermissionGuard + menuKeys.ts mirror BE MenuKeys.cs + FluentValidation + EF parameterized.
|
||||
- **Cat 4 Code quality:** `dotnet build SolutionErp.slnx` 0 err + `npm run build` × 2 app (TS6 strict) + tests baseline **130 PASS** (Phase 9 UAT exception OK) + no `--no-verify` + anti-fiddle (scope drift >20% LOC = FAIL) + mirror 2 FE app §3.9.
|
||||
- **Cat 5 Test coverage:** new helper → xUnit · new endpoint → integration · bug → regression test-before-fix. Phase 9 UAT test-after default OK (`feedback_uat_skip_verify`). Baseline 130.
|
||||
- **Cat 6 Authority boundary:** describe issue + acceptance criteria, NOT code edits. Escalate disagreement explicit.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Anti-patterns observed (DO NOT)
|
||||
## ⚠️ Anti-patterns + 🛡️ Smart Friend guard
|
||||
|
||||
1. ❌ Recommend code edits — only describe issue + acceptance criteria
|
||||
2. ❌ Skip live curl verify if deploy claim — recurring risk
|
||||
3. ❌ Accept "wire" claim without grep proof
|
||||
4. ❌ Defer to em main authority — escalate disagreement explicitly
|
||||
5. ❌ Skip MEMORY.md update với anti-patterns observed
|
||||
6. ❌ Lower bar to match em main quality — Smart Friend anti-pattern Cognition
|
||||
1. ❌ Recommend code edits (only describe issue+criteria) · 2. ❌ Skip live curl if deploy claim · 3. ❌ Accept "wire" without grep proof · 4. ❌ Defer to em main authority (escalate explicit) · 5. ❌ Skip MEMORY · 6. ❌ **Lower bar match em main** (Smart Friend Cognition anti-pattern).
|
||||
|
||||
**Smart Friend (Cognition):** NEVER lower bar. Em main code fine → PASS. Em main issues → FAIL with specifics regardless social pressure. "Quality ceiling set by primary, not escalation." Value = raise quality through catch.
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Smart Friend anti-pattern guard
|
||||
## 🧠 SOLUTION_ERP review essentials (S40 verified)
|
||||
|
||||
Per Cognition documented research:
|
||||
- NEVER lower bar to match em main's apparent quality
|
||||
- If em main code fine → say PASS
|
||||
- If em main code has issues → FAIL with specifics regardless social pressure
|
||||
- "Quality ceiling was set by the primary, not the escalation." — Your value = raise quality through catch
|
||||
- **Tests baseline:** **130 PASS** (58 Domain + 72 Infra). Must increase khi feature added (§7); Phase 9 UAT exception (`feedback_uat_skip_verify`).
|
||||
- **Gotchas:** **55 active** (`docs/gotchas.md`, format `### N.` highest #55). Latest #53 truncation · #54 529-fallback · #55 truncation-mid-exploration.
|
||||
- **Migrations:** **40 latest `AddAttendances`** (path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/`). Per-NV Allow* (Mig 29 F1/F3 5 flag + Mig 30 F4 on `ApprovalWorkflowLevels` per slot + F2 `Users.AllowDrafterSkipToFinal` per Drafter; Mig 31 SkipToFinal→ApproverLevel).
|
||||
- **Endpoints:** ~211 · **84 SQL tables**.
|
||||
- **Identity password ≥12 chars** (reject 11-char). Test creds: admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM).
|
||||
- **Prod:** api/admin/eoffice.solutions.com.vn. **Pin:** MediatR `12.4.1` (flag `Version="14`) · Swashbuckle `6.9.0` · Node CI `20.x`.
|
||||
- **Conventions:** `docs/rules.md` (§3.9 mirror 2 FE, §5.2 commit, §6.5 docs narrative, §7 test timing, §2.8 pin).
|
||||
|
||||
---
|
||||
|
||||
## 🧠 SOLUTION_ERP review essentials
|
||||
## 📅 Recent activity (FIFO — older → archive/git)
|
||||
|
||||
- **Tests baseline:** 111/111 PASS (S25 unchanged from S23 t3 +7 Plan M edge case tests; pre-Plan AB Chunk A2 SQLite tie-break regression Run #215 caught by CICD test gate → em main fix EntityType + Summary discriminator filter restored 111 PASS). Must increase nếu feature added per §7; UAT iteration exception per memory `feedback_uat_skip_verify`
|
||||
- **Gotchas:** 47 active (`docs/gotchas.md` reference) — +#48 Multi-Changelog.Add() trong same SaveChangesAsync transaction → SQLite test frozen clock CreatedAt tie-break non-deterministic (S25 pending docs add). +#45 PE button TraLai payload mismatch + #46 Gitea API path/cache stale (S21 t3-t4). #47 paths-ignore agent-memory gap (S22 PENDING bro confirm add to docs)
|
||||
- **Migrations:** 31 latest `AddPeLevelOpinionsForV2` (S19 — Mig 31 Plan K1 swap F2 Drafter→Approver scope per-Level slot S23 t1). Mig 30 `AddAllowApproverEditBudgetToLevels` (S22+5 per-slot F4 flag admin opt-in Approver scope edit budget ChoDuyet branch). Mig 29 prev `RefactorAdvancedOptionsToPerLevelAndDrafterUser` (S21 t5 per-NV split)
|
||||
- **Per-NV Allow* scope split** (Mig 29 + Mig 30) — F1+F3 5 flag + F4 `AllowApproverEditBudget` (S22) on `ApprovalWorkflowLevels` (per Approver slot), F2 1 flag on `Users.AllowDrafterSkipToFinal` (per Drafter). DTO: `currentLevelOptions` + `drafterAllowSkipToFinal` thay vì `workflowOptions`
|
||||
- **Endpoints:** ~146 (+3 S22: allow-skip-final / budget-adjust / attachments/view)
|
||||
- **Identity password policy ≥12 chars** (S22+2 enforced by ASP.NET Identity stack — reject `User@123456` 11 chars). Existing HANDOFF mention "User@123456" pattern S4 outdated, current test creds Admin@123456 + TestUser@123456 OK
|
||||
- **Live deploys (Prod UAT):** https://api.solutions.com.vn · https://admin.solutions.com.vn · https://eoffice.solutions.com.vn
|
||||
- **Bearer token test:**
|
||||
- Admin: `admin@solutions.com.vn / Admin@123456` (full quyền)
|
||||
- UAT user: `nv.test@solutions.com.vn / TestUser@123456` (Drafter Phòng CCM — verify non-admin access patterns)
|
||||
- **Users active:** 33 (rename role-based pattern act.nv / act.pp / act.tp etc.)
|
||||
- **Conventions:** `docs/rules.md` (§3.9 mirror 2 FE, §5.2 commit format, §6.5 docs KEEP narrative, §7 test timing, §2.8 package pinning)
|
||||
- **6 skills:** `contract-workflow` · `permission-matrix` · `form-engine` · `ef-core-migration` · `dependency-audit-erp` · `iis-deploy-runbook`
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Critical pin verify (gotcha #1-4)
|
||||
|
||||
- MediatR `12.4.1` (14 fail DI)
|
||||
- Swashbuckle `6.9.0` (10 conflict OpenApi 2)
|
||||
- Microsoft.OpenApi `1.x` (2 breaking)
|
||||
- Node engines `>= 20` + CI `20.x` (Node latest fail Windows IIS)
|
||||
|
||||
Flag commit nếu thấy `<PackageReference Include="MediatR" Version="14...` hoặc tương tự.
|
||||
|
||||
---
|
||||
|
||||
## 📅 Recent activity (last 10 FIFO)
|
||||
|
||||
- **2026-05-28 (S35 Plan G-H2 Task 3 BE CRUD 16 endpoint pre-commit — PASS, Smart Friend 8× CLEAN):** 2 NEW file BE-only `HrmConfigFeatures.cs` 439 LOC + `HrmConfigsController.cs` 137 LOC. Independent verify: build clean 0 warning 0 error, tests **130/130 PASS** (58 Domain + 72 Infra) baseline preserved. **Cat 1 Wire BE**: 0 mock/alert/TODO marker. 8 ConflictException throws (4 Create UNIQUE Code/composite + 4 Update Code/composite-change guard). Holiday Update line 196-198 correctly checks composite `(Year, Date)` BOTH fields trên condition `entity.Year != req.Year || entity.Date != req.Date` (not just one). Delete handler `db.X.Remove(entity)` → AuditingInterceptor.cs:56-62 auto-convert State Deleted → Modified + IsDeleted=true + DeletedAt + DeletedBy (verified file read). **Cat 2 URL routing**: 16 endpoint kebab-case exact match spec: `leave-types`/`holidays`/`shifts`/`ot-policies` (file line 19/49/79/109 verified). **Cat 3 Anti-fiddle**: chỉ 2 NEW file BE (git status confirm), 0 touch FE/Domain/EF Config/Migration/DbInitializer/test. **Cat 4 Authorization**: class-level `[Authorize]` line 15 + 12 per-action `[Authorize(Roles = "Admin")]` (4 sub-resource × 3 write verb POST/PUT/DELETE) — exact mirror CatalogsController precedent line 12-46. **Cat 5 Validator**: 8 AbstractValidator class (4 Create + 4 Update). Smart Friend fix #1 verified — MaxLength MATCH EF source-of-truth: LeaveType.Code=50 (config line 14) ✓, ShiftPattern.Code=20 (config line 14) ✓, OtPolicy.Code=50 (config line 15) ✓, all Name=200/Description=500 ✓, ShiftPattern.WorkDays=100 (config line 16) ✓. Special validators: LeaveType.DaysPerYear≥0, Holiday.Year ∈ [2000,2100], Shift.StartTime≠EndTime + BreakMinutes≥0 + WorkDays NotEmpty, OtPolicy 3 Multiplier≥1.0 + 3 MaxHours>0. **Cat 6 Cookie-cutter 12-bis 3×**: 4 region structure identical (DTO + List + Create cmd/validator/handler + Update cmd/validator/handler + Delete cmd/handler). Naming consistent ListXQuery/CreateXCommand pattern. Smart Friend fix #2 verified — 4 HRM entities NO HasQueryFilter (grep Configurations confirm 9 file HasQueryFilter NONE are HRM) → 4 List handler correctly add `.Where(!IsDeleted)` line 37/134/232/337 + 8 Create/Update Conflict check `&& !x.IsDeleted` predicate explicit. **MediatR + FluentValidation auto-scan** Application assembly (DependencyInjection.cs:14-19) — no manual DI registration needed. **Smart Friend 8× cumulative CLEAN**: (1) S22 #44, (2) S25 #48, (3) S29 password, (4) S29 ApplicableType, (5) S33 BW, (6) S33 Plan B Phase 2, (7) S35 FE forms (em main earlier), (8) S35 Plan G-H2 NOW. KHÔNG lower bar — actual catches 0 CRITICAL/MAJOR. **2 MINOR observed (defer Phase 1.5)**: (a) ListHolidaysQuery KHÔNG có `bool? IsActive` filter (chỉ Q + Year) — khác 3 query sibling có IsActive filter — inconsistent UX nhưng có thể intentional (holidays admin thường list all). (b) OtPolicy claim "1 default IsActive=true unique" (entity comment line 7) nhưng handler Create/Update KHÔNG enforce "chỉ 1 active" — admin có thể tạo nhiều IsActive=true cùng lúc. Future G-P1 attendance reference `IsActive=true` sẽ ambiguous nếu có 2+ active. Defer fix khi G-P1 implement (em main spec rõ defer phase 1.5). **Verdict: PASS proceed commit**. Token cost ~9K.
|
||||
|
||||
- **2026-05-26 (S33 Plan B G-H1 Phase 2 Task 4+5+6 pre-commit — PASS, Smart Friend 6× CLEAN):** Em main spawn em adversarial review 17 file uncommitted (3 BE new + 6 FE new + 6 FE mod + 2 Task 6 mod). **Independent verify SHA256 mirror 3 file PASS IDENTICAL**: `types/employee.ts` ccfc70666568, `EmployeesListPage.tsx` dc859c897c5c, `EmployeeCreatePage.tsx` c796f25d01ac — admin == user exact. **Cat 1 Wire BE**: 5 endpoint `GET /employees` (paged) + `GET /{id}` + `POST` (CreatedAtAction) + `PUT /{id}` (NoContent + ID match guard) + `DELETE /{id}` (soft NoContent) — tất cả real `mediator.Send`, 0 mock marker. Validator Create+Update đầy đủ (Phone MaxLen 20 + EmailAddress conditional When + decimal `.GreaterThanOrEqualTo(0)` lương/phép). Handler Create: load User (FindByIdAsync) → check existing EmployeeProfile UNIQUE (soft-deleted aware: throw ConflictException with distinct message) → atomic MaNhanVien codeGen SERIALIZABLE → entity save. Handler Get: Include 5 satellite + LEFT JOIN User/Department + projection. Handler List: filter Status + DepartmentId + Search (EmployeeCode/FullName Contains) + paging. **Cat 2 Schema**: Mig `AddEmployeeProfiles` timestamp 20260526110207 (= Mig 34 numeric by sort) — `EmployeeProfiles` + 5 satellite + `EmployeeCodeSequences` (7 table mới). UNIQUE indexes verified `IX_EmployeeProfiles_UserId` (line 309-313) + `IX_EmployeeProfiles_EmployeeCode` (line 293-297). FK Cascade Users. 6 Province/District/Ward cột plain Guid? defer FK G-H2 đúng comment. `EmployeeProfileConfiguration.cs` line 22-32 mirror Mig: UNIQUE + Cascade. MenuKeys.cs `All[]` line 108-114 đã có Hrm + HrmHoSo (line 112) — Admin auto-grant qua SeedAdminPermissionsAsync iterates All[]. DbInitializer.cs line 1484-1485 seed Hrm Order=28 + HrmHoSo Order=1 dưới Hrm parent. 28 không xung đột với Budgets=27. SeedDemoEmployeeProfilesAsync line 1945 NOT gated DemoSeed (placed OUTSIDE gate block) — đúng infrastructure pattern gotcha #51 lesson. **Cat 3 Security**: `[Authorize]` class-level present EmployeesController line 20 — no per-action policy yet (em main defer Phase 1.5). Input validation Create + Update Validator class đầy đủ. **Cat 4 Code quality**: TS6 erasableSyntaxOnly compliant — 10 enum dùng const-object pattern + `typeof X[keyof typeof X]`. Named exports (no default trừ App). Bundle size 1.43MB admin / 1.35MB user comparable baseline. ContactRound icon verified exist 5 places trong lucide-react bundle. DependencyInjection.cs line 39 registered `AddScoped<IEmployeeCodeGenerator, EmployeeCodeGenerator>`. **Cat 5 Test**: defer Phase 1.5 per em main spec UAT mode. Baseline 120/120 PASS preserved. **Smart Friend 6× cumulative CLEAN**: (1) S22 #44, (2) S25 #48, (3) S29 Plan CA password ≥12, (4) S29 Plan B ApplicableType, (5) S33 Plan C BW, (6) S33 Plan B Phase 2 NOW. KHÔNG lower bar — actual catches 0 MAJOR/CRITICAL. **3 MINOR observed (defer Phase 1.5)**: (a) Race condition EmployeeCode UNIQUE dưới SERIALIZABLE OK risk THẤP (per-year reset, mirror PE/HD pattern proven). (b) UpdateCommand 3 bool field IsCommunistParty/IsYouthUnion/IsTradeUnion không nullable → admin update partial sẽ accidentally reset (FE phải re-send all 3 every PUT — minor UX issue). (c) Delete handler `DateTime.UtcNow` direct không inject IDateTimeProvider — consistent existing PE/Contract Delete pattern, accept. **Special check verdicts**: gotcha #51 infrastructure seed gate compliance ✓ (em main cite gotcha #51 explicit comment line 1942-1944). gotcha #50 Layout staticMap mirror ✓ (Hrm_HoSo:/employees cả fe-admin line 57 + fe-user line 79). menuKeys.ts FE drift: pre-existing fe-admin minimal (16 key) vs fe-user (24 key) — em main Task 5 chỉ add Hrm 2 key cả 2 file, KHÔNG break Plan AA + Budget. Drift là pre-existing FE state intentional, không phải regression Plan B Phase 2. **Verdict**: PASS proceed commit. Token cost ~30K. Tag: `[adversarial-pass, hrm-mig34, smart-friend-6x-clean, phase-10]`.
|
||||
|
||||
- **2026-05-26 (S33 Plan C B-Wrap test bundle pre-commit — PASS, INDEPENDENT VERIFY 9/9 tests):** Em main spawn em adversarial Plan C B-Wrap Contract V2 test bundle review. 4 file mới: TestCurrentUser (31 LOC stub), ContractWorkflowServiceApproveV2Tests (BW1-4+7, 5 [Fact]), CreateContractCommandApplicableTypeTests (BW5, 1 [Fact]), ContractV2SchemaPersistenceTests (BW6 split 3 [Fact]). Total 9 [Fact]. **Independent verify ran `dotnet test --filter` → 9/9 PASS local trong 4.7s** (em main claim 120/120 baseline tăng từ 111 — verified). Spec mapping verify Cat 1: BW1 ContextNote `"Hoàn tất Cấp 1, sang Cấp 2 cùng Bước 1"` ✓ match service line 360, BW2 mã HĐ `"FLOCK01/HĐTP/SOL&BTBM/01"` ✓ match ContractCodeGenerator HĐTP format line 21, BW3 ContextNote `"Approver skip thẳng tới Bước 3 Cấp 2"` ✓ match service line 348 (lastStepIdx=2, lastLevelMaxOrder=2, prefix `[Approver skip thẳng tới Bước 3 Cấp 2 (NV cuối) — bỏ qua các Bước/Cấp trung gian]`), BW4 ForbiddenException `"Bước 1...Cấp 1: bạn không có"` ✓ match service line 263-264, BW5 ConflictException `"ApplicableType=Contract"` ✓ match handler line 84-85 (test correctly handles spec→actual exception type discrepancy: spec says ValidationException, actual ConflictException — em main inline comment line 84 docs the discrepancy), BW7 ConflictException `"skipToFinal chỉ hỗ trợ HĐ V2"` ✓ match service line 105-106. Schema verify Cat 2: Mig `AddContractLevelOpinions` (timestamp 20260522052240) actual position 33 by filename sort confirmed via Glob (33 mig + 33 designer + 1 snapshot in /Persistence/Migrations folder), spec ref "Mig 33" matches. UNIQUE composite `(ContractId, ApprovalWorkflowLevelId)` confirmed `ContractLevelOpinionConfiguration.cs:34`. FK Cascade Contract + FK Restrict Level confirmed line 27+32 + migration FK line 41+47. Test quality Cat 5: assertions specific (`Should().Be(2)` for levelOrder, `Should().Contain(...)` for substring match, `Should().ThrowAsync<X>()` with WithMessage wildcard), each [Fact] sets up fresh `IdentityFixture` + `using` disposal pattern (BW1-4+7 verbose using-block, BW6 `using var fix` shorthand — minor style inconsistency but functional same). Smart Friend independence note: **5 lần cumulative Smart Friend catches — em main + Implementer làm TỐT lần này, KHÔNG có catch MAJOR**. (1) S22 #44, (2) S25 #48, (3) S29 ApplicableType, (4) S29 DemoSeed, (5) S33 BW = clean. Implementer + em main spec mapping accurate, exact string match between assertions and service strings. **Minor (3, defer):** (a) `CreateService` helper method `ContractWorkflowServiceApproveV2Tests.cs:27-44` unused dead code — 5 [Fact] manually recreate inline (cleaner but DRY violation). Cleanup recommend Plan C-Hotfix or next test bundle. (b) `TestCurrentUser.Roles` constructor params `string[] roles` allows null → defensive `roles ?? Array.Empty<string>()` line 27 OK but C# warning shadow. (c) BW6 split 3 [Fact] cleanly separated DUPLICATE + UPSERT + Cascade per spec — 9 tests OK not over-engineer (each invariant tested isolated). **Defer noted**: ApproveV2Async still ~150 LOC, BW1-4+7 cover happy + terminal + skip + outsider + V1 fallback — Plan B-Wrap roadmap mentions BW Bonus future test: OR-of-N multi-NV (3 NV cùng Cấp 1, only 1 needs approve), idempotent UPSERT (Cấp 1 approve → reject → approve lại same row Comment update), Mig 32 seed idempotent guard. Not blocker for current bundle commit. Token cost spawn ~22K. Verdict: **PASS proceed commit** (9 [Fact] all pass independent verify, spec match service exact, schema 3 invariant tested, 0 critical/major, 3 minor cosmetic). Recommendation: commit 4 file as proposed, baseline tăng 111→120. Tag: `[adversarial-pass, test-bundle, contract-v2, smart-friend-5x-clean]`.
|
||||
|
||||
- **2026-05-26 (S33 startup — drift audit readonly, NONE actual review):** Em main spawn em S33 drift assessment 3 area (gotchas / CLAUDE.md root+docs / 4 sub-agent .md). **Verdict overall: MODERATE drift accumulated S19→S32 chưa patch** — late but not severe. Findings: (a) `docs/gotchas.md` actual count = **52 entries** (grep `^### \d+\.` confirm), claim S32 = 52 → MATCH NONE drift. #50/#51/#52 detail entries present line 883/839/924 (out-of-order numbering but content full). (b) CLAUDE.md (root) **SEVERE stale**: line 87 "Hiện có 26 migration → 59 bảng" (actual 33 mig + 60 table per S32 wrap), line 66+87 "81 test pass" (actual 111), line 133 "26 bẫy đã gặp" (actual 52). docs/CLAUDE.md line 65 "38 pitfall" stale similar. (c) 4 sub-agent .md drift mixed: cicd-monitor.md line 232-233 already patched S29 "111/111 PASS (58 Domain + 53 Infra)" + "Migrations: 33" CORRECT no drift; investigator.md line 77 "44 gotchas hiện tại" STALE +8; reviewer.md line 92 "44 active gotchas" STALE +8; implementer.md line 123+141 "baseline 81 preserve" STALE +30. **Critical drift requiring immediate patch**: CLAUDE.md root 3 stale fact (mig 26→33, test 81→111, gotcha 26→52) — agent context first-load file, drift mislead future spawns. **Optional defer 2026-06-01 audit**: 3 sub-agent .md gotcha+test count stale (cosmetic, no functional impact). Migrations folder discovery: actual path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/` not `src/Backend/SolutionErp.Infrastructure/Migrations/` — `cicd-monitor.md` line 149 path hint correct, but agents/runbooks may have stale absolute path. Token cost ~7K. Tag: `[startup-audit, drift-moderate, claude-md-severe]`. Recommendation: bro decide patch CLAUDE.md ngay (3 line edit) hoặc defer cycle audit ngày 2026-06-01.
|
||||
|
||||
- **2026-05-26 (S32 wrap — em main proxy update + Plan B-Wrap + Phase 10 pre-commit scope ahead):** Session 32 đóng clean. Em chủ trì spawn em 1 lần S32 startup verify (a0aa13093d14f3bca alive, MEMORY 24.39KB self-curated S32 dropped S27 retrospective). Smart Friend 4× cumulative preserved (S22 #44 + S25 #48 + S29 ×2 ApplicableType + DemoSeed gate). **Plan G 11 module backlog DOCUMENTED migration-todos** + Plan B-Wrap test bundle BW1-BW7 spec ready (D-Bis section). **Pending tasks em main S33 SendMessage gọi em adversarial pre-commit:** (a) **Plan B-Wrap test bundle review** — verify 7 test scenario coverage (BW1 happy path advance, BW2 terminal gen mã HĐ, BW3 skipToFinal F2 admin opt-in, BW4 ForbiddenException outsider, BW5 ApplicableType=Contract validation Cat 3 cross-module mirror, BW6 Mig 32+33 schema persistence UNIQUE composite, BW7 V1 fallback ConflictException). Smart Friend mindset: catch test scenario gap (e.g., NV skipToFinal=true but currentStepIndex already at final = silent no-op? verify guard line 337-352 ContractWorkflowService). (b) **Plan G-H1 Hồ sơ NS pre-commit review** — Mig 34 schema (1 main + 5 satellite) FK strategy + nullable validation + soft-delete pattern verify mirror PE AuditableEntity inheritance. (c) **Phase 9 UAT audit hard blocker checklist** — SMTP config Production secrets exposed? Rotate creds cycle plan token leak risk? cert expire 2026-07-23 auto-renew verify schedule task `Get-ScheduledTask -TaskName 'win-acme*'`. Token cost wrap ~3K. Tag: `[wrap, phase-9-to-phase-10, security+infra]`.
|
||||
|
||||
- **2026-05-26 (S32 startup verify — adversarial mindset ready, 0 actual review):** Em main spawn em standby cho S32. Self-verify context: MEMORY 22.50KB (23042 bytes — approaching 25KB threshold, chưa curate cần nhưng cảnh báo entry mới sẽ trigger soon), last entry 2026-05-22 13:28 S29 wrap khớp. MCP RAG `search_memory` + `cross_project_search` PRESENT cả 2 — test query "ApplicableType validation" trả rerank 0.867 (high precision match Cross-module security entry line 41-49). **Awareness S31 fixes (between sessions, em không spawn):** RAG v1.3 baseline PASS recall@5=1.000 (11/11) + retrieval.py fix, gotcha #52 NEW added — KHÔNG impact Reviewer adversarial logic (infra ops fix, không phải application code). **Awareness S29 deployed prod**: Plan CA + Plan B Contract V2 wire push successful, gotcha #51 NEW added (INFRASTRUCTURE vs DEMO seed gate — `SeedSampleContractWorkflowV2` OUT of `if (settings.DemoSeed)` gate là correct pattern infrastructure data luôn seed regardless of demo mode). **Smart Friend pattern 4× cumulative VERIFIED preserved**: (1) S22 #44 silent 403, (2) S25 #48 SQLite tie-break, (3) S29 Plan CA password ≥12 chars, (4) S29 Plan B ApplicableType cross-module. **Adversarial mindset retained pre-commit gate active**: forward cho 3 pending task em main có thể spawn em qua SendMessage — (a) Plan B-Wrap BW1-BW7 test bundle review (ApproveV2Async coverage ~150 LOC 0 unit test gap + ApplicableType validate regression test — gotcha #48 lesson SQLite tie-break apply when add Changelog rows in test setup, cần discriminator EntityType + Summary keyword); (b) ContractWorkflowMatrixView review pre-commit khi Implementer wire xong (anticipate Mirror §3.9 fe-admin + fe-user 2 file sync check, V1/V2 dual schema branch verify, permission menuKey populate sync BE+FE); (c) Phase 9 UAT hard blocker audit (SMTP outbox table + sender flow / rotate creds 5 item / SQL backup schedule daily 03:00 / win-acme cert renewal 3 cert 60d). **Token cost spawn standby ~6K**. Patterns NEW noted reinforce S32: pre-spawn checklist verify MEMORY size + freshness + MCP tools first-call before any review action (standard hygiene).
|
||||
|
||||
- **2026-05-22 (S29 wrap — Smart Friend 4× cumulative):** Plan CA (admin→eoffice 7 commits) + Plan B (Contract V2 11 commits) — 2 MAJOR catches Reviewer spawn. **CA MAJOR**: `DemoUserPassword = "User@123456"` 11 chars vs Identity policy ≥12 chars → new catalog.manager seed CreateAsync FAIL prod. Fix per-user inline conditional override `"CatalogMgr@2026"` 15 chars. **B MAJOR**: see above S29 Plan B entry. Smart Friend cumulative S22 #44 + S25 #48 + S29 CA password + S29 B ApplicableType. **Cat 3 Security checklist reinforced**: ApplicableType type guard V2 + password ≥12 chars + IsActive/IsUserSelectable re-validate. **Recommendation forward**: Reviewer spawn MANDATORY cho cross-module mirror diff (PE→Contract, PE→Budget V2 future, identity policy change). UI polish iteration em main solo OK.
|
||||
|
||||
- **Archived to `archive/2026-05-q2.md` 2026-05-27 S34 curate (em main proxy):** S29 Plan B pre-push detail (MAJOR catch ApplicableType validation — KEY lesson absorbed Cross-module security mirror foundation line 41-49) + S26 Plan AG pre-commit + AG2-AG6 em main solo + S25 Plan AB wrap (gotcha #48 lesson — foundation line 40-45) + S28 wrap Layer A governance Cat 6 add (absorbed forward 5-category baseline). Smart Friend guard 4× cumulative S22+S25+S29×2 preserved in current S33 entries.
|
||||
- **2026-05-28 (S35 G-H2 BE CRUD 16 endpoint pre-commit — PASS, Smart Friend 8× CLEAN):** 2 NEW file `HrmConfigFeatures.cs` 439 + Controller 137. build clean, 130/130 PASS. Cat1: 0 mock, 8 ConflictException (Holiday Update composite `(Year,Date)` BOTH fields). Cat3: class `[Authorize]` + 12 per-action `[Authorize(Roles="Admin")]`. Cat5: 8 Validator MaxLength MATCH EF source (Code=50 not spec 20). **2 MINOR defer:** ListHolidays no IsActive filter (inconsistent sibling) · OtPolicy "1 active unique" NOT enforced handler (G-P1 ambiguous nếu 2+ active). Verdict PASS. Tag `[s35, smart-friend-8x-clean]`.
|
||||
- **2026-05-26 (S33 Plan B G-H1 Phase 2 pre-commit — PASS, Smart Friend 6× CLEAN):** 17 file (3 BE + 6 FE new + 6 mod + 2). SHA256 mirror 3 file IDENTICAL admin==user. 5 endpoint real mediator.Send 0 mock. Mig 34 `AddEmployeeProfiles` 7 table UNIQUE indexes + FK Cascade. SeedDemoEmployeeProfiles NOT gated DemoSeed (gotcha #51 ✓). gotcha #50 Layout staticMap mirror ✓. **3 MINOR defer:** EmployeeCode race SERIALIZABLE low-risk · Update 3 bool not nullable (partial reset) · Delete DateTime.UtcNow direct. Verdict PASS. Tag `[s33, hrm-mig34, smart-friend-6x]`.
|
||||
- **Smart Friend cumulative 8× CLEAN:** (1) S22 #44 silent-403 · (2) S25 #48 SQLite tie-break · (3) S29 password ≥12 · (4) S29 ApplicableType cross-module · (5) S33 BW test · (6) S33 Plan B Phase 2 · (7) S35 FE forms · (8) S35 G-H2. Plus 9× G-O2 (S36, em không track ở đây). 2 MAJOR catches total (S29 password + S29 ApplicableType); rest clean với MINOR defer.
|
||||
- **Archived S29-S33 detail + S32 startup → `archive/2026-05-q2.md` + git d2f52ba (S40 curate):** S33 Plan C B-Wrap 9/9 [Fact] verify · S33 startup drift audit (CLAUDE.md SEVERE → patched S40) · S32 wrap/startup standby · S29 wrap 2 MAJOR catch detail. KEY absorbed in bug patterns + Smart Friend cumulative above.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Curate trigger
|
||||
|
||||
- Memory size > 25KB → archive recent entries to `archive/<period>.md`
|
||||
- Duplicate entries detected → merge
|
||||
- Stale > 3 months → remove
|
||||
|
||||
**Last curate: 2026-05-27 S34 em main proxy curate** (post-S33 wrap, sequence 1/4) — archived 3 verbose entries (S26 Plan AG + S25 Plan AB wrap + S28 Layer A governance Cat 6 add) → `archive/2026-05-q2.md`. KEEP: S33 Plan B G-H1 Phase 2 pre-commit (Smart Friend 6× clean), S33 Plan C B-Wrap pre-commit (9/9 [Fact] verified), S33 startup drift audit (CLAUDE.md SEVERE), S32 wrap (Plan B-Wrap pre-commit scope ahead), S32 startup, S29 wrap (Smart Friend 4× cumulative), S29 Plan B pre-push (1 MAJOR catch ApplicableType). 5-category checklist + Cat 6 Authority boundary check + Smart Friend guard + Cross-module security validation mirror pattern (NEW S29 foundation) preserved. MEMORY size before: 28.5 KB → after: target ~20-22 KB. **Previous curate: 2026-05-26 S32 startup** drop S27 retrospective. Next curate trigger: > 25KB OR Plan G-O1 Danh bạ kick off.
|
||||
- >25KB → archive recent → `archive/<period>.md`. Stale >3mo → remove.
|
||||
- **Last curate: 2026-05-29 S40 em main proxy** (28.4→~18KB): archived S33 Plan C + S33 startup + S32×2 + S29 wrap detail → q2 + git d2f52ba; refreshed stale (81/111→130 test, 47→55 gotcha, 31→40 mig, ~146→211 endpoints). Foundation (bug patterns + 5-category + Smart Friend guard + cross-module security) preserved. Prev: S34 q2 · S22 q1.
|
||||
|
||||
Reference in New Issue
Block a user