[CLAUDE] Docs: S116 closeout — PE negative-quote (STATUS/HANDOFF/session-log + harvest)
- STATUS/HANDOFF prepend S116 (test 486->495 · bundle Dd55jBpj/DVDr1UQ4) + fix
D1 Tests-row (486->495, 441->450 Infra) + D2 bundle-live-pointer (tooling-auditor
caught 2 derived-summary lags below the mega-line).
- Session log 2026-07-13-S116-pe-negative-quote.md.
- Harvest: investigator-codebase on-behalf S116 (invest lanes RETURN-only) +
reviewer/impl-fe/impl-be/test/cicd self-written · monitor diaries (harvest-curator
self-compact moved-not-cut + tooling-auditor archive-move).
- §5.0 squash 2 wal-trailing (dfa1c8c/0edbc58, post-feature Stop-hook flush) folded here.
- Feature already shipped 88368fd (Run 386 PASS 5m28s); this commit = docs/memory/run-trace
only -> CI skip (paths-ignore #41).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
46
docs/changelog/sessions/2026-07-13-S116-pe-negative-quote.md
Normal file
46
docs/changelog/sessions/2026-07-13-S116-pe-negative-quote.md
Normal file
@ -0,0 +1,46 @@
|
||||
# S116 — PE cho nhập giá ÂM ô "Số tiền báo giá cho hạng mục" (2026-07-13)
|
||||
|
||||
**Commit:** `88368fd` · **CI:** Run 386 PASS 5m28s · **State:** Mig 65 · 89 bảng · **495 test** (486→495) · gotcha 81 · bundle admin `Dd55jBpj` / user `DVDr1UQ4`
|
||||
**Lead:** Opus 4.8 (owner-choice; Fable UP — xác nhận qua fable-real `claude-fable-5`) · HMW-ON · em-main-led
|
||||
|
||||
## Đề bài (anh Kiệt FDC ⇄ Duy Nguyen, Zalo)
|
||||
Ô **"Số tiền báo giá cho hạng mục"** (`form.thanhTien` → `Quote.ThanhTien`) trong dialog "Thêm NCC vào phiếu" PE **không nhập được số âm**. Yêu cầu cho nhập âm — số âm = **phát-sinh-giảm / hoàn-tiền** của NCC = giá **THẬT** (không phải lỗi). Rule: **ngân sách GIỮ NGUYÊN**; "có giá là được" (≥1 giá thật âm/dương → gửi được; chỉ chưa-nhập-gì mới chặn).
|
||||
|
||||
## Pipeline (anh chỉ định: /fable-clone invest-review → /fable-real → hmw Opus MAX → commit+deploy)
|
||||
| Stage | Workflow | Kết quả |
|
||||
|---|---|---|
|
||||
| invest | `wf_eaf52972-d18` 4× investigator-codebase | **FE-ONLY** — BE/DB nhận âm sẵn (0 validator `UpsertQuoteCommand`, `decimal(18,2)` no CHECK); ngân sách safe by architecture (`PeWorkItemBudgets` role-gated, quote-path không đụng) |
|
||||
| gate | AskUser ×2 (4 decision) | R1 · R2 · R2-revised · R-CEO (dưới) |
|
||||
| review | `wf_4824f158-b66` 3× reviewer | Lane1 PASS_WITH_FIXES (sign-plumbing) · Lane2/3 PASS |
|
||||
| deep-pass | `wf_9648d207-21b` 1× reviewer (Fable) | **#53 garble → em-main-solo gate GO-WITH-FIXES** |
|
||||
| implement | `wf_48834aca-c41` FE‖(BE→test) Opus MAX | 0-garble, 486→495 |
|
||||
| verify | em-main độc-lập | dotnet test 495 · mirror SHA · BE build |
|
||||
| deploy | cicd-monitor | Run 386 PASS, byte-level ship-proof |
|
||||
|
||||
## Owner-decisions (anh Kiệt chốt)
|
||||
- **R1** — Contract.GiaTri âm: **CHO PHÉP** (no clamp; `CreateContractFromEvaluationFeatures.cs:88-100` giữ âm; validator tạo-tay `ContractFeatures.cs:46` GiaTri≥0 = đường khác, giữ).
|
||||
- **R2 (revised)** — submit-guard `Sum()<=0` → **`All(x=>x==0)`**. Anh **hỏi lại mid-pipeline**: "1 NCC / 1 hạng mục âm thì có chặn không?" → phát hiện guard cũ **mâu-thuẫn R1** (cho HĐ âm nhưng chặn phiếu tạo ra nó). Guard là **proxy sai** cho ý-định "chưa báo giá" → sửa về đúng ý-định.
|
||||
- **R-CEO** — ngưỡng CEO: **giữ NET** (`winnerQuoteTotal` net, dòng âm có thể kéo phiếu dưới ngưỡng → CCM finalize bỏ CEO; owner chấp nhận "duyệt theo net cam-kết").
|
||||
- **R3** — BgVat/ChuaVat giữ nguyên.
|
||||
|
||||
## Thay đổi code (FE + 1 BE, KHÔNG migration)
|
||||
**FE** `PeDetailTabs.tsx` (fe-user + fe-admin byte-identical SHA `3e16dba5`, 112 dòng/app):
|
||||
- Nút **± toggle** 2 input quote (AddSupplierDialog `:2365` + QuoteDialog `:2917`), ghi giá-**CÓ-DẤU** thẳng vào `form.thanhTien` (2 dialog POST commit trực tiếp, không nút Lưu riêng → nếu chỉ flip cờ `neg` = mất-dấu thầm lặng — review Lane-1 bắt).
|
||||
- Submit gate `:2226` + toast `>0` → `!==0`. Ô ngân sách `:2830` giữ ≥0 (không toggle).
|
||||
- Helper mới `hasRealSelectedQuote` thay 2 FE submit-mirror (`:201` missingForApproval + `:235` submitChecklist) — SUM `computeGiaChaoThau` không phân-biệt all-zero vs net-zero → iterate `ev.details[].quotes` (KHÔNG `suppliers[].quotes` — FE-agent tự sửa spec-shape-error).
|
||||
|
||||
**BE** `PurchaseEvaluationWorkflowService.cs:206`: `selectedThanhTien.Sum() <= 0` → `.All(x => x == 0)` (1 điều-kiện) + stale-comment fix. `Count==0` guard giữ riêng.
|
||||
|
||||
**Tests** +9 (486→495): T1 ngân-sách-bất-biến (`PeWorkItemBudgetTests`) · T2 winnerQuoteTotal signed-sum (`PeMultiWinnerTests`) · T3 submit-guard all-zero/pure-neg/net-zero (`PeSubmitGuardAndBypassTests` + helper ext) · T4 CCM-net-threshold (`PeCcmThresholdFinalizeTests`).
|
||||
|
||||
## Lessons
|
||||
- **Owner bắt mâu-thuẫn giữa 2 decision** (R1⇄R2) mà invest+review đều chưa nối — cho dữ-liệu-âm ở đầu-ra nhưng chặn con-đường tạo ra nó. → engine phải nối các quyết-định, không xét độc-lập.
|
||||
- **Guard là proxy sai:** `Sum()<=0` ≠ ý-định "chưa báo giá" (= `All(==0)`). Sửa về đúng ý-định giải mâu-thuẫn + đúng ngữ-nghĩa.
|
||||
- **#53-garble ×19 (fable-real, reasoning-lane):** garble ≠ mất-việc. Recover **transcript-forensics** (thấy nó verify CEO-threshold, chưa kịp verdict) → **em-main-solo gate** vẫn có RĂNG (bắt thêm FE mirror `:235`). `parallel()` + schema-nhỏ → 4/5 workflow 0-garble.
|
||||
- **verify-deployed-byte-level (#77):** cicd curl bundle prod grep feature-string PRESENT (bundle cũ=0) = ship-proof thật, không cache. + bắt bẫy snapshot-while-CI-running → poll-success trước re-snapshot.
|
||||
- **FE agent verify-on-disk** sửa spec-shape-error (quotes ở `details[]` không `suppliers[]`) — lý do worker phải verify, không tin spec mù.
|
||||
|
||||
## Carry NEXT
|
||||
- Anh UAT incognito (7 điểm → HANDOFF).
|
||||
- run-trace + agent-memory `.claude/`-gitignored → force-add @closeout.
|
||||
- PE "lỗi phân quyền vào phiếu" (chờ số-phiếu+user) · BVAAU (`AUTH_ENFORCE_CRM_GATE`+User_ID) · monthly re-tier 2026-08-01.
|
||||
Reference in New Issue
Block a user