From 0d2204219ad02159b9da772757d7384748e1c836 Mon Sep 17 00:00:00 2001 From: stepan Date: Sun, 13 Sep 2026 14:15:23 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=AF=D0=B2=D0=BD=D1=8B=D0=B5=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B2=20=D0=BF=D1=80=D0=BE=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TenantContext, LocalTelegramGateway, DefaultPasswordHasher и WTelegramSessionClient переведены на явные реализации; типы в тестах приведены к ITenantContext. --- .../Deal.Infrastructure/Data/TenantContext.cs | 11 ++---- .../Services/LocalTelegramGateway.cs | 26 ++------------ .../Services/DefaultPasswordHasher.cs | 9 ++--- .../Api/DiscoveryWorkerSchedulerTests.cs | 4 +-- .../Api/MlOutboxFlushSchedulerTests.cs | 10 +++--- .../Support/PipelineWorkerSchedulerTests.cs | 4 +-- .../Support/StorageTickSchedulerTests.cs | 20 +++++------ .../Telegram/WTelegramSessionClient.cs | 36 ++++--------------- 8 files changed, 33 insertions(+), 87 deletions(-) diff --git a/src/core/Deal.Infrastructure/Data/TenantContext.cs b/src/core/Deal.Infrastructure/Data/TenantContext.cs index 65eed6f..ab3520b 100644 --- a/src/core/Deal.Infrastructure/Data/TenantContext.cs +++ b/src/core/Deal.Infrastructure/Data/TenantContext.cs @@ -3,22 +3,17 @@ using Deal.SharedKernel.Tenants.Models; namespace Deal.Infrastructure.Data; -/// -/// Контекст тенанта на AsyncLocal -/// public sealed class TenantContext : ITenantContext { private static readonly AsyncLocal Current = new(); - public TenantId? TenantId => Current.Value; + TenantId? ITenantContext.TenantId => Current.Value; - public bool HasTenant => Current.Value is not null; + bool ITenantContext.HasTenant => Current.Value is not null; - public string? SchemaName => Current.Value?.SchemaName; + string? ITenantContext.SchemaName => Current.Value?.SchemaName; - /// void ITenantContext.SetTenant(TenantId tenantId) => Current.Value = tenantId; - /// void ITenantContext.Reset() => Current.Value = null; } diff --git a/src/core/Deal.Infrastructure/Integrations/Services/LocalTelegramGateway.cs b/src/core/Deal.Infrastructure/Integrations/Services/LocalTelegramGateway.cs index 1af1518..6dee6a7 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/LocalTelegramGateway.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/LocalTelegramGateway.cs @@ -3,21 +3,16 @@ using Deal.Contracts.Integrations.Models; namespace Deal.Infrastructure.Integrations.Services; -/// -/// Локальная заглушка без telegram-service. -/// public sealed class LocalTelegramGateway : ITelegramGateway { // Фаза idle-формы (аккаунт не подключён — сервиса нет). private const string IdlePhase = "idle"; - /// Task ITelegramGateway.StatusAsync(CancellationToken ct) { return Task.FromResult(new TelegramAccountStatusDto(IdlePhase, false, false, string.Empty, null, null)); } - /// Task ITelegramGateway.StartPhoneAsync( string phone, int apiId, @@ -25,76 +20,61 @@ public sealed class LocalTelegramGateway : ITelegramGateway CancellationToken ct) => Task.FromResult(new TelegramAuthResultDto(IdlePhase, null)); - /// Task ITelegramGateway.StartQrAsync( int apiId, string apiHash, CancellationToken ct) => Task.FromResult(new TelegramAuthResultDto(IdlePhase, null)); - /// - public Task SendCodeAsync(string code, CancellationToken ct) => Task.FromResult(IdlePhase); + Task ITelegramGateway.SendCodeAsync(string code, CancellationToken ct) => Task.FromResult(IdlePhase); - /// - public Task SendPasswordAsync(string password, CancellationToken ct) => Task.FromResult(IdlePhase); + Task ITelegramGateway.SendPasswordAsync(string password, CancellationToken ct) => Task.FromResult(IdlePhase); - /// Task ITelegramGateway.LogoutAsync(CancellationToken ct) => Task.CompletedTask; - /// Task> ITelegramGateway.RefreshDialogsAsync(CancellationToken ct) => Task.FromResult>([]); - /// Task ITelegramGateway.SetMonitorAsync( string dialogId, bool enabled, CancellationToken ct) => Task.CompletedTask; - /// Task ITelegramGateway.SetMonitorAllAsync(bool enabled, CancellationToken ct) => Task.CompletedTask; - /// - public Task BackfillAsync( + Task ITelegramGateway.BackfillAsync( string dialogId, bool force, CancellationToken ct) => Task.FromResult(0); - /// Task> ITelegramGateway.ReadRecentAsync( string dialogId, int limit, CancellationToken ct) => Task.FromResult>([]); - /// Task ITelegramGateway.ReadSourceAsync( string dialogId, long msgId, CancellationToken ct) => Task.FromResult(new TelegramSourceContentDto(false, null, null)); - /// Task> ITelegramGateway.SearchAsync( string query, int limit, CancellationToken ct) => Task.FromResult>([]); - /// Task ITelegramGateway.InfoAsync(string dialogId, CancellationToken ct) => Task.FromResult(new TelegramChannelInfoDto(dialogId, string.Empty, string.Empty, string.Empty, SourceDefaults.DefaultHue, null, false)); - /// Task ITelegramGateway.ReadForEvalAsync( string dialogId, int limit, CancellationToken ct) => Task.FromResult(new TelegramEvalReadDto(false, "no_history", [])); - /// Task ITelegramGateway.JoinAsync(string username, CancellationToken ct) => Task.CompletedTask; - /// Task ITelegramGateway.LeaveAsync(string dialogId, CancellationToken ct) => Task.CompletedTask; } diff --git a/src/core/Deal.Modules.Tenants/Application/Services/DefaultPasswordHasher.cs b/src/core/Deal.Modules.Tenants/Application/Services/DefaultPasswordHasher.cs index ba7e7c3..1876f4c 100644 --- a/src/core/Deal.Modules.Tenants/Application/Services/DefaultPasswordHasher.cs +++ b/src/core/Deal.Modules.Tenants/Application/Services/DefaultPasswordHasher.cs @@ -3,14 +3,9 @@ using Isopoh.Cryptography.Argon2; namespace Deal.Modules.Tenants.Application.Services; -/// -/// Реализация на Argon2id. -/// public sealed class DefaultPasswordHasher : IPasswordHasher { - /// - public string Hash(string password) => Argon2.Hash(password); + string IPasswordHasher.Hash(string password) => Argon2.Hash(password); - /// - public bool Verify(string password, string encodedHash) => Argon2.Verify(encodedHash, password); + bool IPasswordHasher.Verify(string password, string encodedHash) => Argon2.Verify(encodedHash, password); } diff --git a/src/core/tests/Deal.Tests.Unit/Api/DiscoveryWorkerSchedulerTests.cs b/src/core/tests/Deal.Tests.Unit/Api/DiscoveryWorkerSchedulerTests.cs index 8e12fd4..8d8ade1 100644 --- a/src/core/tests/Deal.Tests.Unit/Api/DiscoveryWorkerSchedulerTests.cs +++ b/src/core/tests/Deal.Tests.Unit/Api/DiscoveryWorkerSchedulerTests.cs @@ -39,7 +39,7 @@ public sealed class DiscoveryWorkerSchedulerTests TestDiscoveryStore StoreB, TestDiscoveryGateway GatewayA, TestDiscoveryGateway GatewayB, - TenantContext TenantContext, + ITenantContext TenantContext, ListLogger Logs); [Fact] @@ -91,7 +91,7 @@ public sealed class DiscoveryWorkerSchedulerTests private static Context CreateContext() { var tenants = new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); var storeA = new TestDiscoveryStore(); var storeB = new TestDiscoveryStore(); var settingsA = new TestSettingsStore(); diff --git a/src/core/tests/Deal.Tests.Unit/Api/MlOutboxFlushSchedulerTests.cs b/src/core/tests/Deal.Tests.Unit/Api/MlOutboxFlushSchedulerTests.cs index ef50d41..fb26843 100644 --- a/src/core/tests/Deal.Tests.Unit/Api/MlOutboxFlushSchedulerTests.cs +++ b/src/core/tests/Deal.Tests.Unit/Api/MlOutboxFlushSchedulerTests.cs @@ -41,7 +41,7 @@ public sealed class MlOutboxFlushSchedulerTests { var store = new TestMlLearningStore(); SeedRows(store, count: 25, prefix: "a"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( port, new TestTenantRepository(Tenant(TenantA)), @@ -67,7 +67,7 @@ public sealed class MlOutboxFlushSchedulerTests service.TrainUnavailable = true; var store = new TestMlLearningStore(); SeedRows(store, count: 5, prefix: "a"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( port, new TestTenantRepository(Tenant(TenantA)), @@ -95,7 +95,7 @@ public sealed class MlOutboxFlushSchedulerTests SeedRows(storeA, count: 12, prefix: "a"); var storeB = new TestMlLearningStore(); SeedRows(storeB, count: 3, prefix: "b"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( port, new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)), @@ -121,7 +121,7 @@ public sealed class MlOutboxFlushSchedulerTests { var store = new TestMlLearningStore(); SeedRows(store, count: 105, prefix: "a"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( port, new TestTenantRepository(Tenant(TenantA)), @@ -148,7 +148,7 @@ public sealed class MlOutboxFlushSchedulerTests private static ServiceProvider BuildProvider( int port, TestTenantRepository tenants, - TenantContext tenantContext, + ITenantContext tenantContext, Dictionary storesByTenant) { var services = new ServiceCollection(); diff --git a/src/core/tests/Deal.Tests.Unit/Support/PipelineWorkerSchedulerTests.cs b/src/core/tests/Deal.Tests.Unit/Support/PipelineWorkerSchedulerTests.cs index 9bd8504..79a645d 100644 --- a/src/core/tests/Deal.Tests.Unit/Support/PipelineWorkerSchedulerTests.cs +++ b/src/core/tests/Deal.Tests.Unit/Support/PipelineWorkerSchedulerTests.cs @@ -47,7 +47,7 @@ public sealed class PipelineWorkerSchedulerTests TestKanjStore KanjB, SseSubscription SubscriptionB, PipelinePumpGate PumpGate, - TenantContext TenantContext, + ITenantContext TenantContext, ListLogger Logs); // ─── Цикл: pump каждого тенанта в собственном scope + new_card ───────── @@ -149,7 +149,7 @@ public sealed class PipelineWorkerSchedulerTests private static Context CreateContext(bool withThrowingQueueReadA = false) { var tenants = new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); var pipelineA = new TestPipelineStore(throwOnList: withThrowingQueueReadA); var pipelineB = new TestPipelineStore(); var kanjA = new TestKanjStore(); diff --git a/src/core/tests/Deal.Tests.Unit/Support/StorageTickSchedulerTests.cs b/src/core/tests/Deal.Tests.Unit/Support/StorageTickSchedulerTests.cs index e694a76..95198d0 100644 --- a/src/core/tests/Deal.Tests.Unit/Support/StorageTickSchedulerTests.cs +++ b/src/core/tests/Deal.Tests.Unit/Support/StorageTickSchedulerTests.cs @@ -46,7 +46,7 @@ public sealed class StorageTickSchedulerTests TestKanjStore storeB = StoreWithExpiredInboxCard("l_b_old"); var settings = new TestSettingsStore(); var tenants = new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider(tenants, tenantContext, storeA, storeB, settings); SseBroker broker = provider.GetRequiredService(); @@ -74,7 +74,7 @@ public sealed class StorageTickSchedulerTests var storeB = new TestKanjStore(); storeB.SeedCard(Card("l_b_fresh", KanbanColumns.Inbox, ReceivedAtMsAgo(TimeSpan.FromHours(1)))); var settings = new TestSettingsStore(); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)), tenantContext, @@ -100,7 +100,7 @@ public sealed class StorageTickSchedulerTests { // У тенанта A настройки падают (имитация сбоя схемы/БД) — тик A логирует ошибку, B обрабатывается. TestKanjStore storeB = StoreWithExpiredInboxCard("l_b_old"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); var settingsByTenant = new Dictionary { [TenantA] = new ThrowingSettingsStore(), @@ -133,7 +133,7 @@ public sealed class StorageTickSchedulerTests [Fact] public async Task RunCycle_TenantListFailure_DoesNotThrow() { - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( new ThrowingTenantRepository(), tenantContext, @@ -152,7 +152,7 @@ public sealed class StorageTickSchedulerTests { var kanjStore = new TestKanjStore(); var settings = new TestSettingsStore(); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); var pipelineStoreA = new TestPipelineStore(); long nowMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); pipelineStoreA.SeedRejected(Rejected("r_old_a", (long)(nowMs - TimeSpan.FromDays(4).TotalMilliseconds))); @@ -186,7 +186,7 @@ public sealed class StorageTickSchedulerTests cardStoreA.SeedCard(HoldCard("c_a_future", title: "Будущий", reminderAtMs: NowMs() + 60_000)); cardStoreA.SeedCard(HoldCard("c_a_work", stage: "work", title: "В работе", reminderAtMs: NowMs() - 60_000)); var cardStoreB = new TestKanjStore(); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)).Repository, tenantContext, @@ -221,7 +221,7 @@ public sealed class StorageTickSchedulerTests cardStoreA.SeedCard(HoldCard("c_past", title: "Старое", reminderAtMs: NowMs() - 60_000)); var settingsA = new TestSettingsStore(); settingsA.Preload(SettingsKeys.RemindersEnabled, "false"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( new TestTenantRepository(Tenant(TenantA)).Repository, tenantContext, @@ -247,7 +247,7 @@ public sealed class StorageTickSchedulerTests // и тик A завершается, тенант B обрабатывается (автоархив + тост) — проход жив. var cardStoreA = new TestKanjStore(throwOnDueReminders: true); TestKanjStore storeB = StoreWithExpiredInboxCard("l_b_old"); - var tenantContext = new TenantContext(); + ITenantContext tenantContext = new TenantContext(); await using ServiceProvider provider = BuildProvider( new TestTenantRepository(Tenant(TenantA), Tenant(TenantB)).Repository, tenantContext, @@ -280,7 +280,7 @@ public sealed class StorageTickSchedulerTests // Возвращает: Провайдер с зарегистрированными сервисами теста. private static ServiceProvider BuildProvider( TestTenantRepository tenants, - TenantContext tenantContext, + ITenantContext tenantContext, TestKanjStore storeA, TestKanjStore storeB, TestSettingsStore settings) @@ -301,7 +301,7 @@ public sealed class StorageTickSchedulerTests // Возвращает: Провайдер с зарегистрированными сервисами теста. private static ServiceProvider BuildProvider( ITenantRepository tenants, - TenantContext tenantContext, + ITenantContext tenantContext, Dictionary storesByTenant, Dictionary settingsByTenant, Dictionary? pipelineStoresByTenant = null) diff --git a/src/telegram-service/Deal.Telegram/Telegram/WTelegramSessionClient.cs b/src/telegram-service/Deal.Telegram/Telegram/WTelegramSessionClient.cs index 31da04c..211670e 100644 --- a/src/telegram-service/Deal.Telegram/Telegram/WTelegramSessionClient.cs +++ b/src/telegram-service/Deal.Telegram/Telegram/WTelegramSessionClient.cs @@ -11,9 +11,6 @@ namespace Deal.Telegram.Telegram; #pragma warning disable CS0618 // Auth_SendCode/Auth_SignIn используются осознанно: ручной веб-вход 1:1 с прототипом -/// -/// Реальная реализация поверх WTelegramClient. -/// public sealed class WTelegramSessionClient : ISessionClient { private readonly Client _client; @@ -67,25 +64,19 @@ public sealed class WTelegramSessionClient : ISessionClient _updateManager = new UpdateManager(_client, OnSingleUpdateAsync); } - /// - public bool IsAuthorized => _client.UserId != 0; + bool ISessionClient.IsAuthorized => _client.UserId != 0; - /// - public bool IsConnected => _connected && !_client.Disconnected; + bool ISessionClient.IsConnected => _connected && !_client.Disconnected; - /// - public int ApiId => _apiId; + int ISessionClient.ApiId => _apiId; - /// - public string ApiHash => _apiHash; + string ISessionClient.ApiHash => _apiHash; - /// - public byte[]? SessionBytes => Volatile.Read(ref _latestSessionBytes); + byte[]? ISessionClient.SessionBytes => Volatile.Read(ref _latestSessionBytes); - /// async Task ISessionClient.ConnectAsync(CancellationToken cancellationToken) { - if (IsConnected) + if (((ISessionClient)this).IsConnected) { return; } @@ -94,7 +85,6 @@ public sealed class WTelegramSessionClient : ISessionClient _connected = true; } - /// async Task ISessionClient.RequestCodeAsync(string phone, CancellationToken cancellationToken) { _phone = phone; @@ -118,7 +108,6 @@ public sealed class WTelegramSessionClient : ISessionClient } } - /// async Task ISessionClient.SubmitCodeAsync(string code, CancellationToken cancellationToken) { if (_phoneAlreadyAuthorized) @@ -158,7 +147,6 @@ public sealed class WTelegramSessionClient : ISessionClient return null; } - /// async Task ISessionClient.SubmitPasswordAsync(string password, CancellationToken cancellationToken) { try @@ -178,7 +166,6 @@ public sealed class WTelegramSessionClient : ISessionClient } } - /// async Task ISessionClient.StartQrAsync(Action onQrUrl, CancellationToken cancellationToken) { try @@ -196,13 +183,11 @@ public sealed class WTelegramSessionClient : ISessionClient } } - /// async Task ISessionClient.LogOutAsync(CancellationToken cancellationToken) { await _client.Auth_LogOut().WaitAsync(cancellationToken).ConfigureAwait(false); } - /// async Task ISessionClient.GetAccountAsync(CancellationToken cancellationToken) { UserBase[] users = await _client.Users_GetUsers(InputUser.Self).WaitAsync(cancellationToken).ConfigureAwait(false); @@ -221,7 +206,6 @@ public sealed class WTelegramSessionClient : ISessionClient /// public event Func? MessageReceived; - /// async Task> ISessionClient.GetDialogsAsync(int limit, CancellationToken cancellationToken) { Messages_DialogsBase result = await RunTlCallAsync(() => _client.Messages_GetDialogs(limit: limit), cancellationToken).ConfigureAwait(false); @@ -241,7 +225,6 @@ public sealed class WTelegramSessionClient : ISessionClient return items; } - /// async Task> ISessionClient.GetMessagesAsync( string dialogId, int limit, @@ -265,7 +248,6 @@ public sealed class WTelegramSessionClient : ISessionClient return items; } - /// async Task ISessionClient.GetMessageAsync( string dialogId, long msgId, @@ -295,7 +277,6 @@ public sealed class WTelegramSessionClient : ISessionClient return null; } - /// async Task ISessionClient.MarkReadAsync(string dialogId, CancellationToken cancellationToken) { InputPeer peer = await ResolvePeerAsync(dialogId, cancellationToken).ConfigureAwait(false); @@ -303,7 +284,6 @@ public sealed class WTelegramSessionClient : ISessionClient } - /// async Task> ISessionClient.SearchAsync( string query, int limit, @@ -327,7 +307,6 @@ public sealed class WTelegramSessionClient : ISessionClient return items; } - /// async Task ISessionClient.GetInfoAsync(string dialogId, CancellationToken cancellationToken) { TelegramSourceInfo unknown = DefaultSourceInfo(dialogId); @@ -361,7 +340,6 @@ public sealed class WTelegramSessionClient : ISessionClient return unknown; } - /// async Task ISessionClient.ReadForEvalAsync( string dialogId, int limit, @@ -410,7 +388,6 @@ public sealed class WTelegramSessionClient : ISessionClient } } - /// async Task ISessionClient.JoinAsync(string username, CancellationToken cancellationToken) { Contacts_ResolvedPeer resolved = await RunTlCallAsync(() => _client.Contacts_ResolveUsername(username), cancellationToken).ConfigureAwait(false); @@ -425,7 +402,6 @@ public sealed class WTelegramSessionClient : ISessionClient await RunTlCallAsync(() => _client.Channels_JoinChannel(new InputChannel(channel.id, channel.access_hash)), cancellationToken).ConfigureAwait(false); } - /// async Task ISessionClient.LeaveAsync(string dialogId, CancellationToken cancellationToken) { if (!TryParseSignedId(dialogId, out bool isChannel, out _, out _, out long rawId) || !isChannel) From b8570e319786c6bc31a8f80697140aa6a2b42003 Mon Sep 17 00:00:00 2001 From: stepan Date: Sun, 13 Sep 2026 14:15:23 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20XML-?= =?UTF-8?q?=D0=B4=D0=BE=D0=BA=D0=B8=20=D0=B8=D0=B7=20=D1=80=D0=B5=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B9=20=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Описание живёт только в интерфейсе: удалены классовые summary и док-блоки членов-реализаций (28 файлов). Правило уточнено в §11. --- docs/spec/Код-стайл-Дейл.md | 3 ++- src/ai-service/Deal.Ai/Llm/LlmHttpClient.cs | 10 ---------- .../Services/AiConnectionChecker.cs | 4 ---- .../Services/BudgetedAiClassifier.cs | 5 ----- .../Integrations/Services/BudgetedAiTools.cs | 5 ----- .../Integrations/Services/CbrRateSource.cs | 4 ---- .../Integrations/Services/GrpcAiClassifier.cs | 5 ----- .../Integrations/Services/GrpcAiTools.cs | 5 ----- .../Integrations/Services/GrpcMlClient.cs | 8 -------- .../Services/GrpcTelegramClient.cs | 20 ------------------- .../Integrations/Services/LocalAiTools.cs | 5 ----- .../Storage/Services/LocalFileStorage.cs | 7 ------- .../Storage/Services/MinioFileStorage.cs | 7 ------- .../Repositories/DiscoveryStore.cs | 3 --- .../Persistence/Repositories/KanbanStore.cs | 3 --- .../Repositories/TenantLimitStore.cs | 10 ---------- .../Security/AesGcmSecretCipher.cs | 5 ----- .../Services/DiscoverySearchErrorCounter.cs | 5 ----- .../Deal.Telegram/Core/CoreIngressClient.cs | 5 ----- .../Dialogs/RandomBackfillPacer.cs | 4 ---- .../Deal.Telegram/Telegram/ClientFactory.cs | 4 ---- 21 files changed, 2 insertions(+), 125 deletions(-) diff --git a/docs/spec/Код-стайл-Дейл.md b/docs/spec/Код-стайл-Дейл.md index 5296b09..2755cef 100644 --- a/docs/spec/Код-стайл-Дейл.md +++ b/docs/spec/Код-стайл-Дейл.md @@ -259,7 +259,8 @@ - **Явная реализация интерфейсов — по умолчанию** (`Task ICardStore.GetAsync(...)`). **[изм. 2026-09-11, решение владельца]** Классы напрямую не вызываются — только через интерфейсы; исключения: DTO/модели (напр. `Card` и семейство `I*Card`), хелперы, extension-классы. Весь прод-код уже переведён на явные - реализации (codemod `scripts/make_explicit.py`, идемпотентный). + реализации (codemod'ы `scripts/make_explicit.py` и `scripts/strip_implementation_docs.py` — идемпотентны, + `--apply` применяет правки, без флага — dry-run-отчёт). - Один публичный тип интерфейса = один файл (как и для классов); имя файла = имя типа. - **Маркерные классы не используются** — если нужен маркер, это маркерный интерфейс (`IKanbanModule`, `ISharedKernel` и т.п.). **[изм. 2026-09-11]** diff --git a/src/ai-service/Deal.Ai/Llm/LlmHttpClient.cs b/src/ai-service/Deal.Ai/Llm/LlmHttpClient.cs index 04e3072..9e0b5a2 100644 --- a/src/ai-service/Deal.Ai/Llm/LlmHttpClient.cs +++ b/src/ai-service/Deal.Ai/Llm/LlmHttpClient.cs @@ -4,9 +4,6 @@ using System.Text.Json.Nodes; namespace Deal.Ai.Llm; -/// -/// HTTP-реализация -/// public sealed class LlmHttpClient : IProviderClient { // Относительный путь OpenAI-совместимого эндпоинта (база уже без хвостового «/»). @@ -58,13 +55,6 @@ public sealed class LlmHttpClient : IProviderClient _anthropicCallTimeout = anthropicCallTimeout; } - /// - /// Выполняет один вызов модели по выбранной схеме API. - /// - /// Конфиг провайдера (стиль — ApiStyle). - /// Системный промпт. - /// Пользовательское сообщение/контекст. - /// Текст ответа и usage API-ответа (null при его отсутствии). async Task IProviderClient.ChatAsync( LlmConfig config, string systemPrompt, diff --git a/src/core/Deal.Infrastructure/Integrations/Services/AiConnectionChecker.cs b/src/core/Deal.Infrastructure/Integrations/Services/AiConnectionChecker.cs index 78cf24b..5af4c4f 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/AiConnectionChecker.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/AiConnectionChecker.cs @@ -6,9 +6,6 @@ using Deal.Modules.Settings.Application.Models; namespace Deal.Infrastructure.Integrations.Services; -/// -/// HTTP-реализация проверки подключения к AI-провайдеру. -/// public sealed class AiConnectionChecker : IAiConnectionChecker { /// @@ -78,7 +75,6 @@ public sealed class AiConnectionChecker : IAiConnectionChecker _httpClient = httpClient; } - /// async Task IAiConnectionChecker.CheckAsync(AiCheckRequest request, CancellationToken ct) { ArgumentNullException.ThrowIfNull(request); diff --git a/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiClassifier.cs b/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiClassifier.cs index c4a7807..bb21ea1 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiClassifier.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiClassifier.cs @@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// Декоратор бюджетного гейта порта -/// public sealed class BudgetedAiClassifier : IAiClassifier { // Текст ошибки вызова вне tenant-контекста (гейт читает лимиты по тенанту). @@ -54,7 +51,6 @@ public sealed class BudgetedAiClassifier : IAiClassifier _logger = logger; } - /// async Task IAiClassifier.FilterAsync(string text, CancellationToken ct) { if (await IsPaidAllowedAsync(ct)) @@ -67,7 +63,6 @@ public sealed class BudgetedAiClassifier : IAiClassifier return await _localClassifier.FilterAsync(text, ct); } - /// async Task IAiClassifier.ClassifyAsync(string text, CancellationToken ct) { if (await IsPaidAllowedAsync(ct)) diff --git a/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiTools.cs b/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiTools.cs index 381775d..6fd005c 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiTools.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/BudgetedAiTools.cs @@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// Декоратор бюджетного гейта порта -/// public sealed class BudgetedAiTools : IAiTools { private const string ExhaustedKeywordsError = "ИИ-бюджет исчерпан — генерация ключевых слов недоступна"; @@ -50,7 +47,6 @@ public sealed class BudgetedAiTools : IAiTools _logger = logger; } - /// async Task IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct) { BudgetStateDto state = await GateStateAsync(ct); @@ -69,7 +65,6 @@ public sealed class BudgetedAiTools : IAiTools Error: state.Status == TenantStatuses.Suspended ? SuspendedKeywordsError : ExhaustedKeywordsError); } - /// async Task IAiTools.EvaluateFitAsync( string text, string description, diff --git a/src/core/Deal.Infrastructure/Integrations/Services/CbrRateSource.cs b/src/core/Deal.Infrastructure/Integrations/Services/CbrRateSource.cs index 3dce510..bd4f630 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/CbrRateSource.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/CbrRateSource.cs @@ -5,9 +5,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// HTTP-источник курсов ЦБ РФ -/// public sealed class CbrRateSource : IRatesSource { /// @@ -47,7 +44,6 @@ public sealed class CbrRateSource : IRatesSource _logger = logger; } - /// async Task?> IRatesSource.FetchAsync(CancellationToken ct) { try diff --git a/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiClassifier.cs b/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiClassifier.cs index c9bd692..8f58d8c 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiClassifier.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiClassifier.cs @@ -11,9 +11,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// gRPC-адаптер порта к автономному ai-service. -/// public sealed class GrpcAiClassifier : IAiClassifier { /// @@ -70,7 +67,6 @@ public sealed class GrpcAiClassifier : IAiClassifier _logger = logger; } - /// async Task IAiClassifier.FilterAsync(string text, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -106,7 +102,6 @@ public sealed class GrpcAiClassifier : IAiClassifier } } - /// async Task IAiClassifier.ClassifyAsync(string text, CancellationToken ct) { TenantId tenantId = RequireTenant(); diff --git a/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiTools.cs b/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiTools.cs index c0c92ae..1fe6f5e 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiTools.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/GrpcAiTools.cs @@ -10,9 +10,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// gRPC-адаптер порта к автономному ai-service. -/// public sealed class GrpcAiTools : IAiTools { /// @@ -70,7 +67,6 @@ public sealed class GrpcAiTools : IAiTools _logger = logger; } - /// async Task IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -104,7 +100,6 @@ public sealed class GrpcAiTools : IAiTools } } - /// async Task IAiTools.EvaluateFitAsync( string text, string description, diff --git a/src/core/Deal.Infrastructure/Integrations/Services/GrpcMlClient.cs b/src/core/Deal.Infrastructure/Integrations/Services/GrpcMlClient.cs index 2b53c3a..882f12d 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/GrpcMlClient.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/GrpcMlClient.cs @@ -16,9 +16,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// gRPC-адаптер порта IMlClient к автономному ml-service. -/// public sealed class GrpcMlClient : IMlClient, IMlTrainClient { /// @@ -97,7 +94,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient _logger = logger; } - /// async Task IMlClient.StatusAsync(CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -122,7 +118,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient return new MlStatusResponseDto(Enabled: enabled, Service: snapshot.Service, Reachable: snapshot.Reachable, Stats: stats); } - /// async Task IMlClient.PredictAsync(string text, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -143,7 +138,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient } } - /// async Task IMlClient.ResetAsync(CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -171,7 +165,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient return new MlResetResultDto(Ok: true, Error: null); } - /// async Task IMlClient.PushAsync( string text, string label, @@ -181,7 +174,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient await MlOutboxQueue.PushAsync(_learningStore, text, label, delta, ct); } - /// async Task IMlTrainClient.TrainBatchAsync(IReadOnlyList items, CancellationToken ct) { TenantId tenantId = RequireTenant(); diff --git a/src/core/Deal.Infrastructure/Integrations/Services/GrpcTelegramClient.cs b/src/core/Deal.Infrastructure/Integrations/Services/GrpcTelegramClient.cs index d7465bf..a51d70c 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/GrpcTelegramClient.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/GrpcTelegramClient.cs @@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging; namespace Deal.Infrastructure.Integrations.Services; -/// -/// gRPC-адаптер порта к автономному telegram-service. -/// public sealed class GrpcTelegramClient : ITelegramGateway { /// @@ -58,7 +55,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway _logger = logger; } - /// async Task ITelegramGateway.StatusAsync(CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -81,7 +77,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.StartPhoneAsync( string phone, int apiId, @@ -104,7 +99,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.StartQrAsync( int apiId, string apiHash, @@ -128,7 +122,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.SendCodeAsync(string code, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -146,7 +139,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.SendPasswordAsync(string password, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -164,7 +156,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.LogoutAsync(CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -180,7 +171,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task> ITelegramGateway.RefreshDialogsAsync(CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -197,7 +187,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.SetMonitorAsync( string dialogId, bool enabled, @@ -217,7 +206,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.SetMonitorAllAsync(bool enabled, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -234,7 +222,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.BackfillAsync( string dialogId, bool force, @@ -255,7 +242,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task> ITelegramGateway.ReadRecentAsync( string dialogId, int limit, @@ -278,7 +264,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.ReadSourceAsync( string dialogId, long msgId, @@ -302,7 +287,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task> ITelegramGateway.SearchAsync( string query, int limit, @@ -323,7 +307,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.InfoAsync(string dialogId, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -349,7 +332,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.ReadForEvalAsync( string dialogId, int limit, @@ -380,7 +362,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.JoinAsync(string username, CancellationToken ct) { TenantId tenantId = RequireTenant(); @@ -397,7 +378,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway } } - /// async Task ITelegramGateway.LeaveAsync(string dialogId, CancellationToken ct) { TenantId tenantId = RequireTenant(); diff --git a/src/core/Deal.Infrastructure/Integrations/Services/LocalAiTools.cs b/src/core/Deal.Infrastructure/Integrations/Services/LocalAiTools.cs index a67f332..ca97b26 100644 --- a/src/core/Deal.Infrastructure/Integrations/Services/LocalAiTools.cs +++ b/src/core/Deal.Infrastructure/Integrations/Services/LocalAiTools.cs @@ -3,20 +3,15 @@ using Deal.Contracts.Integrations.Models; namespace Deal.Infrastructure.Integrations.Services; -/// -/// Локальная реализация без внешнего ИИ-сервиса. -/// public sealed class LocalAiTools : IAiTools { // Сообщение исключения методов (локальный режим = ai-service не подключён). private const string NotSupportedMessage = "ИИ-инструменты доступны только при подключённом ai-service (Services:Ai:UseLocal=false)."; - /// Task IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct) => throw new NotSupportedException(NotSupportedMessage); - /// Task IAiTools.EvaluateFitAsync( string text, string description, diff --git a/src/core/Deal.Infrastructure/Integrations/Storage/Services/LocalFileStorage.cs b/src/core/Deal.Infrastructure/Integrations/Storage/Services/LocalFileStorage.cs index 2619ddb..29e0a86 100644 --- a/src/core/Deal.Infrastructure/Integrations/Storage/Services/LocalFileStorage.cs +++ b/src/core/Deal.Infrastructure/Integrations/Storage/Services/LocalFileStorage.cs @@ -3,9 +3,6 @@ using Deal.Contracts.Integrations.Models; namespace Deal.Infrastructure.Integrations.Storage.Services; -/// -/// Локальное файловое хранилище вложений — каталог на диске. -/// public sealed class LocalFileStorage : IFileStorage { // Размер буфера чтения при скачивании (async FileStream). @@ -31,7 +28,6 @@ public sealed class LocalFileStorage : IFileStorage /// Строка вида LocalFileStorage (root: …). public override string ToString() => $"LocalFileStorage (root: {_rootPath})"; - /// async Task IFileStorage.PutAsync( string objectKey, Stream content, @@ -55,7 +51,6 @@ public sealed class LocalFileStorage : IFileStorage return objectKey; } - /// Task IFileStorage.GetAsync(string objectKey, CancellationToken ct) { string path = ResolvePath(objectKey); @@ -68,7 +63,6 @@ public sealed class LocalFileStorage : IFileStorage return Task.FromResult(stream); } - /// Task IFileStorage.StatAsync(string objectKey, CancellationToken ct) { string path = ResolvePath(objectKey); @@ -81,7 +75,6 @@ public sealed class LocalFileStorage : IFileStorage return Task.FromResult(new FileMeta(objectKey, info.Length, string.Empty)); } - /// Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct) { string path = ResolvePath(objectKey); diff --git a/src/core/Deal.Infrastructure/Integrations/Storage/Services/MinioFileStorage.cs b/src/core/Deal.Infrastructure/Integrations/Storage/Services/MinioFileStorage.cs index 8e47439..e9df842 100644 --- a/src/core/Deal.Infrastructure/Integrations/Storage/Services/MinioFileStorage.cs +++ b/src/core/Deal.Infrastructure/Integrations/Storage/Services/MinioFileStorage.cs @@ -9,9 +9,6 @@ using Minio.Exceptions; namespace Deal.Infrastructure.Integrations.Storage.Services; -/// -/// Хранилище вложений на MinIO -/// public sealed class MinioFileStorage : IFileStorage { private const string DefaultContentType = "application/octet-stream"; @@ -66,7 +63,6 @@ public sealed class MinioFileStorage : IFileStorage /// Строка вида MinioFileStorage (endpoint: …; bucket: …). public override string ToString() => $"MinioFileStorage (endpoint: {_endpoint}; bucket: {_bucket})"; - /// async Task IFileStorage.PutAsync( string objectKey, Stream content, @@ -98,7 +94,6 @@ public sealed class MinioFileStorage : IFileStorage return objectKey; } - /// async Task IFileStorage.GetAsync(string objectKey, CancellationToken ct) { MemoryStream buffer = new(); @@ -128,7 +123,6 @@ public sealed class MinioFileStorage : IFileStorage return buffer; } - /// async Task IFileStorage.StatAsync(string objectKey, CancellationToken ct) { try @@ -144,7 +138,6 @@ public sealed class MinioFileStorage : IFileStorage } } - /// async Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct) { try diff --git a/src/core/Deal.Infrastructure/Persistence/Repositories/DiscoveryStore.cs b/src/core/Deal.Infrastructure/Persistence/Repositories/DiscoveryStore.cs index d1e3e13..23305ee 100644 --- a/src/core/Deal.Infrastructure/Persistence/Repositories/DiscoveryStore.cs +++ b/src/core/Deal.Infrastructure/Persistence/Repositories/DiscoveryStore.cs @@ -5,9 +5,6 @@ using Deal.Modules.Discovery.Application.Models; namespace Deal.Infrastructure.Persistence.Repositories; -/// -/// EF-адаптер хранилища Discovery -/// public sealed partial class DiscoveryStore : IDiscoveryStore { private readonly TenantDbContext _dbContext; diff --git a/src/core/Deal.Infrastructure/Persistence/Repositories/KanbanStore.cs b/src/core/Deal.Infrastructure/Persistence/Repositories/KanbanStore.cs index 5bce02b..e48a5f0 100644 --- a/src/core/Deal.Infrastructure/Persistence/Repositories/KanbanStore.cs +++ b/src/core/Deal.Infrastructure/Persistence/Repositories/KanbanStore.cs @@ -9,9 +9,6 @@ using Microsoft.EntityFrameworkCore; namespace Deal.Infrastructure.Persistence.Repositories; -/// -/// EF-адаптер хранилища карточек и контейнеров -/// public sealed partial class KanbanStore : ICardStore { private readonly TenantDbContext _dbContext; diff --git a/src/core/Deal.Infrastructure/Persistence/Repositories/TenantLimitStore.cs b/src/core/Deal.Infrastructure/Persistence/Repositories/TenantLimitStore.cs index 368b0e4..7918de9 100644 --- a/src/core/Deal.Infrastructure/Persistence/Repositories/TenantLimitStore.cs +++ b/src/core/Deal.Infrastructure/Persistence/Repositories/TenantLimitStore.cs @@ -6,9 +6,6 @@ using Microsoft.EntityFrameworkCore; namespace Deal.Infrastructure.Persistence.Repositories; -/// -/// EF-адаптер хранилища лимитов ИИ-бюджета -/// public sealed class TenantLimitStore : ITenantLimitStore { private readonly DealDbContext _dbContext; @@ -58,7 +55,6 @@ public sealed class TenantLimitStore : ITenantLimitStore _utcNow = utcNow; } - /// async Task ITenantLimitStore.GetOrCreateAsync( Guid tenantId, CancellationToken ct, @@ -68,7 +64,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return ToLimitDto(entity); } - /// async Task ITenantLimitStore.GetStateAsync(Guid tenantId, CancellationToken ct) { TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct); @@ -76,7 +71,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return await ToStateDtoAsync(entity, ct); } - /// async Task ITenantLimitStore.AddUsageAsync( Guid tenantId, long tokens, @@ -109,7 +103,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return await ToStateDtoAsync(entity, ct); } - /// async Task ITenantLimitStore.UpdateBudgetAsync( Guid tenantId, long budgetTokens, @@ -132,7 +125,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return await ToStateDtoAsync(entity, ct); } - /// async Task ITenantLimitStore.TryMarkWarnedAsync(Guid tenantId, CancellationToken ct) { TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct); @@ -148,7 +140,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return true; } - /// async Task ITenantLimitStore.TryMarkNotifiedExhaustedAsync(Guid tenantId, CancellationToken ct) { TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct); @@ -219,7 +210,6 @@ public sealed class TenantLimitStore : ITenantLimitStore return true; } - /// async Task ITenantLimitStore.ResetExpiredPeriodsAsync(DateTimeOffset now, CancellationToken ct) { // Трогаем только строки с накоплениями (расход/флаги): строки без накоплений чистить нечего. diff --git a/src/core/Deal.Infrastructure/Security/AesGcmSecretCipher.cs b/src/core/Deal.Infrastructure/Security/AesGcmSecretCipher.cs index 979b214..7e036a6 100644 --- a/src/core/Deal.Infrastructure/Security/AesGcmSecretCipher.cs +++ b/src/core/Deal.Infrastructure/Security/AesGcmSecretCipher.cs @@ -4,9 +4,6 @@ using Deal.Modules.Settings.Application.Abstractions; namespace Deal.Infrastructure.Security; -/// -/// AES-256-GCM-шифр секретов -/// public sealed class AesGcmSecretCipher : ISecretCipher { // Префикс зашифрованного значения (маркер формата в хранилище). @@ -39,7 +36,6 @@ public sealed class AesGcmSecretCipher : ISecretCipher _key = key; } - /// string ISecretCipher.Encrypt(string plainText) { if (string.IsNullOrEmpty(plainText)) @@ -65,7 +61,6 @@ public sealed class AesGcmSecretCipher : ISecretCipher return EncryptedPrefix + Convert.ToBase64String(payload); } - /// string ISecretCipher.Decrypt(string cipherText) { if (string.IsNullOrEmpty(cipherText) || !cipherText.StartsWith(EncryptedPrefix, StringComparison.Ordinal)) diff --git a/src/core/Deal.Modules.Discovery/Application/Services/DiscoverySearchErrorCounter.cs b/src/core/Deal.Modules.Discovery/Application/Services/DiscoverySearchErrorCounter.cs index 98d1b42..cb1aa66 100644 --- a/src/core/Deal.Modules.Discovery/Application/Services/DiscoverySearchErrorCounter.cs +++ b/src/core/Deal.Modules.Discovery/Application/Services/DiscoverySearchErrorCounter.cs @@ -3,9 +3,6 @@ using Deal.Modules.Discovery.Application.Abstractions; namespace Deal.Modules.Discovery.Application.Services; -/// -/// Потокобезопасная реализация -/// public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter { /// @@ -43,7 +40,6 @@ public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter _utcNow = utcNow; } - /// int IDiscoverySearchErrorCounter.Next(string taskId) { EvictExpired(); @@ -55,7 +51,6 @@ public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter return fresh.Count; } - /// void IDiscoverySearchErrorCounter.Reset(string taskId) { EvictExpired(); diff --git a/src/telegram-service/Deal.Telegram/Core/CoreIngressClient.cs b/src/telegram-service/Deal.Telegram/Core/CoreIngressClient.cs index a70bff6..866be39 100644 --- a/src/telegram-service/Deal.Telegram/Core/CoreIngressClient.cs +++ b/src/telegram-service/Deal.Telegram/Core/CoreIngressClient.cs @@ -11,9 +11,6 @@ using Deal.Telegram.Core; namespace Deal.Telegram.Core; -/// -/// Исходящий gRPC-канал в ядро -/// public sealed class CoreIngressClient : ICoreIngressClient { public const string TenantIdMetadataKey = "tenant-id"; @@ -44,7 +41,6 @@ public sealed class CoreIngressClient : ICoreIngressClient _mtlsCertificates = mtlsCertificates; } - /// async Task ICoreIngressClient.PushSourceAsync( string tenantId, PushSourceRequest request, @@ -61,7 +57,6 @@ public sealed class CoreIngressClient : ICoreIngressClient } } - /// async Task> ICoreIngressClient.SyncDialogsAsync( string tenantId, IReadOnlyList entries, diff --git a/src/telegram-service/Deal.Telegram/Dialogs/RandomBackfillPacer.cs b/src/telegram-service/Deal.Telegram/Dialogs/RandomBackfillPacer.cs index ad2a112..41e168c 100644 --- a/src/telegram-service/Deal.Telegram/Dialogs/RandomBackfillPacer.cs +++ b/src/telegram-service/Deal.Telegram/Dialogs/RandomBackfillPacer.cs @@ -1,12 +1,8 @@ using Deal.Telegram.Dialogs; namespace Deal.Telegram.Dialogs; -/// -/// Реальная реализация -/// public sealed class RandomBackfillPacer : IBackfillPacer { - /// async Task IBackfillPacer.WaitAsync( double minSeconds, double maxSeconds, diff --git a/src/telegram-service/Deal.Telegram/Telegram/ClientFactory.cs b/src/telegram-service/Deal.Telegram/Telegram/ClientFactory.cs index 9051ac9..3e51e14 100644 --- a/src/telegram-service/Deal.Telegram/Telegram/ClientFactory.cs +++ b/src/telegram-service/Deal.Telegram/Telegram/ClientFactory.cs @@ -1,12 +1,8 @@ using Deal.Telegram.Telegram; namespace Deal.Telegram.Telegram; -/// -/// Фабрика реальных клиентов WTelegramClient. -/// public sealed class ClientFactory : ITelegramClientFactory { - /// ISessionClient ITelegramClientFactory.Create( int apiId, string apiHash,