using Fitness_core_BE.Exceptions; using Fitness_core_BE.Helpers; using Fitness_core_BE.Infra.UoW; using Fitness_core_BE.Interfaces.Services; using Fitness_core_BE.Models; using Fitness_core_BE.Models.Enums; using Microsoft.EntityFrameworkCore; namespace Fitness_core_BE.Services { // GYM's onboarding/activation flow (ClientController's "onboarding/requests" -> // "activation/{token}" endpoints) is a multi-gym SaaS signup wizard -- OTP checks, NIC // upload, a payment-method + platform-billing charge step -- built for a platform onboarding // many paying gym clients. Vijaya is a single, already-real club, not a SaaS signup; this // is the one-time "create the club" step instead, guarded so it can only ever run once // (before that first Client row exists) rather than being a repeatable registration path. public class BootstrapService : IBootstrapService { private readonly CentralDbContext _central; private readonly IUnitOfWork _uow; public BootstrapService(CentralDbContext central, IUnitOfWork uow) { _central = central; _uow = uow; } public async Task BootstrapClub(object payload) { await _uow.BeginAsync(); try { if (await _central.Client.AnyAsync()) throw new BadRequestException("The club is already set up."); var data = DeserializePayload.Deserialize(payload); if (!data.ContainsKey("userId")) throw new ArgumentException("userId is required"); if (!data.ContainsKey("clientName")) throw new ArgumentException("clientName is required"); var userId = Guid.Parse(data["userId"].GetString()!); var clientName = data["clientName"].GetString()!; // core-api keeps its own local mirror of user identity (see CustomerRepository/ // StaffRepository doing the same on customer/staff creation) -- Client.FKUserId // has a real local FK to this table, not to auth-service's database, since the // two services no longer share a connection. Idempotent: harmless if a mirror // row already exists for this user id. if (!await _central.Users.AnyAsync(u => u.UserId == userId)) { _central.Users.Add(new User { UserId = userId, Email = data.ContainsKey("clientEmail") ? data["clientEmail"].GetString() : null, PhoneNumber = data.ContainsKey("clientPhone") ? data["clientPhone"].GetString() : null, IsActive = true }); } var client = new Client { ClientId = Guid.NewGuid(), FKUserId = userId, ClientName = clientName, ClientPhone = data.ContainsKey("clientPhone") ? data["clientPhone"].GetString() : null, ClientEmail = data.ContainsKey("clientEmail") ? data["clientEmail"].GetString() : null }; _central.Client.Add(client); _central.ClientBusiness.Add(new ClientBusiness { Bid = Guid.NewGuid(), FKClientId = client.ClientId, BusinessType = BusinessType.institute, BusinessName = clientName, IsActive = true }); await _uow.CommitAsync(); return new { clientId = client.ClientId, clientName = client.ClientName }; } catch { await _uow.RollbackAsync(); throw; } } } }