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)