diff --git a/deployments/local/docker-compose.yml b/deployments/local/docker-compose.yml
index aad24f4a..f306bbd3 100644
--- a/deployments/local/docker-compose.yml
+++ b/deployments/local/docker-compose.yml
@@ -301,7 +301,7 @@ services:
start_period: 40s
labels:
- "traefik.enable=true"
- - "traefik.http.routers.wallet-service.rule=PathPrefix(`/api/v1/wallets`) || PathPrefix(`/api/v1/points`)"
+ - "traefik.http.routers.wallet-service.rule=PathPrefix(`/api/v1/wallets`) || PathPrefix(`/api/v1/points`) || PathPrefix(`/api/v1/admin/wallets`) || PathPrefix(`/api/v1/admin/points`)"
- "traefik.http.routers.wallet-service.entrypoints=web"
- "traefik.http.services.wallet-service.loadbalancer.server.port=8080"
- "traefik.http.services.wallet-service.loadbalancer.healthcheck.path=/health/live"
diff --git a/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminPointsCommandHandlers.cs b/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminPointsCommandHandlers.cs
new file mode 100644
index 00000000..6b747d32
--- /dev/null
+++ b/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminPointsCommandHandlers.cs
@@ -0,0 +1,99 @@
+namespace WalletService.API.Application.Commands;
+
+using MediatR;
+using WalletService.Domain.AggregatesModel.PointAccountAggregate;
+using WalletService.Domain.Exceptions;
+
+///
+/// EN: Handler for AdminAdjustPointsCommand.
+/// VI: Handler cho AdminAdjustPointsCommand.
+///
+public class AdminAdjustPointsCommandHandler : IRequestHandler
+{
+ private readonly IPointAccountRepository _pointAccountRepository;
+ private readonly ILogger _logger;
+
+ public AdminAdjustPointsCommandHandler(
+ IPointAccountRepository pointAccountRepository,
+ ILogger logger)
+ {
+ _pointAccountRepository = pointAccountRepository;
+ _logger = logger;
+ }
+
+ public async Task Handle(
+ AdminAdjustPointsCommand request,
+ CancellationToken cancellationToken)
+ {
+ var account = await _pointAccountRepository.GetByIdAsync(request.AccountId)
+ ?? throw new WalletDomainException($"Point account {request.AccountId} not found");
+
+ var previousPoints = account.AvailablePoints;
+
+ // EN: Adjust points directly using domain method
+ // VI: Điều chỉnh điểm trực tiếp bằng phương thức domain
+ account.AdjustPoints(request.Points, $"Admin Adjustment: {request.Reason}");
+
+ _pointAccountRepository.Update(account);
+ await _pointAccountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
+
+ _logger.LogInformation(
+ "Point account {AccountId} adjusted by Admin {AdminId}. Points: {Points}. Reason: {Reason}",
+ request.AccountId, request.AdminId, request.Points, request.Reason);
+
+ return new AdminAdjustPointsResult(
+ account.Id,
+ previousPoints,
+ request.Points,
+ account.AvailablePoints,
+ request.Reason,
+ DateTime.UtcNow);
+ }
+}
+
+///
+/// EN: Handler for AdminGrantBonusCommand.
+/// VI: Handler cho AdminGrantBonusCommand.
+///
+public class AdminGrantBonusCommandHandler : IRequestHandler
+{
+ private readonly IPointAccountRepository _pointAccountRepository;
+ private readonly ILogger _logger;
+
+ public AdminGrantBonusCommandHandler(
+ IPointAccountRepository pointAccountRepository,
+ ILogger logger)
+ {
+ _pointAccountRepository = pointAccountRepository;
+ _logger = logger;
+ }
+
+ public async Task Handle(
+ AdminGrantBonusCommand request,
+ CancellationToken cancellationToken)
+ {
+ var account = await _pointAccountRepository.GetByIdAsync(request.AccountId)
+ ?? throw new WalletDomainException($"Point account {request.AccountId} not found");
+
+ var expiryMonths = request.ExpiryMonths ?? 12;
+ var expiresAt = DateTime.UtcNow.AddMonths(expiryMonths);
+
+ // EN: Earn bonus points with expiry
+ // VI: Tích điểm thưởng với thời hạn
+ account.AddBonusPoints(request.Points, "AdminBonus", $"Admin Bonus: {request.Reason}", expiresAt);
+
+ _pointAccountRepository.Update(account);
+ await _pointAccountRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
+
+ _logger.LogInformation(
+ "Point account {AccountId} granted {Points} bonus points by Admin {AdminId}. Reason: {Reason}",
+ request.AccountId, request.Points, request.AdminId, request.Reason);
+
+ return new AdminGrantBonusResult(
+ account.Id,
+ request.Points,
+ account.AvailablePoints,
+ expiresAt,
+ DateTime.UtcNow);
+ }
+}
diff --git a/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminWalletCommandHandlers.cs b/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminWalletCommandHandlers.cs
new file mode 100644
index 00000000..67bc9628
--- /dev/null
+++ b/services/wallet-service-net/src/WalletService.API/Application/Commands/AdminWalletCommandHandlers.cs
@@ -0,0 +1,145 @@
+namespace WalletService.API.Application.Commands;
+
+using MediatR;
+using WalletService.Domain.AggregatesModel.WalletAggregate;
+using WalletService.Domain.Exceptions;
+
+///
+/// EN: Handler for AdminFreezeWalletCommand.
+/// VI: Handler cho AdminFreezeWalletCommand.
+///
+public class AdminFreezeWalletCommandHandler : IRequestHandler
+{
+ private readonly IWalletRepository _walletRepository;
+ private readonly ILogger _logger;
+
+ public AdminFreezeWalletCommandHandler(
+ IWalletRepository walletRepository,
+ ILogger logger)
+ {
+ _walletRepository = walletRepository;
+ _logger = logger;
+ }
+
+ public async Task Handle(
+ AdminFreezeWalletCommand request,
+ CancellationToken cancellationToken)
+ {
+ var wallet = await _walletRepository.GetByIdAsync(request.WalletId)
+ ?? throw new WalletDomainException($"Wallet {request.WalletId} not found");
+
+ wallet.Freeze();
+
+ _walletRepository.Update(wallet);
+ await _walletRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
+
+ _logger.LogInformation(
+ "Wallet {WalletId} frozen by Admin {AdminId}. Reason: {Reason}",
+ request.WalletId, request.AdminId, request.Reason);
+
+ return new AdminWalletActionResult(
+ wallet.Id,
+ wallet.Status.Name,
+ request.AdminId.ToString(),
+ DateTime.UtcNow);
+ }
+}
+
+///
+/// EN: Handler for AdminUnfreezeWalletCommand.
+/// VI: Handler cho AdminUnfreezeWalletCommand.
+///
+public class AdminUnfreezeWalletCommandHandler : IRequestHandler
+{
+ private readonly IWalletRepository _walletRepository;
+ private readonly ILogger _logger;
+
+ public AdminUnfreezeWalletCommandHandler(
+ IWalletRepository walletRepository,
+ ILogger logger)
+ {
+ _walletRepository = walletRepository;
+ _logger = logger;
+ }
+
+ public async Task Handle(
+ AdminUnfreezeWalletCommand request,
+ CancellationToken cancellationToken)
+ {
+ var wallet = await _walletRepository.GetByIdAsync(request.WalletId)
+ ?? throw new WalletDomainException($"Wallet {request.WalletId} not found");
+
+ wallet.Unfreeze();
+
+ _walletRepository.Update(wallet);
+ await _walletRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
+
+ _logger.LogInformation(
+ "Wallet {WalletId} unfrozen by Admin {AdminId}. Reason: {Reason}",
+ request.WalletId, request.AdminId, request.Reason);
+
+ return new AdminWalletActionResult(
+ wallet.Id,
+ wallet.Status.Name,
+ request.AdminId.ToString(),
+ DateTime.UtcNow);
+ }
+}
+
+///
+/// EN: Handler for AdminAdjustBalanceCommand.
+/// VI: Handler cho AdminAdjustBalanceCommand.
+///
+public class AdminAdjustBalanceCommandHandler : IRequestHandler
+{
+ private readonly IWalletRepository _walletRepository;
+ private readonly ILogger _logger;
+
+ public AdminAdjustBalanceCommandHandler(
+ IWalletRepository walletRepository,
+ ILogger logger)
+ {
+ _walletRepository = walletRepository;
+ _logger = logger;
+ }
+
+ public async Task Handle(
+ AdminAdjustBalanceCommand request,
+ CancellationToken cancellationToken)
+ {
+ var wallet = await _walletRepository.GetByIdAsync(request.WalletId)
+ ?? throw new WalletDomainException($"Wallet {request.WalletId} not found");
+
+ var currencyType = Domain.SeedWork.Enumeration.FromValue(request.CurrencyTypeId);
+ var previousBalance = wallet.GetBalance(currencyType);
+
+ // EN: Positive amount = credit, negative = debit
+ // VI: Số dương = cộng, số âm = trừ
+ if (request.Amount > 0)
+ {
+ wallet.Deposit(request.Amount, currencyType, $"Admin Adjustment: {request.Reason}");
+ }
+ else if (request.Amount < 0)
+ {
+ wallet.Withdraw(Math.Abs(request.Amount), currencyType, $"Admin Adjustment: {request.Reason}");
+ }
+
+ _walletRepository.Update(wallet);
+ await _walletRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
+
+ var newBalance = wallet.GetBalance(currencyType);
+
+ _logger.LogInformation(
+ "Wallet {WalletId} balance adjusted by Admin {AdminId}. Amount: {Amount} {Currency}. Reason: {Reason}",
+ request.WalletId, request.AdminId, request.Amount, currencyType.Name, request.Reason);
+
+ return new AdminAdjustBalanceResult(
+ wallet.Id,
+ previousBalance,
+ request.Amount,
+ newBalance,
+ currencyType.Name,
+ request.Reason,
+ DateTime.UtcNow);
+ }
+}
diff --git a/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminPointsQueryHandlers.cs b/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminPointsQueryHandlers.cs
new file mode 100644
index 00000000..2e0267e1
--- /dev/null
+++ b/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminPointsQueryHandlers.cs
@@ -0,0 +1,181 @@
+namespace WalletService.API.Application.Queries;
+
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using WalletService.Domain.AggregatesModel.PointAccountAggregate;
+using WalletService.Infrastructure;
+
+///
+/// EN: Handler for GetAllPointAccountsQuery (Admin).
+/// VI: Handler cho GetAllPointAccountsQuery (Admin).
+///
+public class GetAllPointAccountsQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetAllPointAccountsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetAllPointAccountsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var query = _context.PointAccounts.AsQueryable();
+
+ // EN: Filter by points range if provided
+ // VI: Lọc theo khoảng điểm nếu có
+ if (request.MinPoints.HasValue)
+ query = query.Where(p => p.AvailablePoints >= request.MinPoints.Value);
+
+ if (request.MaxPoints.HasValue)
+ query = query.Where(p => p.AvailablePoints <= request.MaxPoints.Value);
+
+ var totalCount = await query.CountAsync(cancellationToken);
+
+ var accounts = await query
+ .OrderByDescending(p => p.TotalPoints)
+ .Skip((request.Page - 1) * request.PageSize)
+ .Take(request.PageSize)
+ .Select(p => new AdminPointAccountSummaryDto(
+ p.Id,
+ p.UserId,
+ p.TotalPoints,
+ p.AvailablePoints,
+ p.CreatedAt))
+ .ToListAsync(cancellationToken);
+
+ return new AdminPointAccountsListDto(accounts, totalCount, request.Page, request.PageSize);
+ }
+}
+
+///
+/// EN: Handler for GetPointAccountByIdQuery (Admin).
+/// VI: Handler cho GetPointAccountByIdQuery (Admin).
+///
+public class GetPointAccountByIdQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetPointAccountByIdQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetPointAccountByIdQuery request,
+ CancellationToken cancellationToken)
+ {
+ var account = await _context.PointAccounts
+ .Include(p => p.Transactions)
+ .FirstOrDefaultAsync(p => p.Id == request.AccountId, cancellationToken);
+
+ if (account == null) return null;
+
+ return new AdminPointAccountDetailDto(
+ account.Id,
+ account.UserId,
+ account.TotalPoints,
+ account.AvailablePoints,
+ account.Transactions.Count,
+ account.CreatedAt,
+ account.UpdatedAt);
+ }
+}
+
+///
+/// EN: Handler for SearchPointAccountsQuery (Admin).
+/// VI: Handler cho SearchPointAccountsQuery (Admin).
+///
+public class SearchPointAccountsQueryHandler : IRequestHandler>
+{
+ private readonly WalletServiceContext _context;
+
+ public SearchPointAccountsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task> Handle(
+ SearchPointAccountsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var query = _context.PointAccounts
+ .Include(p => p.Transactions)
+ .AsQueryable();
+
+ if (request.UserId.HasValue)
+ query = query.Where(p => p.UserId == request.UserId.Value);
+
+ var accounts = await query
+ .Take(50)
+ .Select(p => new AdminPointAccountDetailDto(
+ p.Id,
+ p.UserId,
+ p.TotalPoints,
+ p.AvailablePoints,
+ p.Transactions.Count,
+ p.CreatedAt,
+ p.UpdatedAt))
+ .ToListAsync(cancellationToken);
+
+ return accounts;
+ }
+}
+
+///
+/// EN: Handler for GetPointsStatisticsQuery (Admin).
+/// VI: Handler cho GetPointsStatisticsQuery (Admin).
+///
+public class GetPointsStatisticsQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetPointsStatisticsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetPointsStatisticsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var today = DateTime.UtcNow.Date;
+
+ var totalAccounts = await _context.PointAccounts.CountAsync(cancellationToken);
+
+ var totalPointsIssued = await _context.PointAccounts
+ .SumAsync(p => p.TotalPoints, cancellationToken);
+
+ var totalPointsAvailable = await _context.PointAccounts
+ .SumAsync(p => p.AvailablePoints, cancellationToken);
+
+ // EN: Calculate spent and expired from transactions
+ // VI: Tính điểm đã tiêu và hết hạn từ giao dịch
+ var totalPointsSpent = await _context.PointTransactions
+ .Where(t => t.TypeId == PointTransactionType.Spend.Id)
+ .SumAsync(t => t.Points, cancellationToken);
+
+ var totalPointsExpired = await _context.PointTransactions
+ .Where(t => t.TypeId == PointTransactionType.Expire.Id)
+ .SumAsync(t => t.Points, cancellationToken);
+
+ var pointsEarnedToday = await _context.PointTransactions
+ .Where(t => t.CreatedAt >= today && t.TypeId == PointTransactionType.Earn.Id)
+ .SumAsync(t => t.Points, cancellationToken);
+
+ var pointsSpentToday = await _context.PointTransactions
+ .Where(t => t.CreatedAt >= today && t.TypeId == PointTransactionType.Spend.Id)
+ .SumAsync(t => t.Points, cancellationToken);
+
+ return new PointsStatisticsDto(
+ totalAccounts,
+ totalPointsIssued,
+ totalPointsAvailable,
+ totalPointsSpent,
+ totalPointsExpired,
+ pointsEarnedToday,
+ pointsSpentToday);
+ }
+}
diff --git a/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminWalletQueryHandlers.cs b/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminWalletQueryHandlers.cs
new file mode 100644
index 00000000..166d6e4a
--- /dev/null
+++ b/services/wallet-service-net/src/WalletService.API/Application/Queries/AdminWalletQueryHandlers.cs
@@ -0,0 +1,211 @@
+namespace WalletService.API.Application.Queries;
+
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using WalletService.Domain.AggregatesModel.WalletAggregate;
+using WalletService.Infrastructure;
+
+///
+/// EN: Handler for GetAllWalletsQuery (Admin).
+/// VI: Handler cho GetAllWalletsQuery (Admin).
+///
+public class GetAllWalletsQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetAllWalletsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetAllWalletsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var query = _context.Wallets
+ .Include(w => w.Balances)
+ .AsQueryable();
+
+ // EN: Filter by status if provided
+ // VI: Lọc theo trạng thái nếu có
+ if (!string.IsNullOrEmpty(request.Status))
+ {
+ var status = WalletStatus.FromDisplayName(request.Status);
+ if (status != null)
+ query = query.Where(w => w.StatusId == status.Id);
+ }
+
+ var totalCount = await query.CountAsync(cancellationToken);
+
+ var wallets = await query
+ .OrderByDescending(w => w.CreatedAt)
+ .Skip((request.Page - 1) * request.PageSize)
+ .Take(request.PageSize)
+ .Select(w => new AdminWalletSummaryDto(
+ w.Id,
+ w.UserId,
+ WalletStatus.FromValue(w.StatusId).Name,
+ w.Balances.Select(b => new BalanceItemDto(
+ CurrencyType.FromValue(b.CurrencyTypeId).Name,
+ b.Balance)).ToList(),
+ w.CreatedAt,
+ w.UpdatedAt))
+ .ToListAsync(cancellationToken);
+
+ return new AdminWalletsListDto(wallets, totalCount, request.Page, request.PageSize);
+ }
+}
+
+///
+/// EN: Handler for GetWalletByIdQuery (Admin).
+/// VI: Handler cho GetWalletByIdQuery (Admin).
+///
+public class GetWalletByIdQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetWalletByIdQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetWalletByIdQuery request,
+ CancellationToken cancellationToken)
+ {
+ var wallet = await _context.Wallets
+ .Include(w => w.Balances)
+ .Include(w => w.Transactions)
+ .FirstOrDefaultAsync(w => w.Id == request.WalletId, cancellationToken);
+
+ if (wallet == null) return null;
+
+ return new AdminWalletDetailDto(
+ wallet.Id,
+ wallet.UserId,
+ WalletStatus.FromValue(wallet.StatusId).Name,
+ wallet.Balances.Select(b => new BalanceItemDto(
+ CurrencyType.FromValue(b.CurrencyTypeId).Name,
+ b.Balance)).ToList(),
+ wallet.Transactions.Count,
+ wallet.CreatedAt,
+ wallet.UpdatedAt);
+ }
+}
+
+///
+/// EN: Handler for SearchWalletsQuery (Admin).
+/// VI: Handler cho SearchWalletsQuery (Admin).
+///
+public class SearchWalletsQueryHandler : IRequestHandler>
+{
+ private readonly WalletServiceContext _context;
+
+ public SearchWalletsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task> Handle(
+ SearchWalletsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var query = _context.Wallets
+ .Include(w => w.Balances)
+ .Include(w => w.Transactions)
+ .AsQueryable();
+
+ if (request.UserId.HasValue)
+ query = query.Where(w => w.UserId == request.UserId.Value);
+
+ if (request.WalletId.HasValue)
+ query = query.Where(w => w.Id == request.WalletId.Value);
+
+ if (!string.IsNullOrEmpty(request.Status))
+ {
+ var status = WalletStatus.FromDisplayName(request.Status);
+ if (status != null)
+ query = query.Where(w => w.StatusId == status.Id);
+ }
+
+ var wallets = await query
+ .Take(50) // Limit results
+ .Select(w => new AdminWalletDetailDto(
+ w.Id,
+ w.UserId,
+ WalletStatus.FromValue(w.StatusId).Name,
+ w.Balances.Select(b => new BalanceItemDto(
+ CurrencyType.FromValue(b.CurrencyTypeId).Name,
+ b.Balance)).ToList(),
+ w.Transactions.Count,
+ w.CreatedAt,
+ w.UpdatedAt))
+ .ToListAsync(cancellationToken);
+
+ return wallets;
+ }
+}
+
+///
+/// EN: Handler for GetWalletStatisticsQuery (Admin).
+/// VI: Handler cho GetWalletStatisticsQuery (Admin).
+///
+public class GetWalletStatisticsQueryHandler : IRequestHandler
+{
+ private readonly WalletServiceContext _context;
+
+ public GetWalletStatisticsQueryHandler(WalletServiceContext context)
+ {
+ _context = context;
+ }
+
+ public async Task Handle(
+ GetWalletStatisticsQuery request,
+ CancellationToken cancellationToken)
+ {
+ var today = DateTime.UtcNow.Date;
+
+ var totalWallets = await _context.Wallets.CountAsync(cancellationToken);
+ var activeWallets = await _context.Wallets
+ .CountAsync(w => w.StatusId == WalletStatus.Active.Id, cancellationToken);
+ var frozenWallets = await _context.Wallets
+ .CountAsync(w => w.StatusId == WalletStatus.Frozen.Id, cancellationToken);
+ var closedWallets = await _context.Wallets
+ .CountAsync(w => w.StatusId == WalletStatus.Closed.Id, cancellationToken);
+
+ // EN: Total balance by currency
+ // VI: Tổng số dư theo loại tiền tệ
+ var balancesByCurrency = await _context.WalletItems
+ .GroupBy(wi => wi.CurrencyTypeId)
+ .Select(g => new { CurrencyId = g.Key, Total = g.Sum(wi => wi.Balance) })
+ .ToListAsync(cancellationToken);
+
+ var totalBalanceByCurrency = balancesByCurrency.ToDictionary(
+ b => CurrencyType.FromValue(b.CurrencyId).Name,
+ b => b.Total);
+
+ // EN: Today's transactions
+ // VI: Giao dịch hôm nay
+ var todayTransactions = await _context.WalletTransactions
+ .Where(t => t.CreatedAt >= today)
+ .SumAsync(t => t.Amount.Amount, cancellationToken);
+
+ var todayDeposits = await _context.WalletTransactions
+ .Where(t => t.CreatedAt >= today && t.TypeId == TransactionType.Credit.Id)
+ .SumAsync(t => t.Amount.Amount, cancellationToken);
+
+ var todayWithdrawals = await _context.WalletTransactions
+ .Where(t => t.CreatedAt >= today && t.TypeId == TransactionType.Debit.Id)
+ .SumAsync(t => t.Amount.Amount, cancellationToken);
+
+ return new WalletStatisticsDto(
+ totalWallets,
+ activeWallets,
+ frozenWallets,
+ closedWallets,
+ totalBalanceByCurrency,
+ todayTransactions,
+ todayDeposits,
+ todayWithdrawals);
+ }
+}
diff --git a/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/PointAccountAggregate/IPointAccountRepository.cs b/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/PointAccountAggregate/IPointAccountRepository.cs
index 657e1faa..be6590e5 100644
--- a/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/PointAccountAggregate/IPointAccountRepository.cs
+++ b/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/PointAccountAggregate/IPointAccountRepository.cs
@@ -8,6 +8,12 @@ using WalletService.Domain.SeedWork;
///
public interface IPointAccountRepository : IRepository
{
+ ///
+ /// EN: Get point account by ID
+ /// VI: Lấy tài khoản điểm theo ID
+ ///
+ Task GetByIdAsync(Guid accountId);
+
///
/// EN: Get point account by user ID
/// VI: Lấy tài khoản điểm theo ID người dùng
diff --git a/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/WalletAggregate/IWalletRepository.cs b/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/WalletAggregate/IWalletRepository.cs
index e87cc6e4..f3c7b777 100644
--- a/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/WalletAggregate/IWalletRepository.cs
+++ b/services/wallet-service-net/src/WalletService.Domain/AggregatesModel/WalletAggregate/IWalletRepository.cs
@@ -8,6 +8,12 @@ using WalletService.Domain.SeedWork;
///
public interface IWalletRepository : IRepository
{
+ ///
+ /// EN: Get wallet by ID
+ /// VI: Lấy ví theo ID
+ ///
+ Task GetByIdAsync(Guid walletId);
+
///
/// EN: Get wallet by user ID
/// VI: Lấy ví theo ID người dùng
diff --git a/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/PointAccountRepository.cs b/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/PointAccountRepository.cs
index 29d0ce7b..4654aa82 100644
--- a/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/PointAccountRepository.cs
+++ b/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/PointAccountRepository.cs
@@ -19,6 +19,12 @@ public class PointAccountRepository : IPointAccountRepository
_context = context ?? throw new ArgumentNullException(nameof(context));
}
+ public async Task GetByIdAsync(Guid accountId)
+ {
+ return await _context.PointAccounts
+ .FirstOrDefaultAsync(p => p.Id == accountId);
+ }
+
public async Task GetByUserIdAsync(Guid userId)
{
return await _context.PointAccounts
diff --git a/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/WalletRepository.cs b/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/WalletRepository.cs
index c6f34fba..9ff8293b 100644
--- a/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/WalletRepository.cs
+++ b/services/wallet-service-net/src/WalletService.Infrastructure/Repositories/WalletRepository.cs
@@ -19,9 +19,17 @@ public class WalletRepository : IWalletRepository
_context = context ?? throw new ArgumentNullException(nameof(context));
}
+ public async Task GetByIdAsync(Guid walletId)
+ {
+ return await _context.Wallets
+ .Include(w => w.Balances)
+ .FirstOrDefaultAsync(w => w.Id == walletId);
+ }
+
public async Task GetByUserIdAsync(Guid userId)
{
return await _context.Wallets
+ .Include(w => w.Balances)
.FirstOrDefaultAsync(w => w.UserId == userId);
}