using CostingDAL.CustomCode.CostAnalysis; using CostingDAL.DTO.Costing; using GB5Shared.GOP.Qualifier; using FastEndpoints; using FastEndpoints.Swagger; using GB5Shared.Connection; using GB5Shared.DateConverter; using static GB5Shared.DateConverter.GB5JsonOptions; using GB5Shared.DTO.Framework.CommonConfig; using GB5Shared.EntityHandler; using GB5Shared.FileUpload; using GB5Shared.GB5CommonFunction; using GB5Shared.GB5Library.Qualifier; using GB5Shared.GenerateAutoNumber; 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.Reflection; using System.Text; 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 Encoding // ======================================================= Console.OutputEncoding = Encoding.UTF8; // ======================================================= // Dapr // ======================================================= builder.Services.AddDaprClient(); // ======================================================= // Base Entity Service // ======================================================= builder.Services.AddScoped>(); // ======================================================= // 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(); }); // ======================================================= // Hybrid Cache // ======================================================= #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(); // ======================================================= // CORS // ======================================================= // ======================================================= // Core Framework Services // ======================================================= 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; }); // ======================================================= // Costing DAL // ======================================================= builder.Services.AddScoped(); // ======================================================= // Qualifier Engine (FIXED) // ======================================================= builder.Services.AddScoped(); builder.Services.AddGB5QualifierEngine(); // ======================================================= // Workflow Engine // ======================================================= builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // ── OpenTelemetry (Tracing + Metrics) ──────────────────────────────── builder.Services.AddGB5Telemetry(builder.Configuration, "GB5-COSTING"); // ======================================================= // Assembly Scanning // ======================================================= var costingBLLAssembly = Assembly.Load("CostingBLL"); var costingDALAssembly = Assembly.Load("CostingDAL"); builder.Services.Scan(scan => scan .FromAssemblies(costingBLLAssembly, costingDALAssembly) .AddClasses() .AsImplementedInterfaces() .WithScopedLifetime()); // ======================================================= // FastEndpoints // ======================================================= builder.Services.AddFastEndpoints(); // ======================================================= // Outbox // ======================================================= builder.Services.AddScoped(); // ======================================================= // Swagger // ======================================================= builder.Services.SwaggerDocument(options => { options.DocumentSettings = settings => { settings.Title = "GB5 Costing API"; settings.Version = "v1"; settings.Description = "GB5 Costing Module Microservice"; }; }); var app = builder.Build(); // ======================================================= // Middleware Pipeline // ======================================================= app.UseCloudEvents(); app.UseAuthorization(); app.UseMiddleware(); app.UseFastEndpoints(config => { config.Serializer.Options.PropertyNamingPolicy = null; config.Serializer.Options.DictionaryKeyPolicy = null; config.Serializer.Options.AddGB5Converters(); }); app.MapControllers(); app.MapSubscribeHandler(); app.UseOpenApi(); app.UseSwaggerUi(options => { options.Path = "/GB5Documentation"; options.DocumentPath = "/swagger/{documentName}/swagger.json"; options.TransformToExternalPath = (internalPath, _) => "/cts" + internalPath; }); app.MapGet("/", () => "Hello from GB5 Costing Module (.NET 9)"); app.Run();