All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m8s
Số dư phép theo (User × LeaveType × Year) + trừ tự động khi đơn nghỉ duyệt cuối. Policy: cho phép vượt số dư (âm) + cảnh báo (anh main chốt), tích hợp vào trang đơn nghỉ. Schema (Mig 42 AddLeaveBalances — pure additive, 1 bảng): - LeaveBalance: UserId + LeaveTypeId + Year + EntitledDays + UsedDays + AdjustmentDays. UNIQUE (UserId,LeaveTypeId,Year), FK LeaveType Restrict, decimal(5,2). Remaining = Entitled + Adjustment − Used (computed, không store). Deduction hook (ApproveLeaveRequestHandler nhánh terminal DaDuyet — exactly-once): - Upsert LeaveBalance(RequesterUserId, LeaveTypeId, StartDate.Year), auto-create từ LeaveType.DaysPerYear, UsedDays += NumDays. Guard Status!=DaGuiDuyet chặn re-approve. FK invariant guard (em main thêm sau test reveal FK risk): - Create + UpdateDraft validate LeaveTypeId tồn tại (AnyAsync) → ConflictException. Đóng cửa vào — bogus type không thể tới deduction FK insert (tránh 500 kẹt đơn). CQRS LeaveBalanceFeatures.cs: GetMy (self, lazy merge active LeaveType) + GetUser (admin) + AdjustLeaveBalance (admin upsert carry-over). Controller [Authorize] + admin Roles=Admin. Embed: GetLeaveRequestByIdHandler trả balance NGƯỜI TẠO (approver xem thấy đúng). FE: WorkflowAppDetailPage ×2 — block "Số dư phép" + cảnh báo vượt khi kind=leave (SHA256 identical). Tests (+11, 130→154 PASS): deduction single/multi-level/accumulate/negative-allowed/ reject-return-no-deduct + lazy-merge + adjust upsert + Create guard bogus→Conflict. Cũng repair 2 test S42 terminal FK-fail (template BuildLeave +seed LeaveType). Verify: build 0 error · 154 test · FE ×2 · reviewer Max PASS (deduction exactly-once + FK invariant fully closed, 2 minor concurrency/comment defer). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
3.8 KiB
Markdown
55 lines
3.8 KiB
Markdown
# Implementer-Frontend Agent — Persistent Memory
|
||
|
||
> **Persistent diary cross-session.** Auto-injected first 200 lines / 25KB at spawn.
|
||
> 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).
|
||
> **NEW agent S39 (2026-05-29)** — split từ implementer (FE 2 app half). Backend scaffold history ở `implementer-backend`.
|
||
|
||
---
|
||
|
||
## 🎯 Role baseline
|
||
|
||
WRITE specialist FE 2 app (fe-admin + fe-user). Cookie-cutter mirror SHA256 IDENTICAL + Pattern 16-bis 4-place + declarative KIND_CONFIG + npm build × 2. Case 1+2 only. Tools: Read, Edit, Write, Bash, Skill, Grep, Glob + 5 RAG. Skill: `permission-matrix`.
|
||
|
||
## 🚫 Split boundary
|
||
- ✅ MINE: `fe-admin/src/**` + `fe-user/src/**`
|
||
- ❌ NOT: `src/Backend/**` → `implementer-backend` (chỉ Read DTO shape) · tests/ → `test-specialist`
|
||
- ❌ NOT: UX flow decision (drawer/tab/modal) → em main solo
|
||
|
||
## 📋 Patterns proven (apply confidently)
|
||
|
||
### Pattern 16-bis 4-place mirror (9× cumulative — BLESSED FOUNDATION)
|
||
Add/move page cross-app MUST mirror 4 places:
|
||
1. Page/types file · 2. `App.tsx` Route · 3. `lib/menuKeys.ts` const · 4. ⚠️ `components/Layout.tsx` `resolvePath` staticMap (**DỄ MISS** → silent sidebar drop gotcha #50)
|
||
Verified clean S33/S34/S35/S36/S37/S38 = 9× cumulative. Spec MUST list 4 places explicit.
|
||
|
||
### SHA256 IDENTICAL × 2 app
|
||
Viết fe-admin → `cp` fe-user → `sha256sum` verify. Khác UX (admin full sidebar vs user filter) → mirror tay + `diff`. Proven S36 (3 pair) + S37 (4 pair) + S38 (5 pair).
|
||
|
||
### Declarative KIND_CONFIG Record (S35, 2× proven)
|
||
Single-page multi-kind CRUD URL `:kind` param + `Record<Kind, {fields, columns, icon, label}>` + renderField switch FieldType. Reuse: HrmConfigs (S35) + WorkflowApps (S38).
|
||
|
||
### Pattern 14 Tailwind JIT palette
|
||
Dynamic class purged. PALETTE array full literal `as const` cycle `index % length`.
|
||
|
||
### TS6 / convention
|
||
- `erasableSyntaxOnly` cấm enum → `const X = {...} as const` + `type X = typeof X[keyof typeof X]`
|
||
- Named export only (trừ App). UI 100% tiếng Việt.
|
||
- **PageHeader signature (S37):** `title/description/actions` only — KHÔNG `icon` / `children` prop (build fail TS2322)
|
||
- fe-user thiếu Card/Badge shadcn → fallback inline `<div className="rounded-lg border bg-card">`
|
||
|
||
## ✅ Verify protocol
|
||
`cd fe-admin && npm run build` + `cd fe-user && npm run build` BOTH 0 TS error + `sha256sum` mirror proof. Bundle >500KB warning OK pre-existing.
|
||
|
||
## 📅 Recent activity (last 10 FIFO)
|
||
|
||
- **2026-05-30 (S42 P11-B Wave 2 — leave balance display):** WorkflowAppDetailPage.tsx + workflowApps.ts (2 app SHA256 identical). +3 optional `leaveBalance{Entitled,Used,Remaining}?: number|null` trong `// leave` block (BE `decimal?` → camelCase). Block "Số dư phép" sau Section 1 IIFE `kind==='leave' && d.leaveBalanceRemaining != null`: year từ StartDate, banner amber/red khi `remaining<0 || (status!==DaDuyet && remaining<numDays)`. Case 1, KHÔNG 4-place (enrich existing page). cp fe-admin→fe-user. Build PASS ×2 (page 8ef83e4b, type 1c4f167a). Lesson reuse: IIFE inline `(() => {...})()` cho conditional block có derived vars — sạch hơn tách helper.
|
||
- **2026-05-29 (S39 agent split setup):** NEW agent từ split implementer. Seeded FE patterns (16-bis 9× + SHA256 mirror + KIND_CONFIG + Tailwind palette + PageHeader S37). Prior FE work absorbed: S33 EmployeesListPage + S34 Directory + S35 HrmConfigs declarative + S36 MeetingCalendar + S37 Proposal + S38 WorkflowApps generic.
|
||
|
||
---
|
||
|
||
## ⚠️ Anti-patterns (DO NOT)
|
||
1. ❌ Touch BE files · 2. ❌ Miss 4th Layout staticMap · 3. ❌ Skip npm build × 2 · 4. ❌ `git add -A` · 5. ❌ Push remote · 6. ❌ UX decision autonomous → REFUSE
|
||
|
||
## 🔄 Curate trigger
|
||
Size > 25KB → archive. Commit scope (em main commits): `FE-Admin` · `FE-User`.
|