# S113 — Supplier import v2 (SHIP PROD, Run #497)

**Date:** 2026-07-12 · **Owner:** anh Kiệt · **Lead:** Opus 4.8 (1M) Max · **Mode:** HMW-ON · **Commit:** `5fa11b5` (feature) + closeout.

## Đề bài (anh Kiệt — 7 yêu cầu R1-R7)
Nâng Supplier Excel-import (S112 Phase B) → v2: R1 đọc đúng file thật · R2 nút "Tải file mẫu" · R3 nhập Mã NCC thủ công sau upload · R4 thiếu Mã NCC→nháp/ẩn · R5 dedup theo MST · R6 không MST&không Mã NCC→không public · R7 badge Public/ẩn.

## Flow (invest → spec → decision → implement → test → review → deploy)
1. **Đọc file thật** `Data base - 1_7_2027.xlsx` (Sheet1, header ROW 4, 30 cột, MST=c12, TÊN VIẾT TẮT=c4→Code, 4 NCC). Phát hiện: file KHÔNG có cột "Mã NCC" → xác nhận R3 = user tự nhập.
2. **`/fable-clone investigator-codebase` invest ensemble** (`wf_e7896ca6-901`, 5 lăng-kính cùng vai): schema · import-service · fe-ux · visibility · dedup. 4/5 structured + lane visibility **#53-garble** → em-main grep recover.
3. **Spec 3-mục** (`runs/2026-07-12-S113-supplier-import-v2-invest/spec-...md`) + trích 30 token header THẬT byte-exact.
4. **Anh Kiệt 3 decision:** **D1=A** (Mã NCC = field Code hiện có) · **D2** (Code=cổng public; MST=cảnh-báo-mềm không chặn; existing-public giữ; import-scope) · **D3** (nới quyền: mọi user có quyền cập-nhật danh-mục = `Suppliers.Update`, không admin-only).
5. **HMW-Opus implement** (BE⟂FE disjoint parallel): implementer-backend + implementer-frontend.
6. **test-specialist** +19 test (477 PASS) → **reviewer** GO-WITH-ADJ (2 must-fix) → deploy.

## Ship
- **Mig 64 `AddSupplierPublishState`:** +IsPublic bit (cổng công-bố) + backfill 37/37 prod→public + filtered-unique đổi `[Code]<>''` (nhiều nháp) + no-new-table (89) + reversible Down.
- **BE:** dedup MST-primary+Code-backstop (chống 500) · re-bake 30-token LayoutValid · `PublishSupplierCommand` riêng (né #73) · `GET /import/template` ClosedXML · authz `Policy=Suppliers.Update`.
- **FE 2-app SHA-mirror:** badge Public/Nháp · nút Công bố · filter · nút Tải-file-mẫu · cột Mã editable · cảnh-báo-MST · picker PE+HĐ lọc `published=true`.

## 4 BUG caught + fixed PRE-PROD (giá trị multi-agent)
1. **#53-garble invest-visibility-lane** → em-main-solo grep recover (identify consumers).
2. **null-Code NRE `NewSupplier` (gotcha #80)** — test-specialist bắt: `Code=r.Code!.Trim()` NRE khi ô cột-4 trống (path R4 lõi, 500 cả batch); `!` che → build 0/0 không thấy. Fix `(r.Code??"").Trim()` + flip characterization-test.
3. **authz-403 Import-nút** — em-main verify-chéo: FE Import `action="Create"` ⧣ BE `Policy=Suppliers.Update` → khớp Update 2-app.
4. **draft-leak-picker + CreateSupplier-quên-IsPublic** — reviewer 2 must-fix: 4 picker (PeDetailTabs+ContractCreate ×2) chưa truyền `published=true` (draft lọt → mã HĐ hỏng) + `CreateSupplierCommand` không set IsPublic → NCC tạo tay thành nháp. Fix cả 2.

## cicd Run #497 PASS (5m14s)
Bundle admin `Cixlt_MA`→`acprMqfB` (CSS `CfunQHbd`) / user `BhBOG1dn`→`Ck3BTDdA` (CSS `DGqqHQXS`) rotate ×2 ship-proof · Mig 64 prod (history-top + IsPublic-col + 37/37-backfill + sys.tables 89) · byte-verify `Tải file mẫu`×1/`Đã công bố`×3/`Nháp (ẩn)`×4/`import/template`×1/`published`×5 PRESENT · smoke health/admin/eoffice 200 + `import/template`-401-live + `suppliers?published=true`-401-live + bogus-404-control.

## State
**Mig 64 · 89 bảng · 477 test (45D+432I) · gotcha 80 · menu 54 · bundle admin `acprMqfB`/user `Ck3BTDdA` (Run #497) · prod 37 NCC/17 user.**

## Lessons
- `!` null-forgiving trên external-parsed data = mìn (gotcha #80); build-0/0 không bắt, chỉ test-before-critical bắt.
- Verify-chéo BE⟷FE bắt authz-mismatch (build-pass ≠ contract-match); policy-name là string, compiler không check → verify Program.cs auto-reg.
- Cardinality (S87/S88): đổi visibility = grep MỌI consumer; reviewer bắt FE sót wiring dù spec đã flag (recover-lane).
- #53-garble ×2 → SendMessage-resume in-session finish sạch (1/3 lifetime) + em-main ground-truth qua git/grep (không tin self-review sau garble).

## NEXT
- **anh Kiệt (UAT):** test luồng end-to-end + upload file "Database NCC" ĐẦY ĐỦ (file test chỉ 4 dòng) xác nhận LayoutValid=true.
- **em:** OQ4 open (MST-A-Code-B silent-precedence — anh refine nếu muốn conflict-error) · nice-to-have reviewer (stale-comment service + Mig64-Down-edge + template-roundtrip-test) · monthly re-tier 2026-08-01.
