Files
Teamup/src/Modules/TeamUp.Modules.Integrations/IntegrationsModule.cs
T

63 lines
2.9 KiB
C#
Raw Normal View History

2026-06-09 06:41:28 +03:30
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
2026-06-09 06:41:28 +03:30
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;
2026-06-09 06:41:28 +03:30
using TeamUp.SharedKernel.Modularity;
using TeamUp.SharedKernel.Persistence;
2026-06-09 06:41:28 +03:30
namespace TeamUp.Modules.Integrations;
/// <summary>
/// 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.
/// </summary>
2026-06-09 06:41:28 +03:30
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<IntegrationsDbContext>(options => options.UseNpgsql(connectionString));
services.AddScoped<IModuleDbContext>(sp => sp.GetRequiredService<IntegrationsDbContext>());
services.Configure<EncryptionOptions>(configuration.GetSection(EncryptionOptions.SectionName));
services.AddSingleton<ISecretProtector, AesGcmSecretProtector>();
services.AddScoped<IApiConfigResolver, ApiConfigResolver>();
services.TryAddSingleton(TimeProvider.System);
// Model clients: a router over per-provider adapters.
services.AddSingleton<StubModelClient>();
services.AddHttpClient<OpenAiCompatibleModelClient>();
services.AddScoped<IModelClient, ModelClientRouter>();
// MCP: a JSON-RPC client over HTTP + the org-scoped gateway agents talk through.
services.AddHttpClient<Mcp.McpClient>();
services.AddScoped<IMcpGateway, Mcp.McpGateway>();
// Git source (M2) — filesystem for dogfood, Gitea over REST when configured.
services.Configure<GitSourceOptions>(configuration.GetSection(GitSourceOptions.SectionName));
var gitOptions = configuration.GetSection(GitSourceOptions.SectionName).Get<GitSourceOptions>() ?? new GitSourceOptions();
if (string.Equals(gitOptions.Provider, "gitea", StringComparison.OrdinalIgnoreCase))
{
services.AddHttpClient<IGitProvider, GiteaGitProvider>();
}
else
{
services.AddSingleton<IGitProvider, FileSystemGitProvider>();
}
2026-06-09 06:41:28 +03:30
}
public void MapEndpoints(IEndpointRouteBuilder endpoints) => IntegrationsEndpoints.Map(endpoints);
2026-06-09 06:41:28 +03:30
}