Implement pricing management functionality and update related components
- Added new endpoints for managing global pricing settings, including retrieval and updates for `PricePerConfigPerQuarter` and `PricePerConfigPerYear`. - Updated `RoleService` and related commands to remove pricing fields from role management, ensuring a clear separation between role configurations and global pricing. - Enhanced the `FactoryResetCommandHandler` to include seeding of pricing settings during a factory reset. - Modified frontend components to support new pricing settings, including forms for creating and updating pricing information. - Updated API documentation to reflect changes in pricing management endpoints and their expected request/response formats. - Adjusted tests to ensure proper coverage for new pricing functionalities and their integration with existing role management features.
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
||||
using PnvPanel.Application.Common.Interfaces;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Common.Models;
|
||||
|
||||
@@ -6,5 +7,5 @@ namespace PnvPanel.Application.Support.ListSelectableRoles;
|
||||
/// <summary>Список ролей для выбора в заявке на роль (без admin) — в отличие от ListRolesQuery
|
||||
/// (Admin/Roles), доступен любому активированному пользователю.</summary>
|
||||
public sealed record ListSelectableRolesQuery
|
||||
: IQuery<Result<IReadOnlyList<SelectableRoleDto>>>,
|
||||
: IQuery<Result<IReadOnlyList<RoleDto>>>,
|
||||
IRequiresActivation;
|
||||
|
||||
+4
-6
@@ -9,31 +9,29 @@ public sealed class ListSelectableRolesQueryHandler(
|
||||
IRoleService roleService,
|
||||
IIdentityService identityService,
|
||||
ICurrentUser currentUser
|
||||
) : IQueryHandler<ListSelectableRolesQuery, Result<IReadOnlyList<SelectableRoleDto>>>
|
||||
) : IQueryHandler<ListSelectableRolesQuery, Result<IReadOnlyList<RoleDto>>>
|
||||
{
|
||||
// Совпадает со значением Infrastructure.Identity.RoleNames.Admin — см. пояснение в
|
||||
// CreateRoleRequestTicketCommandHandler (Application не может ссылаться на Infrastructure).
|
||||
private const string AdminRoleName = "admin";
|
||||
|
||||
public async Task<Result<IReadOnlyList<SelectableRoleDto>>> Handle(
|
||||
public async Task<Result<IReadOnlyList<RoleDto>>> Handle(
|
||||
ListSelectableRolesQuery query,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
if (currentUser.UserId is not { } userId)
|
||||
return Result.Failure<IReadOnlyList<SelectableRoleDto>>(AuthErrors.Unauthorized);
|
||||
return Result.Failure<IReadOnlyList<RoleDto>>(AuthErrors.Unauthorized);
|
||||
|
||||
var profile = await identityService.GetProfileAsync(userId, cancellationToken);
|
||||
var roles = await roleService.ListRolesAsync(cancellationToken);
|
||||
|
||||
// Без admin (нельзя запросить) и без текущей роли пользователя (уже есть — нечего запрашивать).
|
||||
// Цена (RoleDto.PricePerConfigPer*) намеренно не пробрасывается — видна только админу.
|
||||
var selectable = roles
|
||||
.Where(r => !r.Name.Equals(AdminRoleName, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(r => profile is null || r.Id != profile.RoleId)
|
||||
.Select(r => new SelectableRoleDto(r.Id, r.Name, r.MaxConfigs, r.MaxIpLimit))
|
||||
.ToList();
|
||||
|
||||
return Result.Success<IReadOnlyList<SelectableRoleDto>>(selectable);
|
||||
return Result.Success<IReadOnlyList<RoleDto>>(selectable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
namespace PnvPanel.Application.Support.ListSelectableRoles;
|
||||
|
||||
/// <summary>Роль для выбора в заявке на роль. Без справочной цены (RoleDto.PricePerConfigPer*) —
|
||||
/// она видна только админу, этот эндпоинт доступен любому активированному пользователю.</summary>
|
||||
public sealed record SelectableRoleDto(Guid Id, string Name, int MaxConfigs, int MaxIpLimit);
|
||||
Reference in New Issue
Block a user