Implement NotifyOnStatusChange feature for nodes and enhance Telegram notifications
CI / Backend (build + test) (push) Successful in 1m24s
CI / Frontend (lint + typecheck + build) (push) Successful in 34s

- Added `NotifyOnStatusChange` property to the `Node` class and related DTOs to allow individual node configuration for status change notifications.
- Updated `NodeHealthCheckService` to send Telegram notifications to admins when a node's status changes, based on the new property.
- Enhanced the `ITelegramNotifier` interface with a method for notifying admins about node status changes.
- Modified the frontend to include a checkbox for `NotifyOnStatusChange` in the node editing dialog, allowing admins to easily configure this setting.
- Updated API documentation to reflect the new `notifyOnStatusChange` parameter in the node update endpoint.
- Added tests to ensure the correct behavior of the new feature and its integration with existing functionality.
This commit is contained in:
Leonid Pershin
2026-07-23 11:04:38 +03:00
parent 2f6bb26e97
commit fb97093bd6
20 changed files with 1272 additions and 6 deletions
@@ -37,6 +37,7 @@ public sealed class NodeHealthCheckService(
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var gateway = scope.ServiceProvider.GetRequiredService<IXuiPanelGateway>();
var notifier = scope.ServiceProvider.GetRequiredService<IRealtimeNotifier>();
var telegramNotifier = scope.ServiceProvider.GetRequiredService<ITelegramNotifier>();
var nodes = await dbContext.Nodes.Where(n => n.IsEnabled).ToListAsync(cancellationToken);
@@ -54,6 +55,16 @@ public sealed class NodeHealthCheckService(
node.LastSyncAt,
cancellationToken
);
if (node.NotifyOnStatusChange)
{
await telegramNotifier.NotifyAdminsNodeStatusChangedAsync(
node.Id,
node.Name,
newStatus,
cancellationToken
);
}
}
}
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PnvPanel.Infrastructure.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddNodeNotifyOnStatusChange : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "NotifyOnStatusChange",
table: "Nodes",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "NotifyOnStatusChange",
table: "Nodes");
}
}
}
@@ -17,7 +17,7 @@ namespace PnvPanel.Infrastructure.Persistence.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("ProductVersion", "10.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@@ -577,6 +577,9 @@ namespace PnvPanel.Infrastructure.Persistence.Migrations
.HasMaxLength(100)
.HasColumnType("character varying(100)");
b.Property<bool>("NotifyOnStatusChange")
.HasColumnType("boolean");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)