Вынести магические строки статусов, видов и ключей в каталоги

Литералы статусов/видов/фаз и wire-ключей заменены каталогами: значения сущностей и репозиториев — TenantStatuses/TenantLimitPeriods/InviteStatuses/ContainerKinds/ContainerSpaces/CardIds/Discovery*/PipelineQueueStatuses; контакты и виды вложений — CardContactTypes/CardFileKinds; источники и этапы отсева — PipelineRejectStages/PipelineRejectSources; ключи промптов/провайдеров — SettingsFieldKeys; wire-ключи канбана — KanbanWireKeys; режимы правил — ColumnRuleModes; операции/фазы/виды диалогов/контакты Telegram и общий BoolText — в Deal.Contracts/Deal.SharedKernel; имена метрик — DealMetrics. Значения не менялись.
This commit is contained in:
2026-09-13 20:51:36 +03:00
parent 8dde35de49
commit 1fbe29a838
61 changed files with 907 additions and 167 deletions
@@ -56,7 +56,7 @@ public static class ColumnMatcher
bool budgetOk = !budgetEnabled || BudgetInRange.IsInRange(AmountParser.Parse(text), rules.Budget!, rates);
bool pricesOk = !pricesEnabled || BudgetInRange.IsInRange(AmountParser.Parse(text), rules.Prices!, rates);
if (string.Equals(rules.Mode, "any", StringComparison.OrdinalIgnoreCase))
if (string.Equals(rules.Mode, ColumnRuleModes.Any, StringComparison.OrdinalIgnoreCase))
{
// «любое»: совпасть должна хотя бы одна ВКЛЮЧЁННАЯ (непустая) группа.
return (keywords.Count > 0 && keywordsOk)
@@ -69,7 +69,7 @@ public static class RulesDescriber
return NoRulesText;
}
string mode = string.Equals(rules.Mode, "any", StringComparison.OrdinalIgnoreCase)
string mode = string.Equals(rules.Mode, ColumnRuleModes.Any, StringComparison.OrdinalIgnoreCase)
? AnyModePrefix
: AllModePrefix;
return mode + " · " + string.Join("; ", parts);
@@ -0,0 +1,17 @@
namespace Deal.Modules.Kanban.Application.Models;
/// <summary>
/// Режимы сопоставления правил колонки
/// </summary>
public static class ColumnRuleModes
{
/// <summary>
/// Достаточно любого условия
/// </summary>
public const string Any = "any";
/// <summary>
/// Нужны все условия
/// </summary>
public const string All = "all";
}
@@ -15,8 +15,8 @@ public sealed record ContainerCreateDto(
string Name,
string Description = "",
string? Color = null,
string Space = "dashboard",
string Kind = "board",
string Space = ContainerSpaces.Dashboard,
string Kind = ContainerKinds.Board,
bool Suggested = false,
ContainerRulesDto? Rules = null,
string Note = "");
@@ -0,0 +1,52 @@
namespace Deal.Modules.Kanban.Application.Models;
/// <summary>
/// Ключи wire-контракта канбана (ответы API и патчи карточки)
/// </summary>
public static class KanbanWireKeys
{
/// <summary>
/// Счётчик новых карточек
/// </summary>
public const string New = "new";
/// <summary>
/// Счётчик в обучении ML
/// </summary>
public const string Learning = "learning";
/// <summary>
/// Счётчик решённых ML
/// </summary>
public const string Ml = "ml";
/// <summary>
/// Счётчик решённых ИИ
/// </summary>
public const string Ai = "ai";
/// <summary>
/// Признак свёрнутой колонки
/// </summary>
public const string Collapsed = "collapsed";
/// <summary>
/// Ширина колонки
/// </summary>
public const string Width = "width";
/// <summary>
/// Нижняя граница бюджета
/// </summary>
public const string From = "from";
/// <summary>
/// Верхняя граница бюджета
/// </summary>
public const string To = "to";
/// <summary>
/// Валюта бюджета
/// </summary>
public const string Currency = "cur";
}
@@ -361,9 +361,9 @@ public sealed partial class CardsService
return ClearedBudget;
}
double? from = ReadNumber(element, "from");
double? to = ReadNumber(element, "to");
string cur = ReadText(element, "cur");
double? from = ReadNumber(element, KanbanWireKeys.From);
double? to = ReadNumber(element, KanbanWireKeys.To);
string cur = ReadText(element, KanbanWireKeys.Currency);
return new CardBudgetDto(from, to, cur);
}