[CLAUDE] AwV2: Mig 25 +IsUserSelectable + Designer pin toggle + Workspace filter, bỏ "(clone)"
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Has been cancelled

Hai yêu cầu UAT 2026-05-08:
1. Bỏ "(clone)" auto-append khi clone version mới — version đã đủ phân biệt.
2. Thêm pin toggle để admin chọn workflows nào cho user pick lúc tạo phiếu.

Migration 25 AddIsUserSelectableToApprovalWorkflows:
- ALTER ApprovalWorkflows ADD IsUserSelectable bit NOT NULL DEFAULT 0
- UPDATE backfill SET IsUserSelectable=1 WHERE IsActive=1 (giữ behavior cũ
  cho active versions, archived = false default — admin tự pin nếu cần)

BE:
- Domain ApprovalWorkflow +property IsUserSelectable
- DTO AwDefinitionDto +field
- CreateAwDefinitionCommandHandler set default true cho version mới
- New SetAwUserSelectableCommand + Handler
- API PATCH /api/approval-workflows-v2/{id}/user-selectable (Workflows.Create policy)
- DbInitializer SeedSampleApprovalWorkflowsV2Async set IsUserSelectable=true

FE Designer (fe-admin):
- DefinitionDto +isUserSelectable
- Badge amber "Pin Cho user chọn" khi true (cạnh Đang áp dụng/Archived)
- Button "Pin/PinOff Ghim cho user / Bỏ ghim" trong action group + mutation toggle
- Auto-fill name khi clone: bỏ "(clone)" suffix → giữ nguyên name

FE Workspace (fe-admin + fe-user):
- approvalWorkflows query filter w.isUserSelectable === true
- User dropdown chỉ thấy workflows admin đã pin

Verify: dotnet build pass · 81 test pass · npm build × 2 pass · Mig 25 apply LocalDB OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-08 19:15:23 +07:00
parent a9c0857a84
commit 2a53107602
12 changed files with 3943 additions and 8 deletions

View File

@ -45,6 +45,7 @@ public record AwDefinitionDto(
string Name,
string? Description,
bool IsActive,
bool IsUserSelectable,
DateTime? ActivatedAt,
DateTime CreatedAt,
List<AwStepDto> Steps);
@ -126,6 +127,7 @@ public class GetAwAdminOverviewQueryHandler(
d.Name,
d.Description,
d.IsActive,
d.IsUserSelectable,
d.ActivatedAt,
d.CreatedAt,
d.Steps.OrderBy(s => s.Order).Select(s => new AwStepDto(
@ -268,6 +270,7 @@ public class CreateAwDefinitionCommandHandler(IApplicationDbContext db)
Name = request.Name,
Description = request.Description,
IsActive = true,
IsUserSelectable = true, // Mig 25 — version mới mặc định cho user pick
ActivatedAt = DateTime.UtcNow,
Steps = request.Steps.OrderBy(s => s.Order)
.Select(s => new ApprovalWorkflowStep
@ -291,6 +294,27 @@ public class CreateAwDefinitionCommandHandler(IApplicationDbContext db)
}
}
// ========== PATCH user-selectable toggle (Mig 25 — admin pin/unpin cho user pick) ==========
// Independent với IsActive: cho phép multiple version cùng selectable. Default
// version mới IsUserSelectable=true (mirror IsActive default), admin có thể
// unstick để dấu khỏi Workspace dropdown, hoặc stick lại version cũ archived.
public record SetAwUserSelectableCommand(Guid Id, bool IsUserSelectable) : IRequest;
public class SetAwUserSelectableCommandHandler(IApplicationDbContext db)
: IRequestHandler<SetAwUserSelectableCommand>
{
public async Task Handle(SetAwUserSelectableCommand request, CancellationToken ct)
{
var def = await db.ApprovalWorkflows
.FirstOrDefaultAsync(d => d.Id == request.Id, ct)
?? throw new KeyNotFoundException($"ApprovalWorkflow {request.Id} không tồn tại.");
def.IsUserSelectable = request.IsUserSelectable;
await db.SaveChangesAsync(ct);
}
}
// ========== DELETE version (chỉ khi chưa có phiếu pin) ==========
// Hiện chưa có phiếu nào pin schema mới → unconditional delete OK cho UAT.
// Sau UAT khi link với PE/Contract thật cần check usage trước khi delete.