5.3 KiB
5.3 KiB
sub-reviewer-diff-tongquan — soi đối kháng diff fe-user/src/pages/UserDashboardPage.tsx (S159 L8)
Run:
2026-07-29-S159-tong-quan-pipeline-menu· vai: reviewer (adversarial, READ-only) Vật soi:git diff -- fe-user/src/pages/UserDashboardPage.tsx— 728 dòng (585+/143−), 1 file. 🔴 Ghi đĩa TRONG LÚC LÀM (chống #53). Mỗi FLAG ghi ngay khi tìm ra, không đợi cuối. 🔴 Giới hạn đã khai: KHÔNG live-verify (route/dashboardcần login, FE chưa deploy) ⇒ toàn bộ kết luận là soi TĨNH trên diff + đọc file nguồn BE/FE + đọc route/type. Mọi phát biểu về hành vi runtime là suy luận từ mã, đã đánh dấu rõ chỗ nào chưa chứng được.
0 — Xác nhận phạm vi (đã chạm đĩa, không tin lời khai)
git diff --stat→ đúng 1 filefe-user/src/pages/UserDashboardPage.tsx, 585+/143−. ✅ khớp lệnh.git status --porcelain→ các file M khác (WAL.md,docs/STATUS.md,docs/HANDOFF.md,scripts/*,.claude/commands/*) không thuộc vật soi, đúng như FD khai là của lead. 0 filefe-admin/**bị chạm. ✅ ràng buộc "fe-user ONLY" THOẢ.- Named export
UserDashboardPagegiữ nguyên (dòng context không đổi trong hunk@@ -113,20 +351,180 @@phía trên). ✅ - 0 dependency mới (chỉ thêm icon
lucide-reactđã có sẵn). ✅
A — Những claim của FD tôi đã ĐỘC LẬP kiểm và XÁC NHẬN ĐÚNG (không phải tin lời)
| Claim | Kiểm bằng | Kết quả |
|---|---|---|
Paged<T> có total, không có totalCount |
fe-user/src/types/master.ts:1-9 |
✅ ĐÚNG — lead brief ghi totalCount là SAI, FD đính chính đúng |
phase là query-param BE thật |
PurchaseEvaluationsController.cs:23 [FromQuery] PurchaseEvaluationPhase? phase |
✅ |
PurchaseEvaluationPhase.DaDuyet === 7 |
fe-user/src/types/purchaseEvaluation.ts:28 |
✅ |
pendingMe KHÔNG phải query-param BE; /inbox trả mảng phẳng |
PurchaseEvaluationsController.cs:30-35 trả List<...> (không PagedResult) |
✅ — dùng .length là đúng |
/reports/my-dashboard chỉ đếm bảng Contracts ⇒ gán GĐ3 đúng nghĩa |
GetMyDashboardQuery.cs — mọi query đi từ db.Contracts |
✅ |
.icon-chip có size nội tại 2.25rem ⇒ bỏ h-9 w-9 là no-op |
index.css:128-137 |
✅ |
h1..h4 + .stat-value là rule unlayered ⇒ phải dùng ! để đè màu |
index.css:79-83 + :140-146 — cả 2 set color, KHÔNG set font-size |
✅ và FD áp ! ĐÚNG CHỖ: text-brand-800! / text-brand-700! / text-accent-600! / text-slate-600!. text-base / text-[15px] không cần ! vì 2 rule đó không set font-size — tôi đã đọc để bác giả thuyết "chữ phình to". |
Mọi stop màu dùng đều CÓ THẬT trong @theme |
index.css:7-51 — brand 50-900 · teal 50/100/500/600/700 · violet · amberx · accent 500/600 |
✅ 0 stop ma (không có -800 của teal/violet/amberx nào bị dùng) |
.label-eyebrow = brand-600 chỉ 4.42:1 |
tự tính lại luminance từ #1f7dc1 |
✅ 4.41 — số FD khai đo được và đúng, né sang text-brand-700 là hợp lý |
slate-500 = 4.76:1 (FD ghi 4.8) |
tự tính từ #64748b |
✅ |
Button có size="sm" + gap-1.5 sẵn ⇒ bỏ mr-1 là đúng |
fe-user/src/components/ui/button.tsx |
✅ |
1 file, 0 file fe-admin/**, 0 dep mới, named export giữ |
git diff --stat + đọc file |
✅ |
Giả thuyết tôi TỰ ĐẶT RA rồi TỰ BÁC (ghi lại để khỏi ai đào lại):
- "Số GĐ1 là toàn hệ thống còn GĐ3 là của riêng tôi ⇒ lệch phạm vi, user đọc sai tỷ lệ rơi rụng" → BÁC: cả 2 endpoint đều IDOR-scoped per-user (
PurchaseEvaluationFeatures.cs:596-614+ContractFeatures.cs:297-303). Cùng phạm vi ⇒ so sánh được. - "
Chờ tôi duyệtGĐ1 =inbox.lengthsẽ LỚN HƠN số ở màn đích vì màn đích lọc thêm client-sideDaGuiDuyet" (PurchaseEvaluationsListPage.tsx:211-212) → BÁC: BE inbox chỉ trả phase ∈ {ChoPurchasing, ChoDuAn, ChoCCM, ChoCEODuyetPA, ChoCEODuyetNCC, ChoDuyet} (PurchaseEvaluationFeatures.cs:731-742,762), tất cả đều map vềDaGuiDuyet(purchaseEvaluation.ts:105-110) ⇒ bộ lọc client là no-op, 2 số khớp nhau. - "
?phase=7/?pendingMe=1là URL bịa, màn đích không đọc" → BÁC:PurchaseEvaluationsListPage.tsx:37,45,95đọc cả 2. Route/purchase-evaluations,/my-contracts,/inboxđều có thật trongApp.tsx:50,58,59. - "queryKey mới đè cache trang list" → BÁC: trang list dùng
['pe-list', {...}]/['pe-detail', id]; key mới là['pipeline-pe-approved']/['pipeline-pe-inbox']— không giao. - "bắn request bão" → BÁC:
main.tsx:7-14refetchOnWindowFocus:false,retry:1; +2 request đúng trần ≤3. - "chia 0 / NaN khi rỗng" → BÁC: diff không có phép chia nào;
value ?? 0chặn undefined. - "skeleton che cả pipeline" → BÁC: loading là per-row (
StageStatRow), khung 4 GĐ luôn render.