SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/ Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue, контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер), Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог). Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0, тесты 1340/130/52/38/9 зелёные.
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
using Deal.Contracts.Integrations.Abstractions;
|
||||
using Deal.Infrastructure.Integrations.Abstractions;
|
||||
using Deal.Infrastructure.Integrations.Models;
|
||||
using Deal.Infrastructure.Integrations.Options;
|
||||
using Deal.Infrastructure.Integrations.Services;
|
||||
using Deal.Infrastructure.Integrations.Sources;
|
||||
using Deal.Infrastructure.Persistence;
|
||||
using Deal.Infrastructure.Persistence.Repositories;
|
||||
using Deal.Infrastructure.Security;
|
||||
using Deal.Infrastructure.Services;
|
||||
using Deal.Infrastructure.Tenancy;
|
||||
using Deal.Modules.Cards.Application.Abstractions;
|
||||
using Deal.Modules.Cards.Application.Sources;
|
||||
using Deal.Modules.Discovery.Application.Abstractions;
|
||||
using Deal.Modules.Kanban.Application.Abstractions;
|
||||
using Deal.Modules.Pipeline.Application.Abstractions;
|
||||
using Deal.Modules.Settings.Application.Abstractions;
|
||||
using Deal.Modules.Telegram.Application;
|
||||
using Deal.Modules.Tenants.Application.Abstractions;
|
||||
using Deal.Modules.Tenants.Application.Models;
|
||||
using Deal.SharedKernel.Tenants.Abstractions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Deal.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// DI-регистрация адаптеров персистентности Deal.Infrastructure.
|
||||
/// </summary>
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Регистрирует EF-адаптеры портов модулей
|
||||
/// </summary>
|
||||
/// <param name="tenantLimitDefaults">Дефолт-бюджет лениво создаваемых строк tenant_limits. Передаётся из конфигурации/env DEAL_DEFAULT_AI_BUDGET в Program.cs.</param>
|
||||
public static IServiceCollection AddDealPersistence(this IServiceCollection services, TokenLimitDefaults? tenantLimitDefaults = null)
|
||||
{
|
||||
services.AddScoped<IAuthStore, AuthStore>();
|
||||
|
||||
services.AddScoped<IOperatorAuthStore, OperatorAuthStore>();
|
||||
services.AddScoped<ITenantRepository, TenantRepository>();
|
||||
|
||||
services.AddScoped<IAuditLogStore, AuditLogStore>();
|
||||
|
||||
services.AddScoped<ITokenUsageEventStore, TokenUsageEventStore>();
|
||||
|
||||
services.AddScoped<IInviteStore, InviteStore>();
|
||||
|
||||
services.AddScoped<ITenantLimitStore>(provider => new TenantLimitStore(
|
||||
provider.GetRequiredService<DealDbContext>(),
|
||||
tenantLimitDefaults ?? TokenBudgetDefaults.Default));
|
||||
|
||||
services.AddScoped<IRateLimitCounterStore, RateLimitCounterStore>();
|
||||
|
||||
services.AddScoped<ISettingsStore, SettingsStore>();
|
||||
|
||||
services.AddScoped<IGlobalSettingsStore, GlobalSettingsStore>();
|
||||
|
||||
services.AddScoped<ICardStore, KanbanStore>();
|
||||
|
||||
services.AddScoped<ISourceContentProvider, TelegramSourceContentProvider>();
|
||||
|
||||
services.AddScoped<IPipelineStore, PipelineStore>();
|
||||
|
||||
services.AddScoped<IMlLearningStore, MlLearningStore>();
|
||||
|
||||
services.AddScoped<ITelegramStore, TelegramStore>();
|
||||
|
||||
services.AddScoped<IDiscoveryStore, DiscoveryStore>();
|
||||
|
||||
services.AddScoped<ITenantProvisioner, TenantProvisioningService>();
|
||||
|
||||
services.AddScoped<TenantSchemaMigrationService>();
|
||||
|
||||
services.AddScoped<ICardMover, CardMover>();
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Регистрирует адаптеры внешних интеграций
|
||||
/// </summary>
|
||||
/// <param name="mlOptions">Конфигурация секции <c>Services:Ml</c> — выбор реализации IMlClient.</param>
|
||||
/// <param name="aiOptions">Конфигурация секции <c>Services:Ai</c> — выбор реализации IAiClassifier/IAiTools.</param>
|
||||
/// <param name="telegramOptions">Конфигурация секции <c>Services:Telegram</c> — выбор реализации ITelegramGateway.</param>
|
||||
public static IServiceCollection AddDealIntegrations(
|
||||
this IServiceCollection services,
|
||||
MlServiceOptions mlOptions,
|
||||
AiServiceOptions aiOptions,
|
||||
TelegramServiceOptions telegramOptions,
|
||||
MtlsCertificates? mtlsCertificates = null)
|
||||
{
|
||||
services.AddScoped<TokenUsageRecorder>();
|
||||
|
||||
if (mlOptions.UseLocal)
|
||||
{
|
||||
services.AddScoped<IMlClient, LocalMlClient>();
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton(new MlGrpcConnection(mlOptions, mtlsCertificates));
|
||||
services.AddSingleton<MlStatusCache>();
|
||||
services.AddScoped<GrpcMlClient>();
|
||||
services.AddScoped<IMlClient>(provider => provider.GetRequiredService<GrpcMlClient>());
|
||||
services.AddScoped<IMlTrainClient>(provider => provider.GetRequiredService<GrpcMlClient>());
|
||||
}
|
||||
|
||||
services.AddScoped<IColumnSuggester, LocalColumnSuggester>();
|
||||
|
||||
if (aiOptions.UseLocal)
|
||||
{
|
||||
services.AddScoped<IAiClassifier, LocalAiClassifier>();
|
||||
services.AddScoped<IAiTools, LocalAiTools>();
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton(new AiGrpcConnection(aiOptions, mtlsCertificates));
|
||||
services.AddScoped<AiProviderConfigBuilder>();
|
||||
services.AddScoped<GrpcAiClassifier>();
|
||||
services.AddScoped<LocalAiClassifier>();
|
||||
services.AddScoped<IAiClassifier>(provider => new BudgetedAiClassifier(
|
||||
provider.GetRequiredService<GrpcAiClassifier>(),
|
||||
provider.GetRequiredService<LocalAiClassifier>(),
|
||||
provider.GetRequiredService<ITenantLimitStore>(),
|
||||
provider.GetRequiredService<ITenantContext>(),
|
||||
provider.GetRequiredService<ILogger<BudgetedAiClassifier>>()));
|
||||
services.AddScoped<GrpcAiTools>();
|
||||
services.AddScoped<IAiTools>(provider => new BudgetedAiTools(
|
||||
provider.GetRequiredService<GrpcAiTools>(),
|
||||
provider.GetRequiredService<ITenantLimitStore>(),
|
||||
provider.GetRequiredService<ITenantContext>(),
|
||||
provider.GetRequiredService<ILogger<BudgetedAiTools>>()));
|
||||
}
|
||||
|
||||
if (telegramOptions.UseLocal)
|
||||
{
|
||||
services.AddSingleton<ITelegramGateway, LocalTelegramGateway>();
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton(new TelegramGrpcConnection(telegramOptions, mtlsCertificates));
|
||||
services.AddScoped<GrpcTelegramClient>();
|
||||
services.AddScoped<ITelegramGateway>(provider => provider.GetRequiredService<GrpcTelegramClient>());
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Регистрирует сервисы шифрования секретов
|
||||
/// </summary>
|
||||
/// <param name="contentRootPath">ContentRoot приложения — каталог по умолчанию для файла-ключа data/encryption.key.</param>
|
||||
public static IServiceCollection AddDealSecurity(this IServiceCollection services, string contentRootPath)
|
||||
{
|
||||
EncryptionKeyProvider keyProvider = new(contentRootPath);
|
||||
byte[] key = keyProvider.GetKey();
|
||||
services.AddSingleton<ISecretCipher>(new AesGcmSecretCipher(key));
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user