wal: flush 20260712T1454

This commit is contained in:
pqhuy1987
2026-07-12 14:54:18 +07:00
parent d95bb0e210
commit d19ea13ae1
9 changed files with 291 additions and 7 deletions

View File

@ -6,6 +6,13 @@
---
## 🆕 2026-07-12 — Supplier import Excel FE (Phase B Approach A) ×2 app byte-identical (lead chốt UX; BE done+450 tests)
NEW `components/master/SupplierImportDialog.tsx` (folder `master/` MỚI cả 2 app) + wire `pages/master/SuppliersPage.tsx` (nút "Import Excel NCC" outline cạnh "Thêm NCC" trong PageHeader actions flex + render dialog). KHÔNG 4-place mirror — dialog trên page ĐÃ routed → no new route/menuKey/Layout.
- **Flow:** .xlsx → POST `/suppliers/import/preview` multipart field `file` → preview. `layoutValid===false`→alert đỏ+warnings, ẩn nút xác nhận. Else: badge counts (New/Update/Skip/Error) + warnings amber + `<table>` raw (Dòng·StatusBadge·Mã·Tên·Loại·Thông báo). "Xác nhận nhập" disabled `errorCount>0` → POST `/import/confirm` body `{rows}` = echo `preview.rows` VERBATIM. committed→toast+`invalidateQueries(['suppliers'])`+close; !committed→alert `errors[]`.
- **BE contract (Read-only DTO):** enum serialize = **INT** (chỉ UtcDateTimeJsonConverter đăng ký, KHÔNG JsonStringEnumConverter) → `type` 1-6 reuse `SupplierTypeLabel`, `status` RowImportStatus 0-3 const-object; camelCase wire (default web JSON); confirm bind positional record `(IReadOnlyList Rows)`. Round-trip 30 field verbatim → TS type partial vẫn OK runtime.
- **Mirror lesson (tái xác nhận S97-badge):** Dialog (fe-user gradient title bar) + PageHeader + types/master (khác MỖI `Department.parentId` admin-only S65) ĐỀU DIVERGED 2 app — NHƯNG import alias-path `@/…` + symbol-signature giống → new file VẪN byte-identical. Byte-identical SuppliersPage cũ (build 2 app) = proof mọi symbol tương thích. UI: KHÔNG shadcn Badge/Alert/Table primitive (chỉ PhaseBadge) → inline Tailwind badge/alert + `<table>`. Multipart = pattern `ContractAttachmentsSection` (FormData + `Content-Type: multipart/form-data`).
- **SHA256 ×2 pair:** SupplierImportDialog `6313529c…`, SuppliersPage `e9143d93…`. Build PASS ×2 (admin 1950mod `index-DyOk34HV.js` 19.5s / user 1939mod `index-DXK9ebaz.js` 8.75s, 0 TS err). Pre-existing warn: @import CSS-order + >500KB + realtime.ts dynamic. NO BE touch. Full precedent. Tag `[supplier-import-excel, multipart-preview-confirm, enum-int-wire, byte-identical-2app, no-4place-dialog-on-routed-page]`.
## 🆕 S97-badge (2026-07-01) — PE chip "✅ Đã được CEO duyệt" khi phiếu ĐÃ DUYỆT đi hết lên CEO (anh Kiệt FDC UAT, em-main chốt)
FE-ONLY, PROD LIVE. Đối xứng fix endsBeforeCeo (Mig 60). EDIT1 mở rộng `PeFinalizeChip.tsx` (2 app) + EDIT2 wire `phase={p.phase}` ở 6 call-site.
- **EDIT1 component:** +prop `phase?` + nhánh: `if(!endsBeforeCeo){ if(phase===DaDuyet) return emerald "✅ Đã được CEO duyệt"; return null }` else giữ violet "⚑ Kết thúc·X". Import `PurchaseEvaluationPhase` từ `@/types/purchaseEvaluation`**cùng alias 2 app** → byte-identical (KHÔNG ngoại-lệ import-path). SHA256 IDENTICAL ×2 = `da9c3ed9…`.