daad79d28287de442316f311836bfcc48bf065bb
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| ff21120c8c |
[CLAUDE] Workflow: State machine 5 trạng thái — Trả lại = Phase riêng
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m17s
Session 17 spec: chốt 5 trạng thái phiếu PE/HĐ/Budget theo state diagram:
Nháp ─trình──► Đã gửi duyệt ─approve cấp cuối──► Đã duyệt (terminal)
├─ Trả lại ────────► Trả lại
└─ Từ chối ────────► Từ chối (terminal)
Trả lại ──Drafter sửa+gửi lại──► Đã gửi duyệt (chạy LẠI từ đầu)
Khác Mig 21 (Session 16): bỏ smart-reject jump-back. Trả lại = Phase
RIÊNG (TraLai=98), không revert về DangSoanThao + không jump-back step.
Drafter từ TraLai gửi lại như case Nháp — workflow chạy lại từ Cấp 1
Bước 1 (Option A diagram chốt với user).
BE Domain:
- ContractPhase + TraLai = 98
- BudgetPhase + TraLai = 98
- PurchaseEvaluationPhase: TraLai=98 đổi từ [LEGACY deprecated] thành
primary state. Comment update enum docs cho cả 3.
BE Policy (PE/HĐ/Budget):
- Reject transitions trỏ về TraLai (thay DangSoanThao)
- Mirror entry transitions: TraLai → next phase (cho Drafter resubmit)
- ActivePhases thêm TraLai
- FromDefinition mirror: TraLai → step.Phase + reject → TraLai
- DefaultSla cho TraLai = same as DangSoanThao
BE Service (PE + Contract):
- Reject branch: target=TuChoi giữ; else set Phase=TraLai, clear
CurrentWorkflowStepIndex=null
- Bỏ ResumeAfterReject branch + RejectedAtStepIndex/RejectedFromPhase
assignment (DB column giữ deprecated cho data cũ)
- Drafter trình branch: từ DangSoanThao HOẶC TraLai → ChoDuyet, init
CurrentWorkflowStepIndex=0 (cùng entry point, chạy lại từ đầu)
- Notification: TraLai when fromPhase=ChoDuyet → "bị trả lại"
- Budget Handler: simplify reject → TraLai, bỏ smart-reject + isResuming
BE Tests update:
- WorkflowPolicyTests: Standard_RejectFromCCM → TraLai (rename + assert)
+ Standard_TraLai_To_DangGopY_Allowed_For_Drafter (new)
- PurchaseEvaluationPolicyTests: BothPolicies_RejectFromCCM → TraLai
+ BothPolicies_TraLai_To_ChoPurchasing_AllowedForDrafter (new theory)
- BudgetPolicyTests: Default_CostControl_ChoCCM_To_TraLai (rename)
+ ActivePhases All6States (was All5) + NextPhasesFrom_TraLai (new)
+ NextPhasesFrom_ChoCEO_Includes_DaDuyet_And_TraLai (rename)
- 77 → 81 test pass (+4 tests TraLai entry point)
FE rename "Bản nháp" → "Nháp" (cả 2 app + types):
- types/purchaseEvaluation.ts: PurchaseEvaluationPhaseLabel 1=Nháp,
10=Đã gửi duyệt. PeDisplayStatus.BanNhap → Nhap (key + value).
PhaseLabel/Color cho TraLai update active.
- types/contracts.ts: +ChoDuyet=10, +TraLai=98 const + label/color.
Phase 2 'Đang soạn thảo' → 'Nháp'.
- types/budget.ts: +TraLai=98 const + label/color. Phase 1 → 'Nháp'.
- PeListPanel + PurchaseEvaluationsListPage filter dropdown: Nhap +
TraLai map đúng phase value.
BE label maps update consistent:
- ContractExcelExporter PhaseLabel: DangSoanThao → "Nháp" + add ChoDuyet/
TraLai entries.
- PeWorkflowAdminFeatures + WorkflowAdminFeatures PhaseLabels: same.
Verify: dotnet test 81 pass · npm build × 2 app pass · BE 0 error.
Field RejectedAtStepIndex/RejectedFromPhase giữ DB column (nullable,
không set value mới). Cleanup migration sau.
|
|||
| dbb0089e28 |
[CLAUDE] Drastic refactor: flat workflow Phòng × Cấp + Migration 21 (Chunk A)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m18s
User chốt drastic refactor — bỏ phase enum hoàn toàn, dùng ChoDuyet=10 đơn nhất + currentStepIndex tracking. Workflow flat list (Phòng × Cấp × Approvers). Mỗi PE/HĐ pin WorkflowDefinitionId chạy hết quy trình đó. Schema (Migration 21 `RefactorWorkflowToFlatModel`): - Phase enum +ChoDuyet=10 (PE + Contract). Legacy 2-9 + 98 deprecated. - WorkflowStep + DepartmentId Guid? (FK Restrict) + PositionLevel int? (PE + Contract — mirror). - PE/Contract + CurrentWorkflowStepIndex int? + RejectedAtStepIndex int? - DROP table PurchaseEvaluationWorkflowStepInnerSteps (Mig 18) - DROP table WorkflowStepInnerSteps (Mig 20) - DROP column ContractDeptApproval.InnerStepId (Mig 20) - DROP column PEDeptApproval.InnerStepId (Mig 18) - DROP filtered indexes (Mig 19/20) + restore simple unique (TargetId, Phase, Dept, Stage) non-filtered Service rewrite (PE + Contract WorkflowService.TransitionAsync): - Phase transitions: DangSoanThao → ChoDuyet (Drafter trình, init idx=0) - ChoDuyet → ChoDuyet (advance idx per approve) - ChoDuyet → DaDuyet/DaPhatHanh (idx >= steps.Count → terminal) - ChoDuyet → DangSoanThao (Trả lại — save RejectedAtStepIndex) - ChoDuyet → TuChoi (Từ chối — khoá vĩnh viễn) - DangSoanThao + RejectedAtStepIndex → ChoDuyet jump-back to saved idx - Approver match: actor.Dept == step.Dept AND actor.PositionLevel >= step.PositionLevel (OR-of-many cùng cấp/dept = pass) OR Approvers.Any(Kind=User AND id match) OR Approvers.Any(Kind=Role AND actorRoles contains) - Admin role bypass policy. Last step done → gen mã HĐ (Contract only) App CQRS: - WorkflowStepDto + WorkflowStepInput drop InnerStep, add DepartmentId + PositionLevel fields. PE + Contract mirror. Tests rewrite: - DROP PeNStageApprovalTests.cs (6 test) + ContractNStageApprovalTests.cs (6 test) + PeTwoStageApprovalTests.cs (7 test) — legacy N-stage/2-stage no longer applicable - UPDATE PeWorkflowAdminTests signature to new flat input - 96 → 77 test pass (drop 19 legacy) Reference Domain entities removed: - WorkflowStepInnerStep (Contract) - PurchaseEvaluationWorkflowStepInnerStep (PE) - DTOs WorkflowStepInnerStepDto / CreateWorkflowStepInnerStepInput per module Memory `feedback_drastic_refactor_scope.md` validated: drastic refactor done in dedicated session với context fresh, scope ~5h actual (planned ~8-10h with 2x buffer). Verify: - dotnet build SolutionErp.slnx 0 error - dotnet ef database update Mig 21 LocalDB applied OK - dotnet test 77 pass (54 Domain + 23 Infra) - 3-file rule: Migration .cs + Designer.cs + Snapshot updated Pending Chunk B: FE Designer flat UI (PeWorkflowsPage + WorkflowsPage). Pending Chunk C: FE PeWorkflowPanel + workflow timeline display. Pending Chunk D: Docs + Skill + Memory + session log. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 0d776987e4 |
[CLAUDE] PE workflow 3-button Duyệt/Trả lại/Từ chối (Task 4)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m6s
User chỉ thị thay 2-button hiện tại bằng 3 hành động rõ ràng:
- Duyệt = forward phase tiếp theo
- Trả lại = về DangSoanThao + Drafter sửa → workflow tự jump tới phase
đã reject (smart reject Mig 16 pattern + clear N-stage rows)
- Từ chối = phiếu khoá hoàn toàn (Phase=TuChoi → 17 handler Mig 16 lock
edit). Drafter phải tạo phiếu mới.
Domain (PurchaseEvaluationPolicy.cs):
- NccOnly + NccWithPlan: thêm (X → TuChoi) transition cho mọi phase
trung gian (ChoPurchasing/ChoCCM/ChoCEODuyetNCC/ChoDuAn/ChoCEODuyetPA)
với roles của phase đó. Trước đây chỉ DangSoanThao → TuChoi (Drafter).
- FromDefinition expand: mỗi step (trừ DangSoanThao) thêm
(step.Phase → TuChoi) với roles của step.
Service (PurchaseEvaluationWorkflowService.cs):
- Reject branch tách 2 case:
* target=TuChoi → giữ nguyên (KHÔNG override + KHÔNG set
RejectedFromPhase + KHÔNG clear N-stage rows). Phiếu khoá vĩnh viễn.
* target khác (thường DangSoanThao) → smart reject (set
RejectedFromPhase + force DangSoanThao + clear N-stage rows).
FE (PeWorkflowPanel.tsx, fe-admin + fe-user mirror):
- next.phases render 3 button rõ ràng:
* "✓ Duyệt → <label>" brand (forward)
* "← Trả lại (về Drafter sửa)" red (target=DangSoanThao + isSendBack)
* "✗ Hủy / Từ chối" red (target=TuChoi)
- Decision logic: target=TuChoi || isSendBack → Reject (2), else Approve (1)
- Dialog confirm:
* Title rõ theo loại hành động
* Cancel case: warning red "Phiếu sẽ bị khoá hoàn toàn"
* SendBack case: hint amber "Phiếu sẽ về Đang soạn thảo, Drafter sửa
rồi trình lại — workflow tự jump tới phase này"
Tests update + add 1 test mới:
- Reject_Sets_RejectedFromPhase_And_Forces_DangSoanThao →
Reject_To_DangSoanThao_Sets_RejectedFromPhase_TraLai (rename + change
target từ TuChoi → DangSoanThao để test Trả lại pattern)
- + Reject_To_TuChoi_Locks_Permanently_No_RejectedFromPhase (NEW test
Từ chối — phase=TuChoi + RejectedFromPhase null)
- NStage_Reject_Clears_InnerStep_Rows_At_Phase: target TuChoi →
DangSoanThao (test Trả lại + clear N-stage rows pattern)
Verify:
- dotnet build 0 error
- dotnet test 95 → **96 pass** (+1 test mới Từ chối)
- npm build fe-admin + fe-user pass
Pending Task 2: Sample data seed N-stage.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 7c0772acca |
[CLAUDE] Tests: Contract N-stage approval 6 test mirror PE (Chunk D)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m1s
ContractNStageApprovalTests.cs (NEW, 6 test) cover N-stage logic Mig 20 mirror PeNStageApprovalTests pattern: 1. NStage_FirstInner_NV_Approve_Blocks_Phase_Transition NV cấp 1 → 1 row InnerStepId set, phase chưa đổi. 2. NStage_All_3_Levels_Sequential_Pass_Allow_Phase_Transition NV → PP → TP duyệt lần lượt → 3 rows + phase chuyển. 3. NStage_TP_Bypass_Skips_Lower_Levels_Same_Dept TP có CanBypassReview → 1 transition tạo 3 rows (NV+PP IsBypassed, TP exact match). 4. NStage_Wrong_Department_Throws_Forbidden Actor dept khác inner step's dept → ForbiddenException. 5. NStage_Reject_Clears_InnerStep_Rows_At_Phase NV approve → 1 row. Admin reject → DangSoanThao + RejectedFromPhase set + N-stage rows cleared. 6. LegacyFallback_NoInnerSteps_Uses_2Stage_Logic Contract không pin WorkflowDefinitionId → fallback hardcoded Standard policy → no inner steps → legacy 2-stage Stage=Review row. Phase pair DangKiemTraCCM → DangTrinhKy + role CostControl khớp Standard.Transitions (DangGopY → DangDamPhan trong test ban đầu fail vì policy chỉ cho [Drafter, DeptManager]; switched to phase pair work). Helper SeedWorkflowDefinitionAsync 2 step adjacent (DangGopY + DangDamPhan) + SeedContractAsync với Project + Supplier seed cho FK. FakeChangelogService + FakeContractCodeGenerator stubs (no-op cho tests không cần verify changelog/codegen path). Verify: 89 → **95 test pass** (54 Domain + 41 Infra: 17 codegen + 6 PE WF versioning + 6 PE 2-stage + 6 PE N-stage + 6 Contract N-stage). Pending Chunk E: API check (Workflows controller likely auto-bind via DTO, skip nếu OK). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 3d76c6bc0c |
[CLAUDE] Tests: PE N-stage workflow approval (6 test) + IdentityFixture extend (Chunk D)
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Has been cancelled
PeNStageApprovalTests.cs (NEW, 6 test) cover N-stage logic Mig 18:
1. NStage_FirstInner_NV_Approve_Blocks_Phase_Transition
NV.PRO duyệt cấp 1 → 1 row InnerStepId set, phase chưa đổi (còn 2 cấp).
2. NStage_All_3_Levels_Sequential_Pass_Allow_Phase_Transition
NV → PP → TP duyệt lần lượt → 3 rows + phase chuyển. Order asc enforce.
3. NStage_TP_Bypass_Skips_Lower_Levels_Same_Dept
TP có CanBypassReview → 1 transition tạo 3 rows (NV+PP IsBypassed=true,
TP exact match). Audit chuẩn.
4. NStage_Wrong_Department_Throws_Forbidden
Actor dept khác inner step's dept → ForbiddenException.
5. NStage_Reject_Clears_InnerStep_Rows_At_Phase
NV approve → 1 row. Reject → DangSoanThao + RejectedFromPhase set +
N-stage rows cleared (resume sẽ approve lại).
6. LegacyFallback_NoInnerSteps_Uses_2Stage_Logic
PE không pin WorkflowDefinitionId → service fallback hardcoded policy →
no inner steps → legacy 2-stage Stage=Review/Confirm logic kick in.
IdentityFixture.CreateUserAsync extend +PositionLevel? param (default null
cho admin/system user).
Helper SeedWorkflowDefinitionAsync: tạo definition với 2 steps adjacent
(ChoPurchasing có inner steps + ChoCCM next) — đủ cho FromDefinition build
transition policy guard pass actor role Procurement.
Verify: 83 → **89 test pass** (54 Domain + 35 Infra: 17 codegen + 6 PE WF
versioning + 6 PE 2-stage + 6 PE N-stage). 0 fail.
Pending Chunk E: API endpoints (PATCH /users/{id}/position-level + DTO
extend in PeWorkflowsController bind tự động).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 8353fe87c0 |
[CLAUDE] Tests: Chunk E6 — 6 test 2-stage approval (PE) + IdentityFixture helper
Đóng "Tests Phase 3 mini cần UserManager DI helper" defer từ session 8. IdentityFixture (Common/IdentityFixture.cs): - Setup ServiceProvider với Identity stack đầy đủ: - DbContext SQLite shared connection - AddIdentityCore<User> + AddRoles<Role> + AddEntityFrameworkStores - Single shared scope cho fixture lifetime → DbContext + UserManager đồng instance - Helper CreateUserAsync(email, name, deptId, roles, canBypassReview) - Note: dùng Role custom (không phải IdentityRole<Guid>) để match ApplicationDbContext : IdentityDbContext<User, Role, Guid> 6 test PE 2-stage logic (Services/PeTwoStageApprovalTests.cs): - NV_Review_Blocks_Phase_Transition (đóng bug anh Kiệt — chính xác) - TPB_Confirm_After_NV_Review_Allows_Transition (happy path 2-stage) - NV_With_BypassReview_Allows_Transition_With_IsBypassed_True (bypass NV) - Admin_Skips_TwoStage_Logic_Entirely (admin bypass) - Reject_Sets_RejectedFromPhase_And_Forces_DangSoanThao (smart reject) - Resume_After_Reject_Jumps_Back_To_RejectedPhase (jump-back logic) Stub FakeNotificationService — best effort path không cần verify. Note: tests cho Contract + Budget 2-stage skip — logic identical PE, ROI thấp. Pattern PeTwoStageApprovalTests reusable nếu cần test riêng tương lai. Total: 54 Domain + 29 Infra (17 codegen + 6 PE WF Application + 6 PE 2-stage) = **83 test pass** (+6 mới). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| b874743081 |
[CLAUDE] Docs+Tests: chốt final session 5 — 77 test (Phase 3 mini PE WF) + 3 gotcha CI + 8 doc updates
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m21s
Final close session 5 — bao gồm: ==== Tests Phase 3 mini (NEW) ==== tests/SolutionErp.Infrastructure.Tests/Application/PeWorkflowAdminTests.cs - 6 test CreatePeWorkflowDefinitionCommandHandler: - First version → IsActive=true, Version=1, ActivatedAt set - Second version same Code → auto-increment v2 + deactivate v1 (atomic) - Different EvaluationType (A vs B) → independent active state - Persists steps ordered by Order field - Persists approvers per step - Third version → v1 + v2 deactivate, v3 active Total tests: 71 → 77 pass / ~2s (54 Domain + 23 Infra). Skip Phase 3 full (UpsertOpinion + Budget link validation) — cần Identity UserManager DI helper, defer session sau. ==== 3 gotcha CI mới (#39 #40 #41) ==== - #39 act_runner github.com TCP timeout 21s → manual checkout fix (run #108/#109 fail, #110 pass) - #40 npm junction cache `tsc not found` after Move-Item — rolled back, hypothesis nested junctions trong node_modules disrupt .bin/ paths. TODO debug session sau với robocopy hoặc act_runner cache.host - #41 Gitea Actions paths-ignore behavior — workflow file change vẫn trigger (correct), commit MD-only skip 100% (verify |
|||
| df5988b7a9 |
[CLAUDE] Tests Phase 2: Code generator format + sequence tests (SQLite in-memory)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m16s
Phase 2 — chống regression code generator. 17 test mới integration với
DB thật (SQLite in-memory) tổng cộng 71 test pass < 3 giây.
Test project:
- tests/SolutionErp.Infrastructure.Tests/ (xUnit + FluentAssertions + EF SQLite 10)
- ProjectReference SolutionErp.Infrastructure (transitively get Application + Domain)
- Added vào SolutionErp.slnx
Test fixtures:
- Common/SqliteDbFixture.cs:
- SQLite ":memory:" + shared connection + EnsureCreated() từ DbContext model
- TestApplicationDbContext subclass — override OnModelCreating replace
'nvarchar(max)' → 'TEXT' (SQLite không support max keyword)
- FixedDateTime stub IDateTime cho deterministic year boundary test
Test files:
- Services/ContractCodeGeneratorTests.cs (10 test):
- Format per ContractType (5 type × Project scope) — RG-001 spec
- Framework HĐ (NguyenTacNCC + NguyenTacDV) → year scope thay vì project
- Sequence increment per prefix (3 calls → /01, /02, /03)
- Different prefixes (project / supplier) → independent sequences
- Year change (2026 → 2027) → reset sequence vì prefix khác
- PersistsSequenceRow LastSeq verification
- Services/PurchaseEvaluationCodeGeneratorTests.cs (7 test):
- Format A/B (DuyetNcc → 'A', DuyetNccPhuongAn → 'B')
- Seq là 3-digit padded (001..012)
- Type A và B sequence độc lập trong cùng năm
- Year boundary reset cả A và B
CI gate update (.gitea/workflows/deploy.yml):
- Step "Run integration tests (Infrastructure)" thêm sau Domain tests
- TRX log saved riêng (infra-tests.trx)
- Cả 2 step đều exit non-zero → no deploy
Verify local:
- dotnet test SolutionErp.slnx → Total tests: 71 (54 Domain + 17 Infra) / Passed: 71 / 2.1s
- dotnet build SolutionErp.slnx → 0 error
Phase 3+ pending:
- Application handler tests (CQRS) với EF InMemory hoặc SQLite (~1 ngày)
- API smoke tests qua WebApplicationFactory (~0.5 ngày)
- FE Vitest cho lib utility (~0.5 ngày)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| d3f9346840 |
[CLAUDE] Tests Phase 1: Domain unit tests + CI gate (xUnit + FluentAssertions)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m25s
Phase 1 (MVP) — chống regression Workflow state machine. 54 test pure function (no DB / IO), all pass < 7 giây. Test project: - tests/SolutionErp.Domain.Tests/ (xUnit 2.9.3 + FluentAssertions 7.2 — pin trước v8 commercial license) - ProjectReference SolutionErp.Domain - Added vào SolutionErp.slnx folder /tests/ Test files: - Contracts/WorkflowPolicyTests.cs (~17 test): - Standard policy 9-phase: role transitions, CCM check, BOD signing, terminal - SkipCcm policy 7-phase: bypass CCM verify, no DangKiemTraCCM transition - Registry: DefaultPolicyName per ContractType (7 type), bypass flag override - FromDefinition versioned: build từ ordered steps + reject path + TuChoi auto-add + UserKindApprover populate UserTransitions - PurchaseEvaluations/PurchaseEvaluationPolicyTests.cs (~17 test): - NccOnly (A) 3-step: skip ChoDuAn + ChoCEODuyetPA, CCM đẩy thẳng CEO duyệt NCC - NccWithPlan (B) 5-step: có ChoDuAn (PM) + ChoCEODuyetPA (Director) trước - Reject path cả 2 quy trình về DangSoanThao - Registry mapping per PEType - Budgets/BudgetPolicyTests.cs (~13 test): - Default 3-step (Drafter→CCM→CEO) role guard - Reject paths về DangSoanThao - DaDuyet + TuChoi terminal (no NextPhases) - SLA spec 5d/3d/2d cho 3 phase đầu CI gate (.gitea/workflows/deploy.yml): - Step "Run unit tests (Domain)" thêm TRƯỚC build/publish/deploy - Test fail (LASTEXITCODE != 0) → exit → KHÔNG deploy - TRX log saved + upload artifact (continue-on-error nếu Gitea runner thiếu actions/upload-artifact) Verify local: - dotnet test tests/SolutionErp.Domain.Tests → Total tests: 54 / Passed: 54 / 6.4s - dotnet build SolutionErp.slnx (full solution incl. test project) → 0 error Phase 2-5 pending (xem plan ở chat): - Code generator atomic concurrency tests (Infra) - DbInitializer reconcile drift tests (Infra) - Application handler smoke tests (CQRS) với EF InMemory - API smoke tests qua WebApplicationFactory - FE Vitest cho lib utility (queryMatches, fmtMoney) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |