Files
solution-erp/docs/changelog/sessions/2026-06-24-S87-pe-multiwinner-budget-finalize-sectionb.md
pqhuy1987 121f5cc128 [CLAUDE] Docs: S87 closeout — PE multi-winner + budget=0 + cấp-KẾT-THÚC (Mig 58) + Section B 3-cột (Mig 59)
STATUS + HANDOFF S87 narrative + count flush (Migrations 57->59, test 377->402,
gotcha 73 unchanged) + session log 2026-06-24-S87 + agent-memory harvest
(cicd-monitor #344 / implementer-backend / investigator-codebase / reviewer /
test-specialist — spawn-record on-disk).

State THẬT: Mig 59 · 88 bảng (cicd flag 89 drift, re-ground monthly) · 402 test
(45D+357I) · gotcha 73 · menu 54 · bundle admin CXCKlNay/user Di40ewrF
(Run #344; #345 cicd-verifying Section B). Docs-only -> CI skip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 16:14:54 +07:00

35 lines
5.3 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.

# S87 (2026-06-24) — PE multi-winner + budget=0 + cấp-KẾT-THÚC (Mig 58) + Section B 3-cột (Mig 59)
**HMW-mode ON · ~14 spawn (nhiều #53 truncate → recover-disk + reviewer cross-verify + em-main self-gate) · 2 commit prod-verified.**
## Bối cảnh
Anh forward PDF `CCM - 4 ý can sua PM.pdf` (OneNote export) — 4 ý CCM muốn sửa, anh dặn **BỎ mục 3** ("CCM sửa Ngân sách-kỳ-này", nói riêng sau). Rồi anh giao thêm Section B 3-cột qua screenshot + "workflow chạy review test kỹ".
## (1) CCM 3-fix — Mig 58 `AddPeMultiWinnerAndLevelFinalize` (`f1b10e9`, Run #344 PASS ~5m11s)
- **① Multi-winner:** chọn NHIỀU NTP/NCC/ĐVDV cùng trúng → tổng CP = SUM. Thêm `PurchaseEvaluationSupplier.IsWinner` (nguồn-sự-thật mới, backfill từ `SelectedSupplierId` 13/13 phiếu cũ). `SelectWinnerCommand(Guid? SupplierId)``(IReadOnlyList<Guid> SupplierIds)` multi-toggle; `winnerQuoteTotal` 3 site đổi predicate `==SelectedSupplierId``IsWinner`. `SelectedSupplierId` giữ làm "primary" (= 1 winner ? đó : null). FE bảng so sánh tick-nhiều-ô + "Tổng chi phí đã chọn (N đơn vị)".
- **② Budget=0 hợp lệ:** submit-guard nới `effectiveBudget is null || <= 0``is null` only (0 cố-ý đi qua, null chặn). Fallback ProInitial CHỈ khi null (bảo-vệ 0-cố-ý khỏi bị override→null-block). 3 validator `GreaterThan(0)``GreaterThanOrEqualTo(0)`.
- **④ Cấp KẾT THÚC quy trình:** `ApprovalWorkflowLevel.AllowApproverFinalize`. **Diễn-tiến thiết-kế:** ban đầu em làm opt-in checkbox (an-toàn S73) → anh "cho bật trong quy trình thì hay hơn" → đổi **AUTO** theo cấu-hình-cấp: nhánh `if (matchingLevel.AllowApproverFinalize)` trong ApproveV2Async tự DaDuyet bỏ CEO, GỠ runtime-flag `finalizeByApprover` (revert 9 site plumbing). FE bỏ checkbox → banner "Cấp này KẾT THÚC quy trình" + bắt chọn giá-chốt. Designer per-level checkbox.
- **⚠️ Self-review bắt 8 chỗ FE keyed `selectedSupplierId`** (null khi ≥2 winner → vỡ submit-guard/checklist/`computeGiaChaoThau`/`canCreateContract`/display) → đổi `isWinner`. → bài học `feedback_cardinality_change_grep_consumers`.
- Test 377→**395** (+20 2 finalize-auto-rework). Bundle admin `aKuNip19``CXCKlNay`/user `BUsL0HeQ``Di40ewrF`. cicd #344: Mig 58 applied, backfill 13/13, 2 bundle rotate, select-winner 401 wired.
## (2) Section B 3-cột — Mig 59 `AddCcmBudgetPeriodToPurchaseEvaluation` (`9b1ee0c`, Run #345 cicd-verifying)
- Anh muốn Section B (THỰC HIỆN) tách 3 cột Dự án|PRO|CCM giống Section A. **AskUserQuestion** chốt scope → **"mỗi cột nhập kỳ-này RIÊNG"**.
- BE: `PurchaseEvaluation.CcmBudgetPeriodAmount decimal(18,2)?` + `SetPeCcmBudgetPeriodCommand` (role-gate Admin|CostControl fail-closed, GTE0, absolute-set) + endpoint `PATCH /budget/ccm-period` + DTO. (⚠️ command rơi `PeSuggestedPriceFeatures.cs` — lệch chỗ, dọn monthly.)
- FE: Section B `<BudgetRow>` list → `<table>` 3 cột. Helper `colCalc(period, colFull, remaining)` tính per-cột (PRO: budgetPeriodAmount/proFull · CCM: ccmBudgetPeriodAmount/ccmFull · Dự án —). Số chung row1/2/4/6 `colSpan=3`.
- **Workflow `wf_aafb18fe-d9d`** (anh yêu cầu "review test kỹ"): BE→FE+test→3-lane review. math PASS (traced colCalc no-column-crossing) · authz PASS (setter persist+role-gate, 402 test) · **mirror+FE return NULL** (#53) → em-main self-gate: mirror byte-identical 2 app + 402 test + 2 npm build.
- Test 395→**402** (+7 `PeCcmBudgetPeriodSetterAuthzTests`).
## Lessons
- **Cardinality single→multi = grep MỌI consumer** (`feedback_cardinality_change_grep_consumers`) — impl sửa write-site, sót dependent read-site, vỡ feature vừa thêm; build+test+reviewer PASS vẫn miss (lỗi logic-runtime case multi).
- **Design-dialog tránh rework:** item-4 auto-vs-optin (anh chốt auto qua workflow-config) + Section B scope (AskUserQuestion per-cột-kỳ-này) — hỏi-trước-build chỗ ambiguous-high-rework.
- **Workflow review-lane value dù lane NULL:** 2/5 lane (FE-impl + mirror-review) return NULL, nhưng math+authz lane verify disk độc-lập → trust PASS + em-main self-gate phần NULL. Workflow vẫn hữu-ích cho review (≠ phải mọi-lane-return).
- **#53 truncate dày-đặc session này** — impl-backend, test-spec, impl-frontend ×2, workflow FE+mirror; TẤT CẢ recover-disk OK (git/build/test = source-of-truth). Carry `feedback_agent_kill_recovery` + `feedback_workflow_fanout_reliability`.
## State THẬT cuối S87
**Mig 59 · 88 bảng (cicd flag 89 — drift cũ KHÔNG do Mig 58/59 AddColumn-only) · 402 test (45D+357I) · gotcha 73 · menu 54 · bundle admin `CXCKlNay`/user `Di40ewrF` (Run #344; #345 rotate pending).**
## NEXT
- **Anh:** restart CLI (carry). UAT (Ctrl+F5): multi-winner tick-nhiều + tổng · budget=0 submit · Designer bật "Duyệt là kết thúc" cấp anh Chương · Section B cột CCM nhập kỳ-này (tài khoản CCM).
- **Em:** curate L1 over-cap carry · monthly 2026-07-01 (dọn CCM-setter lệch-chỗ · re-ground sys.tables 88→89 · STATUS/HANDOFF re-tier · ef-core SKILL Mig→59).
- **Pending product:** Section B cột Dự-án wire (chờ anh) · Ngưỡng giá CEO Mig 54 Designer · "C" chuyển phiếu→dự án chờ spec.