10 KiB
IMPLFE-GD3: BLOCKED
Lane FE GĐ3 — áp cây 4-folder GĐ lên cụm "Duyệt hợp đồng"
Spawn: implementer-frontend @S167 (2026-08-01). Owner slot 55 "Nên đồng nhất".
Rào: chỉ fe-admin/src + fe-user/src. KHÔNG BE, KHÔNG commit.
Kết quả: BLOCKED tại §0 — 0 file chạm. Không phải "không làm được", mà là: khuôn 3 trang kia KHÔNG PORT sang trang GĐ3 nếu không có 1 quyết định bố cục của em-main. Mirror y-hệt (prepend cột 19rem) là hỏng ĐO ĐƯỢC ở 1366 (số bên dưới), và hỏng CÂM — build vẫn xanh.
§0 — ĐO ĐĨA (làm trước khi gõ; bài học #1)
§0.1 Khuôn S162 bfc7b79 áp lên trang HÌNH DẠNG NÀO
| Trang khuôn | Vỏ ngoài | Cách áp |
|---|---|---|
pe/PurchaseEvaluationsListPage.tsx (GĐ1) |
trang giấy-cuộn, đã CÓ cây trái riêng | nhét PipelineStageFolders vào TRONG cây sẵn có, stage1Content giữ nguyên khối leaf cũ |
khkk/KhkkListPage.tsx (GĐ2) |
trang giấy-cuộn (space-y, thẻ card) |
bọc grid gap-5 lg:grid-cols-[19rem_minmax(0,1fr)] xl:grid-cols-[21rem_…] + <PipelineTreePanel currentStage={2}/> |
contracts/HardCopiesPage.tsx (GĐ4) |
trang giấy-cuộn | y hệt trên, currentStage={4} |
Neo đo: fe-admin/src/pages/khkk/KhkkListPage.tsx:197 · …/HardCopiesPage.tsx:116 — CẢ HAI
là grid gap-5 lg:grid-cols-[19rem_minmax(0,1fr)], tức trang trôi theo chiều dọc, cột trái
chỉ ăn bề ngang.
§0.2 Trang GĐ3 là trang nào (lead hỏi: 1 trang chung hay 7 file?)
Trả lời: 1 COMPONENT TRANG dùng chung cho cả 7 loại HĐ, lọc bằng ?type=N — KHÔNG phải 7 file.
Bằng chứng: fe-user/src/components/Layout.tsx:143-153 regex ^Ct_([^_]+)_(List|Create|Pending|WfView|Approved|Deleted)$
→ mọi loại đều trỏ CÙNG 1 route + đổi query.
| App | File trang | Route | Leaf Ct_* trỏ tới |
Vỏ ngoài |
|---|---|---|---|---|
| fe-admin | pages/contracts/ContractsListPage.tsx (254 dòng) |
/contracts |
List Create Pending (Layout.tsx:117-125) |
3-panel cao-cố-định |
| fe-user | pages/contracts/MyContractsPage.tsx (231 dòng) |
/my-contracts |
List Approved Deleted |
3-panel cao-cố-định |
| fe-user | pages/InboxPage.tsx (352 dòng) |
/inbox |
Pending (= đúng nghĩa "đang duyệt") |
3-panel + dải stats |
| fe-user | pages/pe/WorkflowMatrixViewPage.tsx |
/contracts/workflow-matrix?type=3&ct=N |
WfView |
dùng chung PE/KHKK |
fe-admin KHÔNG có MyContractsPage, KHÔNG có InboxPage, KHÔNG có WorkflowMatrixViewPage
(cố ý — Layout.tsx:138-142).
§0.3 🔴 Ba lệch so với tiền-đề đề bài
A-1 (CHẶN — bố cục): trang GĐ3 ×2 app KHÔNG phải trang giấy-cuộn. Cả 3 đều là
flex h-[calc(100vh-4rem)] flex-col + grid flex-1 overflow-hidden lg:grid-cols-[320px|340px_1fr_360px]
(ContractsListPage.tsx:105,124 · MyContractsPage.tsx:104,135 · InboxPage.tsx:165,188).
Khuôn 19rem_minmax(0,1fr) không có chỗ cắm: bọc grid ngoài thì cột trái cao 100vh cạnh
một khối đã tự cuộn trong; prepend cột vào chính grid 3-panel thì:
Sidebar app =
w-72/xl:w-80(Layout.tsx:499user,:372admin) = 288/320px. Grid 3-panel không cógap⇒ cộng thẳng.
Bề ngang màn Vùng nội dung Panel 2 (chi tiết HĐ) HÔM NAY Sau khi thêm cột cây 19rem (304px) 1366 1046 346px 42px ⛔ 1536 1216 516px 212px ⛔ 1920 1600 900px 596px ✅ Panel 2 render
ContractDetailContent(form chi tiết HĐ đầy đủ). 42px = chết trang. Chính khuôn S162 đã lo đúng bề ngang này: commentKhkkListPage.tsx:198-200"bảng 7 cột không thổi vỡ lưới ở 1366".
Cơ chế thu gọn có sẵn của PipelineTreePanel KHÔNG cứu được: nút "Hiện cây / Ẩn cây" là
lg:hidden (PipelineTreePanel.tsx:197) — chỉ sống DƯỚI lg, tức đúng dải mà panel 2/3 đã bị
hidden lg:block. Ở desktop panel luôn mở, không có chế độ đóng.
⇒ Đây là "thiếu prop cho GĐ3" theo đúng ngoại lệ lead nêu, nhưng nới prop nào (collapsible?
defaultCollapsed? mở ra thì ĐẨY hay PHỦ?) là quyết định UX ⇒ trả về em-main (refuse-criteria #1
"page layout", anti-pattern #7).
A-2 (CHẶN NHẸ — phạm vi): "trang GĐ3" ×2 app không đối xứng. fe-admin có ĐÚNG 1 ứng viên
(ContractsListPage); fe-user có 3 (MyContractsPage = danh sách · InboxPage = Pending,
đúng nghĩa "đang duyệt" nhất · WorkflowMatrixViewPage). Khuôn cho mỗi GĐ đúng 1 trang ⇒ phải
chốt trang nào. (Tôi nghiêng MyContractsPage — nó là cặp đối xứng của ContractsListPage.)
A-3 (KHÔNG chặn — tiền-đề "SHA-pair identical" bất khả thi): yêu cầu "mirror ×2 app SHA-pair identical cho MỌI file chạm" KHÔNG áp được cho cặp trang GĐ3: hai app dùng file KHÁC TÊN, KHÁC RUỘT, lệch sẵn từ trước, không phải do lượt này.
792cc373… fe-admin/src/pages/contracts/ContractsListPage.tsx (254 dòng, có Select phase + phân trang)
768728e3… fe-user/src/pages/contracts/MyContractsPage.tsx (231 dòng, có view "Đã xóa" + nút Tạo HĐ)
Đối chứng DƯƠNG cho phép đo hash (cùng lệnh, cùng lượt, ra BẰNG NHAU — chứng phép đo không mù):
d70ac315… = d70ac315… components/pipeline/PipelineTreePanel.tsx (admin = user)
bed52f39… = bed52f39… components/pipeline/PipelineStageFolders.tsx (admin = user)
76e18233… = 76e18233… hooks/usePipelineStages.ts (admin = user, ĐÃ gồm K7 aaed699)
e4cb0bbb… = e4cb0bbb… pages/contracts/HardCopiesPage.tsx (admin = user, trang khuôn GĐ4)
⇒ SHA-pair chỉ khả thi cho component/hook (vốn đã bằng). Với trang GĐ3 phải đổi sang bằng chứng
diff khối chèn + khai lệch tại chỗ (bài học #10).
§0.4 Bối cảnh mới hôm nay — fe-admin GĐ3 đã BỊ ẨN khỏi sidebar
fe-admin/src/components/Layout.tsx:227-240 (K6 — S166, land HÔM NAY 2026-08-01):
ADMIN_HIDDEN_KEYS chứa 'Contracts' (GĐ3 root) + 'HopDongCung' (GĐ4 root) + luật prefix
key.startsWith('Ct_') (:248). filterForAdmin lọc ĐỆ QUY ⇒ toàn bộ lối vào GĐ3 trên
sidebar fe-admin đã chết; /contracts chỉ còn vào được bằng deep-link.
Hệ quả cho lượt này: nửa fe-admin của việc là trang không ai thấy trên menu. Không sai (route
còn sống, và tiền lệ HardCopiesPage fe-admin cũng đang ở đúng tình trạng đó từ K6), nhưng lead
nên biết TRƯỚC khi trả công: "đồng nhất ×2 app" hôm nay ≠ "2 app cùng dùng được".
§1 — 4 đường đi, để em-main chốt 1 chữ
| # | Cách | Panel 2 @1366 | Đụng file khuôn? | Ghi chú |
|---|---|---|---|---|
| A | prepend cột 19rem vào grid 3-panel |
42px ⛔ | không | mirror chữ-nghĩa đúng nhất, hỏng thật |
| B | cột cây chỉ hiện ≥2xl, dưới đó ẩn hẳn |
346px (không có cây) | không | 1366/1536 = KHÔNG có cây ⇒ "đồng nhất" chỉ đúng ở màn to |
| C | nới PipelineTreePanel +chế độ thu gọn desktop (nút "Cây toàn trình" ở đầu cột, GĐ3 mặc định ĐÓNG) |
346px khi đóng | CÓ (2 file SHA-pair) | đúng ngoại lệ "thiếu prop cho GĐ3"; còn 1 câu hỏi: mở ra thì ĐẨY panel hay PHỦ lên |
| D | cây thay chỗ Panel 3 khi chưa chọn HĐ | 346px | không | Panel 3 đang là ô trống "Quy trình duyệt sẽ hiện khi chọn HĐ" ⇒ tận dụng chỗ đã trống, nhưng cây nhảy chỗ khi chọn HĐ |
Tôi nghiêng C (giữ được "đồng nhất" ở MỌI bề ngang, không cướp chỗ của chi tiết HĐ, và là
lần nới prop DUY NHẤT dùng lại được cho InboxPage nếu sau này áp tiếp). Nhưng C sửa file
SHA-pair dùng chung 4 trang khác ⇒ không tự quyết.
§2 — UAT-NÓI-TRƯỚC (ghi sẵn cho lượt ship, chưa dùng tới)
- Prod hiện 0 HĐ (lead khẳng định — tôi KHÔNG tự đo prod lượt này) ⇒ khi cây GĐ3 lên, mọi gói thầu sẽ hiện folder "Duyệt Hợp đồng" rỗng + chip SẮP. Đó là ĐÚNG SPEC, cùng lớp K5, không phải lỗi nối dữ liệu.
- Phân biệt 2 cái im khác nhau: folder rỗng vì gói CHƯA có HĐ (chip SẮP) ⟂ folder khoá vì
tài khoản không có quyền
Contracts/Ct_*_List(usePipelineStages.ts:58,328— khoá thì KHÔNG gọi API). Đọc nhầm ổ khoá thành "chưa có dữ liệu" là bẫy quen. - Nguồn dữ liệu GĐ3 đã là TẬP
contractIds(unionpe.contractIdlegacy +khkkPlanContractIds) sau K7 —usePipelineStages.ts:293-299. Không cần sửa hook cho lượt GĐ3 này.
§3 — Bằng chứng "0 chạm"
$ git status --porcelain fe-admin/src fe-user/src
(rỗng — xem §4 dòng chạy cuối)
Không chạy npx tsc -b / npm run build: 0 file thay đổi ⇒ build chỉ đo lại baseline của
aaed699, không chứng minh được gì về lượt này. Đổi lại, git status rỗng là bằng chứng MẠNH
HƠN cho "không để lại việc dở".
§4 — Đã chạm / đã đo
- Đọc:
bfc7b79(diff 3 trang khuôn) ·aaed699(diffusePipelineStages) ·PipelineTreePanel.tsx·PipelineStageFolders.tsx·usePipelineStages.ts(bản đĩa, đã gồm K7) ·ContractsListPage.tsx·MyContractsPage.tsx·InboxPage.tsx(đầu file + grid) ·Layout.tsx×2 app (khốiresolvePath+ADMIN_HIDDEN_KEYS) ·App.tsx×2 app (routes). - Ghi: DUY NHẤT file artifact này.
END implfe-gd3 — VERDICT=BLOCKED (§0 chặn: A-1 bố cục 3-panel không nhận khuôn cột-19rem, số đo 1366 → Panel 2 còn 42px; A-2 fe-user có 3 ứng viên trang; A-3 cặp trang GĐ3 khác file nên SHA-pair identical bất khả thi). 0 file chạm. Cần em-main chốt 1 trong 4 đường ở §1 (tôi nghiêng C) + chốt trang đích ở A-2, rồi tôi scaffold trong 1 lượt.