feat(T4.13): add PackageFeature CRUD support
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m41s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m41s
- Proto: add feature_ids to Create/Update/Get package messages - Commands: add FeatureIds to Create/Update commands - Handlers: sync PackageFeature join entities on create/update - Queries: include PackageFeatures, map FeatureIds in responses - Bump NuGet to v0.0.188
This commit is contained in:
+1
@@ -22,4 +22,5 @@ public record CreateNewPackageCommand : IRequest<CreateNewPackageResponseDto>
|
|||||||
public int MaxNetworkLevel { get; init; } = 15;
|
public int MaxNetworkLevel { get; init; } = 15;
|
||||||
public long MagicWalletMaxDeposit { get; init; } = 1_000_000_000;
|
public long MagicWalletMaxDeposit { get; init; } = 1_000_000_000;
|
||||||
public long MagicWalletMaxCredit { get; init; } = 2_500_000_000;
|
public long MagicWalletMaxCredit { get; init; } = 2_500_000_000;
|
||||||
|
public List<long> FeatureIds { get; init; } = new();
|
||||||
}
|
}
|
||||||
+16
@@ -16,6 +16,22 @@ public class CreateNewPackageCommandHandler : IRequestHandler<CreateNewPackageCo
|
|||||||
await _context.Packages.AddAsync(entity, cancellationToken);
|
await _context.Packages.AddAsync(entity, cancellationToken);
|
||||||
entity.AddDomainEvent(new CreateNewPackageEvent(entity));
|
entity.AddDomainEvent(new CreateNewPackageEvent(entity));
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
|
// Sync PackageFeatures
|
||||||
|
if (request.FeatureIds.Any())
|
||||||
|
{
|
||||||
|
foreach (var featureId in request.FeatureIds)
|
||||||
|
{
|
||||||
|
_context.PackageFeatures.Add(new PackageFeature
|
||||||
|
{
|
||||||
|
PackageId = entity.Id,
|
||||||
|
ClubFeatureId = featureId,
|
||||||
|
IsIncluded = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
return entity.Adapt<CreateNewPackageResponseDto>();
|
return entity.Adapt<CreateNewPackageResponseDto>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -24,4 +24,5 @@ public record UpdatePackageCommand : IRequest<Unit>
|
|||||||
public int MaxNetworkLevel { get; init; }
|
public int MaxNetworkLevel { get; init; }
|
||||||
public long MagicWalletMaxDeposit { get; init; }
|
public long MagicWalletMaxDeposit { get; init; }
|
||||||
public long MagicWalletMaxCredit { get; init; }
|
public long MagicWalletMaxCredit { get; init; }
|
||||||
|
public List<long> FeatureIds { get; init; } = new();
|
||||||
}
|
}
|
||||||
+17
@@ -16,6 +16,23 @@ public class UpdatePackageCommandHandler : IRequestHandler<UpdatePackageCommand,
|
|||||||
request.Adapt(entity);
|
request.Adapt(entity);
|
||||||
_context.Packages.Update(entity);
|
_context.Packages.Update(entity);
|
||||||
entity.AddDomainEvent(new UpdatePackageEvent(entity));
|
entity.AddDomainEvent(new UpdatePackageEvent(entity));
|
||||||
|
|
||||||
|
// Sync PackageFeatures — remove old, add new
|
||||||
|
var existingFeatures = await _context.PackageFeatures
|
||||||
|
.Where(pf => pf.PackageId == request.Id)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
_context.PackageFeatures.RemoveRange(existingFeatures);
|
||||||
|
|
||||||
|
foreach (var featureId in request.FeatureIds)
|
||||||
|
{
|
||||||
|
_context.PackageFeatures.Add(new PackageFeature
|
||||||
|
{
|
||||||
|
PackageId = request.Id,
|
||||||
|
ClubFeatureId = featureId,
|
||||||
|
IsIncluded = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await _context.SaveChangesAsync(cancellationToken);
|
await _context.SaveChangesAsync(cancellationToken);
|
||||||
return Unit.Value;
|
return Unit.Value;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-2
@@ -14,6 +14,7 @@ public class GetAllPackageByFilterQueryHandler : IRequestHandler<GetAllPackageBy
|
|||||||
.Where(x => !x.IsDeleted)
|
.Where(x => !x.IsDeleted)
|
||||||
.ApplyOrder(sortBy: request.SortBy)
|
.ApplyOrder(sortBy: request.SortBy)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
|
.Include(x => x.PackageFeatures)
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
if (request.Filter is not null)
|
if (request.Filter is not null)
|
||||||
{
|
{
|
||||||
@@ -25,11 +26,24 @@ public class GetAllPackageByFilterQueryHandler : IRequestHandler<GetAllPackageBy
|
|||||||
.Where(x => request.Filter.Price == null || x.Price == request.Filter.Price)
|
.Where(x => request.Filter.Price == null || x.Price == request.Filter.Price)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
var packages = await query
|
||||||
|
.PaginatedListAsync(paginationState: request.PaginationState)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
var models = packages.Select(p =>
|
||||||
|
{
|
||||||
|
var model = p.Adapt<GetAllPackageByFilterResponseModel>();
|
||||||
|
model.FeatureIds = p.PackageFeatures?
|
||||||
|
.Where(pf => pf.IsIncluded)
|
||||||
|
.Select(pf => pf.ClubFeatureId)
|
||||||
|
.ToList() ?? new();
|
||||||
|
return model;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return new GetAllPackageByFilterResponseDto
|
return new GetAllPackageByFilterResponseDto
|
||||||
{
|
{
|
||||||
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
|
MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
|
||||||
Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
|
Models = models
|
||||||
.ProjectToType<GetAllPackageByFilterResponseModel>().ToListAsync(cancellationToken)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -31,4 +31,5 @@ public class GetAllPackageByFilterResponseDto
|
|||||||
public int MaxNetworkLevel { get; set; }
|
public int MaxNetworkLevel { get; set; }
|
||||||
public long MagicWalletMaxDeposit { get; set; }
|
public long MagicWalletMaxDeposit { get; set; }
|
||||||
public long MagicWalletMaxCredit { get; set; }
|
public long MagicWalletMaxCredit { get; set; }
|
||||||
|
public List<long> FeatureIds { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-4
@@ -11,12 +11,19 @@ public class GetPackageQueryHandler : IRequestHandler<GetPackageQuery, GetPackag
|
|||||||
public async Task<GetPackageResponseDto> Handle(GetPackageQuery request,
|
public async Task<GetPackageResponseDto> Handle(GetPackageQuery request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var response = await _context.Packages
|
var package = await _context.Packages
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
|
.Include(x => x.PackageFeatures)
|
||||||
.Where(x => x.Id == request.Id)
|
.Where(x => x.Id == request.Id)
|
||||||
.ProjectToType<GetPackageResponseDto>()
|
.FirstOrDefaultAsync(cancellationToken)
|
||||||
.FirstOrDefaultAsync(cancellationToken);
|
?? throw new NotFoundException(nameof(Package), request.Id);
|
||||||
|
|
||||||
return response ?? throw new NotFoundException(nameof(Package), request.Id);
|
var response = package.Adapt<GetPackageResponseDto>();
|
||||||
|
response.FeatureIds = package.PackageFeatures?
|
||||||
|
.Where(pf => pf.IsIncluded)
|
||||||
|
.Select(pf => pf.ClubFeatureId)
|
||||||
|
.ToList() ?? new();
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,5 @@ public class GetPackageResponseDto
|
|||||||
public int MaxNetworkLevel { get; set; }
|
public int MaxNetworkLevel { get; set; }
|
||||||
public long MagicWalletMaxDeposit { get; set; }
|
public long MagicWalletMaxDeposit { get; set; }
|
||||||
public long MagicWalletMaxCredit { get; set; }
|
public long MagicWalletMaxCredit { get; set; }
|
||||||
|
public List<long> FeatureIds { get; set; } = new();
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>0.0.187</Version>
|
<Version>0.0.188</Version>
|
||||||
<DebugType>None</DebugType>
|
<DebugType>None</DebugType>
|
||||||
<DebugSymbols>False</DebugSymbols>
|
<DebugSymbols>False</DebugSymbols>
|
||||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ message CreateNewPackageRequest
|
|||||||
int32 max_network_level = 15;
|
int32 max_network_level = 15;
|
||||||
int64 magic_wallet_max_deposit = 16;
|
int64 magic_wallet_max_deposit = 16;
|
||||||
int64 magic_wallet_max_credit = 17;
|
int64 magic_wallet_max_credit = 17;
|
||||||
|
repeated int64 feature_ids = 18;
|
||||||
}
|
}
|
||||||
message CreateNewPackageResponse
|
message CreateNewPackageResponse
|
||||||
{
|
{
|
||||||
@@ -124,6 +125,7 @@ message UpdatePackageRequest
|
|||||||
int32 max_network_level = 16;
|
int32 max_network_level = 16;
|
||||||
int64 magic_wallet_max_deposit = 17;
|
int64 magic_wallet_max_deposit = 17;
|
||||||
int64 magic_wallet_max_credit = 18;
|
int64 magic_wallet_max_credit = 18;
|
||||||
|
repeated int64 feature_ids = 19;
|
||||||
}
|
}
|
||||||
message DeletePackageRequest
|
message DeletePackageRequest
|
||||||
{
|
{
|
||||||
@@ -152,6 +154,7 @@ message GetPackageResponse
|
|||||||
int32 max_network_level = 15;
|
int32 max_network_level = 15;
|
||||||
int64 magic_wallet_max_deposit = 16;
|
int64 magic_wallet_max_deposit = 16;
|
||||||
int64 magic_wallet_max_credit = 17;
|
int64 magic_wallet_max_credit = 17;
|
||||||
|
repeated int64 feature_ids = 18;
|
||||||
}
|
}
|
||||||
message GetAllPackageByFilterRequest
|
message GetAllPackageByFilterRequest
|
||||||
{
|
{
|
||||||
@@ -191,6 +194,7 @@ message GetAllPackageByFilterResponseModel
|
|||||||
int32 max_network_level = 15;
|
int32 max_network_level = 15;
|
||||||
int64 magic_wallet_max_deposit = 16;
|
int64 magic_wallet_max_deposit = 16;
|
||||||
int64 magic_wallet_max_credit = 17;
|
int64 magic_wallet_max_credit = 17;
|
||||||
|
repeated int64 feature_ids = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetUserPackageStatusRequest
|
message GetUserPackageStatusRequest
|
||||||
|
|||||||
Reference in New Issue
Block a user