[CLAUDE] Docs: S114 PE multi-NCC per hạng mục closeout (STATUS/HANDOFF/gotcha #81/Mig 65/session-log)

Closeout feature multi-NCC per hạng mục (ship d436af2):
- STATUS/HANDOFF: S114 blurb + CURRENT STATE canonical Mig 64→65 · test 477→486 · gotcha 80→81 · bundle D51OYyGV/BVdssm5S.
- gotcha #81: derived-invariant re-derive sót DELETE writer (DeleteQuote/DeleteDetail) → IsWinner kẹt stale → HĐ giaTri=0 phantom (Bước 4 fable-clone verify bắt; fix helper PeWinnerInvariant test-before).
- ef-core skill: +Mig 65 BackfillPeQuoteIsSelectedAndWinnerInvariant row.
- session log 2026-07-12-S114 + 2 reviewer diary harvest (verify run) + run-trace fold.
- cicd on-behalf record (garble #53 ×5 → em-main-solo deploy verify).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-07-12 23:45:08 +07:00
parent d436af2971
commit 16a199f031
11 changed files with 108 additions and 24 deletions

View File

@ -16,7 +16,9 @@
- [S111 PE sign-off 6-decision design review (schema/history lens)](project_pe_signoff_history_schema_review.md) — GO-WITH-ADJ; Decision-5 opinion-history: RECOMMEND (a) append-only table, REJECT (b) version-col (drops UNIQUE + breaks UPSERT read every site), (c) Changelog zero-mig fallback. Hook @ ApproveV2Async UPSERT :784-790. Decision-3 caller-safe (SlaExpiryJob=Contract-only, not PE). A1 breaks 4 bypass tests.
- [PE multi-NCC per-hạng-mục cardinality#3 review (consumer-completeness lens)](project_pe_multiwinner_perhangmuc_review.md) — PASS_WITH_ADJ; 6 BE read-site inventory COMPLETE (grep 1:1, no sót — unlike S87). 2 MUST: (1) giaTri isSingle/detailsSum branch silent-financial under per-hạng-mục; (2) derive-completeness — seed:1310-1316 sets IsSelected never IsWinner → seeded phiếu empty names + CreateContract throws. Lesson: derived source-of-truth = EVERY write-path of base field must re-derive.
- [S113 Supplier import v2 close-review (owner anh Kiệt)](project_s113_supplier_import_v2_review.md) — GO-WITH-ADJ 2 must-fix: consumers (PeDetailTabs:2222 + ContractCreatePage:321 ×2app) DON'T pass published=true → drafts leak into pickers (R4/R6 "ẩn" undelivered) + CreateSupplier:86 missing IsPublic=true. Dedup/publish/mig/authz SOLID. Lesson: "filter added" ≠ "drafts hidden" — grep-all-consumer + create write-path.
- [S114 PE multi-NCC per-hạng-mục BE-financial close-review](project_s114_pe_multi_ncc_perhangmuc_financial_review.md) — NEEDS-FIX 1 MUST: 6 financial-SUM đều→IsSelected (grep độc-lập, 0 sót) NHƯNG DeleteQuote:396 + DeleteDetail:262(cascade) KHÔNG re-derive IsWinner → stranded winner → phantom HĐ GiaTri=0 @CreateContract:56 + FE row kẹt; reachable "Xóa" btn:2897; 0 test. Lesson: derived-invariant re-establish MỌI mutation kể cả DELETE.
- [PE multi-NCC per-hạng-mục spec review (winner-truth cardinality lần 3)](project_pe_multi_ncc_perhangmuc_specreview.md) — PASS_WITH_ADJ. MUST: CreateContract isSingle→detailsSum (`:76-77,89-90`) over-count khi 1-winner≠cả-gói, phá `Σgiari==winnerQuoteTotal`; spec cite `84-93` LOẠI isSingle = bẫy partial-re-key S87. SHOULD: derive-integrity 3 write-path (winner-cmd + UpsertQuote:308/332 + seed:1257 KHÔNG set IsWinner). 6-site IsWinner grep ĐỦ (0 sót). Lesson: grep write-path field-NGUỒN (IsSelected) không chỉ field-đọc; cite-range bọc branch-decision.
- [S114 PE multi-NCC per-hạng-mục IMPL review (winner-truth flip lần 3)](project_s114_multi_ncc_perhangmuc_impl_review.md) — NEEDS-FIX. CAUGHT MUST: DeleteQuote (`PurchaseEvaluationDetailFeatures.cs:371-397`) KHÔNG re-derive IsWinner → xóa quote IsSelected cuối (nút Xóa FE:2897) VỠ invariant → phantom winner + HĐ giá 0 (CreateContract:56 Where(IsWinner)). Spec A2 enumerate writer sót DeleteQuote. Lesson: cardinality grep-consumer PHẢI gồm Delete-handler field-nguồn; spec-enum writer KHÔNG đáng tin. SOLID: 5 SUM IsSelected + test non-tautology (threshold-cross 1.2tỷ/500tr, giaTri 300/800/2000) + 2-app hash ae3788e9.
---