using System.Reflection; using System.Text; using FastEndpoints; using FastEndpoints.Swagger; using GB5Shared.Connection; using GB5Shared.Telemetry; using GB5Shared.DaprCache; using GB5Shared.DateConverter; using static GB5Shared.DateConverter.GB5JsonOptions; using GB5Shared.DTO.Framework.CommonConfig; using GB5Shared.EventLogPublish; using GB5Shared.GB5CommonFunction; using GB5Shared.GenerateAutoNumber; using GB5Shared.QueryExecutor; using GB5Shared.Validation; using GB5Shared.Vault; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Caching.Hybrid; using ECPSL.Communication.Hubs; // ------------------------- // Bootstrap — standalone dev/test host for the whole ECP module set (Communication + // Correspondence + Collaboration + Meeting, consolidated from 4 separate module project sets // into one, mirroring CRM's single-module/multi-sub-feature structure). Production deployment // maps this module through EngagementHost instead (see // GB5Solution/Hosts/Engagement/EngagementHost/Program.cs + EcpModule.cs). // ------------------------- var builder = WebApplication.CreateBuilder(args); Console.OutputEncoding = Encoding.UTF8; var appPort = builder.Configuration.GetValue("AppPort"); builder.WebHost.UseUrls($"http://0.0.0.0:{appPort}"); builder.Services.AddDaprClient(); builder.Services.AddControllers() .AddDapr() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.DictionaryKeyPolicy = null; options.JsonSerializerOptions.AddGB5Converters(); }); #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(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // CommunicationModule.Register() registers FrameworkBLL.PushNotificationDAL (offline notification // fallback for CommentThreadBLL), which needs IVaultService. When this module runs inside // EngagementHost, DMSSL's own AddGB5Vault() already provides it; standalone, nothing else does. builder.Services.AddGB5Vault(builder.Configuration); builder.Services.Configure( builder.Configuration.GetSection("Gb5SystemDTO")); builder.Services.Configure(options => { options.AllowSynchronousIO = true; }); builder.Services.AddGB5Telemetry(builder.Configuration, "GB5-ECP"); // ------------------------- // Module registration (same EcpModule used by EngagementHost) // ------------------------- var module = new ECPSL.EcpModule(); module.Register(builder.Services, builder.Configuration); var endpointAssemblies = new[] { Assembly.Load("ECPSL"), Assembly.Load("ECPBLL"), Assembly.Load("ECPDAL"), Assembly.Load("GB5Shared"), }; builder.Services.AddFastEndpoints(o => { o.Assemblies = endpointAssemblies; }); builder.Services.SwaggerDocument(o => { o.DocumentSettings = s => { s.Title = "GB5 ECP API"; s.Version = "v1"; s.Description = "Enterprise Communication Platform - Communication | Correspondence | Collaboration | Meeting"; }; o.EnableJWTBearerAuth = false; o.ShortSchemaNames = true; }); var app = builder.Build(); app.UseCloudEvents(); app.UseMiddleware(); app.UseMiddleware(); app.UseFastEndpoints(c => { c.Serializer.Options.PropertyNamingPolicy = null; c.Serializer.Options.DictionaryKeyPolicy = null; c.Serializer.Options.AddGB5Converters(); }); app.MapControllers(); app.MapSubscribeHandler(); module.MapEndpoints(app); app.UseOpenApi(); app.UseSwaggerUi(o => { o.Path = "/GB5Documentation"; o.DocumentPath = "/swagger/{documentName}/swagger.json"; o.TransformToExternalPath = (internalUiRoute, _) => "/ecp" + internalUiRoute; }); app.MapGet("/", () => "Hello from GB5 ECP API (.NET 9)"); app.UseAuthorization(); app.Run();