[CLAUDE] Domain+App+Infra: Plan B G-H1 Mig 34 EmployeeProfile + seed 30 demo
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m38s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m38s
Phase 10.1 G-H1 Hồ sơ Nhân sự Foundation — port từ NamGroup CT_NHANSU
(1675 NV, 10 bảng TblNhanVien*) sau anh main chốt S32 4 quyết định
(scope FULL 11 module + DB single schema dbo + reuse Workflow V2 +
chunk per-module Plan riêng). G-H1 CRITICAL FIRST vì depend by 8/11
module Phase 10 sau (Đề xuất/Đơn từ/OT/Đặt xe/Ticket/Dashboard NS/
Chấm công đều cần EmployeeProfile data).
Investigator pre-flight (a103d20) audit NamGroup confirm:
- Main TblNhanVien 105 cols (drop 35 cols duplicate User/UX legacy)
- 5 satellite Phase 10.1 (defer 3 HĐLĐ Plan H2): WorkHistory + Education
+ FamilyRelation + Skill polymorphic Kind + Document
- 6 enum thay catalog FK (Gender/MaritalStatus/EmployeeStatus/...)
- DiaChi dual-write FK + freetext lesson Plan C NamGroup 1675 NV drift
Em main 4 decision chốt:
1. 5 satellite Phase 10.1 (defer 3 HĐLĐ Plan H2)
2. Skill polymorphic Kind enum (gộp 3 NamGroup table)
3. DiaChi 6 FK Province/District/Ward declare nullable + freetext dual-write
ngày đầu (FK constraint defer G-H2 khi catalog scaffold — Implementer
smart decision documented EmployeeProfile.cs comment line 14-17)
4. MaNhanVien format NV/{YYYY}/{Seq:D4} atomic Serializable reset/year
Implementer Case 2 (a8f4567) Pattern 12-bis cross-module mirror PE → Hrm
cookie-cutter scaffold 17 file mới + 4 modified + 3-file mig rule:
Domain (8 file SolutionErp.Domain.Hrm):
- EmployeeProfile.cs (main ~70 cols inherit AuditableEntity, 1-1 UNIQUE User)
- EmployeeWorkHistory.cs + EmployeeEducation.cs + EmployeeFamilyRelation.cs
- EmployeeSkill.cs (polymorphic Kind=Computer/Language/Other)
- EmployeeDocument.cs (IdCard/Passport/Degree/Certificate/LaborContract/Other)
- EmployeeCodeSequence.cs (PK string Prefix, NOT BaseEntity Id Guid)
- Enums.cs (10 enum gọn 1 file)
Application (1 file):
- IEmployeeCodeGenerator.cs interface (mirror IContractCodeGenerator)
Infrastructure (8 file):
- EmployeeCodeGenerator.cs impl IsolationLevel.Serializable transaction
- 7 EF Configuration file (HasIndex UNIQUE UserId/EmployeeCode/Phone +
HasMaxLength + HasColumnType decimal(18,2) + FK Cascade satellite)
- DependencyInjection.cs (M): register IEmployeeCodeGenerator → impl
Persistence (3 file modified + 2 new mig + 1 snapshot):
- IApplicationDbContext.cs (M): +7 DbSet<EmployeeProfile/...>
- ApplicationDbContext.cs (M): +7 DbSet impl
- ApplicationDbContextModelSnapshot.cs (M): EF auto-update
- 20260526110207_AddEmployeeProfiles.cs (NEW, EF auto-gen)
- 20260526110207_AddEmployeeProfiles.Designer.cs (NEW, EF auto-gen)
DbInitializer.cs (M, em main solo Task 3b ~90 LOC):
- using SolutionErp.Domain.Hrm import added
- SeedDemoEmployeeProfilesAsync method appended (end of class)
- Register call after SeedDemoUsersAsync line 88 (depend user exist first)
- NOT gated DemoSeed:Disabled flag (infrastructure data per gotcha #51 lesson)
- 30 demo profile mirror 30 user @solutions.com.vn + sequential code
NV/{YYYY}/0001..0030 + placeholder masked CMND/BHXH/Bank (bro UAT update
qua FE Page Task 5) + EmployeeCodeSequence row LastSeq=30 → production
gen tiếp 0031+
Verify:
- dotnet build: 0 err 2 unrelated warn DocxRenderer (2.49s + 7.86s rebuild)
- dotnet ef database update _Dev: Mig 34 applied (top of __EFMigrationsHistory)
- dotnet test: **120/120 PASS** baseline preserved (no test add Phase 10
test-after per §7 UAT mode — test bundle defer Task 4+5+6 done)
Stats target Phase 10 end: 33→42 mig (+9 Mig 34-42), 60→85 tables (+25),
~148→250 endpoint (+100), 38→60 FE pages (+22). Current after this commit:
33→34 mig + 60→66 tables + endpoint/FE unchanged (G-H1 Task 4+5 next).
Pattern reusable cross-project:
- Pattern 12-bis cross-module entity cookie-cutter mirror reinforced 3×
(S29 Plan B Contract V2 + S33 Plan B G-H1 EmployeeProfile)
- Infrastructure seed OUT of DemoSeed gate (gotcha #51 lesson, mirror Mig 32
SeedSampleContractWorkflowV2)
- DiaChi dual-write FK + freetext từ ngày đầu (NamGroup 1675 NV drift lesson)
Pending Plan B G-H1 Phase 2 (chờ anh main signal kick off):
- Task 4 — Implementer BE CQRS handler + 6 endpoint controller
- Task 5 — Implementer FE 2 app EmployeesPage 3-panel + 6 section tabs
- Task 6 — Em main Permission menu Hrm_HoSo* seed
- Task 7 — Reviewer pre-commit + CICD post-deploy verify
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -4,6 +4,7 @@ using SolutionErp.Domain.Budgets;
|
||||
using SolutionErp.Domain.Contracts;
|
||||
using SolutionErp.Domain.Contracts.Details;
|
||||
using SolutionErp.Domain.Forms;
|
||||
using SolutionErp.Domain.Hrm;
|
||||
using SolutionErp.Domain.Identity;
|
||||
using SolutionErp.Domain.Master;
|
||||
using SolutionErp.Domain.Master.Catalogs;
|
||||
@ -83,5 +84,16 @@ public interface IApplicationDbContext
|
||||
DbSet<BudgetChangelog> BudgetChangelogs { get; }
|
||||
DbSet<BudgetDepartmentApproval> BudgetDepartmentApprovals { get; }
|
||||
|
||||
// Phase 10.1 G-H1 (Mig 34 — S33) — Hồ sơ Nhân sự port từ NamGroup.
|
||||
// 1 main + 5 satellite + 1 sequence. 1-1 với User qua UserId UNIQUE.
|
||||
// 3 HĐLĐ satellite defer Plan H2 sau.
|
||||
DbSet<EmployeeProfile> EmployeeProfiles { get; }
|
||||
DbSet<EmployeeWorkHistory> EmployeeWorkHistories { get; }
|
||||
DbSet<EmployeeEducation> EmployeeEducations { get; }
|
||||
DbSet<EmployeeFamilyRelation> EmployeeFamilyRelations { get; }
|
||||
DbSet<EmployeeSkill> EmployeeSkills { get; }
|
||||
DbSet<EmployeeDocument> EmployeeDocuments { get; }
|
||||
DbSet<EmployeeCodeSequence> EmployeeCodeSequences { get; }
|
||||
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
namespace SolutionErp.Application.Hrm.Services;
|
||||
|
||||
// Atomic sequence generator cho MaNhanVien — mirror IContractCodeGenerator
|
||||
// + IPurchaseEvaluationCodeGenerator pattern.
|
||||
//
|
||||
// Format: "NV/{YYYY}/{Seq:D4}"
|
||||
// - YYYY = năm hiện tại (UTC)
|
||||
// - Seq = 4 chữ số tăng dần, reset per năm
|
||||
//
|
||||
// VD: NV/2026/0001, NV/2026/0002, ... ; sang 2027 reset NV/2027/0001.
|
||||
//
|
||||
// Transaction SERIALIZABLE để tránh race condition khi 2 admin tạo NV cùng lúc.
|
||||
public interface IEmployeeCodeGenerator
|
||||
{
|
||||
Task<string> GenerateAsync(CancellationToken ct = default);
|
||||
}
|
||||
Reference in New Issue
Block a user