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);
}