using Serilog; using StellaOps.VexHub.Core.Extensions; using StellaOps.VexHub.Persistence.Extensions; using StellaOps.VexHub.WebService.Extensions; using StellaOps.VexHub.WebService.Middleware; using StellaOps.Router.AspNet; var builder = WebApplication.CreateBuilder(args); // Configure Serilog Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration) .Enrich.FromLogContext() .CreateLogger(); builder.Host.UseSerilog(); // Add services to the container builder.Services.AddVexHubCore(builder.Configuration); builder.Services.AddVexHubPersistence(builder.Configuration); builder.Services.AddVexHubWebService(builder.Configuration); // Add authentication builder.Services.AddAuthentication("ApiKey") .AddScheme("ApiKey", options => { options.AllowAnonymous = true; // Allow anonymous for public read endpoints // API keys can be configured via configuration var apiKeysSection = builder.Configuration.GetSection("VexHub:ApiKeys"); foreach (var keySection in apiKeysSection.GetChildren()) { var key = keySection.Key; options.ApiKeys[key] = new ApiKeyInfo { KeyId = keySection["KeyId"] ?? key, ClientId = keySection["ClientId"] ?? "unknown", ClientName = keySection["ClientName"] ?? "Unknown Client", Scopes = keySection.GetSection("Scopes").Get() ?? Array.Empty(), RateLimitPerMinute = keySection.GetValue("RateLimitPerMinute") }; } }); builder.Services.AddAuthorization(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddOpenApi(); // Stella Router integration var routerOptions = builder.Configuration.GetSection("VexHub:Router").Get(); builder.Services.TryAddStellaRouter( serviceName: "vexhub", version: System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0", routerOptions: routerOptions); var app = builder.Build(); // Configure the HTTP request pipeline if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } app.UseHttpsRedirection(); app.UseSerilogRequestLogging(); // Add rate limiting middleware app.UseVexHubRateLimiting(); // Add authentication and authorization app.UseAuthentication(); app.UseAuthorization(); app.TryUseStellaRouter(routerOptions); // Map API endpoints app.MapVexHubEndpoints(); // Health check app.MapGet("/health", () => Results.Ok(new { Status = "Healthy", Service = "VexHub" })) .WithName("HealthCheck") .WithTags("Health"); // Refresh Router endpoint cache app.TryRefreshStellaRouterEndpoints(routerOptions); app.Run(); // Make Program class explicit to avoid conflicts with imported types namespace StellaOps.VexHub.WebService { public partial class Program { } }