Files
PnvPanel/backend/src/PnvPanel.Application/Admin/Nodes/UpdateNodeCommandHandler.cs
T
Leonid Pershin ee6b8a35b8
CI / Backend (build + test) (push) Successful in 1m25s
CI / Frontend (lint + typecheck + build) (push) Successful in 33s
Enhance node update functionality to include base address
- Added `BaseAddress` property to `UpdateNodeCommand` and `UpdateNodeBody` for improved node management.
- Implemented validation for the base address in `UpdateNodeCommandHandler`, ensuring it is a valid absolute URI.
- Updated `Node` class to support address updates, including logic to invalidate cached clients on address changes.
- Enhanced frontend components to handle base address input in the node editing dialog and API requests.
- Updated validation rules to enforce base address requirements in `UpdateNodeCommandValidator`.
2026-07-23 01:05:02 +03:00

80 lines
2.8 KiB
C#

using Microsoft.EntityFrameworkCore;
using PnvPanel.Application.Common.Interfaces;
using PnvPanel.Application.Common.Messaging;
using PnvPanel.Application.Common.Models;
using PnvPanel.Domain.Audit;
using PnvPanel.Domain.Nodes;
namespace PnvPanel.Application.Admin.Nodes;
public sealed class UpdateNodeCommandHandler(
IAppDbContext dbContext,
IXuiPanelGateway gateway,
ISecretProtector secretProtector,
ICurrentUser currentUser
) : ICommandHandler<UpdateNodeCommand, Result<NodeDto>>
{
public async Task<Result<NodeDto>> Handle(
UpdateNodeCommand command,
CancellationToken cancellationToken
)
{
var node = await dbContext.Nodes.FirstOrDefaultAsync(
n => n.Id == command.NodeId,
cancellationToken
);
if (node is null)
return Result.Failure<NodeDto>(NodeErrors.NotFound);
if (!Uri.TryCreate(command.BaseAddress, UriKind.Absolute, out var baseAddress))
return Result.Failure<NodeDto>(NodeErrors.InvalidBaseAddress);
var addressChanged = baseAddress != node.BaseAddress;
if (addressChanged)
{
var validation = gateway.ValidateBaseAddress(baseAddress);
if (!validation.IsSuccess)
return Result.Failure<NodeDto>(validation.Error);
}
node.UpdateDetails(command.Name, command.Location);
if (addressChanged)
node.UpdateAddress(baseAddress);
if (command.IsEnabled)
node.Enable();
else
node.Disable();
var credentialsChanged =
!string.IsNullOrWhiteSpace(command.Username)
&& !string.IsNullOrWhiteSpace(command.Password);
if (credentialsChanged)
{
node.UpdateCredentials(
new NodeCredentials(command.Username!, secretProtector.Protect(command.Password!))
);
}
// Клиент в гейтвее закэширован per-node (адрес+креденшлы захвачены при первом создании) —
// при смене любого из них старый закэшированный клиент нужно выбросить, иначе гейтвей
// продолжит стучаться по старому адресу/с старым паролем до перезапуска процесса.
if (addressChanged || credentialsChanged)
gateway.InvalidateClient(node.Id);
dbContext.AuditLogs.Add(
AuditLog.Create(
currentUser.UserId,
"NodeUpdated",
"Node",
node.Id.ToString(),
metadata: null,
AuditSource.Web
)
);
return Result.Success(NodeDto.FromDomain(node));
}
}