[CLAUDE] Domain+App+Infra+Api+FE-Admin+FE-User: S38 G-O4+G-O5+G-O6+G-P1+G-H3 SKELETON full-stack
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m53s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m53s
Phase 10.3-10.4 SKELETON 5 plan combo finish — Mig 39+40 + BE skeleton 7 module + FE 2 app SHA256 IDENTICAL + 11 menu key. UAT visible end-to-end. ⚠️ SKELETON Phase 1 trade-off rõ: - Status flat 5-state WorkflowAppStatus enum share Leave/OT/Travel/Vehicle - ApproveV2 workflow advance DEFER Phase 11 (Drafter Create OK, Approve flow chưa wire) - LevelOpinions per-module DEFER Phase 11 - LeaveBalance calc + Auto-assign + SLA timer DEFER Phase 11 - CodeGen atomic + MaDonTu/MaTicket gen DEFER Phase 11 - Vehicle catalog + Driver catalog DEFER Phase 11 (free text VehicleLicense) - ItTicketComments thread DEFER Phase 11 (free text Resolution field) Mig 39 (em main solo): 5 entity Workflow Apps schema - LeaveRequest (G-O4, FK LeaveType Hrm Mig 35, ApplicableType=5) - OtRequest (G-O4, FK OtPolicy optional, ApplicableType=6) - TravelRequest (G-O4, reuse ApplicableType=4 Proposal) - VehicleBooking (G-O5, free text vehicle, ApplicableType=7) - ItTicket (G-O6, NO workflow V2 — kanban status flow) Mig 40 (em main solo): Attendance entity (G-P1) - GPS lat/long check-in/out + Source enum Web/Mobile/Device - UNIQUE composite (UserId, AttendanceDate) - WorkHours computed simple diff (NO OtPolicy multiplier yet) BE CQRS (em main solo, single mega ~1100 LOC): - WorkflowAppsFeatures.cs 7 region (5 module Create+List + Attendance CheckIn/Out/GetMonth + HrDashboard) - 7 Controller: /api/leave-requests + /ot-requests + /travel-requests + /vehicle-bookings + /it-tickets + /attendances + /hr/dashboard - Class-level [Authorize] any authenticated - 13 endpoint total FE 2 app (em main solo fallback gotcha #53 risk): - types/workflowApps.ts × 2 SHA256 IDENTICAL 77470e182a15de88 (all DTOs + Status badge) - WorkflowAppsListPage.tsx × 2 IDENTICAL 58139d0301a60ddf — generic declarative KIND_CONFIG handles 4 module (Leave/OT/Travel/Vehicle) - ItTicketsPage.tsx × 2 IDENTICAL d3062de2f54c794c — kanban 5 status column - MyAttendancePage.tsx × 2 IDENTICAL 86da48ae147db012 — GPS check-in/out + tháng calendar - HrmDashboardPage.tsx × 2 IDENTICAL d9c6c12a5a8694f8 — 4 KPI card + gender ratio + status breakdown - Pattern 16-bis 9× cumulative (App.tsx +4 routes + menuKeys +8 const + Layout staticMap +7 entry) - 7 amber banner "Skeleton Phase 1 — full feature Phase 11" rõ ràng UAT Menu seed: +11 const + SeedMenuTreeAsync 8 row (Off_DonTu sub-group + 3 leaf + Off_DatXe + Off_ItTicket + Off_ChamCong + Hrm_Dashboard). DbInitializer Sample workflow seed DEFER (workflows V2 already seeded từ S29+S37 reuse — admin clone tạo riêng per ApplicableType=5/6/7). Verify: - dotnet build PASS 0 error 2 pre-existing warning - dotnet test 130/130 PASS baseline preserve - npm build × 2 PASS clean - SHA256 verify 5 file × 2 app all IDENTICAL Plan G-* progress 11/11 ✅ (100% COMPLETE): ✅ G-H1 (S33) + G-O1 (S34) + G-H2 (S35) + G-O2 (S36) + G-O3 (S37) + ✅ G-O4 + G-O5 + G-O6 + G-P1 + G-H3 (S38 skeleton) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -111,6 +111,16 @@ public static class MenuKeys
|
||||
public const string OffDeXuatCreate = "Off_DeXuat_Create"; // Tạo đề xuất mới
|
||||
public const string OffDeXuatInbox = "Off_DeXuat_Inbox"; // Inbox phê duyệt
|
||||
|
||||
// Phase 10.3-10.4 G-O4+G-O5+G-O6+G-P1 (Mig 39+40 — S38 2026-05-28) — Skeleton Workflow Apps.
|
||||
public const string OffDonTu = "Off_DonTu"; // sub-group Đơn từ
|
||||
public const string OffDonTuLeave = "Off_DonTu_Leave"; // Đơn nghỉ phép
|
||||
public const string OffDonTuOt = "Off_DonTu_Ot"; // Đơn OT
|
||||
public const string OffDonTuTravel = "Off_DonTu_Travel"; // Đơn công tác
|
||||
public const string OffDatXe = "Off_DatXe"; // Đặt xe công
|
||||
public const string OffItTicket = "Off_ItTicket"; // Ticket CNTT helpdesk
|
||||
public const string OffChamCong = "Off_ChamCong"; // Chấm công GPS (G-P1)
|
||||
public const string HrmDashboard = "Hrm_Dashboard"; // Dashboard HRM (G-H3)
|
||||
|
||||
public static readonly string[] PurchaseEvaluationTypeCodes =
|
||||
["DuyetNcc", "DuyetNccPhuongAn"];
|
||||
|
||||
@ -140,6 +150,8 @@ public static class MenuKeys
|
||||
Off, OffDanhBa, // Phase 10.2 G-O1 — Văn phòng số
|
||||
OffPhongHop, OffPhongHopView, OffPhongHopManage, OffPhongHopBook, // Phase 10.2 G-O2 — Phòng họp
|
||||
OffDeXuat, OffDeXuatList, OffDeXuatCreate, OffDeXuatInbox, // Phase 10.3 G-O3 — Đề xuất
|
||||
OffDonTu, OffDonTuLeave, OffDonTuOt, OffDonTuTravel, // Phase 10.3 G-O4 — Đơn từ
|
||||
OffDatXe, OffItTicket, OffChamCong, HrmDashboard, // Phase 10.3-10.4 — G-O5/G-O6/G-P1/G-H3
|
||||
System, Users, Roles, Permissions, MenuVisibility, Workflows, PeWorkflows,
|
||||
ApprovalWorkflowsV2, ApprovalWorkflowDuyetNccV2, ApprovalWorkflowDuyetNccPhuongAnV2, // Mig 22
|
||||
];
|
||||
|
||||
45
src/Backend/SolutionErp.Domain/Office/Attendance.cs
Normal file
45
src/Backend/SolutionErp.Domain/Office/Attendance.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.4 G-P1 (Mig 40 — S38 2026-05-28) — Chấm công.
|
||||
// Pure web GPS check-in (NO device integration per anh main chốt S32).
|
||||
// Mỗi row = 1 ngày × 1 user. Composite UNIQUE (UserId, AttendanceDate).
|
||||
// Monthly report aggregate query — OT calc tham chiếu Hrm_OtPolicy (Mig 35).
|
||||
public class Attendance : AuditableEntity
|
||||
{
|
||||
public Guid UserId { get; set; }
|
||||
public string UserFullName { get; set; } = string.Empty; // denorm
|
||||
|
||||
public DateTime AttendanceDate { get; set; } // chỉ Date (Time=00:00)
|
||||
|
||||
public DateTime? CheckInAt { get; set; } // UTC datetime full timestamp
|
||||
public DateTime? CheckOutAt { get; set; }
|
||||
|
||||
// GPS coordinates check-in (lat, long, accuracy meters)
|
||||
public decimal? CheckInLatitude { get; set; }
|
||||
public decimal? CheckInLongitude { get; set; }
|
||||
public decimal? CheckInAccuracy { get; set; }
|
||||
public decimal? CheckOutLatitude { get; set; }
|
||||
public decimal? CheckOutLongitude { get; set; }
|
||||
public decimal? CheckOutAccuracy { get; set; }
|
||||
|
||||
public AttendanceSource SourceIn { get; set; } = AttendanceSource.Web;
|
||||
public AttendanceSource SourceOut { get; set; } = AttendanceSource.Web;
|
||||
|
||||
public string? IpAddressIn { get; set; }
|
||||
public string? IpAddressOut { get; set; }
|
||||
|
||||
public string? Note { get; set; } // "Đi muộn do tắc đường"
|
||||
|
||||
// Computed total work hours (decimal hours, vd 8.5 = 8h30min)
|
||||
public decimal? WorkHours { get; set; }
|
||||
public decimal? OtHours { get; set; } // hours beyond shift end
|
||||
}
|
||||
|
||||
public enum AttendanceSource
|
||||
{
|
||||
Web = 1,
|
||||
Mobile = 2,
|
||||
Device = 3, // device integration future (vân tay/face recog)
|
||||
}
|
||||
@ -22,3 +22,42 @@ public enum ProposalStatus
|
||||
TuChoi = 4, // Terminal — không thể edit/resubmit
|
||||
DaDuyet = 5, // Terminal — workflow complete tất cả Cấp
|
||||
}
|
||||
|
||||
// Phase 10.3 G-O4 (Mig 39 — S38 2026-05-28) — 5-state generic workflow status share.
|
||||
// Dùng chung cho LeaveRequest + OtRequest + TravelRequest + VehicleBooking + ItTicket.
|
||||
// Skeleton Phase 1: ApproveV2 wire DEFER Phase 11 polish.
|
||||
public enum WorkflowAppStatus
|
||||
{
|
||||
Nhap = 1,
|
||||
DaGuiDuyet = 2,
|
||||
TraLai = 3,
|
||||
TuChoi = 4,
|
||||
DaDuyet = 5,
|
||||
}
|
||||
|
||||
// G-O6 IT Ticket category + priority enum.
|
||||
public enum ItTicketCategory
|
||||
{
|
||||
Hardware = 1,
|
||||
Software = 2,
|
||||
Network = 3,
|
||||
Account = 4,
|
||||
Other = 99,
|
||||
}
|
||||
|
||||
public enum ItTicketPriority
|
||||
{
|
||||
Low = 1,
|
||||
Medium = 2,
|
||||
High = 3,
|
||||
Urgent = 4,
|
||||
}
|
||||
|
||||
public enum ItTicketStatus
|
||||
{
|
||||
Open = 1,
|
||||
InProgress = 2,
|
||||
Resolved = 3,
|
||||
Closed = 4,
|
||||
Reopened = 5,
|
||||
}
|
||||
|
||||
26
src/Backend/SolutionErp.Domain/Office/ItTicket.cs
Normal file
26
src/Backend/SolutionErp.Domain/Office/ItTicket.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.3 G-O6 (Mig 39 — S38) — Ticket CNTT helpdesk.
|
||||
// KHÔNG dùng Workflow V2 (kanban status flow Open → InProgress → Resolved → Closed).
|
||||
// Auto-assign round-robin + SLA timer DEFER Phase 11.
|
||||
public class ItTicket : AuditableEntity
|
||||
{
|
||||
public string? MaTicket { get; set; } // "IT/2026/001"
|
||||
public Guid RequesterUserId { get; set; }
|
||||
public string RequesterFullName { get; set; } = string.Empty;
|
||||
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public ItTicketCategory Category { get; set; }
|
||||
public ItTicketPriority Priority { get; set; } = ItTicketPriority.Medium;
|
||||
public ItTicketStatus Status { get; set; } = ItTicketStatus.Open;
|
||||
|
||||
public Guid? AssignedToUserId { get; set; } // IT staff được assign (admin set manual hoặc round-robin defer)
|
||||
public string? AssignedToFullName { get; set; } // denorm
|
||||
|
||||
public DateTime? ResolvedAt { get; set; }
|
||||
public string? Resolution { get; set; } // ghi chú giải pháp (free text replace ItTicketComments thread defer Phase 11)
|
||||
}
|
||||
22
src/Backend/SolutionErp.Domain/Office/LeaveRequest.cs
Normal file
22
src/Backend/SolutionErp.Domain/Office/LeaveRequest.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.3 G-O4 (Mig 39 — S38 2026-05-28) — Đơn xin nghỉ phép.
|
||||
// Workflow V2 dynamic ApplicableType=LeaveRequest=5 (Mig 37 enum extend).
|
||||
// Skeleton Phase 1: status flat WorkflowAppStatus + ApproveV2 wire DEFER Phase 11.
|
||||
// LeaveBalance calculation business logic DEFER Phase 11.
|
||||
public class LeaveRequest : AuditableEntity
|
||||
{
|
||||
public string? MaDonTu { get; set; } // "DT/LR/2026/001"
|
||||
public Guid RequesterUserId { get; set; }
|
||||
public string RequesterFullName { get; set; } = string.Empty; // denorm
|
||||
public Guid LeaveTypeId { get; set; } // FK Hrm_LeaveType (Mig 35)
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public decimal NumDays { get; set; } // computed client-side or BE
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
public WorkflowAppStatus Status { get; set; } = WorkflowAppStatus.Nhap;
|
||||
public Guid? ApprovalWorkflowId { get; set; } // pin ApplicableType=5
|
||||
public int? CurrentApprovalLevelOrder { get; set; }
|
||||
}
|
||||
22
src/Backend/SolutionErp.Domain/Office/OtRequest.cs
Normal file
22
src/Backend/SolutionErp.Domain/Office/OtRequest.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.3 G-O4 (Mig 39 — S38) — Đơn đăng ký làm thêm giờ (OT).
|
||||
// Workflow V2 ApplicableType=OtRequest=6 (Mig 37 enum extend).
|
||||
// Reference OtPolicy (Hrm Mig 35) cho multiplier weekday/weekend/holiday.
|
||||
public class OtRequest : AuditableEntity
|
||||
{
|
||||
public string? MaDonTu { get; set; } // "DT/OT/2026/001"
|
||||
public Guid RequesterUserId { get; set; }
|
||||
public string RequesterFullName { get; set; } = string.Empty;
|
||||
public DateTime OtDate { get; set; }
|
||||
public TimeSpan StartTime { get; set; }
|
||||
public TimeSpan EndTime { get; set; }
|
||||
public decimal Hours { get; set; } // computed (EndTime - StartTime)
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
public Guid? OtPolicyId { get; set; } // FK Hrm_OtPolicy (Mig 35) optional
|
||||
public WorkflowAppStatus Status { get; set; } = WorkflowAppStatus.Nhap;
|
||||
public Guid? ApprovalWorkflowId { get; set; }
|
||||
public int? CurrentApprovalLevelOrder { get; set; }
|
||||
}
|
||||
21
src/Backend/SolutionErp.Domain/Office/TravelRequest.cs
Normal file
21
src/Backend/SolutionErp.Domain/Office/TravelRequest.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.3 G-O4 (Mig 39 — S38) — Đơn đăng ký đi công tác.
|
||||
// Reuse workflow ApplicableType=ProposalGeneral=4 (KHÔNG có enum riêng — share Proposal pool).
|
||||
public class TravelRequest : AuditableEntity
|
||||
{
|
||||
public string? MaDonTu { get; set; } // "DT/TR/2026/001"
|
||||
public Guid RequesterUserId { get; set; }
|
||||
public string RequesterFullName { get; set; } = string.Empty;
|
||||
public string Destination { get; set; } = string.Empty; // "Hà Nội", "TP.HCM", ...
|
||||
public DateTime StartDate { get; set; }
|
||||
public DateTime EndDate { get; set; }
|
||||
public int NumDays { get; set; } // computed
|
||||
public string Purpose { get; set; } = string.Empty;
|
||||
public decimal? EstimatedCost { get; set; } // dự toán chi phí
|
||||
public WorkflowAppStatus Status { get; set; } = WorkflowAppStatus.Nhap;
|
||||
public Guid? ApprovalWorkflowId { get; set; }
|
||||
public int? CurrentApprovalLevelOrder { get; set; }
|
||||
}
|
||||
23
src/Backend/SolutionErp.Domain/Office/VehicleBooking.cs
Normal file
23
src/Backend/SolutionErp.Domain/Office/VehicleBooking.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using SolutionErp.Domain.Common;
|
||||
|
||||
namespace SolutionErp.Domain.Office;
|
||||
|
||||
// Phase 10.3 G-O5 (Mig 39 — S38) — Đặt xe công.
|
||||
// Workflow V2 ApplicableType=VehicleBooking=7 (Mig 37 enum extend).
|
||||
// Skeleton Phase 1: free text vehicle license/name (NO Vehicle catalog table — defer Phase 11).
|
||||
public class VehicleBooking : AuditableEntity
|
||||
{
|
||||
public string? MaDonTu { get; set; } // "DT/VB/2026/001"
|
||||
public Guid RequesterUserId { get; set; }
|
||||
public string RequesterFullName { get; set; } = string.Empty;
|
||||
public string VehicleLicense { get; set; } = string.Empty; // free text "30A-12345"
|
||||
public string? VehicleName { get; set; } // "Xe 7 chỗ Innova"
|
||||
public DateTime StartAt { get; set; }
|
||||
public DateTime EndAt { get; set; }
|
||||
public string Destination { get; set; } = string.Empty;
|
||||
public string Purpose { get; set; } = string.Empty;
|
||||
public string? DriverName { get; set; } // free text "Anh Tài 0901xxx" — defer Driver catalog Phase 11
|
||||
public WorkflowAppStatus Status { get; set; } = WorkflowAppStatus.Nhap;
|
||||
public Guid? ApprovalWorkflowId { get; set; }
|
||||
public int? CurrentApprovalLevelOrder { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user