🐛 Fix Pass service missing perks subscription
This commit is contained in:
@@ -4,6 +4,7 @@ using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Shared.Networking;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -22,7 +23,8 @@ public class AccountCurrentController(
|
||||
AccountEventService events,
|
||||
AuthService auth,
|
||||
FileService.FileServiceClient files,
|
||||
Credit.SocialCreditService creditService
|
||||
Credit.SocialCreditService creditService,
|
||||
RemoteSubscriptionService remoteSubscription
|
||||
) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
@@ -39,6 +41,24 @@ public class AccountCurrentController(
|
||||
.Where(e => e.Id == userId)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
// Populate PerkSubscription from Wallet service via gRPC
|
||||
try
|
||||
{
|
||||
var subscription = await remoteSubscription.GetPerkSubscription(account.Id);
|
||||
if (subscription != null)
|
||||
{
|
||||
account.PerkSubscription = SnWalletSubscription.FromProtoValue(subscription).ToReference();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log error but don't fail the request - PerkSubscription is optional
|
||||
Console.WriteLine($"Failed to populate PerkSubscription for account {account.Id}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(account);
|
||||
}
|
||||
|
||||
@@ -321,7 +341,10 @@ public class AccountCurrentController(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentUser.PerkSubscription is null)
|
||||
// Check PerkSubscription via RemoteSubscriptionService instead of relying on currentUser.PerkSubscription
|
||||
// which is not populated when currentUser comes from HttpContext.Items
|
||||
var perkSubscription = await remoteSubscription.GetPerkSubscription(currentUser.Id);
|
||||
if (perkSubscription == null)
|
||||
return StatusCode(403, ApiError.Unauthorized(
|
||||
message: "You need to have a subscription to check-in backdated.",
|
||||
forbidden: true,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using DysonNetwork.Pass.Credit;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Shared.Networking;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -10,7 +11,8 @@ namespace DysonNetwork.Pass.Account;
|
||||
[Route("/api/accounts")]
|
||||
public class AccountPublicController(
|
||||
AppDatabase db,
|
||||
SocialCreditService socialCreditService
|
||||
SocialCreditService socialCreditService,
|
||||
RemoteSubscriptionService remoteSubscription
|
||||
) : ControllerBase
|
||||
{
|
||||
[HttpGet("{name}")]
|
||||
@@ -26,6 +28,21 @@ public class AccountPublicController(
|
||||
.FirstOrDefaultAsync();
|
||||
if (account is null) return NotFound(ApiError.NotFound(name, traceId: HttpContext.TraceIdentifier));
|
||||
|
||||
// Populate PerkSubscription from Wallet service via gRPC
|
||||
try
|
||||
{
|
||||
var subscription = await remoteSubscription.GetPerkSubscription(account.Id);
|
||||
if (subscription != null)
|
||||
{
|
||||
account.PerkSubscription = SnWalletSubscription.FromProtoValue(subscription).ToReference();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log error but don't fail the request - PerkSubscription is optional
|
||||
Console.WriteLine($"Failed to populate PerkSubscription for account {account.Id}: {ex.Message}");
|
||||
}
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
@@ -67,11 +84,44 @@ public class AccountPublicController(
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
return [];
|
||||
return await db.Accounts
|
||||
|
||||
var accounts = await db.Accounts
|
||||
.Include(e => e.Profile)
|
||||
.Where(a => EF.Functions.ILike(a.Name, $"%{query}%") ||
|
||||
EF.Functions.ILike(a.Nick, $"%{query}%"))
|
||||
.Take(take)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
if (accounts.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var accountIds = accounts.Select(a => a.Id).ToList();
|
||||
var subscriptions = await remoteSubscription.GetPerkSubscriptions(accountIds);
|
||||
|
||||
var subscriptionDict = subscriptions
|
||||
.Where(s => s != null)
|
||||
.ToDictionary(
|
||||
s => Guid.Parse(s.AccountId),
|
||||
s => SnWalletSubscription.FromProtoValue(s).ToReference()
|
||||
);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
if (subscriptionDict.TryGetValue(account.Id, out var subscription))
|
||||
{
|
||||
account.PerkSubscription = subscription;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log error but don't fail the request - PerkSubscription is optional
|
||||
Console.WriteLine($"Failed to populate PerkSubscriptions for search results: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return accounts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using NATS.Net;
|
||||
using NodaTime;
|
||||
using OtpNet;
|
||||
using AuthService = DysonNetwork.Pass.Auth.AuthService;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
@@ -31,6 +32,7 @@ public class AccountService(
|
||||
IStringLocalizer<EmailResource> emailLocalizer,
|
||||
ICacheService cache,
|
||||
ILogger<AccountService> logger,
|
||||
RemoteSubscriptionService remoteSubscription,
|
||||
INatsConnection nats
|
||||
)
|
||||
{
|
||||
@@ -757,4 +759,56 @@ public class AccountService(
|
||||
}).ToByteArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the PerkSubscription property for a single account by calling the Wallet service via gRPC.
|
||||
/// </summary>
|
||||
public async Task PopulatePerkSubscriptionAsync(SnAccount account)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subscription = await remoteSubscription.GetPerkSubscription(account.Id);
|
||||
if (subscription != null)
|
||||
{
|
||||
account.PerkSubscription = SnWalletSubscription.FromProtoValue(subscription).ToReference();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Failed to populate PerkSubscription for account {AccountId}", account.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the PerkSubscription property for multiple accounts by calling the Wallet service via gRPC.
|
||||
/// </summary>
|
||||
public async Task PopulatePerkSubscriptionsAsync(List<SnAccount> accounts)
|
||||
{
|
||||
if (accounts.Count == 0) return;
|
||||
|
||||
try
|
||||
{
|
||||
var accountIds = accounts.Select(a => a.Id).ToList();
|
||||
var subscriptions = await remoteSubscription.GetPerkSubscriptions(accountIds);
|
||||
|
||||
var subscriptionDict = subscriptions
|
||||
.Where(s => s != null)
|
||||
.ToDictionary(
|
||||
s => Guid.Parse(s.AccountId),
|
||||
s => SnWalletSubscription.FromProtoValue(s).ToReference()
|
||||
);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
if (subscriptionDict.TryGetValue(account.Id, out var subscription))
|
||||
{
|
||||
account.PerkSubscription = subscription;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Failed to populate PerkSubscriptions for {Count} accounts", accounts.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Core;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -10,6 +12,7 @@ public class AccountServiceGrpc(
|
||||
AppDatabase db,
|
||||
AccountEventService accountEvents,
|
||||
RelationshipService relationships,
|
||||
RemoteSubscriptionService remoteSubscription,
|
||||
ILogger<AccountServiceGrpc> logger
|
||||
)
|
||||
: Shared.Proto.AccountService.AccountServiceBase
|
||||
@@ -33,6 +36,9 @@ public class AccountServiceGrpc(
|
||||
if (account == null)
|
||||
throw new RpcException(new Status(StatusCode.NotFound, $"Account {request.Id} not found"));
|
||||
|
||||
// Populate PerkSubscription from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionAsync(account);
|
||||
|
||||
return account.ToProtoValue();
|
||||
}
|
||||
|
||||
@@ -51,6 +57,9 @@ public class AccountServiceGrpc(
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound,
|
||||
$"Account with automated ID {request.AutomatedId} not found"));
|
||||
|
||||
// Populate PerkSubscription from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionAsync(account);
|
||||
|
||||
return account.ToProtoValue();
|
||||
}
|
||||
|
||||
@@ -69,6 +78,9 @@ public class AccountServiceGrpc(
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionsAsync(accounts);
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
@@ -90,6 +102,9 @@ public class AccountServiceGrpc(
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionsAsync(accounts);
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
@@ -126,6 +141,9 @@ public class AccountServiceGrpc(
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionsAsync(accounts);
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
@@ -140,6 +158,9 @@ public class AccountServiceGrpc(
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionsAsync(accounts);
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
@@ -176,6 +197,9 @@ public class AccountServiceGrpc(
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
// Populate PerkSubscriptions from Wallet service via gRPC
|
||||
await PopulatePerkSubscriptionsAsync(accounts);
|
||||
|
||||
var response = new ListAccountsResponse
|
||||
{
|
||||
TotalSize = totalCount,
|
||||
@@ -264,4 +288,56 @@ public class AccountServiceGrpc(
|
||||
);
|
||||
return new BoolValue { Value = hasRelationship };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the PerkSubscription property for a single account by calling the Wallet service via gRPC.
|
||||
/// </summary>
|
||||
private async Task PopulatePerkSubscriptionAsync(SnAccount account)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subscription = await remoteSubscription.GetPerkSubscription(account.Id);
|
||||
if (subscription != null)
|
||||
{
|
||||
account.PerkSubscription = SnWalletSubscription.FromProtoValue(subscription).ToReference();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to populate PerkSubscription for account {AccountId} in gRPC service", account.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the PerkSubscription property for multiple accounts by calling the Wallet service via gRPC.
|
||||
/// </summary>
|
||||
private async Task PopulatePerkSubscriptionsAsync(List<SnAccount> accounts)
|
||||
{
|
||||
if (accounts.Count == 0) return;
|
||||
|
||||
try
|
||||
{
|
||||
var accountIds = accounts.Select(a => a.Id).ToList();
|
||||
var subscriptions = await remoteSubscription.GetPerkSubscriptions(accountIds);
|
||||
|
||||
var subscriptionDict = subscriptions
|
||||
.Where(s => s != null)
|
||||
.ToDictionary(
|
||||
s => Guid.Parse(s.AccountId),
|
||||
s => SnWalletSubscription.FromProtoValue(s).ToReference()
|
||||
);
|
||||
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
if (subscriptionDict.TryGetValue(account.Id, out var subscription))
|
||||
{
|
||||
account.PerkSubscription = subscription;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to populate PerkSubscriptions for {Count} accounts in gRPC service", accounts.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user