Описание живёт только в интерфейсе: удалены классовые summary и док-блоки членов-реализаций (28 файлов). Правило уточнено в §11.
This commit is contained in:
@@ -259,7 +259,8 @@
|
|||||||
- **Явная реализация интерфейсов — по умолчанию** (`Task ICardStore.GetAsync(...)`). **[изм. 2026-09-11,
|
- **Явная реализация интерфейсов — по умолчанию** (`Task ICardStore.GetAsync(...)`). **[изм. 2026-09-11,
|
||||||
решение владельца]** Классы напрямую не вызываются — только через интерфейсы; исключения: DTO/модели
|
решение владельца]** Классы напрямую не вызываются — только через интерфейсы; исключения: DTO/модели
|
||||||
(напр. `Card` и семейство `I*Card`), хелперы, extension-классы. Весь прод-код уже переведён на явные
|
(напр. `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]**
|
(`IKanbanModule`, `ISharedKernel` и т.п.). **[изм. 2026-09-11]**
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ using System.Text.Json.Nodes;
|
|||||||
|
|
||||||
namespace Deal.Ai.Llm;
|
namespace Deal.Ai.Llm;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HTTP-реализация <see cref="IProviderClient"/>
|
|
||||||
/// </summary>
|
|
||||||
public sealed class LlmHttpClient : IProviderClient
|
public sealed class LlmHttpClient : IProviderClient
|
||||||
{
|
{
|
||||||
// Относительный путь OpenAI-совместимого эндпоинта (база уже без хвостового «/»).
|
// Относительный путь OpenAI-совместимого эндпоинта (база уже без хвостового «/»).
|
||||||
@@ -58,13 +55,6 @@ public sealed class LlmHttpClient : IProviderClient
|
|||||||
_anthropicCallTimeout = anthropicCallTimeout;
|
_anthropicCallTimeout = anthropicCallTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Выполняет один вызов модели по выбранной схеме API.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="config">Конфиг провайдера (стиль — <c>ApiStyle</c>).</param>
|
|
||||||
/// <param name="systemPrompt">Системный промпт.</param>
|
|
||||||
/// <param name="userText">Пользовательское сообщение/контекст.</param>
|
|
||||||
/// <returns>Текст ответа и usage API-ответа (null при его отсутствии).</returns>
|
|
||||||
async Task<ProviderChatResult> IProviderClient.ChatAsync(
|
async Task<ProviderChatResult> IProviderClient.ChatAsync(
|
||||||
LlmConfig config,
|
LlmConfig config,
|
||||||
string systemPrompt,
|
string systemPrompt,
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ using Deal.Modules.Settings.Application.Models;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HTTP-реализация проверки подключения к AI-провайдеру.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class AiConnectionChecker : IAiConnectionChecker
|
public sealed class AiConnectionChecker : IAiConnectionChecker
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -78,7 +75,6 @@ public sealed class AiConnectionChecker : IAiConnectionChecker
|
|||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiCheckResultDto> IAiConnectionChecker.CheckAsync(AiCheckRequest request, CancellationToken ct)
|
async Task<AiCheckResultDto> IAiConnectionChecker.CheckAsync(AiCheckRequest request, CancellationToken ct)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(request);
|
ArgumentNullException.ThrowIfNull(request);
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Декоратор бюджетного гейта порта <see cref="IAiClassifier"/>
|
|
||||||
/// </summary>
|
|
||||||
public sealed class BudgetedAiClassifier : IAiClassifier
|
public sealed class BudgetedAiClassifier : IAiClassifier
|
||||||
{
|
{
|
||||||
// Текст ошибки вызова вне tenant-контекста (гейт читает лимиты по тенанту).
|
// Текст ошибки вызова вне tenant-контекста (гейт читает лимиты по тенанту).
|
||||||
@@ -54,7 +51,6 @@ public sealed class BudgetedAiClassifier : IAiClassifier
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiFilterResultDto> IAiClassifier.FilterAsync(string text, CancellationToken ct)
|
async Task<AiFilterResultDto> IAiClassifier.FilterAsync(string text, CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (await IsPaidAllowedAsync(ct))
|
if (await IsPaidAllowedAsync(ct))
|
||||||
@@ -67,7 +63,6 @@ public sealed class BudgetedAiClassifier : IAiClassifier
|
|||||||
return await _localClassifier.FilterAsync(text, ct);
|
return await _localClassifier.FilterAsync(text, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiParsedCardDto> IAiClassifier.ClassifyAsync(string text, CancellationToken ct)
|
async Task<AiParsedCardDto> IAiClassifier.ClassifyAsync(string text, CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (await IsPaidAllowedAsync(ct))
|
if (await IsPaidAllowedAsync(ct))
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Декоратор бюджетного гейта порта <see cref="IAiTools"/>
|
|
||||||
/// </summary>
|
|
||||||
public sealed class BudgetedAiTools : IAiTools
|
public sealed class BudgetedAiTools : IAiTools
|
||||||
{
|
{
|
||||||
private const string ExhaustedKeywordsError = "ИИ-бюджет исчерпан — генерация ключевых слов недоступна";
|
private const string ExhaustedKeywordsError = "ИИ-бюджет исчерпан — генерация ключевых слов недоступна";
|
||||||
@@ -50,7 +47,6 @@ public sealed class BudgetedAiTools : IAiTools
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
async Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
||||||
{
|
{
|
||||||
BudgetStateDto state = await GateStateAsync(ct);
|
BudgetStateDto state = await GateStateAsync(ct);
|
||||||
@@ -69,7 +65,6 @@ public sealed class BudgetedAiTools : IAiTools
|
|||||||
Error: state.Status == TenantStatuses.Suspended ? SuspendedKeywordsError : ExhaustedKeywordsError);
|
Error: state.Status == TenantStatuses.Suspended ? SuspendedKeywordsError : ExhaustedKeywordsError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
async Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
||||||
string text,
|
string text,
|
||||||
string description,
|
string description,
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HTTP-источник курсов ЦБ РФ
|
|
||||||
/// </summary>
|
|
||||||
public sealed class CbrRateSource : IRatesSource
|
public sealed class CbrRateSource : IRatesSource
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -47,7 +44,6 @@ public sealed class CbrRateSource : IRatesSource
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<Dictionary<string, double>?> IRatesSource.FetchAsync(CancellationToken ct)
|
async Task<Dictionary<string, double>?> IRatesSource.FetchAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// gRPC-адаптер порта <see cref="IAiClassifier"/> к автономному ai-service.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class GrpcAiClassifier : IAiClassifier
|
public sealed class GrpcAiClassifier : IAiClassifier
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -70,7 +67,6 @@ public sealed class GrpcAiClassifier : IAiClassifier
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiFilterResultDto> IAiClassifier.FilterAsync(string text, CancellationToken ct)
|
async Task<AiFilterResultDto> IAiClassifier.FilterAsync(string text, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -106,7 +102,6 @@ public sealed class GrpcAiClassifier : IAiClassifier
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiParsedCardDto> IAiClassifier.ClassifyAsync(string text, CancellationToken ct)
|
async Task<AiParsedCardDto> IAiClassifier.ClassifyAsync(string text, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// gRPC-адаптер порта <see cref="IAiTools"/> к автономному ai-service.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class GrpcAiTools : IAiTools
|
public sealed class GrpcAiTools : IAiTools
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -70,7 +67,6 @@ public sealed class GrpcAiTools : IAiTools
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
async Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -104,7 +100,6 @@ public sealed class GrpcAiTools : IAiTools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
async Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
||||||
string text,
|
string text,
|
||||||
string description,
|
string description,
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// gRPC-адаптер порта IMlClient к автономному ml-service.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -97,7 +94,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<MlStatusResponseDto> IMlClient.StatusAsync(CancellationToken ct)
|
async Task<MlStatusResponseDto> IMlClient.StatusAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
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);
|
return new MlStatusResponseDto(Enabled: enabled, Service: snapshot.Service, Reachable: snapshot.Reachable, Stats: stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<MlPredictResultDto> IMlClient.PredictAsync(string text, CancellationToken ct)
|
async Task<MlPredictResultDto> IMlClient.PredictAsync(string text, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -143,7 +138,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<MlResetResultDto> IMlClient.ResetAsync(CancellationToken ct)
|
async Task<MlResetResultDto> IMlClient.ResetAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -171,7 +165,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
|||||||
return new MlResetResultDto(Ok: true, Error: null);
|
return new MlResetResultDto(Ok: true, Error: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task IMlClient.PushAsync(
|
async Task IMlClient.PushAsync(
|
||||||
string text,
|
string text,
|
||||||
string label,
|
string label,
|
||||||
@@ -181,7 +174,6 @@ public sealed class GrpcMlClient : IMlClient, IMlTrainClient
|
|||||||
await MlOutboxQueue.PushAsync(_learningStore, text, label, delta, ct);
|
await MlOutboxQueue.PushAsync(_learningStore, text, label, delta, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<int> IMlTrainClient.TrainBatchAsync(IReadOnlyList<MlOutboxEntryDto> items, CancellationToken ct)
|
async Task<int> IMlTrainClient.TrainBatchAsync(IReadOnlyList<MlOutboxEntryDto> items, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// gRPC-адаптер порта <see cref="ITelegramGateway"/> к автономному telegram-service.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class GrpcTelegramClient : ITelegramGateway
|
public sealed class GrpcTelegramClient : ITelegramGateway
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -58,7 +55,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramAccountStatusDto> ITelegramGateway.StatusAsync(CancellationToken ct)
|
async Task<TelegramAccountStatusDto> ITelegramGateway.StatusAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -81,7 +77,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramAuthResultDto> ITelegramGateway.StartPhoneAsync(
|
async Task<TelegramAuthResultDto> ITelegramGateway.StartPhoneAsync(
|
||||||
string phone,
|
string phone,
|
||||||
int apiId,
|
int apiId,
|
||||||
@@ -104,7 +99,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramAuthResultDto> ITelegramGateway.StartQrAsync(
|
async Task<TelegramAuthResultDto> ITelegramGateway.StartQrAsync(
|
||||||
int apiId,
|
int apiId,
|
||||||
string apiHash,
|
string apiHash,
|
||||||
@@ -128,7 +122,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<string> ITelegramGateway.SendCodeAsync(string code, CancellationToken ct)
|
async Task<string> ITelegramGateway.SendCodeAsync(string code, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -146,7 +139,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<string> ITelegramGateway.SendPasswordAsync(string password, CancellationToken ct)
|
async Task<string> ITelegramGateway.SendPasswordAsync(string password, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -164,7 +156,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task ITelegramGateway.LogoutAsync(CancellationToken ct)
|
async Task ITelegramGateway.LogoutAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -180,7 +171,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<IReadOnlyList<TelegramDialogEntryDto>> ITelegramGateway.RefreshDialogsAsync(CancellationToken ct)
|
async Task<IReadOnlyList<TelegramDialogEntryDto>> ITelegramGateway.RefreshDialogsAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -197,7 +187,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task ITelegramGateway.SetMonitorAsync(
|
async Task ITelegramGateway.SetMonitorAsync(
|
||||||
string dialogId,
|
string dialogId,
|
||||||
bool enabled,
|
bool enabled,
|
||||||
@@ -217,7 +206,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task ITelegramGateway.SetMonitorAllAsync(bool enabled, CancellationToken ct)
|
async Task ITelegramGateway.SetMonitorAllAsync(bool enabled, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -234,7 +222,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<int> ITelegramGateway.BackfillAsync(
|
async Task<int> ITelegramGateway.BackfillAsync(
|
||||||
string dialogId,
|
string dialogId,
|
||||||
bool force,
|
bool force,
|
||||||
@@ -255,7 +242,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<IReadOnlyList<TelegramRecentMessageDto>> ITelegramGateway.ReadRecentAsync(
|
async Task<IReadOnlyList<TelegramRecentMessageDto>> ITelegramGateway.ReadRecentAsync(
|
||||||
string dialogId,
|
string dialogId,
|
||||||
int limit,
|
int limit,
|
||||||
@@ -278,7 +264,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramSourceContentDto> ITelegramGateway.ReadSourceAsync(
|
async Task<TelegramSourceContentDto> ITelegramGateway.ReadSourceAsync(
|
||||||
string dialogId,
|
string dialogId,
|
||||||
long msgId,
|
long msgId,
|
||||||
@@ -302,7 +287,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<IReadOnlyList<TelegramDialogEntryDto>> ITelegramGateway.SearchAsync(
|
async Task<IReadOnlyList<TelegramDialogEntryDto>> ITelegramGateway.SearchAsync(
|
||||||
string query,
|
string query,
|
||||||
int limit,
|
int limit,
|
||||||
@@ -323,7 +307,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramChannelInfoDto> ITelegramGateway.InfoAsync(string dialogId, CancellationToken ct)
|
async Task<TelegramChannelInfoDto> ITelegramGateway.InfoAsync(string dialogId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -349,7 +332,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TelegramEvalReadDto> ITelegramGateway.ReadForEvalAsync(
|
async Task<TelegramEvalReadDto> ITelegramGateway.ReadForEvalAsync(
|
||||||
string dialogId,
|
string dialogId,
|
||||||
int limit,
|
int limit,
|
||||||
@@ -380,7 +362,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task ITelegramGateway.JoinAsync(string username, CancellationToken ct)
|
async Task ITelegramGateway.JoinAsync(string username, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
@@ -397,7 +378,6 @@ public sealed class GrpcTelegramClient : ITelegramGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task ITelegramGateway.LeaveAsync(string dialogId, CancellationToken ct)
|
async Task ITelegramGateway.LeaveAsync(string dialogId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantId tenantId = RequireTenant();
|
TenantId tenantId = RequireTenant();
|
||||||
|
|||||||
@@ -3,20 +3,15 @@ using Deal.Contracts.Integrations.Models;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Services;
|
namespace Deal.Infrastructure.Integrations.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Локальная реализация <see cref="IAiTools"/> без внешнего ИИ-сервиса.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class LocalAiTools : IAiTools
|
public sealed class LocalAiTools : IAiTools
|
||||||
{
|
{
|
||||||
// Сообщение исключения методов (локальный режим = ai-service не подключён).
|
// Сообщение исключения методов (локальный режим = ai-service не подключён).
|
||||||
private const string NotSupportedMessage =
|
private const string NotSupportedMessage =
|
||||||
"ИИ-инструменты доступны только при подключённом ai-service (Services:Ai:UseLocal=false).";
|
"ИИ-инструменты доступны только при подключённом ai-service (Services:Ai:UseLocal=false).";
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
Task<AiGenerateKeywordsResultDto> IAiTools.GenerateKeywordsAsync(string description, CancellationToken ct)
|
||||||
=> throw new NotSupportedException(NotSupportedMessage);
|
=> throw new NotSupportedException(NotSupportedMessage);
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
Task<AiEvaluateFitResultDto> IAiTools.EvaluateFitAsync(
|
||||||
string text,
|
string text,
|
||||||
string description,
|
string description,
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ using Deal.Contracts.Integrations.Models;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Storage.Services;
|
namespace Deal.Infrastructure.Integrations.Storage.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Локальное файловое хранилище вложений — каталог на диске.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class LocalFileStorage : IFileStorage
|
public sealed class LocalFileStorage : IFileStorage
|
||||||
{
|
{
|
||||||
// Размер буфера чтения при скачивании (async FileStream).
|
// Размер буфера чтения при скачивании (async FileStream).
|
||||||
@@ -31,7 +28,6 @@ public sealed class LocalFileStorage : IFileStorage
|
|||||||
/// <returns>Строка вида <c>LocalFileStorage (root: …)</c>.</returns>
|
/// <returns>Строка вида <c>LocalFileStorage (root: …)</c>.</returns>
|
||||||
public override string ToString() => $"LocalFileStorage (root: {_rootPath})";
|
public override string ToString() => $"LocalFileStorage (root: {_rootPath})";
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<string> IFileStorage.PutAsync(
|
async Task<string> IFileStorage.PutAsync(
|
||||||
string objectKey,
|
string objectKey,
|
||||||
Stream content,
|
Stream content,
|
||||||
@@ -55,7 +51,6 @@ public sealed class LocalFileStorage : IFileStorage
|
|||||||
return objectKey;
|
return objectKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
Task<Stream?> IFileStorage.GetAsync(string objectKey, CancellationToken ct)
|
Task<Stream?> IFileStorage.GetAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
string path = ResolvePath(objectKey);
|
string path = ResolvePath(objectKey);
|
||||||
@@ -68,7 +63,6 @@ public sealed class LocalFileStorage : IFileStorage
|
|||||||
return Task.FromResult<Stream?>(stream);
|
return Task.FromResult<Stream?>(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
Task<FileMeta?> IFileStorage.StatAsync(string objectKey, CancellationToken ct)
|
Task<FileMeta?> IFileStorage.StatAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
string path = ResolvePath(objectKey);
|
string path = ResolvePath(objectKey);
|
||||||
@@ -81,7 +75,6 @@ public sealed class LocalFileStorage : IFileStorage
|
|||||||
return Task.FromResult<FileMeta?>(new FileMeta(objectKey, info.Length, string.Empty));
|
return Task.FromResult<FileMeta?>(new FileMeta(objectKey, info.Length, string.Empty));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct)
|
Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
string path = ResolvePath(objectKey);
|
string path = ResolvePath(objectKey);
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Minio.Exceptions;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Integrations.Storage.Services;
|
namespace Deal.Infrastructure.Integrations.Storage.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Хранилище вложений на MinIO
|
|
||||||
/// </summary>
|
|
||||||
public sealed class MinioFileStorage : IFileStorage
|
public sealed class MinioFileStorage : IFileStorage
|
||||||
{
|
{
|
||||||
private const string DefaultContentType = "application/octet-stream";
|
private const string DefaultContentType = "application/octet-stream";
|
||||||
@@ -66,7 +63,6 @@ public sealed class MinioFileStorage : IFileStorage
|
|||||||
/// <returns>Строка вида <c>MinioFileStorage (endpoint: …; bucket: …)</c>.</returns>
|
/// <returns>Строка вида <c>MinioFileStorage (endpoint: …; bucket: …)</c>.</returns>
|
||||||
public override string ToString() => $"MinioFileStorage (endpoint: {_endpoint}; bucket: {_bucket})";
|
public override string ToString() => $"MinioFileStorage (endpoint: {_endpoint}; bucket: {_bucket})";
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<string> IFileStorage.PutAsync(
|
async Task<string> IFileStorage.PutAsync(
|
||||||
string objectKey,
|
string objectKey,
|
||||||
Stream content,
|
Stream content,
|
||||||
@@ -98,7 +94,6 @@ public sealed class MinioFileStorage : IFileStorage
|
|||||||
return objectKey;
|
return objectKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<Stream?> IFileStorage.GetAsync(string objectKey, CancellationToken ct)
|
async Task<Stream?> IFileStorage.GetAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
MemoryStream buffer = new();
|
MemoryStream buffer = new();
|
||||||
@@ -128,7 +123,6 @@ public sealed class MinioFileStorage : IFileStorage
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<FileMeta?> IFileStorage.StatAsync(string objectKey, CancellationToken ct)
|
async Task<FileMeta?> IFileStorage.StatAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -144,7 +138,6 @@ public sealed class MinioFileStorage : IFileStorage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct)
|
async Task IFileStorage.DeleteAsync(string objectKey, CancellationToken ct)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ using Deal.Modules.Discovery.Application.Models;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Persistence.Repositories;
|
namespace Deal.Infrastructure.Persistence.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EF-адаптер хранилища Discovery
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class DiscoveryStore : IDiscoveryStore
|
public sealed partial class DiscoveryStore : IDiscoveryStore
|
||||||
{
|
{
|
||||||
private readonly TenantDbContext _dbContext;
|
private readonly TenantDbContext _dbContext;
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Persistence.Repositories;
|
namespace Deal.Infrastructure.Persistence.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EF-адаптер хранилища карточек и контейнеров
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class KanbanStore : ICardStore
|
public sealed partial class KanbanStore : ICardStore
|
||||||
{
|
{
|
||||||
private readonly TenantDbContext _dbContext;
|
private readonly TenantDbContext _dbContext;
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Persistence.Repositories;
|
namespace Deal.Infrastructure.Persistence.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// EF-адаптер хранилища лимитов ИИ-бюджета
|
|
||||||
/// </summary>
|
|
||||||
public sealed class TenantLimitStore : ITenantLimitStore
|
public sealed class TenantLimitStore : ITenantLimitStore
|
||||||
{
|
{
|
||||||
private readonly DealDbContext _dbContext;
|
private readonly DealDbContext _dbContext;
|
||||||
@@ -58,7 +55,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
_utcNow = utcNow;
|
_utcNow = utcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<TenantLimitDto> ITenantLimitStore.GetOrCreateAsync(
|
async Task<TenantLimitDto> ITenantLimitStore.GetOrCreateAsync(
|
||||||
Guid tenantId,
|
Guid tenantId,
|
||||||
CancellationToken ct,
|
CancellationToken ct,
|
||||||
@@ -68,7 +64,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return ToLimitDto(entity);
|
return ToLimitDto(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<BudgetStateDto> ITenantLimitStore.GetStateAsync(Guid tenantId, CancellationToken ct)
|
async Task<BudgetStateDto> ITenantLimitStore.GetStateAsync(Guid tenantId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
||||||
@@ -76,7 +71,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return await ToStateDtoAsync(entity, ct);
|
return await ToStateDtoAsync(entity, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<BudgetStateDto> ITenantLimitStore.AddUsageAsync(
|
async Task<BudgetStateDto> ITenantLimitStore.AddUsageAsync(
|
||||||
Guid tenantId,
|
Guid tenantId,
|
||||||
long tokens,
|
long tokens,
|
||||||
@@ -109,7 +103,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return await ToStateDtoAsync(entity, ct);
|
return await ToStateDtoAsync(entity, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<BudgetStateDto> ITenantLimitStore.UpdateBudgetAsync(
|
async Task<BudgetStateDto> ITenantLimitStore.UpdateBudgetAsync(
|
||||||
Guid tenantId,
|
Guid tenantId,
|
||||||
long budgetTokens,
|
long budgetTokens,
|
||||||
@@ -132,7 +125,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return await ToStateDtoAsync(entity, ct);
|
return await ToStateDtoAsync(entity, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<bool> ITenantLimitStore.TryMarkWarnedAsync(Guid tenantId, CancellationToken ct)
|
async Task<bool> ITenantLimitStore.TryMarkWarnedAsync(Guid tenantId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
||||||
@@ -148,7 +140,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<bool> ITenantLimitStore.TryMarkNotifiedExhaustedAsync(Guid tenantId, CancellationToken ct)
|
async Task<bool> ITenantLimitStore.TryMarkNotifiedExhaustedAsync(Guid tenantId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
TenantLimitEntity entity = await LoadOrCreateAsync(tenantId, _defaults, ct);
|
||||||
@@ -219,7 +210,6 @@ public sealed class TenantLimitStore : ITenantLimitStore
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<int> ITenantLimitStore.ResetExpiredPeriodsAsync(DateTimeOffset now, CancellationToken ct)
|
async Task<int> ITenantLimitStore.ResetExpiredPeriodsAsync(DateTimeOffset now, CancellationToken ct)
|
||||||
{
|
{
|
||||||
// Трогаем только строки с накоплениями (расход/флаги): строки без накоплений чистить нечего.
|
// Трогаем только строки с накоплениями (расход/флаги): строки без накоплений чистить нечего.
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ using Deal.Modules.Settings.Application.Abstractions;
|
|||||||
|
|
||||||
namespace Deal.Infrastructure.Security;
|
namespace Deal.Infrastructure.Security;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// AES-256-GCM-шифр секретов
|
|
||||||
/// </summary>
|
|
||||||
public sealed class AesGcmSecretCipher : ISecretCipher
|
public sealed class AesGcmSecretCipher : ISecretCipher
|
||||||
{
|
{
|
||||||
// Префикс зашифрованного значения (маркер формата в хранилище).
|
// Префикс зашифрованного значения (маркер формата в хранилище).
|
||||||
@@ -39,7 +36,6 @@ public sealed class AesGcmSecretCipher : ISecretCipher
|
|||||||
_key = key;
|
_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
string ISecretCipher.Encrypt(string plainText)
|
string ISecretCipher.Encrypt(string plainText)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(plainText))
|
if (string.IsNullOrEmpty(plainText))
|
||||||
@@ -65,7 +61,6 @@ public sealed class AesGcmSecretCipher : ISecretCipher
|
|||||||
return EncryptedPrefix + Convert.ToBase64String(payload);
|
return EncryptedPrefix + Convert.ToBase64String(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
string ISecretCipher.Decrypt(string cipherText)
|
string ISecretCipher.Decrypt(string cipherText)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(cipherText) || !cipherText.StartsWith(EncryptedPrefix, StringComparison.Ordinal))
|
if (string.IsNullOrEmpty(cipherText) || !cipherText.StartsWith(EncryptedPrefix, StringComparison.Ordinal))
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ using Deal.Modules.Discovery.Application.Abstractions;
|
|||||||
|
|
||||||
namespace Deal.Modules.Discovery.Application.Services;
|
namespace Deal.Modules.Discovery.Application.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Потокобезопасная реализация <see cref="IDiscoverySearchErrorCounter"/>
|
|
||||||
/// </summary>
|
|
||||||
public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter
|
public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -43,7 +40,6 @@ public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter
|
|||||||
_utcNow = utcNow;
|
_utcNow = utcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
int IDiscoverySearchErrorCounter.Next(string taskId)
|
int IDiscoverySearchErrorCounter.Next(string taskId)
|
||||||
{
|
{
|
||||||
EvictExpired();
|
EvictExpired();
|
||||||
@@ -55,7 +51,6 @@ public sealed class DiscoverySearchErrorCounter : IDiscoverySearchErrorCounter
|
|||||||
return fresh.Count;
|
return fresh.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
void IDiscoverySearchErrorCounter.Reset(string taskId)
|
void IDiscoverySearchErrorCounter.Reset(string taskId)
|
||||||
{
|
{
|
||||||
EvictExpired();
|
EvictExpired();
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ using Deal.Telegram.Core;
|
|||||||
|
|
||||||
namespace Deal.Telegram.Core;
|
namespace Deal.Telegram.Core;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Исходящий gRPC-канал в ядро
|
|
||||||
/// </summary>
|
|
||||||
public sealed class CoreIngressClient : ICoreIngressClient
|
public sealed class CoreIngressClient : ICoreIngressClient
|
||||||
{
|
{
|
||||||
public const string TenantIdMetadataKey = "tenant-id";
|
public const string TenantIdMetadataKey = "tenant-id";
|
||||||
@@ -44,7 +41,6 @@ public sealed class CoreIngressClient : ICoreIngressClient
|
|||||||
_mtlsCertificates = mtlsCertificates;
|
_mtlsCertificates = mtlsCertificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<PushSourceReply> ICoreIngressClient.PushSourceAsync(
|
async Task<PushSourceReply> ICoreIngressClient.PushSourceAsync(
|
||||||
string tenantId,
|
string tenantId,
|
||||||
PushSourceRequest request,
|
PushSourceRequest request,
|
||||||
@@ -61,7 +57,6 @@ public sealed class CoreIngressClient : ICoreIngressClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
async Task<IReadOnlyList<string>> ICoreIngressClient.SyncDialogsAsync(
|
async Task<IReadOnlyList<string>> ICoreIngressClient.SyncDialogsAsync(
|
||||||
string tenantId,
|
string tenantId,
|
||||||
IReadOnlyList<DialogEntry> entries,
|
IReadOnlyList<DialogEntry> entries,
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
using Deal.Telegram.Dialogs;
|
using Deal.Telegram.Dialogs;
|
||||||
namespace Deal.Telegram.Dialogs;
|
namespace Deal.Telegram.Dialogs;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Реальная реализация <see cref="IBackfillPacer"/>
|
|
||||||
/// </summary>
|
|
||||||
public sealed class RandomBackfillPacer : IBackfillPacer
|
public sealed class RandomBackfillPacer : IBackfillPacer
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
async Task IBackfillPacer.WaitAsync(
|
async Task IBackfillPacer.WaitAsync(
|
||||||
double minSeconds,
|
double minSeconds,
|
||||||
double maxSeconds,
|
double maxSeconds,
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
using Deal.Telegram.Telegram;
|
using Deal.Telegram.Telegram;
|
||||||
namespace Deal.Telegram.Telegram;
|
namespace Deal.Telegram.Telegram;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Фабрика реальных клиентов WTelegramClient.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class ClientFactory : ITelegramClientFactory
|
public sealed class ClientFactory : ITelegramClientFactory
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
|
||||||
ISessionClient ITelegramClientFactory.Create(
|
ISessionClient ITelegramClientFactory.Create(
|
||||||
int apiId,
|
int apiId,
|
||||||
string apiHash,
|
string apiHash,
|
||||||
|
|||||||
Reference in New Issue
Block a user