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

299 lines
14 KiB
C#

using Fitness_core_BE;
using Fitness_core_BE.AI;
using Fitness_core_BE.Auth;
using Fitness_core_BE.Helpers;
using Fitness_core_BE.Hubs;
using Fitness_core_BE.Infra.UoW;
using Fitness_core_BE.Interfaces;
using Fitness_core_BE.Interfaces.Services;
using Fitness_core_BE.Repos;
using Fitness_core_BE.Services;
using Fitness_core_BE.Services.ActivityLog;
using Fitness_core_BE.Services.Auth;
using Fitness_core_BE.Services.Chat;
using Fitness_core_BE.Services.ClientInvoice;
using Fitness_core_BE.Services.CustomerService;
using Fitness_core_BE.Services.CustomerInvoice;
using Fitness_core_BE.Services.Payment;
using Fitness_core_BE.Services.CustomerPlanService;
using Fitness_core_BE.Services.CustomerSubscription;
using Fitness_core_BE.Services.Document;
using Fitness_core_BE.Services.Feed;
using Fitness_core_BE.Services.FunctionHandler;
using Fitness_core_BE.Services.Meal;
using Fitness_core_BE.Services.Staff;
using Fitness_core_BE.Services.Ticket;
using Fitness_core_BE.Services.Workout;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community;
// Add services to the container.
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "Fitness Core Backend API",
Version = "v1",
Description = "API for managing fitness-related operations including ticket management system",
Contact = new Microsoft.OpenApi.Models.OpenApiContact
{
Name = "Development Team",
Email = "dev@fitness-core.com"
}
});
// Enable XML comments if available
var xmlFile = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = System.IO.Path.Combine(AppContext.BaseDirectory, xmlFile);
if (System.IO.File.Exists(xmlPath))
{
options.IncludeXmlComments(xmlPath);
}
});
// AppDBContext is kept as inert legacy code (not deleted, per the non-destructive migration
// principle) but is intentionally left unregistered -- CentralDbContext/TenantDbContext below
// are what every repo/service now actually uses.
builder.Services.AddHttpContextAccessor();
// Single club, single database -- both contexts share one connection string. (GYM's split
// used CentralDbContext/TenantDbContext to route each request to one of many per-client MySQL
// schemas; Vijaya has exactly one club, so that routing layer is gone and both contexts just
// point at the same DB. The two C# context classes stay separate to avoid a much larger,
// riskier refactor across every repo that injects one or the other.)
builder.Services.AddDbContext<CentralDbContext>(options =>
{
options.UseMySql(
builder.Configuration.GetConnectionString("DefaultConnection"),
// Keep startup and EF tooling independent of database network availability.
// This is the minimum supported MySQL baseline; Pomelo adjusts generated SQL.
new MySqlServerVersion(new Version(8, 0, 0))
);
});
builder.Services.AddDbContext<TenantDbContext>(options =>
{
options.UseMySql(
builder.Configuration.GetConnectionString("DefaultConnection"),
new MySqlServerVersion(new Version(8, 0, 0))
);
});
builder.Services.AddCors(o =>
o.AddPolicy("AllowAll", p =>
p.SetIsOriginAllowed(origin => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
)
);
builder.Services.AddHttpClient();
builder.Services.AddScoped<IUnitOfWork, EFUnitOfWork>();
builder.Services.AddSignalR();
builder.Services.AddHttpContextAccessor();
// Register Repositories
builder.Services.AddScoped<ITicketRepository, TicketRepository>();
builder.Services.AddScoped<ITermsRepository, TermsRepository>();
builder.Services.AddScoped<IActivityLogRepository, ActivityLogRepository>();
builder.Services.AddScoped<IClientRepository, ClientRepository>();
builder.Services.AddScoped<IStaffRepository, StaffRepository>();
builder.Services.AddScoped<IClientInvoiceRepository, ClientInvoiceRepository>();
builder.Services.AddScoped<ICustomerRepository, CustomerRepository>();
builder.Services.AddScoped<ICustomerInvoiceRepository, CustomerInvoiceRepository>();
builder.Services.AddScoped<ICustomerSubscriptionRepository, CustomerSubscriptionRepository>();
builder.Services.AddScoped<ICustomerPlanRepository, CustomerPlanRepository>();
builder.Services.AddScoped<IMealRepository, MealRepository>();
builder.Services.AddScoped<IWorkoutRepository, WorkoutRepository>();
builder.Services.AddScoped<IChatRepo, ChatRepository>();
builder.Services.AddScoped<IDocumentRepository, DocumentRepository>();
builder.Services.AddScoped<IFeedRepository, FeedRepository>();
builder.Services.AddScoped<IAttendanceRepository, AttendanceRepository>();
builder.Services.AddScoped<IClientStatRepository, ClientStatRepository>();
builder.Services.AddScoped<IPaymentRepository, PaymentRepository>();
builder.Services.AddScoped<IPaymentsEnablementRepository, PaymentsEnablementRepository>();
builder.Services.AddScoped<IAdminClientDirectoryRepository, AdminClientDirectoryRepository>();
builder.Services.AddScoped<IAdminSuggestionRepository, AdminSuggestionRepository>();
builder.Services.AddScoped<IGymRoleRepository, GymRoleRepository>();
builder.Services.AddScoped<INavItemRepository, NavItemRepository>();
builder.Services.AddScoped<IProfitLossRepository, ProfitLossRepository>();
builder.Services.AddScoped<IOverdueLockRepository, OverdueLockRepository>();
builder.Services.AddScoped<IPlatformBillingRepository, PlatformBillingRepository>();
builder.Services.AddScoped<ICustomerNotificationRepository, CustomerNotificationRepository>();
builder.Services.AddScoped<IFacilityRepository, FacilityRepository>();
builder.Services.AddScoped<IBookingRepository, BookingRepository>();
builder.Services.AddScoped<ITimeBankCardRepository, TimeBankCardRepository>();
builder.Services.AddScoped<IPlaceRepo, PlaceRepo>();
// Register Helpers
builder.Services.AddScoped<Fitness_core_BE.Infra.Tenancy.ITenantContext, Fitness_core_BE.Infra.Tenancy.TenantContext>();
builder.Services.AddScoped<UserRoleHelper>();
builder.Services.AddScoped<RequestAccessTokenHelper>();
builder.Services.AddScoped<InvoicePaymentTokenHelper>();
builder.Services.AddScoped<PlatformInvoicePaymentTokenHelper>();
// Register Services
builder.Services.AddScoped<ITicketService, TicketService>();
builder.Services.AddScoped<IActivityLogService, ActivityLogService>();
builder.Services.AddScoped<IClientService, ClientService>();
builder.Services.AddScoped<IStaffService, StaffService>();
builder.Services.AddScoped<IClientInvoiceService, ClientInvoiceService>();
builder.Services.AddScoped<ICustomerService, CustomerService>();
builder.Services.AddScoped<ICustomerInvoiceService, CustomerInvoiceService>();
builder.Services.AddScoped<ICustomerSubscriptionService, CustomerSubscriptionService>();
builder.Services.AddScoped<IFacilityService, FacilityService>();
builder.Services.AddScoped<IBookingService, BookingService>();
builder.Services.AddScoped<ITimeBankCardService, TimeBankCardService>();
builder.Services.AddScoped<IBootstrapService, BootstrapService>();
builder.Services.AddScoped<ISubscriptionRenewalApprovalService, SubscriptionRenewalApprovalService>();
builder.Services.AddScoped<ICustomerPlanService, CustomerPlanService>();
builder.Services.AddScoped<IPlaceService, PlaceService>();
builder.Services.AddScoped<IMealService, MealService>();
builder.Services.AddScoped<IWorkoutService, WorkoutService>();
builder.Services.AddScoped<IAuthService, AuthService>();
builder.Services.AddScoped<IDocumentService, DocumentService>();
builder.Services.AddScoped<IFeedService, FeedService>();
builder.Services.AddScoped<IChatService, ChatService>();
builder.Services.AddScoped<IClientStatService, ClientStatService>();
builder.Services.AddScoped<IPaymentService, PaymentService>();
builder.Services.AddScoped<IPaymentsEnablementService, PaymentsEnablementService>();
builder.Services.AddScoped<IThirdPartyService, ThirdPartyService>();
builder.Services.AddScoped<IReceiptService, ReceiptService>();
builder.Services.AddScoped<IPayoutKycReviewService, PayoutKycReviewService>();
builder.Services.AddScoped<IAdminClientDirectoryService, AdminClientDirectoryService>();
builder.Services.AddScoped<IAdminSuggestionService, AdminSuggestionService>();
builder.Services.AddScoped<IPlatformBillingService, PlatformBillingService>();
builder.Services.AddScoped<IClientPaymentMethodService, ClientPaymentMethodService>();
builder.Services.AddScoped<IGymRoleService, GymRoleService>();
builder.Services.AddScoped<IPermissionService, PermissionService>();
builder.Services.AddScoped<INavigationService, NavigationService>();
builder.Services.AddScoped<IPushNotificationService, PushNotificationService>();
// Register Function Handlers
builder.Services.AddScoped<TicketFuncHandler>();
builder.Services.AddScoped<ActivityLogFuncHandler>();
builder.Services.AddScoped<ClientFuncHandler>();
builder.Services.AddScoped<StaffFunctionHandler>();
builder.Services.AddScoped<ClientInvoiceFunctionHandler>();
builder.Services.AddScoped<CustomerFunctionHandler>();
builder.Services.AddScoped<CustomerInvoiceFunctionHandler>();
builder.Services.AddScoped<CustomerPlanFunctionHandler>();
builder.Services.AddScoped<CustomerSubscriptionFunctionHandler>();
builder.Services.AddScoped<MealFunctionHandler>();
builder.Services.AddScoped<WorkoutFunctionHandler>();
builder.Services.AddScoped<AuthFuncHandler>();
builder.Services.AddScoped<DocumentFunctionHandler>();
builder.Services.AddScoped<FeedFuncHandler>();
builder.Services.AddScoped<AccessDeviceFunctionHandler>();
builder.Services.AddScoped<ChatFunctionHandler>();
builder.Services.AddScoped<UserRegisterHandler>();
builder.Services.AddScoped<ClientStatFuncHandler>();
builder.Services.AddScoped<PaymentFunctionHandler>();
// Register AI Services
builder.Services.AddScoped<ModificationGuard>();
builder.Services.AddScoped<MealPlanOrchestrator>();
builder.Services.AddScoped<WorkoutPlanOrchestrator>();
builder.Services.AddHttpClient<IAiClient, GeminiClient>();
// Register Access Device Service
builder.Services.AddScoped<IAccessDeviceService, AccessDeviceService>();
builder.Services.AddScoped<IAccessDeviceRepo, AccessDeviceRepo>();
// Register Payment-Service clients: catalog/provisioning admin proxy (X-Internal-Key),
// and the per-platform HMAC-signed client for real card/payment/refund calls.
builder.Services.AddScoped<IPaymentServiceClient, PaymentServiceClient>();
builder.Services.AddScoped<IPaymentGatewayClient, PaymentGatewayClient>();
// Shared by background jobs that have no HttpContext to resolve a tenant from -- lets them
// loop over every real, provisioned tenant schema directly instead of only ever seeing
// whichever schema TenantConnectionResolver's request-based fallback resolves to.
builder.Services.AddSingleton<Fitness_core_BE.Infra.Tenancy.TenantSchemaIterator>();
builder.Services.AddSingleton<SubscriptionRenewalRunner>();
builder.Services.AddSingleton<OverdueLockRunner>();
builder.Services.AddSingleton<IJobRunHistory, DbJobRunHistory>();
// Auto-lock members after configurable days overdue (req 7) -- disabled at the user's request.
// OverdueLockRunner (above) stays registered, so the manual "trigger now" endpoint
// (POST api/admin/background-jobs/overdue-lock/trigger) still works on demand; only the
// automatic startup + 6-hourly run is turned off. Uncomment to re-enable.
// builder.Services.AddHostedService<OverdueLockJob>();
// Auto-renew expired subscriptions (new plan price + carried-over overdue balance)
builder.Services.AddHostedService<SubscriptionRenewalJob>();
// Basic P&L / ledger for the client portal
builder.Services.AddScoped<IProfitLossService, ProfitLossService>();
// Register On-prem Agent platform
builder.Services.AddScoped<IAgentRepo, AgentRepo>();
builder.Services.AddScoped<IPairingCodeRepo, PairingCodeRepo>();
builder.Services.AddScoped<IDeviceCommandRepo, DeviceCommandRepo>();
builder.Services.AddScoped<IAgentService, AgentService>();
// Agent API-key authentication scheme + policy (does not affect existing admin/user auth).
builder.Services
.AddAuthentication()
.AddScheme<AgentApiKeyAuthenticationOptions, AgentApiKeyAuthenticationHandler>(
AgentApiKeyDefaults.AuthenticationScheme, _ => { })
.AddScheme<UserJwtAuthenticationOptions, UserJwtAuthenticationHandler>(
UserJwtDefaults.AuthenticationScheme, _ => { });
builder.Services.AddAuthorization(options =>
{
options.AddPolicy(AgentApiKeyDefaults.PolicyName, policy =>
{
policy.AddAuthenticationSchemes(AgentApiKeyDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
});
// Register Attendance Service
builder.Services.AddScoped<IAttendanceService, AttendanceService>();
builder.Services.AddScoped<AttendanceFunctionHandler>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// First in the pipeline so it catches anything thrown by everything after it.
app.UseMiddleware<Fitness_core_BE.Helpers.GlobalExceptionMiddleware>();
app.UseRouting();
app.UseCors("AllowAll");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<ChatHub>("/hubs/chat");
app.MapHub<AccessHub>("/hubs/access");
app.Run();