Files
solution-erp/docs/changelog/sessions/2026-05-15-s24-turn1-plan-aa-workflow-matrix.md
pqhuy1987 e23f51c42e [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>
2026-05-16 00:18:48 +07:00

23 KiB
Raw Blame History

Session 24 turn 1 — 2026-05-15 — Plan AA User Workflow Matrix view + Sidebar widen

Dev: Claude Opus 4.7 1M (em main + 3 sub-agent spawn) Duration: ~2h Base commit: 86d8806 (Plan U S23 t11 sidebar truncate) Final HEAD: <this Docs commit> (after ee776d5 Chunk A + c667802 Chunk B) Total commits Plan AA: 3 (A BE+Layout + B FE page + C Docs)

🎯 Trigger session

Bro UAT screenshot 2026-05-15 ~15:40, sau Plan U S23 t11 deploy:

Cho hiển thị đầy đủ nhé, cần thì sliderbar to 1 chút cũng đc. Với thêm 1 menu là: Luồng duyệt phía trên Danh sách → Hiển thị ma trận phân quyền của cấu hình quy trình duyệt trong admin page ra ngoài để User có thể biết đc (Chú ý chỉ những quy trình có ghim).

2 yêu cầu:

  1. Sidebar widen + revert truncate — Plan U S23 t11 vừa add truncate + tooltip "..." → bro muốn hiển thị đầy đủ label custom Mig 27 (DisplayLabel admin set).
  2. Menu "Luồng duyệt" + matrix view page — read-only cho user xem cấu hình workflow V2 ghim trước khi tạo phiếu.

🌳 Q&A clarify (2 lượt)

Câu User chốt
Permission strategy BE Relax class-level [Authorize] (gotcha #44 fix permanent từ S18) + server-side filter IsUserSelectable=true cho non-admin. Reuse endpoint hiện có, KHÔNG duplicate logic.
Matrix display layout Table 2D full 7 Allow cột* (Bước/Cấp/NV/Mô tả + 7 cột flag Trả lại 4 mode + Edit Section 2 + Edit Budget + Skip Cấp cuối). User thấy đầy đủ quyền per slot Approver giống admin Designer read-only.

🔍 Pre-A Investigator audit (🟦, ~32K tokens)

5Q audit verify trước code:

Q Verdict
Q1 Endpoint permission Gotcha #44 đã fix permanent từ S18 (2026-05-08). Class-level chỉ [Authorize] bare, per-method admin Workflows.Create. Handler GetAwAdminOverviewQuery KHÔNG có IsUserSelectable filter — cần ADD param + conditional.
Q2 Menu seed pattern DbInitializer.cs:1429-1437 peOrder global increment. Permission seed 1541-1547 cho 7 role. Accounting KHÔNG trong list (admin manual grant).
Q3 Admin Designer FE ApprovalWorkflowsV2Page.tsx 975 lines. 7 Allow* VI labels có sẵn line 892-948. AwLevelDto 13 fields. KHÔNG có usePermission wrap.
Q4 Sidebar widen impact w-72 xl:w-80 (288/320px) SAFE — sidebar 288 + main 992 → workspace 260+732 fit @ 1280px. w-80 xl:w-96 THRESHOLD RISKY.
Q5 ApplicableType enum {DuyetNcc=1, DuyetNccPhuongAn=2, Contract=3}. FE wire 2 type PE.

Surprises critical:

  • ⚠️ PE Workspace là 2-panel không phải 3-panel → memory feedback_responsive_laptop_breakpoint.md stale, sẽ update memory sau Plan AA.
  • 📝 Order strategy: "Luồng duyệt" Order=2 first → cần shift existing leaves +1 → DbInitializer cần UPDATE Order existing (KHÔNG chỉ INSERT-if-not-exists).
  • 🔸 Contract=3 chưa wire FE — chỉ DuyetNcc + DuyetNccPhuongAn.

🌳 Plan AA execution 3 chunk per-commit

Chunk A — BE filter + menu seed + sidebar widen (ee776d5)

👤 Chủ trì Solo — Cross-stack tight coupling architectural decision. 6 files +73/-24 LOC.

BE changes (4 files)

MenuKeys.cs:85 thêm helper:

// [Plan AA S24 t1] User read-only view ma trận phân quyền của workflow V2
// admin Designer đã ghim (IsUserSelectable=true). Suffix _WfView distinct
// với admin PeWf_* (Designer write).
public static string PurchaseEvaluationWorkflowView(string typeCode) => $"Pe_{typeCode}_WfView";

DbInitializer.cs:1429-1437 thêm tree.Add LuongDuyet (Order=2 first child) cho 2 type PE:

tree.Add((MenuKeys.PurchaseEvaluationGroup(code), label, ..., peOrder++, "FileCheck"));
// [Plan AA S24 t1] "Luồng duyệt" leaf phía trên "Danh sách"
tree.Add((MenuKeys.PurchaseEvaluationWorkflowView(code), "Luồng duyệt", ..., peOrder++, "Network"));
tree.Add((MenuKeys.PurchaseEvaluationList(code), "Danh sách", ..., peOrder++, "List"));
tree.Add((MenuKeys.PurchaseEvaluationCreate(code), "Thao tác", ..., peOrder++, "Plus"));
tree.Add((MenuKeys.PurchaseEvaluationPending(code), "Duyệt", ..., peOrder++, "CheckCircle2"));

DbInitializer.cs:1447-1459 refactor INSERT-only loop → INSERT-OR-UPDATE-Order:

var existingItems = await db.MenuItems.ToDictionaryAsync(m => m.Key);
foreach (var (key, label, parent, o, icon) in tree)
{
    if (existingItems.TryGetValue(key, out var existing))
    {
        if (existing.Order != o) { existing.Order = o; reordered++; }
        continue;
    }
    db.MenuItems.Add(new MenuItem { Key = key, ... });
}

Idempotent: skip nếu Order match, UPDATE nếu mismatch. Shift existing prod rows Order+1 safe.

DbInitializer.cs:~1553 SeedPurchaseEvaluationPermissionDefaultsAsync thêm WfView vào menuKeys list cho 7 role Read.

ApprovalWorkflowV2AdminFeatures.cs:89-110 GetAwAdminOverviewQuery + handler:

public record GetAwAdminOverviewQuery(
    int? ApplicableType = null,
    bool? IsUserSelectable = null) : IRequest<AwAdminOverviewDto>;

// Handler:
if (request.IsUserSelectable is bool ius)
    query = query.Where(d => d.IsUserSelectable == ius);

ApprovalWorkflowsV2Controller.cs:21-26 pass-through:

public async Task<ActionResult<AwAdminOverviewDto>> Overview(
    [FromQuery] int? applicableType,
    [FromQuery] bool? isUserSelectable,
    CancellationToken ct)
    => Ok(await mediator.Send(new GetAwAdminOverviewQuery(applicableType, isUserSelectable), ct));

FE Layout changes (2 files mirror rule §3.9)

fe-user/src/components/Layout.tsx:78 resolvePath regex extend:

const peMatch = key.match(/^Pe_([^_]+)_(List|Create|Pending|WfView)$/)
// ...
if (action === 'WfView') return `/purchase-evaluations/workflow-matrix?type=${typeInt}`

fe-user + fe-admin Layout.tsx:

  • Sidebar w-60 xl:w-72w-72 xl:w-80 (+48px lg, +32px xl)
  • Revert Plan U S23 t11 truncate × 5 sites:
    • fe-user: MenuGroup line 188 + MenuLeaf line 251 + StaticLeaf line 292
    • fe-admin: MenuGroup line 148 + MenuLeaf line 208
  • Keep min-w-0 flex-1 parent + shrink-0 icon/chevron + title tooltip (no harm — accessibility bonus)

Verify Chunk A: dotnet build SolutionErp.slnx PASS clean 0 err 2 warn pre-existing DocxRenderer.

Chunk B — FE WorkflowMatrixViewPage (c667802)

🟨 Implementer Case 2 — Cookie-cutter mirror Designer Designer read-only single file. 3 files +305 LOC.

NEW fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx ~215 LOC

// useQuery GET /approval-workflows-v2?applicableType=N&isUserSelectable=true
// PageHeader "Luồng duyệt — {label}" + Network icon
// Loading/Error/Empty 3 state rõ ràng
// WorkflowCard per ghim version:
//   header: code/version + badge "Đang dùng" emerald + "Được ghim" amber Pin
//   table 10 cột read-only:
//     Bước rowSpan | Cấp | NV duyệt + 7 Allow* flag (✓ emerald / — slate)
// FlagCell helper TS indexed-access type union 7 keys

NEW fe-user/src/types/approvalWorkflowV2.ts ~55 LOC

Subset DTO mirror BE AwAdminOverviewDto:

  • AwLevelDto 13 fields (7 Allow*)
  • AwStepDto, AwDefinitionDto, AwTypeSummaryDto, AwAdminOverviewDto
  • Field name khớp BE record positional param (history not versions)

MODIFIED fe-user/src/App.tsx +2 LOC

import { WorkflowMatrixViewPage } from '@/pages/pe/WorkflowMatrixViewPage'
// trong <Routes>:
<Route path="/purchase-evaluations/workflow-matrix" element={<WorkflowMatrixViewPage />} />

Verify Chunk B: npm run build fe-user PASS clean 0 TS err, 1907 modules, 2.61s, bundle 1282 KB.

Chunk C — Cumulative Reviewer + Docs (this commit)

🟥 Reviewer adversarial pre-commit cumulative ~25K tokens:

Category Verdict
Wire BE/feature claim verify End-to-end Controller → Mediator → Handler → FE useQuery wired
Schema integrity 0 Mig mới, DbInitializer idempotent, 7 Allow* count match
Security Class-level [Authorize] preserved, GET any-auth OK, POST admin policy. 1 Low note: non-admin pass isUserSelectable=false leak workflow chưa ghim (defer follow-up)
Code quality BE 0 err + fe-user PASS + fe-admin PASS 1926 modules 740ms 0 TS err (Reviewer tự verify bonus)
Test coverage Accept Phase 9 UAT exception per feedback_uat_skip_verify

Anti-fiddle: 0% drift, ~346 LOC khớp spec. Mirror 2 FE app §3.9: Sidebar widen + remove truncate mirror cả 2 ✓. WorkflowMatrixViewPage fe-user only (admin Designer riêng). Smart Friend guard: Active, 0 critical/major/minor blocker.

Docs deliverables Chunk C

  • docs/STATUS.md Recently Done newest entry S24 t1
  • docs/HANDOFF.md Last updated S24 t1 prepend
  • docs/changelog/sessions/2026-05-15-s24-turn1-plan-aa-workflow-matrix.md (file này)
  • .claude/agent-memory/investigator/MEMORY.md FIFO entry S24 Pre-A
  • .claude/agent-memory/implementer/MEMORY.md FIFO entry S24 Chunk B
  • .claude/agent-memory/reviewer/MEMORY.md FIFO entry S24 cumulative verify

📊 Stats Plan AA chốt

Metric Trước (S23 t12) Sau (S24 t1) Δ
Migrations 31 31 0 (no Mig mới)
DB tables 59 59 0
Endpoints ~145 ~146 +1 (GET filter param)
FE pages 34 35 +1 (WorkflowMatrixViewPage)
Unit tests 111 111 0 (UAT mode skip)
Gotchas 47 47 0
Memory entries user-level 21 21 0 (no new — recommend memory responsive update sau)
Skills 6 6 0
Sub-agents 4 4 (3 spawn S24 t1)
Commits Plan AA 3 ee776d5 (A BE+Layout) · c667802 (B FE) · this (C Docs)

🎯 Multi-agent ROI Plan AA

Spawn Cost Verdict Catch / Value
🟦 Investigator Pre-A ~32K 5Q audit + 3 surprises (PE 2-panel + Order strategy + Contract enum unwired). Saved em main blind code 4 wrong assumptions.
🟨 Implementer Chunk B ~14K 3 files +305 LOC cookie-cutter Designer read-only mirror. Build PASS. shadcn fe-user no Card/Badge fallback inline div pattern.
🟥 Reviewer Chunk C ~25K 0 critical/major/minor block. Bonus catch fe-admin build (~7s) verify mirror app PASS. 1 Low note non-admin filter leak workflow chưa ghim defer.
👤 Chủ trì Solo Chunk A + coordinate ~80K BE 4 file + Layout 2 file cross-stack architectural decisions. Order shift refactor INSERT→UPDATE idempotent.

Total cost cumulative Plan AA: ~150K (~25% solo equiv). Multi-agent leverage cache 70-90% per session.

📋 Pattern reinforced

  1. Gotcha #44 relax class-level [Authorize] PROVEN cross-stack reuse — Workflows endpoint từ admin-only sang any-auth read accessible. Mảnh pattern reusable cho future read-only user view (Form template view, Department list view, etc.).

  2. DbInitializer INSERT-OR-UPDATE-Order pattern — Idempotent re-deploy safe shift existing prod rows. Cross-project reusable cho menu re-ordering / label rename / icon change without migration.

  3. Plan U truncate revert pattern — widen container + drop truncate + keep min-w-0 flex-1 + shrink-0 + title tooltip. Reusable cross-project sidebar / nav menu / breadcrumb.

  4. Read-only admin Designer mirror page — Implementer Case 2 pattern: drop edit mutations + reuse types + filter via query param. Reusable cho future user view của admin config (Role permission view, Workflow template view, etc.).

⏭ Pending S24+

  • 🟢 Bro UAT verify Plan AA deploy sau ~3-5 phút CI Run #210+
  • 🟩 CICD Monitor spawn post-deploy verify bundle hash 2 app + smoke endpoint ?isUserSelectable=true + DbInitializer Order shift idempotent
  • 🟡 Plan B Contract V2 wire (Mig 32+33) — HIGH priority next (pre-allocated 5-6 chunk in HANDOFF)
  • 📝 Memory feedback_responsive_laptop_breakpoint.md update: PE Workspace 2-panel (NOT 3-panel) — defer Chunk D bonus
  • 🔍 Discovery #3 anomaly CI trigger docs-only (3× reinforced) — Investigator follow-up
  • 🔍 Discovery #4 ASP.NET enum body deserialization (LOW polish)
  • 🔧 Gotcha #47 paths-ignore agent-memory (pending bro chốt)
  • ⚠️ Security follow-up: BE enforce isUserSelectable=true mandatory cho non-admin (Reviewer Low note)

References


🔁 Phase 2 — Polish iteration UAT feedback (4 commit post Plan AA core)

Sau Run #210 deploy Plan AA core (3 commit ee776d5..ac2c859), bro UAT iterate 4 polish chunks back-to-back theo visual feedback. Em main solo 4× CSS/UX polish (KHÔNG spawn agent — criteria #6 < 30 min trivial + criteria #2 UX decision).

Polish 1 — Hotfix container px-2 (da218f1)

Trigger: Bro UAT: "cho nó dịch hết sang bên trái nhé"

Container space-y-4 px-6 py-5space-y-4 px-2 py-5 (24px → 8px). PageHeader + WorkflowCard + Table cùng shift left -16px sát sidebar border.

Verify: npm run build fe-user PASS 486ms, bundle 1282.59 KB unchanged.

Polish 2 — Redesign v1 panel-per-NV color (4d60598)

Trigger: Bro UAT screenshot admin Designer: "cho hiển thị rõ ràng các thông tin như thế này luôn. Giữa các cấp duyệt khác nhau cho màu sắc khác nhau, Giữa các phòng ban khác nhau cho màu sắc khác nhau."

Drop table 11 cột symbol khó hiểu (↶/✎/) → panel-per-NV mirror admin Designer line 853-949:

  • Step (Phòng) container có unique color cycle 5 màu (STEP_PALETTE: blue/purple/emerald/amber/pink)
  • Cấp badge ring có unique color cycle 5 màu (LEVEL_PALETTE: violet/sky/teal/orange/rose)
  • "QUYỀN DUYỆT {NV name} {email}" header amber-700 uppercase
  • 7 checkbox label tiếng Việt nguyên văn (read-only disabled + accent-emerald)
  • Grid grid-cols-1 sm:grid-cols-2 cho 4 return mode + col-span-2 cho 3 long label

Tailwind JIT discipline: Palette arrays với full class strings (KHÔNG dynamic interpolation bg-${color}-100 — JIT purge):

const STEP_PALETTE = [
  { bg: 'bg-blue-50/40', border: 'border-blue-200', headerBg: 'bg-blue-100', headerText: 'text-blue-800' },
  // ... 4 more
] as const

Verify: npm run build fe-user PASS 423ms, bundle 1282.91 KB (+0.32 KB).

Polish 3 — Redesign v2 HTML table rowSpan tận dụng full width (fbbd361)

Trigger: Bro UAT: "Đúng rồi hiển thị như vậy nhưng dạng table cho đẹp và rõ ràng, tận dụng hết toàn bộ layout rộng"

Refactor panel-per-NV → HTML <table> 4 cột với rowSpan:

┌────────────────┬──────┬──────────────┬─────────────────────────────────────┐
│ Bước (Phòng)   │ Cấp  │ NV duyệt     │ Quyền duyệt (grid 2-col 7 checkbox) │
├────────────────┴──────┴──────────────┴─────────────────────────────────────┤
│ Bước 1 (Phòng Cung ứng) - Step bg blue - rowSpan 5                         │
│                          ├ Cấp 1 - rowSpan 4 OR-of-4 ├ NV 1 ├ 7 checkbox  │
│                                                       ├ NV 2 ├ 7 checkbox  │
│                                                       ├ NV 3 ├ 7 checkbox  │
│                                                       ├ NV 4 ├ 7 checkbox  │
│                          ├ Cấp 2 - rowSpan 1          ├ NV 5 ├ 7 checkbox  │
│ Bước 2 (Phòng Kiểm soát) - Step bg purple - rowSpan N                      │
│ ...                                                                        │
└────────────────────────────────────────────────────────────────────────────┘

Helper buildStepRows(step) build flat Row[] với metadata: (isFirstInStep, isFirstInCap, rowSpanStep, rowSpanCap). Render flat <tr> với conditional <td rowSpan={}>.

colgroup width hint: 160px / 100px / 240px / 1fr (rest). Tại 1280-1366px viewport: Quyền duyệt cell ~400-500px → grid md:grid-cols-2 fit 7 label OK.

Color preserved 2 layer (Step bg + Cấp badge cycle). NV + Quyền duyệt cell bg-white/80 lighten Step tone.

Verify: npm run build fe-user PASS 522ms, bundle 1284.22 KB (+1.31 KB).

Polish 4 — Wrap fix sidebar label về đầu hàng (ee0902a)

Trigger: Bro UAT screenshot sidebar: "1. Duyệt Nhà Cung Cấp - Thầu phụ" wrap 2 dòng với dòng 2 "(NCC -TP)" indent sau icon thay vì về đầu hàng. "Cho nó về đầu hàng nhé, thu nhỏ lại cũng đc."

Root cause: Flex container items-center + inner-flex [icon][text] → 2nd line wraps within INNER SPAN (indent past icon area).

Fix pattern (5 sites: 3 fe-user + 2 fe-admin mirror §3.9):

  • Restructure flex → block + inline-block icon + inline text + absolute ChevronDown right
  • inline-block icon + inline text share single line box → wrap continuation text về left edge container
  • ChevronDown absolute để KHÔNG bị đẩy xuống khi label wrap multi-line
- <span className="flex min-w-0 flex-1 items-center gap-2">
-   <Icon className="h-4 w-4 shrink-0" />
-   <span title={label}>{label}</span>
- </span>
- <ChevronDown className="h-3.5 w-3.5 shrink-0 ..." />

+ <Icon className="mr-1.5 -mt-0.5 inline-block h-4 w-4 align-middle" />
+ <span className="align-middle" title={label}>{label}</span>
+ <ChevronDown className="absolute right-2 top-2 ..." />

Smaller text scale:

  • MenuGroup non-top button: text-[13px]text-[12px] leading-snug
  • MenuLeaf top level: text-smtext-[12px] leading-snug
  • MenuLeaf deep: text-[12px]text-[11px] leading-snug
  • StaticLeaf: text-smtext-[12px] leading-snug

Verify: npm run build fe-user PASS 432ms + fe-admin PASS 494ms.


📊 Stats S24 chốt cuối cumulative

Metric S23 t12 chốt S24 chốt Δ
Migrations 31 31 0 (Plan AA no Mig mới)
DB tables 59 59 0
Endpoints ~145 ~146 +1 (GET filter param isUserSelectable)
FE pages 34 35 +1 (WorkflowMatrixViewPage)
Unit tests 111 111 0 (UAT mode skip, baseline confirmed post-Plan AA)
Gotchas 47 47 0
Memory user-level 21 21 0 (no new — pattern captured trong agent MEMORY)
Skills 6 6 0
Sub-agents 4 4 (4 spawn S24)
Commits S24 7 ee776d5..ee0902a push remote

🎯 Multi-agent ROI S24 cumulative

Owner Cost Verdict Value catch
🟦 Investigator Pre-A ~32K 5Q audit + 3 surprises (PE 2-panel correction + Order shift strategy + Contract enum unwired). Saved em main 4 blind code assumptions.
🟨 Implementer Chunk B ~14K 3 files +305 LOC mirror Designer read-only. shadcn no Card/Badge → fallback inline div pattern.
🟥 Reviewer Chunk C ~25K 0 blocker. Bonus catch fe-admin build verify mirror app PASS.
🟩 CICD Monitor Run #210 ~12K 4/4 wire verify + bundle rotate + Order shift idempotent confirm prod.
🟦🟨🟥 3 agent S24 wrap flush ~12K Cumulative MEMORY drift patches (Implementer +3 patterns 13/14/15, Reviewer +4 anti-patterns, Investigator +1 entry).
👤 Chủ trì Solo Chunk A + 4 polish + coordinate ~80K BE 4 file + Layout 2 file + 4 polish iteration UAT feedback ~250 LOC cumulative.

Total cost cumulative S24: ~175K (~28% solo equiv). Cache leverage 70-90% per session.


📋 Patterns reinforced (cross-project reusable)

  1. Gotcha #44 relax class-level [Authorize] PROVEN cross-stack reuse — Workflows endpoint từ admin-only sang any-auth read accessible (cumulative S18 → S24). Pattern reusable cho future user view của admin config.

  2. DbInitializer INSERT-OR-UPDATE-Order idempotent pattern — Shift existing prod rows Order qua re-deploy without migration. Add existingItems = ToDictionaryAsync(m => m.Key) + UPDATE if mismatch logic. Cross-project reusable cho menu re-order / label rename / icon change.

  3. Tailwind JIT palette array pattern — Full class strings (KHÔNG dynamic interpolation bg-${color}-100). const PALETTE = [{bg: 'bg-blue-50/40', ...}, ...] as const cycle theo idx % length. Cross-project reusable cho menu hierarchy color coding, status badge, category tone.

  4. HTML table rowSpan flat row builder helper — Build Row[] với metadata (isFirstInStep + isFirstInCap + rowSpanStep + rowSpanCap). Cleaner than nested loop. Cross-project reusable cho hierarchical data table (org chart, BOM, schedule).

  5. Hanging-indent reverse CSS fix — Sidebar label dài wrap về đầu hàng (under icon) via inline-block icon + inline text + absolute right ChevronDown. Drop flex container wrapper. Cross-project reusable cho long-label nav menu / breadcrumb / list item.

  6. Read-only admin Designer mirror page — Implementer Case 2 pattern: drop edit mutations + reuse types + filter via query param. Cross-project reusable cho future user view của admin config (Role permission view, Workflow template view).

  7. UI/UX polish iteration discipline — UAT visual feedback iteration KHÔNG cần Reviewer spawn mỗi chunk (cost overhead ROI thấp). BUNDLE cumulative verify cho heavy chunk, SKIP < 30 min polish (criteria #6 + #2 REFUSE). S24 validated: ~25K bundle vs ~100K multi-spawn polish.


⏭ Pending S25+

  • 🟢 Bro UAT verify Plan AA polish iteration cumulative qua 4 deploy Run #211-#214
  • 🟡 Plan B Contract V2 wire (Mig 32+33) — HIGH priority next (pre-allocated 5-6 chunk in HANDOFF cũ S23)
  • 📝 Implementer agent MEMORY curate — ~31.5KB > 25KB threshold, archive S20-S22 old entries → archive/2026-05-S20-S22.md. Defer next session spawn.
  • 📝 CICD Monitor agent MEMORY curate — ~43KB also over threshold, archive Run #186-#200 old entries.
  • 🔍 Discovery #3 anomaly CI trigger docs-only (3× reinforced S23) — defer Investigator follow-up
  • 🔍 Discovery #4 ASP.NET enum body deserialization (LOW polish)
  • 🔧 Gotcha #47 paths-ignore agent-memory (pending bro chốt)
  • ⚠️ Security follow-up Low note: BE enforce isUserSelectable=true mandatory non-admin (Reviewer Low note) — defer