[CLAUDE] Docs: chốt Session 11 — Migration 17 manual budget fields PE + HĐ
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m17s

Chunk 5/5 — close session log + STATUS Recently Done + HANDOFF TL;DR Session 11
+ migration-todos tick + 6 cảnh báo Session 12+. KHÔNG update skill (per §9.5
— defer cron audit 2026-06-01 nhỏ enough). KHÔNG update schema-diagram count
55→55 (không bảng mới, chỉ +4 column).

Files:
  ~ docs/STATUS.md       — Last updated S11 + Phase summary 16→17 mig + Recently Done row
  ~ docs/HANDOFF.md      — TL;DR Session 11 prepend + 6 cảnh báo + giữ S10 narrative
  + docs/changelog/sessions/2026-05-07-2300-pe-hd-manual-budget-mig17.md
  ~ docs/changelog/migration-todos.md — Session 11 done block

Validation per §6.5: KHÔNG cắt narrative, chỉ thêm rows + sections mới.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-07 12:43:00 +07:00
parent 14f8d9d808
commit bf177408b0
4 changed files with 154 additions and 3 deletions

View File

@ -219,6 +219,18 @@ Session log: `2026-05-04-1230-chot-session-8-2-stage-dept-approval.md`.
- [x] **Optional polish — fe-user Inbox PE section** (commit `332a90f`). HĐ + PE 2 section trong InboxPage.
- [x] **User Manual 7 file rewrite compact** (commit `16c2c9c`). End-user style: bỏ field/error tables, giữ numbered steps đơn giản. ~86 KB total.
### ✅ Session 11 done (2026-05-07) — Migration 17 manual budget fields PE + HĐ
User feedback: PE/HĐ link Budget Select chỉ Phase=DaDuyet → user phải break flow tạo Budget approved trước. Solution: toggle "Nhập tay" + 2 input field fallback (Tên text + Số tiền number) lưu trên entity, KHÔNG cần Budget entity. Mirror logic PE ↔ HĐ (Q3 chốt).
- [x] **Chunk 1 Domain+Infra** (commit `ecd5f7e`) — Migration 17 `AddManualBudgetFieldsToPeAndContract` 4 ALTER + 2 entity property + 2 EF config (HasMaxLength + HasPrecision). Applied LocalDB. 3-file rule.
- [x] **Chunk 2 App CQRS** (commit `0f7901c`) — Create/Update PE + Contract commands + Validator (>=0 when has value) + Handlers + DTO + diff log audit + CreateContractFromEvaluation carry forward.
- [x] **Chunk 3 FE-Admin** (commit `bab5031`) — types +2 field, PeHeaderForm toggle + 2 input + payload conditional, PeDetailTabs Section "b. Ngân sách" fallback display + badge "nhập tay", refactor PurchaseEvaluationCreatePage wrap PeHeaderForm DRY (222→30 LOC), ContractCreatePage NewForm + EditForm cùng pattern + read-only branch khi !isDraft.
- [x] **Chunk 4 FE-User mirror** (commit `14f8d9d`) — 6 file y hệt content (rule §3.9).
- [x] **Chunk 5 Docs** (commit current) — STATUS row + HANDOFF TL;DR Session 11 + session log `2026-05-07-2300-pe-hd-manual-budget-mig17.md`.
- [x] **Verify**: dotnet build + 83 test pass mỗi chunk · npm build fe-admin + fe-user pass · LocalDB migration applied.
- [x] **KHÔNG đụng** Budget entity / Phase=DaDuyet validation (giữ invariant). Manual fields chỉ là fallback display/note, KHÔNG join với Budget.Details cho per-row comparison ở PE matrix Section 4.
### ✅ Session 10 done (2026-05-07) — PE "Thao tác" 2-panel workspace
User chỉ thị restructure menu PE: leaf "Thao tác" (Pe_*_Create) từ page Create header riêng `/new` sang workspace 2-panel mirror pattern HĐ Thầu phụ ContractCreatePage. Spec chốt 5 câu trước code (xem session log đầy đủ rationale).

View File

@ -0,0 +1,116 @@
# Session 2026-05-07 23:00 — Migration 17 manual budget fields PE + HĐ
**Dev:** Claude
**Duration:** ~1.5h
**Base commit:** `d04bd88` (sau Session 10 PE workspace)
## Bối cảnh
User feedback: trong PE workspace + HĐ Create form, link Budget Select chỉ list ngân sách Phase=DaDuyet. Khi project chưa có Budget approved, user phải break flow đi tạo Budget → trình duyệt → quay lại link. UX đứt mạch.
User chốt: thêm fallback "user tự nhập tiền vào, ko cần link ngân sách". Toggle reveal 2 input field (text Tên + number Số tiền). Mirror logic sang HĐ luôn (Q3).
3 câu chốt spec:
- **Q1** Toggle cho hiện 2 input number/text field. Confirm "stick = toggle, xong cho input vào 2 field".
- **Q2** Cả 2 cùng null OK (BudgetId + manual fields). KHÔNG XOR validate — tạm thời cho phép cả 2 cùng có (BE prefer BudgetId nếu set vì Phase=DaDuyet guarantee, manual chỉ fallback).
- **Q3** Mirror sang HĐ Thầu phụ (cả 7 ContractType qua ContractCreatePage chung).
## Làm được
### Chunk 1 — Domain + Infra Migration 17 (commit `ecd5f7e`, +3674 LOC, 7 files)
**Migration 17** `AddManualBudgetFieldsToPeAndContract` — 4 ALTER:
- `PurchaseEvaluations.BudgetManualName` nvarchar(200) NULL
- `PurchaseEvaluations.BudgetManualAmount` decimal(18,2) NULL
- `Contracts.BudgetManualName` nvarchar(200) NULL
- `Contracts.BudgetManualAmount` decimal(18,2) NULL
3-file rule per `ef-core-migration` skill: `.cs` + `.Designer.cs` + ApplicationDbContextModelSnapshot.cs (auto-overwrite).
**Files:**
- `Domain/PurchaseEvaluations/PurchaseEvaluation.cs` — 2 property mới (cmt rationale Mig 17 + Q2 validation note)
- `Domain/Contracts/Contract.cs` — 2 property mới
- `Infrastructure/Persistence/Configurations/PurchaseEvaluationConfiguration.cs` — HasMaxLength(200) + HasPrecision(18, 2)
- `Infrastructure/Persistence/Configurations/ContractConfiguration.cs` — same
- Migration 17 (3 file)
**Verify:** `dotnet ef migrations add` clean output (4 AddColumn Up + 4 DropColumn Down). `dotnet ef database update` applied LocalDB. `dotnet test SolutionErp.slnx` 83 pass.
### Chunk 2 — App CQRS (commit `0f7901c`, +36/-4 LOC, 5 files)
- `CreatePurchaseEvaluationCommand` + Validator (MaximumLength(200) + GreaterThanOrEqualTo(0) when has value) + Handler wire entity
- `UpdatePurchaseEvaluationDraftCommand` + Handler wire entity
- `PurchaseEvaluationDetailBundleDto` +2 field
- `GetPurchaseEvaluationQuery` handler → DTO mapping pass entity values
- Mirror `CreateContractCommand` + `UpdateContractDraftCommand` + Validator + diff log audit thêm 2 field
- `ContractDetailDto` +2 field + GetContract handler mapping
- `CreateContractFromEvaluationFeatures.cs` — carry forward `pe.BudgetManualName/Amount``contract` khi gen HĐ từ phiếu (nếu PE đã có manual data, HĐ inherit luôn — không lose data khi gen HĐ).
**Controllers KHÔNG đụng**`[FromBody]` bind JSON body → record record optional fields gen auto null cho legacy callers. Backward compat.
### Chunk 3 — FE-Admin (commit `bab5031`, +268/-260 LOC, 6 files)
- `fe-admin/src/types/purchaseEvaluation.ts` PeDetailBundle +2 field
- `fe-admin/src/types/contracts.ts` ContractDetail +2 field
- `fe-admin/src/components/pe/PeHeaderForm.tsx` — toggle checkbox "Nhập tay (không link)" cạnh Label. ON: hide Select, show 2 input grid 2-col (Tên + Số tiền number formatted "≈ X đ" preview). OFF: Select Budget approved cũ. Payload conditional clear opposite mode. Auto-detect mode khi load existing.
- `fe-admin/src/components/pe/PeDetailTabs.tsx` — Section 2 "b. Ngân sách" fallback display khi !ev.budget + có manual data: render "Tên · Số tiền + badge nhập tay" thay vì "(chưa link)".
- `fe-admin/src/pages/pe/PurchaseEvaluationCreatePage.tsx` — refactor wrap PeHeaderForm DRY (222 LOC → 30 LOC). Auto-inherit toggle pattern, không drift.
- `fe-admin/src/pages/contracts/ContractCreatePage.tsx` — apply same toggle pattern cho NewContractForm + EditContractForm. EditForm thêm read-only display branch khi !isDraft + có manual data.
### Chunk 4 — FE-User mirror (commit `14f8d9d`, +268/-260 LOC, 6 files)
Y hệt Chunk 3 (rule §3.9). Copy 3 file mới + 3 file edit identical.
### Chunk 5 — Docs (commit current)
- STATUS.md Last updated + Phase summary count 16→17 migration + Recently Done row chi tiết.
- HANDOFF.md TL;DR Session 11 prepend + 6 cảnh báo Session 12+ + giữ Session 10 narrative.
- Session log (file này).
- KHÔNG update skill `ef-core-migration` table count — defer cron audit 2026-06-01 (small, không drift major).
## E2E verified
- `dotnet build` solution pass · `dotnet test SolutionErp.slnx` 83 pass · `dotnet ef database update` applied LocalDB.
- `npm run build` fe-admin pass — 1922 modules.
- `npm run build` fe-user pass — 1904 modules.
- Manual smoke: pending UAT user thử các flow sau:
- PE workspace tạo mới → toggle "Nhập tay" ON → nhập "Tạm tính T11/2025" + "1000000000" → save → Panel 2 detail tabs → Section 1 b. Ngân sách hiển thị "Tạm tính T11/2025 · 1.000.000.000 đ + badge nhập tay".
- Edit PE đã có Budget link → toggle off (auto-detected) → unlink → toggle on → nhập manual → save → reload → toggle vẫn ON.
- HĐ Thầu phụ /contracts/new → toggle "Nhập tay" trong NewContractForm → save → /contracts/:id → EditForm vẫn toggle ON, hiện 2 field giá trị cũ.
- HĐ DangSoanThao → DangGopY → reload → !isDraft branch hiển thị "Tên · Số tiền + badge nhập tay" read-only.
- PE DaDuyet → tạo HĐ từ phiếu → HĐ inherit manual fields (CreateContractFromEvaluation carry forward).
## Bug gặp + fix
| Bug | Fix |
|---|---|
| fe-user ContractCreatePage NewContractForm Edit thứ nhất (state declaration) lần đầu fail "File has not been read yet" do Edit chưa Read fe-user contracts.ts trước. Sau đó subsequent Edits đến mid-form fail TS2304 "Cannot find name 'budgetManual'" | Re-read file lần thứ 2 + Edit lại state declaration. Build pass sau khi state có đủ. |
## Docs updates
- STATUS.md (1 row Recently Done + count 17 migration)
- HANDOFF.md (TL;DR Session 11 prepend + cảnh báo)
- session log (file này)
- KHÔNG update skill (per §9.5 — không drift đáng audit, defer cho cron 2026-06-01)
- KHÔNG update gotchas (không phát sinh bẫy mới đáng cluster)
- Schema diagram count 55→55 (không bảng mới, chỉ 4 column mới) — defer audit định kỳ
## Handoff
Phase 9 active. Hard blockers user/ops vẫn pending. Manual budget feature mở ra "free pass" cho user tạo phiếu/HĐ nhanh không cần Budget workflow — ROI lớn cho UAT mà không phá invariant.
Cron audit kế: 2026-06-01 (~25 ngày).
## Thông số cumulative (sau Session 11)
| | Trước S11 | Sau S11 |
|---|---:|---:|
| BE LOC | ~14400 | ~14450 (+50 — 2 entity property + 2 EF config + 4 command field + DTO field + carry forward) |
| API endpoints | ~133 | ~133 (no change) |
| Migrations | 16 | **17** (+1 `AddManualBudgetFieldsToPeAndContract`) |
| DB columns mới | 0 | +4 (PE + HĐ × Name + Amount) |
| FE pages | 32 | 32 (no change) |
| FE components | (existing) | (existing — refactor PeHeaderForm reuse + PurchaseEvaluationCreatePage wrap) |
| Tests | 83 | 83 (no change — feature mới = test-after rule §7) |
| Docs | ~53 | ~54 (+session log này) |
| Commits | (after S10) | +5 (C1 + C2 + C3 + C4 + C5) |