✨ Action log service grpc
This commit is contained in:
114
DysonNetwork.Pass/Account/ActionLogServiceGrpc.cs
Normal file
114
DysonNetwork.Pass/Account/ActionLogServiceGrpc.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using Grpc.Core;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
public class ActionLogServiceGrpc : Shared.Proto.ActionLogService.ActionLogServiceBase
|
||||
{
|
||||
private readonly ActionLogService _actionLogService;
|
||||
private readonly AppDatabase _db;
|
||||
private readonly ILogger<ActionLogServiceGrpc> _logger;
|
||||
|
||||
public ActionLogServiceGrpc(
|
||||
ActionLogService actionLogService,
|
||||
AppDatabase db,
|
||||
ILogger<ActionLogServiceGrpc> logger)
|
||||
{
|
||||
_actionLogService = actionLogService ?? throw new ArgumentNullException(nameof(actionLogService));
|
||||
_db = db ?? throw new ArgumentNullException(nameof(db));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public override async Task<CreateActionLogResponse> CreateActionLog(CreateActionLogRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.AccountId) || !Guid.TryParse(request.AccountId, out var accountId))
|
||||
{
|
||||
throw new RpcException(new Grpc.Core.Status(Grpc.Core.StatusCode.InvalidArgument, "Invalid account ID"));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var meta = request.Meta
|
||||
?.Select(x => new KeyValuePair<string, object?>(x.Key, GrpcTypeHelper.ConvertField(x.Value)))
|
||||
.ToDictionary() ?? new Dictionary<string, object?>();
|
||||
|
||||
_actionLogService.CreateActionLog(
|
||||
accountId,
|
||||
request.Action,
|
||||
meta
|
||||
);
|
||||
|
||||
return new CreateActionLogResponse();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error creating action log");
|
||||
throw new RpcException(new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Failed to create action log"));
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<ListActionLogsResponse> ListActionLogs(ListActionLogsRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.AccountId) || !Guid.TryParse(request.AccountId, out var accountId))
|
||||
{
|
||||
throw new RpcException(new Grpc.Core.Status(Grpc.Core.StatusCode.InvalidArgument, "Invalid account ID"));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var query = _db.ActionLogs
|
||||
.AsNoTracking()
|
||||
.Where(log => log.AccountId == accountId);
|
||||
|
||||
if (!string.IsNullOrEmpty(request.Action))
|
||||
{
|
||||
query = query.Where(log => log.Action == request.Action);
|
||||
}
|
||||
|
||||
// Apply ordering (default to newest first)
|
||||
query = (request.OrderBy?.ToLower() ?? "createdat desc") switch
|
||||
{
|
||||
"createdat" => query.OrderBy(log => log.CreatedAt),
|
||||
"createdat desc" => query.OrderByDescending(log => log.CreatedAt),
|
||||
_ => query.OrderByDescending(log => log.CreatedAt)
|
||||
};
|
||||
|
||||
// Apply pagination
|
||||
var pageSize = request.PageSize == 0 ? 50 : Math.Min(request.PageSize, 1000);
|
||||
var logs = await query
|
||||
.Take(pageSize + 1) // Fetch one extra to determine if there are more pages
|
||||
.ToListAsync();
|
||||
|
||||
var hasMore = logs.Count > pageSize;
|
||||
if (hasMore)
|
||||
{
|
||||
logs.RemoveAt(logs.Count - 1);
|
||||
}
|
||||
|
||||
var response = new ListActionLogsResponse
|
||||
{
|
||||
TotalSize = await query.CountAsync()
|
||||
};
|
||||
|
||||
if (hasMore)
|
||||
{
|
||||
// In a real implementation, you'd generate a proper page token
|
||||
response.NextPageToken = (logs.LastOrDefault()?.CreatedAt ?? SystemClock.Instance.GetCurrentInstant())
|
||||
.ToString();
|
||||
}
|
||||
|
||||
response.ActionLogs.AddRange(logs.Select(log => log.ToProtoValue()));
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error listing action logs");
|
||||
throw new RpcException(new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Failed to list action logs"));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user