Files
Core_Be/Helpers/UserRoleHelper.cs
T
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

150 lines
5.2 KiB
C#

using Fitness_core_BE.Exceptions;
using Microsoft.EntityFrameworkCore;
namespace Fitness_core_BE.Helpers
{
public class UserRoleHelper
{
// Admins/Customer/Client are central-bucket; Staff and CustomerSubscriptions are
// tenant-bucket.
private readonly CentralDbContext _central;
private readonly TenantDbContext _context;
public UserRoleHelper(CentralDbContext central, TenantDbContext context)
{
_central = central;
_context = context;
}
public async Task<Guid?> GetAdminId(Guid userId)
{
var admin = await _central.Admins
.AsNoTracking()
.Where(a => a.FKUserId == userId && a.IsActive)
.Select(a => a.AdminId)
.FirstOrDefaultAsync();
return admin == Guid.Empty ? null : admin;
}
public async Task<Guid> GetCusId(Guid userId)
{
var cus = await _central.Customer
.AsNoTracking()
.Where(a => a.FKUserId == userId && a.IsActive)
.Select(a => a.CusId)
.FirstOrDefaultAsync();
if (cus == Guid.Empty)
throw new NotFoundException("Customer not found or inactive");
return cus;
}
public async Task<Guid?> GetStaffId(Guid userId)
{
var staff = await _context.Staff
.AsNoTracking()
.Where(s => s.FKUserId == userId && s.IsActive)
.Select(s => s.StaffId)
.FirstOrDefaultAsync();
return staff == Guid.Empty ? null : staff;
}
public async Task<Guid> GetClientId(Guid userId)
{
var clientId = await _central.Client
.AsNoTracking()
.Where(c => c.FKUserId == userId)
.Select(c => c.ClientId)
.FirstOrDefaultAsync();
// Staff can use the same tenant-scoped dashboard and real-time hub.
if (clientId == Guid.Empty)
{
clientId = await _context.Staff
.AsNoTracking()
.Where(s => s.FKUserId == userId && s.IsActive)
.Select(s => s.FKClientId)
.FirstOrDefaultAsync();
}
if (clientId == Guid.Empty)
throw new NotFoundException("Client not found");
return clientId;
}
// Strict owner lookup used by RBAC decisions. GetClientId intentionally falls
// back to a staff member's tenant so normal tenant-scoped data queries work;
// that fallback must never make staff users appear to be gym owners.
public async Task<Guid?> GetOwnedClientId(Guid userId)
{
var clientId = await _central.Client
.AsNoTracking()
.Where(c => c.FKUserId == userId)
.Select(c => c.ClientId)
.FirstOrDefaultAsync();
return clientId == Guid.Empty ? null : clientId;
}
// Single-club deployment: exactly one Client row exists, so any caller that just needs
// "the club" (rather than a specific user's club) can use this instead of a per-user
// lookup. Used by TenantResolutionAttribute's Customer branch, which used to read a
// caller-supplied X-Tenant-Id header to pick from many gyms -- there's only one now.
public async Task<Guid> GetDefaultClientId()
{
var clientId = await _central.Client
.AsNoTracking()
.Select(c => c.ClientId)
.FirstOrDefaultAsync();
if (clientId == Guid.Empty)
throw new NotFoundException("Club is not configured yet");
return clientId;
}
public async Task<Guid> GetClientIdByCusId(Guid cusId)
{
var clientId = await _context.CustomerSubscriptions
.AsNoTracking()
.Where(s => s.FKCustomerId == cusId && s.IsActive)
.Select(s => s.CustomerPlan.FKClientId)
.FirstOrDefaultAsync();
if (clientId == Guid.Empty)
throw new NotFoundException("No active subscription found for customer");
return clientId;
}
public async Task<string> GetUserType(Guid userId)
{
var isAdmin = await _central.Admins
.AsNoTracking()
.AnyAsync(a => a.FKUserId == userId && a.IsActive);
if (isAdmin)
return "Admin";
var isCustomer = await _central.Customer
.AsNoTracking()
.AnyAsync(c => c.FKUserId == userId && c.IsActive);
if (isCustomer)
return "Customer";
var isClient = await _central.Client
.AsNoTracking()
.AnyAsync(cl => cl.FKUserId == userId);
if (isClient)
return "Client";
var isStaff = await _context.Staff
.AsNoTracking()
.AnyAsync(s => s.FKUserId == userId && s.IsActive);
if (isStaff)
return "Staff";
throw new NotFoundException("User role not found or inactive");
}
}
}