Перевести ядро на единый контракт источника

Карточка, очередь и отсев работают с SourceItem (SourceRef + SourceContent); Telegram-поля убраны из домена, персистентности, конвейера и wire, остались только в адаптере приёма. Tenant-миграции пересозданы с нуля. Фронт переведён на generic source/content с просмотрщиком вложений.
This commit is contained in:
Rustam Khalimov
2026-09-11 14:58:54 +03:00
parent 770dba7257
commit ebc761d40e
94 changed files with 4150 additions and 9398 deletions
@@ -0,0 +1,47 @@
namespace Deal.Modules.Cards.Application.Sources;
/// <summary>
/// Общие значения и производные поля ссылки на источник.
/// </summary>
public static class SourceRefs
{
/// <summary>
/// Цвет источника по умолчанию.
/// </summary>
public const string DefaultHue = "#666";
/// <summary>
/// Ключ прочих метаданных с цветом источника.
/// </summary>
public const string HueKey = "hue";
/// <summary>
/// Пустая ссылка на источник.
/// </summary>
public static SourceRef Empty { get; } = new() { Kind = string.Empty };
/// <summary>
/// Ключ уникальности записи в источнике: вид + оригинал + внешний id.
/// </summary>
/// <param name="source">Ссылка на источник.</param>
/// <returns>Стабильный ключ для дедупликации.</returns>
public static string DedupeKey(this SourceRef source) =>
string.Concat(source.Kind, "|", source.OriginRef ?? string.Empty, "|", source.ExternalId ?? string.Empty);
/// <summary>
/// Цвет источника для интерфейса.
/// </summary>
/// <param name="source">Ссылка на источник.</param>
/// <returns>Цвет из метаданных либо цвет по умолчанию.</returns>
public static string ResolveHue(this SourceRef source)
{
if (source.Extra is not null
&& source.Extra.TryGetValue(HueKey, out string? hue)
&& !string.IsNullOrWhiteSpace(hue))
{
return hue;
}
return DefaultHue;
}
}