[CLAUDE] Docs: Session 24 chốt cuối - Plan AA cumulative 7 commits + 4 agent MEMORY drift wrap
S24 wrap deliverables:
Docs:
- docs/STATUS.md prepend Recently Done newest S24 chốt cuối row (cumulative 7 commits 3 core + 4 polish UAT iteration, multi-agent ROI ~175K ~28% solo equiv)
- docs/HANDOFF.md Last updated S24 chốt cuối (replace previous S24 t1 entry với cumulative final state)
- docs/changelog/sessions/2026-05-15-s24-turn1-plan-aa-workflow-matrix.md EXTEND
- Phase 2 Polish iteration UAT feedback section (4 commit detail):
- Polish 1 da218f1 hotfix container px-2
- Polish 2 4d60598 redesign v1 panel-per-NV color mirror Designer
- Polish 3 fbbd361 redesign v2 HTML table rowSpan tận dụng full width
- Polish 4 ee0902a wrap fix sidebar label về đầu hàng (hanging-indent reverse)
- Stats S24 chốt cuối table
- Multi-agent ROI cumulative S24 table (6 owner)
- 7 Patterns reusable cross-project saved
- Pending S25+ checklist
4 agent MEMORY drift (3 agent flushed cumulative S24 wrap + 1 CICD prior Run #210):
- .claude/agent-memory/investigator/MEMORY.md S24 Pre-A entry + memory drift note
- .claude/agent-memory/implementer/MEMORY.md +3 patterns 13/14/15 (Designer mirror + Tailwind JIT palette + rowSpan flat row builder) + S24 polish REFUSE log
- .claude/agent-memory/reviewer/MEMORY.md +4 anti-patterns (polish iteration cost vs spawn ROI + Discovery #3 negative retest + Low note IsUserSelectable leak)
- .claude/agent-memory/cicd-monitor/MEMORY.md Run #210 PASS entry (Plan AA verify 4/4 wire end-to-end)
⚠️ Implementer + CICD Monitor agent MEMORY both over 25KB curate threshold (~31.5KB + ~43KB).
Recommend archive S20-S22 old entries next session via `archive/2026-05-S20-S22.md`.
User-level memory: NO update needed per §6.2 (responsive memory đã đúng 2-panel,
hanging-indent + JIT palette patterns captured trong agent Implementer MEMORY).
Test verify post-Plan AA: 111/111 PASS unchanged (58 Domain + 53 Infra). No regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -162,6 +162,89 @@ Pattern reusable: test PE workflow → 1 Step + 2 Levels + N approvers per Level
|
||||
|
||||
Tránh API surface bloat. Reusable cho future guard / helper internal cần test.
|
||||
|
||||
### Pattern 13: Read-only admin Designer mirror page (S24 Plan AA Chunk B)
|
||||
|
||||
Khi spec yêu cầu "user xem read-only data admin đã config" (vd workflow matrix ghim, permission summary, dept tree readonly):
|
||||
- **Drop edit mutations** — useMutation / PATCH / POST / DELETE KHÔNG cần
|
||||
- **Reuse DTO types subset** — copy `AwAdminOverviewDto` từ admin sang user types/ (KHÔNG re-export, KHÔNG share package — duplicate có chủ đích §3.9)
|
||||
- **Filter via query param BE-side** — `?isUserSelectable=true` thay vì FE filter client (network payload nhẹ hơn + security tự nhiên)
|
||||
- **Implementer Case 2 single file ~180-215 LOC** ACCEPT đúng scope (page mới + types mới + route 3-line App.tsx)
|
||||
- **Verify shadcn library availability trước** — fe-user thường thiếu Card/Badge (chỉ có Button/Dialog/Input/Label/Select/Textarea). Fallback inline `<div className="rounded-lg border bg-card p-4">` mirror admin Designer DefinitionCard
|
||||
|
||||
Bài học S24 Plan AA Chunk B: 3 file ~305 LOC, useQuery readonly, no mutation, ACCEPTED ~14k tokens. Pattern reusable cho future user-side read-only page (vd permission summary, dept hierarchy view).
|
||||
|
||||
### Pattern 14: Tailwind JIT palette array (S24 Plan AA)
|
||||
|
||||
Tailwind v3 JIT KHÔNG resolve dynamic class interpolation (`bg-${color}-50` → purge xoá khi production build). Solution: PALETTE array với full class strings literal.
|
||||
|
||||
```ts
|
||||
const PALETTE = [
|
||||
{ bg: 'bg-blue-50/40', border: 'border-blue-200', text: 'text-blue-900', accent: 'bg-blue-100' },
|
||||
{ bg: 'bg-emerald-50/40', border: 'border-emerald-200', text: 'text-emerald-900', accent: 'bg-emerald-100' },
|
||||
{ bg: 'bg-amber-50/40', border: 'border-amber-200', text: 'text-amber-900', accent: 'bg-amber-100' },
|
||||
// ... 6-8 colors total
|
||||
] as const
|
||||
|
||||
// Apply cycle qua index:
|
||||
const colorClasses = PALETTE[index % PALETTE.length]
|
||||
<div className={`${colorClasses.bg} ${colorClasses.border}`}>...</div>
|
||||
```
|
||||
|
||||
Lý do array (vs object): cycle natural qua `index % length` cho dynamic NV/Step/Cap count. Lý do `as const`: TypeScript narrow literal type tránh `string`.
|
||||
|
||||
Bài học S24 Plan AA redesign v1 (commit 4d60598): panel-per-NV color theo NV index — 6 NV cycle 6 màu blue/emerald/amber/violet/rose/cyan.
|
||||
|
||||
### Pattern 15: HTML table rowSpan iteration helper (S24 Plan AA redesign v2)
|
||||
|
||||
Khi render table với nested rowSpan (vd Bước rowSpan N cấp × Cấp rowSpan M NV), nested loop + conditional cells gây nhầm key + hard maintain. Solution: flat row builder helper với metadata flags.
|
||||
|
||||
```ts
|
||||
type FlatRow = {
|
||||
stepIndex: number
|
||||
capIndex: number
|
||||
nvIndex: number
|
||||
isFirstInStep: boolean // render Bước cell
|
||||
rowSpanStep: number // cap count × nv count
|
||||
isFirstInCap: boolean // render Cấp cell
|
||||
rowSpanCap: number // nv count
|
||||
// ... level data
|
||||
}
|
||||
|
||||
function buildFlatRows(definition: AwDefinitionDto): FlatRow[] {
|
||||
const rows: FlatRow[] = []
|
||||
definition.steps.forEach((step, si) => {
|
||||
const stepNvCount = step.levels.reduce((sum, lv) => sum + lv.users.length, 0)
|
||||
step.levels.forEach((cap, ci) => {
|
||||
cap.users.forEach((nv, ni) => {
|
||||
rows.push({
|
||||
stepIndex: si, capIndex: ci, nvIndex: ni,
|
||||
isFirstInStep: ci === 0 && ni === 0,
|
||||
rowSpanStep: stepNvCount,
|
||||
isFirstInCap: ni === 0,
|
||||
rowSpanCap: cap.users.length,
|
||||
// ...
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
return rows
|
||||
}
|
||||
|
||||
// Render flat:
|
||||
{rows.map(row => (
|
||||
<tr key={`${row.stepIndex}-${row.capIndex}-${row.nvIndex}`}>
|
||||
{row.isFirstInStep && <td rowSpan={row.rowSpanStep}>{step.name}</td>}
|
||||
{row.isFirstInCap && <td rowSpan={row.rowSpanCap}>{cap.name}</td>}
|
||||
<td>{nv.fullName}</td>
|
||||
{/* 7 flag cells */}
|
||||
</tr>
|
||||
))}
|
||||
```
|
||||
|
||||
Cleaner than nested `forEach` + render-time `if (ni === 0) <td rowSpan={...}>`. Easier debug (console.log rows array thấy structure rõ).
|
||||
|
||||
Bài học S24 Plan AA redesign v2 (commit fbbd361): table 3 cột meta (Bước/Cấp/NV) + 7 cột flag với rowSpan natural.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Anti-patterns observed (DO NOT)
|
||||
@ -204,6 +287,7 @@ KHÔNG `*` / `latest`. Critical pins:
|
||||
|
||||
## 📅 Recent activity (last 10 FIFO)
|
||||
|
||||
- **2026-05-15 (S24, Plan AA wrap):** Cumulative learning post-Chunk B. **3 patterns NEW added** (13 read-only admin Designer mirror, 14 Tailwind JIT palette array full class strings, 15 HTML table rowSpan flat row builder helper). **REFUSE log 4/4 correct** S24 polish chunks (commit da218f1 hotfix px-2 trivial < 30min criteria #6, 4d60598 redesign v1 panel-per-NV color UX flow criteria #2, fbbd361 redesign v2 table rowSpan UX flow criteria #2, ee0902a wrap fix sidebar label CSS polish criteria #6) — em main solo executed all 4, Implementer no-spawn. **Ambiguity Chunk B**: shadcn fe-user thiếu Card/Badge (lib subset minimal — chỉ Button/Dialog/Input/Label/Select/Textarea) → fallback inline `<div className="rounded-lg border bg-card p-4">` + inline `<span className="rounded-full bg-...">` mirror admin Designer DefinitionCard. Pattern reusable cho fe-user pages requiring elevated UI surface (audit shadcn fe-user/src/components/ui/ TRƯỚC khi import). Total S24 commits: 7 (a1a910f..ee0902a — 1 spawn Chunk B accepted + 6 em main solo: Chunk A cross-stack + Chunk C docs + 4 polish). Token cost cumulative S24 Implementer: ~14k (Chunk B only).
|
||||
- **2026-05-15 (S24, Plan AA Chunk B PASS):** FE user read-only matrix view workflow V2 ghim (Mig 25 IsUserSelectable). 3 file: (1) CREATE `fe-user/src/types/approvalWorkflowV2.ts` (~55 LOC) — subset DTO mirror BE `AwAdminOverviewDto` (7 Allow* flag per Level, 5 record type AwLevelDto/AwStepDto/AwDefinitionDto/AwTypeSummaryDto/AwAdminOverviewDto); (2) CREATE `fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx` (~215 LOC) — useQuery GET `/approval-workflows-v2?applicableType=N&isUserSelectable=true` (em main BE Chunk A đã thêm `IsUserSelectable bool?` param + Controller forward), render table 10 cột Bước (rowSpan) | Cấp | NV duyệt | 7 ✓/— flag cell, header với `title` tooltip mô tả từng cột, 3 state Loading/Error/Empty rõ ràng, badge `Đang dùng` (emerald isActive) + `Được ghim` (amber isUserSelectable Pin icon); (3) UPDATE `fe-user/src/App.tsx` — import WorkflowMatrixViewPage + route `/purchase-evaluations/workflow-matrix` đặt TRƯỚC `/workspace` (URL ordering logical matrix → workspace → new → detail). Verify: `npm run build` fe-user PASS clean 0 TS err, 1907 modules, 2.61s, 1282 KB. Surprise: shadcn fe-user KHÔNG có `Card`/`Badge` (chỉ có Button/Dialog/Input/Label/Select/Textarea) → fallback inline `<div className="rounded-lg border...">` + inline `<span className="rounded-full bg-...">` cho badge (mirror pattern admin Designer). Pattern reusable: **read-only mirror admin Designer page** = drop edit mutations + reuse DTO types (subset) + filter param BE-side (`IsUserSelectable=true` thay vì FE filter). Cookie-cutter 0 (lần đầu pattern). Pattern 5 mirror 2 app KHÔNG apply (fe-admin có Designer riêng — Plan AA scope fe-user only). Pattern 7 admin opt-in 7 Allow* flag wire full render trong table (10 cột total = 3 meta + 7 flag). KHÔNG ops git. Token cost ~14k.
|
||||
- **2026-05-15 (S23 t4-t11 cumulative REFUSE — em main solo Plan N+O+P+Q+R+S+T+U):** 8 plan consecutive em main solo, 0 Implementer spawn (REFUSE 100% per criteria #4 bug fix reasoning chain + criteria #3 cross-stack tight coupling). **Plan N+O** 5 lookup site discrimination fix cross-stack BE Service + Application + 3 regression test. **Plan P** Controller TransitionPeBody record drop fix tightly coupled FE wire audit (Investigator confirm BE-only scope ~6 LOC). **Plan Q** FE banner mx-5 layout CSS polish 2 app mirror trivial 8 LOC. **Plan R+S+T5** destructive sqlcmd cleanup prod (scripts/plan-r-*.sql + plan-s-*.sql + plan-t5-*.sql + plan-t-backup.sql, 4 files scp + sqlcmd -i, ~720 rows wiped cumulative). **Plan T** DbInitializer DemoSeed:Disabled flag config (Infrastructure + Api appsettings, ~25 LOC). **Plan U** FE sidebar truncate + tooltip 2 app mirror 25 LOC (em main solo CSS Tailwind). 7 strict-scope criteria validated cumulative S23: pattern reusable saved memory user-level — Plan O wire 9 surface points (point 9 lookup discrimination 5 sites enum), Plan P wire 10 surface points (point 10 Controller body record mirror count check), Plan T DemoSeed flag pattern.
|
||||
- **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.
|
||||
|
||||
Reference in New Issue
Block a user