feat: integrate d3-org-chart for network visualization and add SignalR token notification service

This commit is contained in:
masoodafar-web
2025-12-18 03:19:06 +03:30
parent 27c2c0259b
commit 6b457d0ce6
21 changed files with 1558 additions and 201 deletions
@@ -41,6 +41,39 @@ public class NetworkMembershipService
}
}
/// <summary>
/// Get subordinate's network tree (with security check on backend)
/// Maps to: NetworkMembershipCQ.GetSubordinateTree
/// </summary>
public async Task<NetworkTreeDto> GetSubordinateTreeAsync(long targetUserId, int maxDepth = 3)
{
try
{
var request = new GetSubordinateTreeRequest
{
TargetUserId = targetUserId,
MaxDepth = maxDepth
};
var response = await _client.GetSubordinateTreeAsync(request);
return new NetworkTreeDto
{
RootNode = MapNodeFromProto(response.RootNode),
TotalMembers = response.TotalMembers,
CurrentDepth = response.CurrentDepth
};
}
catch (Grpc.Core.RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.PermissionDenied)
{
throw new UnauthorizedAccessException("شما اجازه مشاهده درخت این کاربر را ندارید");
}
catch
{
// Fallback to current user's tree
return await GetMyNetworkTreeAsync(maxDepth);
}
}
/// <summary>
/// Get current user's network statistics
/// Maps to: NetworkMembershipCQ.GetMyNetworkStatistics
@@ -102,6 +135,10 @@ public class NetworkMembershipService
Avatar = node.Avatar,
Position = node.Position,
Level = node.Level,
IsActive = node.HasChildren, // Temporary: use HasChildren as active indicator until proto is updated
IsClubActive = false, // Will be populated when proto is updated
ActivationWeekNumber = null, // Will be populated when proto is updated
JoinedAt = null, // Will be populated when proto is updated
LeftChild = MapNodeFromProto(node.LeftChild),
RightChild = MapNodeFromProto(node.RightChild)
};
@@ -111,8 +148,8 @@ public class NetworkMembershipService
{
return new NetworkTreeDto
{
CurrentDepth = 2,
TotalMembers = 5,
CurrentDepth = 3,
TotalMembers = 7,
RootNode = new NetworkNodeDto
{
UserId = 1,
@@ -120,13 +157,38 @@ public class NetworkMembershipService
Mobile = "09121234567",
Position = "Root",
Level = 0,
IsActive = true,
IsClubActive = true,
LeftChild = new NetworkNodeDto
{
UserId = 2,
FullName = "علی محمدی",
Mobile = "09121234568",
Position = "Left",
Level = 1
Level = 1,
IsActive = true,
IsClubActive = true,
JoinedAt = DateTime.Now.AddDays(-30),
LeftChild = new NetworkNodeDto
{
UserId = 4,
FullName = "رضا کریمی",
Mobile = "09121234570",
Position = "Left",
Level = 2,
IsActive = true,
JoinedAt = DateTime.Now.AddDays(-15)
},
RightChild = new NetworkNodeDto
{
UserId = 5,
FullName = "زهرا احمدی",
Mobile = "09121234571",
Position = "Right",
Level = 2,
IsActive = false,
JoinedAt = DateTime.Now.AddDays(-10)
}
},
RightChild = new NetworkNodeDto
{
@@ -134,7 +196,20 @@ public class NetworkMembershipService
FullName = "فاطمه حسینی",
Mobile = "09121234569",
Position = "Right",
Level = 1
Level = 1,
IsActive = true,
JoinedAt = DateTime.Now.AddDays(-25),
LeftChild = new NetworkNodeDto
{
UserId = 6,
FullName = "محمد نوری",
Mobile = "09121234572",
Position = "Left",
Level = 2,
IsActive = true,
IsClubActive = true,
JoinedAt = DateTime.Now.AddDays(-5)
}
}
}
};