using Microsoft.AspNetCore.Routing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using TeamUp.Modules.Integrations.Ai; using TeamUp.Modules.Integrations.Endpoints; using TeamUp.Modules.Integrations.Git; using TeamUp.Modules.Integrations.Persistence; using TeamUp.Modules.Integrations.Security; using TeamUp.SharedKernel.Ai; using TeamUp.SharedKernel.Git; using TeamUp.SharedKernel.Modularity; using TeamUp.SharedKernel.Persistence; namespace TeamUp.Modules.Integrations; /// /// BYOK API configs (encrypted, owner-only), the model-client adapters, and the Git connection. /// Encryption keys are owner-only and server-side; the decrypted key never leaves the server. /// public sealed class IntegrationsModule : IModule { public string Name => "integrations"; public void Register(IServiceCollection services, IConfiguration configuration) { var connectionString = configuration.GetConnectionString("Postgres") ?? throw new InvalidOperationException("Missing connection string 'ConnectionStrings:Postgres'."); // BYOK credential store + encryption. services.AddDbContext(options => options.UseNpgsql(connectionString)); services.AddScoped(sp => sp.GetRequiredService()); services.Configure(configuration.GetSection(EncryptionOptions.SectionName)); services.AddSingleton(); services.AddScoped(); services.TryAddSingleton(TimeProvider.System); // Model clients: a router over per-provider adapters. services.AddSingleton(); services.AddSingleton(); services.AddHttpClient(); services.AddScoped(); // MCP: a JSON-RPC client over HTTP + the org-scoped gateway agents talk through. services.AddHttpClient(); services.AddScoped(); // Git source (M2) — filesystem for dogfood, Gitea over REST when configured. services.Configure(configuration.GetSection(GitSourceOptions.SectionName)); var gitOptions = configuration.GetSection(GitSourceOptions.SectionName).Get() ?? new GitSourceOptions(); if (string.Equals(gitOptions.Provider, "gitea", StringComparison.OrdinalIgnoreCase)) { services.AddHttpClient(); } else { services.AddSingleton(); } } public void MapEndpoints(IEndpointRouteBuilder endpoints) => IntegrationsEndpoints.Map(endpoints); }