Files
solution-erp/docs/changelog/sessions/2026-05-07-2500-3-button-workflow.md
pqhuy1987 7c83ac8f17 [CLAUDE] Docs+Skill: chốt Session 14 wrap-up — PE 3-button workflow + Task 2 defer
Session 14 (2026-05-07) docs/skill update:

STATUS.md:
- Last updated + Phase summary count (95→96 test, 20 mig, 57 bảng, 41 gotcha)
- Recently Done row Session 14 chi tiết (3-button + Task 2 in-progress + DesignTime/Runtime DB gotcha)

HANDOFF.md:
- TL;DR Session 14 prepend với 1 commit + Task 2 defer
- 5 cảnh báo Session 15+: TraLai phase orphan / Task 2 sample seed / DesignTime
  vs Runtime DB / Budget N-stage defer / schema-diagram §17-19 defer

migration-todos.md: Phase 9 + Session 14 block 4 sub-task done + 2 defer task

Session log NEW `2026-05-07-2500-3-button-workflow.md`:
- Bối cảnh + spec 3-button (Duyệt/Trả lại/Từ chối) + implementation chi tiết
  (Domain policy expand + Service tách reject + FE button + dialog warning)
- Tests update (95→96 với +1 NEW Reject_To_TuChoi_Locks_Permanently)
- Task 2 in-progress: DesignTime vs Runtime DB gotcha + API exit 255 sớm
- Plan organization sau S14

Skill ef-core-migration:
- description + heading: 17→20 migration
- Bảng migration history thêm Mig 18-19 (PE) + Mig 20 (Contract)
- Section MỚI "N-stage workflow pattern (Mig 18-20)" — architecture decision
  với filtered unique trick + per-module migration packaging guideline
- Phase 8 update: 83→96 test breakdown

Skill contract-workflow:
- Section MỚI "Phase 9+ done (Mig 18-20 — Session 12/13/14)":
  * N-stage workflow PE + Contract (entity + filtered unique split + service
    refactor + tests + FE Designer + UsersPage cấp + API)
  * PE 3-button approval (Duyệt/Trả lại/Từ chối) Session 14
  * Defer: Budget N-stage / Phase TraLai=98 orphan

CLAUDE.md root: 16→20 migration + 55→57 bảng + 83→96 test
docs/rules.md §7: Phase 9 active 83→96 test

Verify: dotnet test 96 pass + npm build (skip — pure docs/skill update).

🎉 Session 14 wrap-up complete. Pushed 1 task (3-button) + Task 2 defer.
Cumulative since session start (13h17): 13 commit (1 button removal +
6 PE N-stage Chunk A-F + 5 Contract N-stage Chunk A,B,C,D,F + 1 3-button).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 19:40:00 +07:00

151 lines
6.7 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 (S14) — PE 3-button workflow Duyệt/Trả lại/Từ chối
**Dev:** Claude
**Duration:** ~1h
**Base commit:** `b06bdce` (sau Session 13 Contract N-stage mirror)
**Final commit:** `0d77698` (+ Task 2 in-progress, không commit)
## Bối cảnh
Sau Session 11+++++++ user thêm Phase TraLai = 98 + FE label/badge. Session 12 bỏ qua wire BE TraLai. Session 14 này user chốt: KHÔNG cần Phase TraLai trung gian (orphan). Thay vào: 3-button approval rõ ràng.
User wording: "Duyệt Trả lại và Từ chối. Từ chối thì xem như phải làm phiếu mới (khóa hết chức năng). Trả lại → đc điều chỉnh → Gửi duyệt."
## Spec chốt
3 hành động cho approver:
- **Duyệt** = forward phase tiếp theo (decision=Approve, target=next phase)
- **Trả lại** = về DangSoanThao + Drafter sửa (decision=Reject, target=DangSoanThao). Smart reject pattern Mig 16 — set RejectedFromPhase + clear N-stage rows tại fromPhase + Drafter resume jump-back tới phase đã reject.
- **Từ chối** = Phase=TuChoi (decision=Reject, target=TuChoi). Phiếu khoá vĩnh viễn (17 handler Mig 16 lock edit khi Phase != DangSoanThao). Drafter phải tạo phiếu mới.
## Implementation (1 commit `0d77698`)
### Domain — `PurchaseEvaluationPolicy.cs`
**NccOnly** + **NccWithPlan** thêm `(X → TuChoi)` transition cho mọi phase trung gian với roles của phase đó:
```csharp
[(ChoPurchasing, TuChoi)] = [Procurement],
[(ChoCCM, TuChoi)] = [CostControl],
[(ChoCEODuyetNCC, TuChoi)] = [Director, AuthorizedSigner],
// + ChoDuAn, ChoCEODuyetPA cho NccWithPlan
```
**FromDefinition** expand: mỗi step (trừ DangSoanThao) thêm `(step.Phase → TuChoi)` với roles step. Trước đây chỉ DangSoanThao→TuChoi (Drafter).
### Service — `PurchaseEvaluationWorkflowService.TransitionAsync`
Reject branch tách 2 case:
```csharp
if (decision == Reject) {
if (target != TuChoi) { // "Trả lại"
RejectedFromPhase = fromPhase
target = DangSoanThao // force
clear N-stage rows tại fromPhase
}
// else target=TuChoi: giữ nguyên TuChoi, KHÔNG set RejectedFromPhase, KHÔNG clear N-stage
// Phiếu khoá vĩnh viễn — không resume.
}
```
### FE — `PeWorkflowPanel.tsx` (admin + user mirror)
3 button rõ ràng:
- "✓ Duyệt → <label phase>" brand (forward)
- "← Trả lại (về Drafter sửa)" red khi `target=DangSoanThao && fromPhase != DangSoanThao`
- "✗ Hủy / Từ chối" red khi `target=TuChoi`
Decision logic FE: `isReject = target=TuChoi || isSendBack`.
Dialog confirm:
- Title rõ theo loại hành động
- Cancel case: warning red "⚠ Phiếu sẽ bị khoá hoàn toàn. Drafter cần tạo phiếu mới nếu muốn làm lại"
- SendBack case: hint amber "Phiếu sẽ về 'Đang soạn thảo'. Drafter có thể sửa rồi trình lại — workflow tự jump tới phase này"
### Tests
- **Rename** `Reject_Sets_RejectedFromPhase_And_Forces_DangSoanThao``Reject_To_DangSoanThao_Sets_RejectedFromPhase_TraLai` (change target từ TuChoi → DangSoanThao để test Trả lại pattern)
- **NEW** `Reject_To_TuChoi_Locks_Permanently_No_RejectedFromPhase` — Phase=TuChoi + RejectedFromPhase=null
- **Update** `NStage_Reject_Clears_InnerStep_Rows_At_Phase` target → DangSoanThao
**95 → 96 test pass** (+1 Từ chối).
## Task 2 sample seed — IN-PROGRESS (defer S15+)
User yêu cầu seed sample data N-stage cho Duyệt NCC. Plan:
1. Update `Users.PositionLevel` (1=NV, 2=PP, 3=TP) cho 30 demo user đã seed
2. INSERT N-stage WorkflowDefinition v2 cho DuyetNcc với InnerSteps (PRO + CCM × 3 cấp NV/PP/TP)
Phát hiện gotcha quan trọng:
- `DesignTimeDbContextFactory` hardcoded `SolutionErp_Design` connection string. `dotnet ef database update` từ Session 12-13 thực ra apply lên `_Design` DB, KHÔNG `_Dev` runtime DB.
- Runtime API dùng `_Dev` (appsettings.Development.json `ConnectionStrings:Default`).
- DbInitializer.MigrateAsync chạy khi API startup → auto apply migrations lên `_Dev`.
Đã xử lý:
- `dotnet ef database update --connection "...SolutionErp_Dev..."` apply Mig 9-20 lên `_Dev` (trước chỉ Mig 1-8).
- Start API để DbInitializer auto-seed 30 demo user. API exit 255 sớm khi log buffer full (~100 lines) — seeding dở dang (chỉ seed Roles, chưa Users).
Defer Session 15+ vì cần guidance:
- (a) User manual `dotnet run` API 1 lần hoàn thành seed → Claude resume seed sample N-stage
- (b) Claude resume với output redirect to file (skip log overflow)
- (c) Manual SQL seed users (nhưng PasswordHash phức tạp)
## Verify
-`dotnet build` 0 error
-`dotnet test` **96 pass** (54 Domain + 42 Infra)
-`npm build` fe-admin + fe-user pass
- ⏸ E2E manual UAT — defer cho user thử 3-button trên menu Duyệt PE
## Bug + Fix log
| # | Issue | Fix |
|---|---|---|
| 1 | Test cũ assume target=TuChoi → Service force DangSoanThao | Update tests: 1 rename + change target sang DangSoanThao + 1 NEW test cho Từ chối behavior |
| 2 | DesignTime vs Runtime DB distinction | `--connection` flag override khi `dotnet ef database update` |
## Docs updates
- ✅ STATUS.md — Last updated + Phase summary count + Recently Done row Session 14 (KEEP narrative)
- ✅ HANDOFF.md — TL;DR Session 14 prepend + 5 cảnh báo Session 15+
- ✅ migration-todos.md — Phase 9 + Session 14 block + 2 defer task
- ✅ Session log (file này)
- ⏸ schema-diagram.md §17 Mig 18 / §18 Mig 19 / §19 Mig 20 — defer cron audit 2026-06-01
## Stats cumulative (sau Session 14)
| | Trước S14 | Sau S14 | Diff |
|---|---:|---:|---:|
| BE LOC | ~15700 | ~15800 | +100 |
| API endpoints | ~134 | ~134 | 0 |
| Migrations | 20 | 20 | 0 |
| DB tables | 57 | 57 | 0 |
| FE pages | 32 | 32 | 0 |
| Tests | 95 | **96** | +1 (Từ chối) |
| Docs | ~57 | ~58 | +1 (session log này) |
| Commits | (after S13) | **+1** | `0d77698` |
## Plan organization sau session 14
```
Plan cha: Phase 9 active — UAT
├── Plan con A: Hard blockers (chờ user/ops) — 6 task
├── ...
├── Plan con S12 ✅ DONE: N-stage PE (Mig 18+19, 6 chunk)
├── Plan con S13 ✅ DONE: N-stage Contract (Mig 20, 5 chunk + skip E)
├── Plan con S14 ✅ DONE: PE 3-button workflow (1 commit)
├── Plan con Task 2 ⏸ DEFER: Sample seed N-stage
└── Plan con Defer S15+:
├── Budget N-stage (cần versioned WF migration trước)
├── Phase TraLai=98 cleanup (orphan, ko gây hại)
├── schema-diagram §17-19 Mig 18-20
└── Skill ef-core-migration / contract-workflow refresh (cron audit)
```
## Handoff
UAT iteration mode. PE 3-button approval ready test. Workflow N-stage Contract + PE backward compat 100% với 2-stage Mig 16.
**Cron audit kế:** 2026-06-01 (~25 ngày).