Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-implfe-k7.md
2026-08-01 12:11:32 +07:00

61 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

IMPLFE-K7: IN-PROGRESS
# Lane FE K7 — bridge KHKK→HĐ (vá-1 FE · vá-16 · vá-4b) — S167 2026-08-01
## §0 ĐO TRƯỚC KHI GÕ (đĩa, không đoán)
**git status TRƯỚC-Write** (`git status --short`): 8 file dirty + 1 untracked, **TẤT CẢ thuộc `.claude/*` + `docs/STATUS.md`** (của lead) — `src/Backend`, `fe-admin`, `fe-user` **SẠCH 0 dòng** (`git status --short -- src/Backend fe-admin fe-user` → rỗng). HEAD = `1c6d77a [CLAUDE] FE-Admin: K6 …`.
**Đo hiện trạng nút bridge trên màn KHKK (2 app):**
```
grep -rn -i -E "vào HĐ|create-contract|bridge|contractId" fe-user/src/pages/khkk fe-admin/src/pages/khkk
→ 0 HIT ⇒ CHƯA CÓ nút bridge nào (W6-S161 KHÔNG dựng phần này)
```
Tiền lệ DUY NHẤT đang sống = bridge PE: `POST /purchase-evaluations/{id}/create-contract`
(`PurchaseEvaluationsController.cs:339-343`, body `CreateContractFromEvaluationBody:379`), FE gọi ở
`components/pe/PeDetailTabs.tsx:2186`.
**Baseline SHA256 (trước sửa) — 3 cặp mirror ĐỀU identical:**
| file | SHA256 (cả 2 app) |
|---|---|
| `src/hooks/usePipelineStages.ts` | `edff9931…94a19ac` |
| `src/types/khkk.ts` | `7a99b865…6f22b6` |
| `src/pages/khkk/KhkkDetailPage.tsx` | `1863153b…95f16be` |
**Chữ ký hook quyền THẬT** (`src/hooks/usePermission.ts:14-26`, 2 app identical):
`usePermission()` trả `{ can(menuKey, action: CrudAction = 'Read') }`**KHÔNG** phải
`usePermission('X','Y')` như đề bài viết. Dùng `const { can } = usePermission()` rồi
`can('KeHoachKyKet','Read') && can('Contracts','Create')`.
---
## §1 [vá-4b] Cây GĐ3/GĐ4 nối qua TẬP — `usePipelineStages.ts` (fe-user XONG, `npx tsc -b` EXIT 0)
**Trạng thái đo được TRƯỚC:** K5 (S166) đã đổi HÌNH DẠNG sẵn (`Set contractIdsOfPackage` + ghi chú
"chỗ cắm nguồn thứ hai") nhưng **chỉ có 1 nguồn** `pe.contractId`. Lượt này CẮM nguồn 2.
- `types/khkk.ts`: +`KhkkListItemDto.lineContractIds?: string[] | null` (OPTIONAL — xem KHỚP-DTO)
+`khkkPlanContractIds(plan)` gom 2 nguồn (`lineContractIds` `lines[].contractId`) — **1 hàm duy
nhất** để BE đổi tên thì sửa 1 chỗ, không vá rải.
- `usePipelineStages.ts`: `contractIdsOfPackage` = `pe.contractId` (legacy) **** `khkkPlanContractIds(k)`
cho mọi phiếu KHKK của gói, dedupe bằng `Set` (2 nguồn CỐ Ý chồng nhau ở HĐ đầu).
`fallbackName` tra CẢ 2 nguồn (HĐ đến từ KHKK thì `peItems` không trỏ tới nó → trước đây rơi về `null`).
- **Sai-thầm-lặng → thấy được:** BE chưa trả field ⇒ nguồn 2 im, mà "im vì chưa nối" trông y hệt "im vì
gói chưa có HĐ". `console.warn` DEV-only **1 lần/phiên** (cờ module `warnedMissingLineContractIds`)
khi có phiếu `DaDuyet`**mọi** phiếu `lineContractIds == null`. BE trả `[]` (gói chưa có HĐ) thì IM
— phân biệt được vắng-field ⟂ rỗng-thật.
### 🔴 KHỚP-DTO (lead đối chiếu khi lane BE trả)
| Vế | Đo được trên đĩa lúc 2026-08-01 | FE làm gì |
|---|---|---|
| `KhkkLineDto.contractId` | ✅ **ĐÃ CÓ 2 phía**: FE `types/khkk.ts:201` · BE `ContractSigningPlanLineDto:74 Guid? ContractId` | không phải thêm gì |
| Line-contract-id trên **LIST** payload | ❌ **KHÔNG CÓ**: `ContractSigningPlanListItemDto:34-64` (17 field) không mang contract-id nào; `KhkkListItemDto` cũng không có `lines[]` | FE thêm **`lineContractIds?: string[]`** (optional) |
| Endpoint bridge | ❌ chưa tồn tại lúc đo (`0 hit` grep `create-contract` phía KHKK) | FE gọi `POST /contract-signing-plans/{id}/create-contract` theo `sub-invest-fable-b2-cum3.md §K7.1:23,54` |
⚠️ **Tên `lineContractIds` là FE chọn** (BE-lane K7 sở hữu tên thật). Nếu BE đặt khác ⇒ sửa **đúng 1 hàm**
`khkkPlanContractIds()` trong `types/khkk.ts` ×2 app. Nếu BE **không** expose trên list ⇒ cây vẫn chạy
bằng nguồn legacy + có chuông DEV (không vỡ, không im).
END implfe-k7 — VERDICT=IN-PROGRESS