using System.Reflection; using Api.Clients.Ai; using Api.Clients.Ai.Contracts; using Api.Data; using Api.Data.Repositories; using Api.Data.Repositories.Contracts; using Api.Services; using Api.Services.Contracts; using Microsoft.EntityFrameworkCore; using Rag.Models.Settings; using Serilog; using Shared.Models.Settings; using StartupHelpers; StartupExtensions.LoadDotEnvFile(); const string ServiceName = "rag-api"; var appVersion = StartupExtensions.GetApplicationVersion(Assembly.GetExecutingAssembly()); try { var builder = WebApplication.CreateBuilder(args); builder.ConfigureJsonSerilog(ServiceName, appVersion); Log.Information("Starting {Service} version {AppVersion}", ServiceName, appVersion); builder.AddAzureKeyVaultIfConfigured(); builder.Services.Configure(builder.Configuration.GetSection("Database")); builder.Services.Configure(builder.Configuration.GetSection("Rag")); builder.Services.Configure(builder.Configuration.GetSection("Ai")); builder.Services.Configure(builder.Configuration.GetSection("InternalApi")); builder.Services.AddDbContext(options => { var configuration = builder.Configuration; var connectionString = builder.Services.GetConfiguredDbConnectionString(configuration); options.UseSqlServer(connectionString, sql => { sql.MigrationsHistoryTable(RagDbContext.MigrationTableName, RagDbContext.SchemaName); }); }); builder.Services.AddHttpClient(); builder.Services.AddScoped(); builder.Services.AddHttpClient(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddControllers(); builder.Services.AddSwaggerWithXmlComments(Assembly.GetExecutingAssembly(), ServiceName); var app = builder.Build(); app.LogStartupDiagnostics(ServiceName); using (var scope = app.Services.CreateScope()) { var repository = scope.ServiceProvider.GetRequiredService(); await repository.InitializeAsync(CancellationToken.None); } app.UseDefaultSerilogRequestLogging(); app.UseJsonExceptionHandler(ServiceName); app.UseInternalApiKeyProtection(); app.UseSwaggerInDevelopment(ServiceName, ServiceName); app.MapControllers(); Log.Information("Running EF Core migrations if any"); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); db.Database.Migrate(); } Log.Information("{Service} startup complete", ServiceName); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "{Service} terminated unexpectedly", ServiceName); } finally { Log.Information("Shutting down {Service}", ServiceName); Log.CloseAndFlush(); }