wal: flush 20260713T1605
This commit is contained in:
@ -6,8 +6,9 @@
|
||||
**Pipeline anh chỉ định:** `/fable-clone invest+review` → `/fable-real review` → hmw Opus 4.8 MAX → commit + deploy.
|
||||
|
||||
## Stages
|
||||
- [!] Stage 1 — invest (fable-clone ensemble, 4× investigator-codebase multi-lens) → em synthesize spec 3-mục
|
||||
- [ ] Stage 2 — review (fable-clone ensemble, reviewer)
|
||||
- [x] Stage 1 — invest (fable-clone ensemble, 4× investigator-codebase) → **DONE 4/4 clean 0-garble** (`wf_eaf52972-d18`, ~11', 516K tok). Kết luận: **FE-ONLY** (BE+DB đã nhận âm; ngân-sách bất-biến bằng kiến-trúc). Spec `spec-pe-negative-quote-13-07-2026.md` ghi xong.
|
||||
- [x] gate — anh Kiệt CHỐT: R1 = CHO HĐ âm (no-op) · R2 = GIỮ chặn net≤0 (no-op). Implement = thuần FE + test.
|
||||
- [!] Stage 2 — review (fable-clone ensemble, 3× reviewer)
|
||||
- [ ] Stage 3 — review (fable-real, reviewer deep-pass)
|
||||
- [ ] gate — owner-decisions (nếu invest/review lòi ra)
|
||||
- [ ] Stage 4 — implement (hmw Opus 4.8 MAX)
|
||||
@ -23,4 +24,5 @@
|
||||
1. FE-surface · 2. BE-surface · 3. Budget-consumers · 4. Edge-precedent-tests
|
||||
|
||||
## wf run-id
|
||||
- Stage 1 invest: `wf_eaf52972-d18` (task `wslm7eymc`) — 4 lane investigator-codebase, launched 2026-07-13, HMW-ON, lead Opus 4.8
|
||||
- Stage 1 invest: `wf_eaf52972-d18` (task `wslm7eymc`) — 4 lane investigator-codebase, DONE 4/4 clean, HMW-ON, lead Opus 4.8
|
||||
- Stage 2 review: `wf_4824f158-b66` (task `wjhpvoyum`) — 3 lane reviewer (correctness-wire · mirror-completeness · financial-invariant-owner)
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
# Spec — PE cho phép nhập SỐ ÂM ô "Số tiền báo giá cho hạng mục" (2026-07-13, S116)
|
||||
|
||||
> Engine: `/fable-clone investigator-codebase` 4-lane ensemble (`wf_eaf52972-d18`, 4/4 clean 0-garble) → lead verify + synthesize. Owner anh Kiệt (Zalo ⇄ Duy Nguyen 2026-07-13).
|
||||
|
||||
## ① Tính-năng / đề-bài
|
||||
Ô **"Số tiền báo giá cho hạng mục"** (React state `form.thanhTien` → `Quote.ThanhTien`) trong dialog **"Thêm NCC vào phiếu"** + dialog sửa giá (QuoteDialog) của module PE hiện **không nhập được số âm**. Yêu cầu: **cho nhập âm** (NCC có phát-sinh-giảm giá trị do có làm trước).
|
||||
|
||||
**Rule chốt (Duy Nguyen xác nhận 11:51):** số âm = khoản trừ/phát-sinh-giảm của **riêng NCC**; **NGÂN SÁCH GIỮ NGUYÊN** — quote âm KHÔNG cộng/trừ vào ngân sách dự án.
|
||||
|
||||
## ② Cách implement — **FE-ONLY** (0 BE · 0 migration · 0 bảng/cột mới)
|
||||
|
||||
**Đã verify (invest 4-lane hội-tụ):** BE + DB **đã chấp nhận âm sẵn** — `UpsertPurchaseEvaluationQuoteCommand` (`PurchaseEvaluationDetailFeatures.cs:272`) KHÔNG validator, cột `ThanhTien decimal(18,2)` (`PurchaseEvaluationConfiguration.cs:131`) 0 CHECK constraint. Ngân sách (`PeWorkItemBudgets`) chỉ ghi bởi command budget role-gated → **quote âm không đụng ngân sách** (rule thỏa bằng kiến-trúc, 0 code). ⇒ **CHỈ sửa FE + gỡ đúng 3 chốt chặn âm.**
|
||||
|
||||
**4 thay đổi FE (mirror 2 app `fe-user` + `fe-admin` byte-identical — SHA-mirror bắt buộc):**
|
||||
|
||||
1. **Input quote — AddSupplierDialog** `PeDetailTabs.tsx:2365` — thêm `neg` state + nút toggle **±**, hiển thị `formatVndInput(Math.abs(thanhTien))`, lưu `neg ? -parseVnd : parseVnd`. **Tái dùng pattern có sẵn `VndInlineEdit:1003`** (prop `allowNegative` + `neg` state `:1015` + toggle `:1025-1037` + save `neg?-n:n` `:1019`). KHÔNG reinvent.
|
||||
2. **Input quote — QuoteDialog** `:2917` — cùng pattern; `neg` init từ dấu của `existing.thanhTien` (mở lại quote âm phải hiện đúng, không trắng ô).
|
||||
3. **Submit gate — AddSupplierDialog** `:2226` `if (detailId && form.thanhTien > 0)` → `!== 0` (âm tạo quote; rỗng/0 vẫn skip = "chưa báo giá"). Toast `:2239` cùng sửa.
|
||||
4. **KHÔNG đụng** `parseVnd`/`formatVndInput` (dùng-chung ô ngân sách cùng file `:51-52`) + **KHÔNG** truyền allowNegative cho ô ngân-sách `thanhTienNganSach:2830` (giữ ≥0).
|
||||
|
||||
**Semantics giữ:** rỗng/0 = "chưa báo giá" (skip tạo quote); âm = quote thật (≠ rỗng). `formatVndInput(-n)→''` là lý do PHẢI tách magnitude+dấu (không chỉ nới parseVnd).
|
||||
|
||||
**Tests (regression-lock invariant tài chính — test-specialist):**
|
||||
1. **Ngân sách giữ nguyên**: upsert quote âm → assert `PeWorkItemBudget` amounts UNCHANGED (`PeWorkItemBudgetTests`).
|
||||
2. `winnerQuoteTotal` = SUM mixed +/- selected (`PeMultiWinnerTests`).
|
||||
3. submit-guard: winner thuần-âm → blocked; mixed net>0 → submittable (`PeSubmitGuardAndBypassTests`).
|
||||
4. CCM-threshold với total giảm do âm (`PeCcmThresholdFinalizeTests`).
|
||||
|
||||
## ✅ Owner-decisions (anh Kiệt CHỐT S116 via AskUser)
|
||||
- **R1 — Contract.GiaTri âm: CHO PHÉP** (khuyến nghị). Luồng PE→HĐ giữ số âm; **KHÔNG thêm clamp/floor**; validator tạo-tay `ContractFeatures.cs:46` (GiaTri≥0) GIỮ nguyên (đường khác). → **code no-op** (allow = không chặn thêm).
|
||||
- **R2 — submit-guard net≤0: GIỮ CHẶN** (khuyến nghị). Guard `PurchaseEvaluationWorkflowService.cs:206` `Sum()<=0` + FE mirror `:201` GIỮ nguyên. → **code no-op**.
|
||||
- R3 (default): BgVat/ChuaVat giữ nguyên (FE chỉ expose input âm cho thanhTien).
|
||||
→ **Cả 2 chốt = giữ hành-vi hiện tại ⇒ implement thuần 4 thay-đổi FE + 4 test, 0 đụng BE.**
|
||||
|
||||
## ③ Checklist (vai · deliverable · acceptance ĐO ĐƯỢC)
|
||||
| # | Vai | Deliverable | Acceptance đo được |
|
||||
|---|---|---|---|
|
||||
| C1 | implementer-frontend | ± toggle + neg-state cho 2 input quote (`:2365`, `:2917`) × 2 app | Nhập `-5.000.000` → ô hiện `-5.000.000` (KHÔNG trắng); reopen quote âm hiện đúng dấu; SHA `fe-user`==`fe-admin` |
|
||||
| C2 | implementer-frontend | Submit gate `:2226` `>0`→`!==0` + toast `:2239` × 2 app | Thêm NCC với quote âm → tạo quote (không bị nuốt im lặng); rỗng/0 vẫn "chỉ tạo NCC" |
|
||||
| C3 | implementer-frontend | Ô ngân-sách `:2830` GIỮ ≥0 (không allowNegative) | Nhập `-` vào ngân sách hạng mục → bị chặn/không nhận |
|
||||
| C4 | test-specialist | 4 test regression-lock (ngân-sách-giữ-nguyên + winnerTotal + submit-guard + CCM-threshold) | `dotnet test` xanh; test #1 chứng budget bất-biến khi quote âm |
|
||||
| C5 | reviewer + cicd | build 2-app + deploy | `npm build` 2-app pass; bundle rotate; prod nhập âm được (anh UAT incognito) |
|
||||
|
||||
**Trạng thái sau implement dự kiến:** Mig 65 (GIỮ) · 89 bảng (GIỮ) · test 486→~490 · FE 2-app bundle rotate. FE-only → CI chạy (path-filter không skip vì `.tsx`).
|
||||
Reference in New Issue
Block a user