Files

147 lines
4.8 KiB
C#
Raw Permalink Normal View History

using Microsoft.EntityFrameworkCore;
using Npgsql;
using WorkClub.Application.Clubs.DTOs;
using WorkClub.Application.Interfaces;
using WorkClub.Domain.Enums;
using WorkClub.Infrastructure.Data;
namespace WorkClub.Api.Services;
public class ClubService
{
private readonly AppDbContext _context;
private readonly ITenantProvider _tenantProvider;
private readonly IHttpContextAccessor _httpContextAccessor;
public ClubService(
AppDbContext context,
ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor)
{
_context = context;
_tenantProvider = tenantProvider;
_httpContextAccessor = httpContextAccessor;
}
public async Task<List<ClubListDto>> GetMyClubsAsync()
{
var clubsClaim = _httpContextAccessor.HttpContext?.User.FindFirst("clubs")?.Value;
if (string.IsNullOrEmpty(clubsClaim))
{
return new List<ClubListDto>();
}
var tenantIds = clubsClaim.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim())
.Where(t => !string.IsNullOrEmpty(t) && Guid.TryParse(t, out _))
.ToList();
if (tenantIds.Count == 0)
{
return new List<ClubListDto>();
}
var clubDtos = new List<ClubListDto>();
var connectionString = _context.Database.GetConnectionString();
foreach (var tenantId in tenantIds)
{
await using var connection = new NpgsqlConnection(connectionString);
await connection.OpenAsync();
await using var transaction = await connection.BeginTransactionAsync();
// Set RLS context
using (var command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandText = $"SET LOCAL app.current_tenant_id = '{tenantId}'";
await command.ExecuteNonQueryAsync();
}
Guid? clubId = null;
string? clubName = null;
int? sportTypeInt = null;
// Fetch club details
using (var command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandText = @"
SELECT c.""Id"", c.""Name"", c.""SportType""
FROM clubs AS c
WHERE c.""TenantId"" = @tenantId";
var parameter = command.CreateParameter();
parameter.ParameterName = "@tenantId";
parameter.Value = tenantId;
command.Parameters.Add(parameter);
using (var reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
clubId = reader.GetGuid(0);
clubName = reader.GetString(1);
sportTypeInt = reader.GetInt32(2);
}
}
}
// Fetch member count if club exists
if (clubId.HasValue && clubName != null && sportTypeInt.HasValue)
{
using (var memberCommand = connection.CreateCommand())
{
memberCommand.Transaction = transaction;
memberCommand.CommandText = @"
SELECT COUNT(*)
FROM members AS m
WHERE m.""ClubId"" = @clubId";
var param = memberCommand.CreateParameter();
param.ParameterName = "@clubId";
param.Value = clubId;
memberCommand.Parameters.Add(param);
var memberCountResult = await memberCommand.ExecuteScalarAsync();
var memberCount = memberCountResult != null ? Convert.ToInt32(memberCountResult) : 0;
var sportTypeEnum = ((SportType)sportTypeInt.Value).ToString();
clubDtos.Add(new ClubListDto(
clubId.Value,
clubName,
sportTypeEnum,
memberCount,
Guid.Parse(tenantId)
));
}
}
await transaction.CommitAsync();
}
return clubDtos;
}
public async Task<ClubDetailDto?> GetCurrentClubAsync()
{
var tenantId = _tenantProvider.GetTenantId();
var club = await _context.Clubs
.FirstOrDefaultAsync(c => c.TenantId == tenantId);
if (club == null)
return null;
return new ClubDetailDto(
club.Id,
club.Name,
club.SportType.ToString(),
club.Description,
club.CreatedAt,
club.UpdatedAt
);
}
}