Implement billing functionality and enhance role management
CI / Backend (build + test) (push) Successful in 1m22s
CI / Frontend (lint + typecheck + build) (push) Successful in 33s

- Introduced billing capabilities, allowing users to request payments for subscription periods (3/6/12 months) with admin approval via Telegram.
- Updated role management to include a `BillingEnabled` property, preventing billing for admin roles.
- Enhanced the `CreateRoleCommand` and `UpdateRoleCommand` to accept billing parameters, ensuring proper handling during role creation and updates.
- Added new endpoints for billing management and integrated billing checks into VPN config creation to enforce payment requirements.
- Updated related services, models, and tests to support the new billing features, ensuring comprehensive coverage and functionality.
- Enhanced documentation to reflect the new billing processes and role management changes.
This commit is contained in:
Leonid Pershin
2026-07-19 01:38:16 +03:00
parent b980dc6cef
commit b2ae358250
106 changed files with 6018 additions and 66 deletions
@@ -36,6 +36,13 @@ public sealed class CreateVpnConfigCommandHandler(
if (!inbound.AllowedRoleIds.Contains(profile.RoleId))
return Result.Failure<VpnConfigDto>(ConfigErrors.InboundNotAllowedForRole);
// Не даём обойти приостановку за неуплату созданием нового конфига — см. BillingService.
if (
profile.BillingEnabled
&& (profile.BillingPaidUntil is null || profile.BillingPaidUntil < DateTimeOffset.UtcNow)
)
return Result.Failure<VpnConfigDto>(ConfigErrors.BillingRequired);
var node = await dbContext
.Nodes.AsNoTracking()
.FirstOrDefaultAsync(n => n.Id == inbound.NodeId, cancellationToken);
@@ -47,6 +54,8 @@ public sealed class CreateVpnConfigCommandHandler(
return Result.Failure<VpnConfigDto>(ConfigErrors.NodeDisabled);
var config = VpnConfig.Create(userId, inbound.Id, inbound.Protocol, command.Label);
if (profile.BillingEnabled)
config.SetBillingExpiry(profile.BillingPaidUntil);
var reserveResult = await ReserveQuotaSlotAsync(
userId,