using FastEndpoints; using FastEndpoints.Swagger; using GB5Shared.Connection; using GB5Shared.DateConverter; using GB5Shared.DTO.Framework.CommonConfig; using GB5Shared.EntityHandler; using GB5Shared.ExcelExport; using GB5Shared.Export; using GB5Shared.Export.CSVExport; using GB5Shared.Export.NativePdf; using GB5Shared.Export.Pivot; using GB5Shared.GB5CommonFunction; using GB5Shared.GB5Library.Qualifier; using GB5Shared.GenerateAutoNumber; using GB5Shared.GOP.ExecuteAsync; using GB5Shared.GOP.Qualifier; using GB5Shared.PubSub.OutBox; using GB5Shared.QueryExecutor; using GB5Shared.Telemetry; using GB5Shared.Validation; using GB5Shared.WorkFlow.WorkFlowEngine; using GB5Shared.WorkFlow.WorkFlowRunTime; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Caching.Hybrid; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using System.Diagnostics; using System.Reflection; using System.Text; using static GB5Shared.DateConverter.GB5JsonOptions; var builder = WebApplication.CreateBuilder(args); // ── Port from config — change "AppPort" in appsettings.json to use any port ── var appPort = builder.Configuration.GetValue("AppPort"); builder.WebHost.UseUrls($"http://0.0.0.0:{appPort}"); // ------------------------------------------------------------ // Console // ------------------------------------------------------------ Console.OutputEncoding = Encoding.UTF8; // ------------------------------------------------------------ // Dapr // ------------------------------------------------------------ builder.Services.AddDaprClient(); // ------------------------------------------------------------ // Controllers + JSON // ------------------------------------------------------------ builder.Services.AddControllers() .AddDapr() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.DictionaryKeyPolicy = null; options.JsonSerializerOptions.AddGB5Converters(); }); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.PropertyNamingPolicy = null; options.SerializerOptions.DictionaryKeyPolicy = null; options.SerializerOptions.AddGB5Converters(); }); // ------------------------------------------------------------ // Caching // ------------------------------------------------------------ #pragma warning disable EXTEXP0018 builder.Services.AddHybridCache(options => { options.DefaultEntryOptions = new HybridCacheEntryOptions(); options.DisableCompression = false; }); #pragma warning restore EXTEXP0018 builder.Services.AddMemoryCache(); builder.Services.AddDistributedMemoryCache(); // ------------------------------------------------------------ // Core Infrastructure // ------------------------------------------------------------ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.Configure( builder.Configuration.GetSection("Gb5SystemDTO")); // ------------------------------------------------------------ // Kestrel // ------------------------------------------------------------ builder.Services.Configure(options => { options.AllowSynchronousIO = true; }); // ------------------------------------------------------------ // HTTP Client // ------------------------------------------------------------ builder.Services.AddHttpClient(); // ------------------------------------------------------------ // Workflow // ------------------------------------------------------------ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // ------------------------------------------------------------ // Generic Entity Services // ------------------------------------------------------------ builder.Services.AddScoped(typeof(BaseEntityAppService<>), typeof(BaseEntityAppService<>)); // ------------------------------------------------------------ // Qualifier Engine // ------------------------------------------------------------ builder.Services.AddScoped(); builder.Services.AddGB5QualifierEngine(); // ------------------------------------------------------------ // Execution Engine // ------------------------------------------------------------ builder.Services.AddScoped(); // ------------------------------------------------------------ // Outbox // ------------------------------------------------------------ builder.Services.AddScoped(); // ── OpenTelemetry (Tracing + Metrics) ──────────────────────────────── builder.Services.AddGB5Telemetry(builder.Configuration, "GB5-CRM"); // ------------------------------------------------------------ // Assembly Scanning // ------------------------------------------------------------ var crmBLLAssembly = Assembly.Load("CRMBLL"); var crmDALAssembly = Assembly.Load("CRMDAL"); builder.Services.Scan(scan => scan .FromAssemblies(crmBLLAssembly, crmDALAssembly) .AddClasses(classes => classes.Where(t => !t.IsAbstract && !t.IsInterface)) .AsImplementedInterfaces() .WithScopedLifetime()); // ------------------------------------------------------------ // FastEndpoints // ------------------------------------------------------------ builder.Services.AddFastEndpoints(); // ------------------------------------------------------------ // Swagger // ------------------------------------------------------------ builder.Services.SwaggerDocument(options => { options.DocumentSettings = settings => { settings.Title = "GB5 CRM API"; settings.Version = "v1"; settings.Description = "CRM Module Microservice"; }; }); // ------------------------------------------------------------ // Build // ------------------------------------------------------------ var app = builder.Build(); // ------------------------------------------------------------ // Middleware // ------------------------------------------------------------ app.UseAuthorization(); app.UseCloudEvents(); app.UseMiddleware(); app.UseFastEndpoints(config => { config.Serializer.Options.PropertyNamingPolicy = null; config.Serializer.Options.DictionaryKeyPolicy = null; config.Serializer.Options.AddGB5Converters(); }); // ------------------------------------------------------------ // Endpoints // ------------------------------------------------------------ app.MapControllers(); app.MapSubscribeHandler(); app.MapGet("/", () => Results.Ok(new { Service = "GB5 CRM Module", Version = "1.0.0", Framework = ".NET 9", Status = "Running", Timestamp = DateTime.UtcNow })); // ------------------------------------------------------------ // Swagger UI // ------------------------------------------------------------ app.UseOpenApi(); app.UseSwaggerUi(options => { options.Path = "/GB5Documentation"; options.DocumentPath = "/swagger/{documentName}/swagger.json"; options.TransformToExternalPath = (internalPath, _) => "/crm" + internalPath; }); // ------------------------------------------------------------ // Run // ------------------------------------------------------------ app.Run();