Files
solution-erp/docs/changelog/sessions/2026-05-07-2300-pe-hd-manual-budget-mig17.md
pqhuy1987 bf177408b0
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m17s
[CLAUDE] Docs: chốt Session 11 — Migration 17 manual budget fields PE + HĐ
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>
2026-05-07 12:43:00 +07:00

117 lines
7.4 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.

# 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) |