Почистить комментарии от упоминаний процесса
Удалены <remarks>, <summary> сжаты до короткой фразы, вырезаны ссылки на Task/Ruling/этап/python/прототип; //-комментарии со ссылками на процесс удалены; то же в .proto. Правила обновлены в docs/spec/Код-стайл-Дейл.md. Строк комментариев 27210 -> ~19100.
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «ИИ»: карточка создана/сгенерирована ИИ (агент, генератор, разборщик).
|
||||
/// Источник «ИИ»: карточка создана/сгенерирована ИИ
|
||||
/// </summary>
|
||||
/// <remarks>Может быть составной частью <see cref="ICompositeSource"/>: первоисточник данных + ИИ-обработка.</remarks>
|
||||
public interface IAiSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
/// Id провайдера ИИ (deepseek/openai/ollama/…).
|
||||
/// Id провайдера ИИ
|
||||
/// </summary>
|
||||
public string ProviderId { get; }
|
||||
|
||||
@@ -17,17 +16,17 @@ public interface IAiSource : ISource
|
||||
public string Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Id ИИ-агента (если источник — агент, ищущий/обрабатывающий данные); null — не агент.
|
||||
/// Id ИИ-агента
|
||||
/// </summary>
|
||||
public string? AgentId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ссылка на промпт/шаблон (если применимо); null — нет.
|
||||
/// Ссылка на промпт/шаблон
|
||||
/// </summary>
|
||||
public string? PromptRef { get; }
|
||||
|
||||
/// <summary>
|
||||
/// API, через который работал агент (для составных сценариев); null — нет.
|
||||
/// API, через который работал агент
|
||||
/// </summary>
|
||||
public IApiSource? ViaApi { get; }
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «внешний API»: карточка пришла из интеграции по API.
|
||||
/// Источник «внешний API»
|
||||
/// </summary>
|
||||
public interface IApiSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ интеграции/провайдера (конфигурация подключения живёт в настройках тенанта).
|
||||
/// Ключ интеграции/провайдера
|
||||
/// </summary>
|
||||
public string ProviderId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Адрес эндпоинта (или иной указатель в рамках провайдера); null — не применимо.
|
||||
/// Адрес эндпоинта
|
||||
/// </summary>
|
||||
public string? Endpoint { get; }
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «атрибуты»: настраиваемые пользователем характеристики (стек, грейд, локация, сроки…).
|
||||
/// Модуль «атрибуты»
|
||||
/// </summary>
|
||||
/// <remarks>Справочник атрибутов живёт в настройках тенанта; карточка хранит только значения по ключам.</remarks>
|
||||
public interface IAttributedCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Значения атрибутов карточки (пусто — не заполнены).
|
||||
/// Значения атрибутов карточки
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardAttribute> Attributes { get; }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «бюджет/цена»: деньги заявки (валюта исходная + сконвертированная).
|
||||
/// Модуль «бюджет/цена»
|
||||
/// </summary>
|
||||
public interface IBudgetedCard
|
||||
{
|
||||
|
||||
@@ -3,29 +3,20 @@ namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
/// <summary>
|
||||
/// Ядро карточки: единственное, что есть у любой карточки во всех дашбордах.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Никаких «полей заявки» в ядре: стек/бюджет/контакты и прочее — опциональные модули-роли
|
||||
/// (см. <c>IContentCard</c>, <c>IBudgetedCard</c> и др.), которые реализует агрегат карточки
|
||||
/// по мере наполнения. <see cref="Source"/> — откуда карточка пришла (см. иерархию <c>ISource</c>);
|
||||
/// у карточки, созданной пайплайном из сообщения канала, источник составной:
|
||||
/// <c>ICompositeSource { Origin: ITelegramSource, Pipeline: [IAiSource/IMl] }</c>.
|
||||
/// Типизированный доступ к конкретному источнику — дискриминация через иерархию ISource
|
||||
/// (паттерн-матчинг), отдельный generic-интерфейс не нужен.
|
||||
/// </remarks>
|
||||
public interface ICard
|
||||
{
|
||||
/// <summary>
|
||||
/// Короткий id карточки (единый префикс карточек, напр. <c>c_</c>).
|
||||
/// Короткий id карточки
|
||||
/// </summary>
|
||||
public string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Заголовок карточки (очищенный).
|
||||
/// Заголовок карточки
|
||||
/// </summary>
|
||||
public string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Источник: откуда карточка пришла (полиморфный, не enum).
|
||||
/// Источник: откуда карточка пришла
|
||||
/// </summary>
|
||||
public ISource Source { get; }
|
||||
}
|
||||
|
||||
@@ -6,13 +6,6 @@ namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
/// <summary>
|
||||
/// Единый механизм перехода карточки между контейнерами.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Заменяет маршрутизацию перехода по эндпоинтам: одна точка знает и контейнеры-стадии пространства
|
||||
/// «Выбранные», и контейнеры дашборда (доски/служебные зоны). Валидацию «откуда → куда можно» выполняют
|
||||
/// политики контейнеров и «ворота» между пространствами (например, дашборд → «Выбранные» — только через
|
||||
/// действие «взять в работу»; «Выбранные» → дашборд — запрещено). Побочные эффекты (запись истории для
|
||||
/// стадий, сброс напоминания, журнал/обучение ML для дашборда) выполняет реализация перехода.
|
||||
/// </remarks>
|
||||
public interface ICardMover
|
||||
{
|
||||
/// <summary>
|
||||
@@ -21,7 +14,6 @@ public interface ICardMover
|
||||
/// <param name="cardId">Id карточки.</param>
|
||||
/// <param name="toContainerId">Id контейнера назначения (стадия «Выбранных» либо дашборд-контейнер).</param>
|
||||
/// <param name="ctx">Контекст перехода (инициатор, причина, обучение).</param>
|
||||
/// <param name="ct">Токен отмены.</param>
|
||||
/// <returns>Результат: Error (400-текст отказа) | Exists=false (карточки нет, 404) | успех (Exists=true).</returns>
|
||||
public Task<CardMoveResultDto> MoveAsync(
|
||||
string cardId,
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
public interface ICommentableCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Комментарии карточки (пусто — комментариев нет).
|
||||
/// Комментарии карточки
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardComment> Comments { get; }
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Составной источник: цепочка «где взято → как обработано/доставлено».
|
||||
/// Составной источник
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// У карточки из пайплайна источник составной: <see cref="Origin"/> — первоисточник контента
|
||||
/// (например, <c>ITelegramSource</c>), <see cref="Pipeline"/> — кто/что его обрабатывал
|
||||
/// (например, ИИ-классификатор). Позволяет строить «третьи» источники без правки ядра.
|
||||
/// </remarks>
|
||||
public interface ICompositeSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,7 +11,7 @@ public interface ICompositeSource : ISource
|
||||
public ISource Origin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Цепочка обработки (пусто — обработки не было).
|
||||
/// Цепочка обработки
|
||||
/// </summary>
|
||||
public IReadOnlyList<ISource> Pipeline { get; }
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
public interface IContactCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Квалифицированные контакты (пусто — контактов нет).
|
||||
/// Квалифицированные контакты
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardContact> Contacts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Контактная строка «как в исходных данных» (fallback, если Contacts пуст).
|
||||
/// Контактная строка «как в исходных данных»
|
||||
/// </summary>
|
||||
public string ContactText { get; }
|
||||
}
|
||||
|
||||
@@ -1,44 +1,37 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Контейнер карточки: колонка дашборда, стадия «Выбранных» или служебная зона.
|
||||
/// Контейнер карточки
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Общая база колонок/стадий/зон: пользовательские колонки (kind=board, создаёт пользователь/ИИ),
|
||||
/// стадии (kind=stage, предзаданный каталог), «Неразобранное», архив, корзина, терминальные зоны.
|
||||
/// Поведение контейнера — через <see cref="Policy"/> (роль, не enum-свойства): правила попадания,
|
||||
/// допустимость возврата, автоочистка, терминальность. Пространство (дашборд/«Выбранные»/третий вид) —
|
||||
/// свойство SpaceId: карточке безразличен вид, у неё только ContainerId.
|
||||
/// </remarks>
|
||||
public interface IContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Короткий id контейнера (доски <c>b_…</c>, стадии <c>planned…</c>, служебные inbox/archive/trash).
|
||||
/// Короткий id контейнера
|
||||
/// </summary>
|
||||
public string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Имя для отображения («WPF», «В работе», «Архив»).
|
||||
/// Имя для отображения
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Цвет контейнера (hex).
|
||||
/// Цвет контейнера
|
||||
/// </summary>
|
||||
public string Color { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Позиция в пространстве (порядок показа слева направо).
|
||||
/// Позиция в пространстве
|
||||
/// </summary>
|
||||
public int Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пространства (доски), которому принадлежит контейнер.
|
||||
/// Id пространства
|
||||
/// </summary>
|
||||
public string SpaceId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Политика контейнера: что можно/нельзя и что происходит (роль).
|
||||
/// Политика контейнера
|
||||
/// </summary>
|
||||
public IContainerPolicy Policy { get; }
|
||||
}
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Политика контейнера: правила размещения карточек и жизненного цикла зоны.
|
||||
/// Политика контейнера
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Роль контейнера (не enum): пользовательская колонка-фильтр, стадия, «Неразобранное», архив/корзина,
|
||||
/// терминальная зона — каждая реализует политику по-своему. Политика отвечает на два вопроса:
|
||||
/// (1) можно ли карточке попасть сюда (правила фильтрации) и (2) что происходит с карточкой здесь
|
||||
/// (возврат, автоочистка, терминальность, напоминания).
|
||||
/// </remarks>
|
||||
public interface IContainerPolicy
|
||||
{
|
||||
/// <summary>
|
||||
/// Правила попадания карточки в контейнер (null — фильтра нет, карточки кладутся вручную/ИИ).
|
||||
/// Правила попадания карточки в контейнер
|
||||
/// </summary>
|
||||
public IContainerRules? Rules { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Можно ли вернуть карточку из контейнера на доску пространства (архив/корзина — да; терминальные — нет).
|
||||
/// Можно ли вернуть карточку из контейнера на доску пространства
|
||||
/// </summary>
|
||||
public bool CanRestore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Терминальная зона: карточка завершила жизненный путь, ручная очистка без возврата.
|
||||
/// Терминальная зона
|
||||
/// </summary>
|
||||
public bool IsTerminal { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Автоочистка контейнера: срок хранения карточек (null — автоочистки нет).
|
||||
/// Автоочистка контейнера
|
||||
/// </summary>
|
||||
public TimeSpan? Retention { get; }
|
||||
}
|
||||
|
||||
@@ -3,38 +3,32 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Правила попадания карточки в контейнер (набор опциональных фильтров).
|
||||
/// Правила попадания карточки в контейнер
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Соответствует «правилам колонки» (§6.3): направление/стек/ключевые слова/грейд/уровень/цена/бюджет/
|
||||
/// локация/тип и отрицательные исключения. Все группы опциональны; режим All/Any решает, как группы
|
||||
/// сочетаются. Пустые правила — контейнер без фильтра (карточки кладутся вручную или ИИ/ML по контексту).
|
||||
/// Проверка — по содержимому карточки (атрибуты, бюджет, текст), чистая функция.
|
||||
/// </remarks>
|
||||
public interface IContainerRules
|
||||
{
|
||||
/// <summary>
|
||||
/// Режим сочетания групп: <c>all</c> — должны совпасть все включённые группы; <c>any</c> — хотя бы одна.
|
||||
/// Режим сочетания групп
|
||||
/// </summary>
|
||||
public string Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключевые слова/фразы (пусто — группа не участвует).
|
||||
/// Ключевые слова/фразы
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Keywords { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ключевые технологии/стек-атрибуты (пусто — не участвует).
|
||||
/// Ключевые технологии/стек-атрибуты
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Stack { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Направление/тема (пусто — не участвует).
|
||||
/// Направление/тема
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Directions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Грейд/уровень (пусто — не участвует).
|
||||
/// Грейд/уровень
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Grades { get; }
|
||||
|
||||
@@ -49,22 +43,22 @@ public interface IContainerRules
|
||||
public IReadOnlyList<string> Locations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип заявки: вакансия/фриланс/объявление (пусто — не участвует).
|
||||
/// Тип заявки: вакансия/фриланс/объявление
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Types { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Бюджетный диапазон (null — не участвует).
|
||||
/// Бюджетный диапазон
|
||||
/// </summary>
|
||||
public CardBudget? Budget { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон цены (отдельная группа §6.3; null — не участвует).
|
||||
/// Диапазон цены
|
||||
/// </summary>
|
||||
public CardBudget? Prices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Исключения: карточка не попадает, если в тексте/атрибутах есть хотя бы одно (veto).
|
||||
/// Исключения: карточка не попадает, если в тексте/атрибутах есть хотя бы одно
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Exclude { get; }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «содержимое»: структурированный блок «О заявке» карточки.
|
||||
/// Модуль «содержимое»
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Единая структура у всех карточек (Компания → Формат → О задаче → Требования → Будет плюсом → Условия);
|
||||
/// у карточки без разобранного содержимого модуль пуст (Summary = "").
|
||||
/// </remarks>
|
||||
public interface IContentCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Блок «О заявке» (строки с метками, ≤2000).
|
||||
/// Блок «О заявке»
|
||||
/// </summary>
|
||||
public string Summary { get; }
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «файлы» карточки (медиа/документы; объекты — в S3/MinIO).
|
||||
/// Модуль «файлы» карточки
|
||||
/// </summary>
|
||||
public interface IFileCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Метаданные файлов карточки (пусто — файлов нет).
|
||||
/// Метаданные файлов карточки
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardFile> Files { get; }
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «файл» (карточка создана из загруженного/импортированного файла).
|
||||
/// Источник «файл»
|
||||
/// </summary>
|
||||
public interface IFileSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
/// Ключ объекта в хранилище (MinIO/локальная папка).
|
||||
/// Ключ объекта в хранилище
|
||||
/// </summary>
|
||||
public string ObjectKey { get; }
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
public interface ILinkCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Прикреплённые ссылки (пусто — ссылок нет).
|
||||
/// Прикреплённые ссылки
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardLink> Links { get; }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «создано вручную/локально» (карточка без внешнего первоисточника).
|
||||
/// Источник «создано вручную/локально»
|
||||
/// </summary>
|
||||
/// <remarks>Покрывает ручное создание карточки пользователем (в UI «Выбранных» и будущих дашбордов).</remarks>
|
||||
public interface ILocalSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «размещение»: контейнер карточки и флаги состояния на доске.
|
||||
/// Модуль «размещение»
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Контейнер (колонка/стадия/зона) — единственное «место» карточки; смена контейнера = переход карточки
|
||||
/// (см. <see cref="ICardMover"/>). «Архив/корзина/отклонено/выполнено» — такие же контейнеры со своими
|
||||
/// политиками, а не отдельные сущности. PrevContainerId — для возврата из архива/корзины.
|
||||
/// </remarks>
|
||||
public interface ILocatedCard
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,12 +11,12 @@ public interface ILocatedCard
|
||||
public string ContainerId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Предыдущий контейнер (для возврата); null — возврат неприменим.
|
||||
/// Предыдущий контейнер
|
||||
/// </summary>
|
||||
public string? PrevContainerId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Признак «новое» (подсветка на доске; снимается просмотром/переходом).
|
||||
/// Признак «новое»
|
||||
/// </summary>
|
||||
public bool IsNew { get; }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «напоминание»: отложенная карточка (контейнер hold).
|
||||
/// Модуль «напоминание»
|
||||
/// </summary>
|
||||
public interface IRemindableCard
|
||||
{
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «импорт данных»: карточка создана из строки/колонки таблицы (csv/sheet/БД).
|
||||
/// Источник «импорт данных»
|
||||
/// </summary>
|
||||
public interface IRowSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
/// Id таблицы/импорта (внешний идентификатор источника данных).
|
||||
/// Id таблицы/импорта
|
||||
/// </summary>
|
||||
public string TableId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Id строки в таблице (первичный ключ строки-источника).
|
||||
/// Id строки в таблице
|
||||
/// </summary>
|
||||
public string RowId { get; }
|
||||
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник карточки: всё, откуда карточка может прийти.
|
||||
/// Источник карточки
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Полиморфная иерархия вместо enum-свойства «тип источника»: конкретные варианты несут свои поля
|
||||
/// (Telegram — диалог/сообщение/тема, Web — url, AI — провайдер/модель и т.д.), а общий контракт —
|
||||
/// только подпись, ссылку на оригинал и сырое содержимое. Составной источник (<see cref="ICompositeSource"/>)
|
||||
/// описывает цепочку «первоисточник → обработка» (например, сообщение Telegram, разобранное ИИ).
|
||||
/// </remarks>
|
||||
public interface ISource
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись источника в UI: «@freelance», «hh.ru», «файл leads.csv»…
|
||||
/// Подпись источника в UI
|
||||
/// </summary>
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Ссылка на оригинал: t.me/…, https://…, objectKey; null — оригинала нет (локальное создание).
|
||||
/// Ссылка на оригинал
|
||||
/// </summary>
|
||||
public string? OriginRef { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Сырое содержимое (текст/JSON), если хранится; null — не хранится.
|
||||
/// Сырое содержимое
|
||||
/// </summary>
|
||||
public string? RawPayload { get; }
|
||||
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «Telegram»: канал/группа/чат/форум, конкретное сообщение.
|
||||
/// Источник «Telegram»
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Покрывает все варианты источника Telegram: канал (DialogId=peer, TopicId=null), группа с темами
|
||||
/// (TopicId задан), личный чат. Ссылка на оригинал строится из PeerHandle/PeerId и MessageId
|
||||
/// (см. контракт tgSourceUrl текущего фронта).
|
||||
/// </remarks>
|
||||
public interface ITelegramSource : ISource
|
||||
{
|
||||
/// <summary>
|
||||
@@ -21,7 +16,7 @@ public interface ITelegramSource : ISource
|
||||
public long MessageId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Handle канала (без «@»); null — диалог без username (приватный).
|
||||
/// Handle канала
|
||||
/// </summary>
|
||||
public string? PeerHandle { get; }
|
||||
|
||||
@@ -31,7 +26,7 @@ public interface ITelegramSource : ISource
|
||||
public string PeerName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Id темы форума (для групп с темами); null — темы нет.
|
||||
/// Id темы форума
|
||||
/// </summary>
|
||||
public string? TopicId { get; }
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ using Deal.Modules.Cards.Application.Models;
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Модуль «история движения» карточки (создание и смены контейнера).
|
||||
/// Модуль «история движения» карточки
|
||||
/// </summary>
|
||||
public interface ITraceableCard
|
||||
{
|
||||
/// <summary>
|
||||
/// История движения, свежие записи — в конце списка (пусто — истории нет).
|
||||
/// История движения, свежие записи — в конце списка
|
||||
/// </summary>
|
||||
public IReadOnlyList<CardHistoryEntry> History { get; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Источник «ссылка на сайт/объявление» (карточка создана из веб-страницы).
|
||||
/// Источник «ссылка на сайт/объявление»
|
||||
/// </summary>
|
||||
public interface IWebSource : ISource
|
||||
{
|
||||
|
||||
@@ -5,11 +5,6 @@ namespace Deal.Modules.Cards.Application.Dtos;
|
||||
/// <summary>
|
||||
/// Результат перехода карточки единым механизмом <see cref="ICardMover"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Error — 400-текст отказа (несуществующий контейнер/исходная колонка, запрет политики); Exists=false —
|
||||
/// карточки нет (404). При успехе оба поля пусты/true — снимок карточки эндпоинт перечитывает единым
|
||||
/// чтением (CardDto), чтобы наружу всегда уходила одна форма.
|
||||
/// </remarks>
|
||||
/// <param name="Error">Текст 400-ошибки либо null.</param>
|
||||
/// <param name="Exists">True — карточка найдена и переход выполнен (либо перенос был no-op).</param>
|
||||
public sealed record CardMoveResultDto(string? Error, bool Exists);
|
||||
|
||||
@@ -3,15 +3,8 @@ using Deal.Modules.Cards.Application.Abstractions;
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Агрегат карточки: ядро + опциональные модули (единая сущность всех дашбордов).
|
||||
/// Агрегат карточки
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Один класс на карточку (не иерархия видов): вид определяется контейнером и наполненностью модулей,
|
||||
/// а не типом. Модули — это секции данных (роли интерфейсов), пустые, пока карточка «входящая»,
|
||||
/// наполняются, когда карточка «в работе» (файлы/ссылки/ТЗ/история/напоминания). Класс неизменяемый
|
||||
/// (init/свойства только для чтения) — изменения применяются сервисами через порт и возвращают новый
|
||||
/// снимок, как единая CardDto (wire 1:1 сохраняется).
|
||||
/// </remarks>
|
||||
public sealed class Card :
|
||||
ICard,
|
||||
IContentCard,
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Настраиваемый атрибут карточки: имя, значение и (опционально) единица измерения.
|
||||
/// Настраиваемый атрибут карточки
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Стек/грейд/локация/сроки/площадь и прочее — не «зашитые» поля карточки, а атрибуты из справочника
|
||||
/// тенанта (пользователь настраивает в UI, «стек» — лишь частый атрибут). Один атрибут = одна запись
|
||||
/// «ключ → значение»; ключом служит строковый id из справочника атрибутов.
|
||||
/// </remarks>
|
||||
public sealed record CardAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Id атрибута (ключ справочника: <c>stack</c>, <c>grade</c>, <c>location</c>, …).
|
||||
/// Id атрибута (ключ справочника
|
||||
/// </summary>
|
||||
public string Key { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Значение атрибута (например, «Python», «Middle», «Москва»).
|
||||
/// Значение атрибута
|
||||
/// </summary>
|
||||
public string Value { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Единица измерения (₽/₽/час/м²/…); null — безразмерный.
|
||||
/// Единица измерения
|
||||
/// </summary>
|
||||
public string? Unit { get; init; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Бюджет/цена карточки в исходной валюте и (опционально) сконвертированный в целевую.
|
||||
/// Бюджет/цена карточки в исходной валюте и
|
||||
/// </summary>
|
||||
public sealed record CardBudget
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Контакт заказчика: квалифицированная запись (тип + значение).
|
||||
/// Контакт заказчика
|
||||
/// </summary>
|
||||
public sealed record CardContact
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Метаданные прикреплённого файла карточки (объект хранится в S3/MinIO или локальной папке).
|
||||
/// Метаданные прикреплённого файла карточки
|
||||
/// </summary>
|
||||
public sealed record CardFile
|
||||
{
|
||||
@@ -21,7 +21,7 @@ public sealed record CardFile
|
||||
public long SizeBytes { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип контента: image/video/audio/archive/document/other (определяет детектор).
|
||||
/// Тип контента: image/video/audio/archive/document/other
|
||||
/// </summary>
|
||||
public string Kind { get; init; } = "other";
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ public sealed record CardHistoryEntry
|
||||
public long AtMs { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип события: <c>created</c>|<c>createdLocal</c>|id контейнера назначения (движение).
|
||||
/// Тип события: <c>created</c>|<c>createdLocal</c>|id контейнера назначения
|
||||
/// </summary>
|
||||
public string Type { get; init; } = string.Empty;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,27 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Реестр коротких id модуля Cards и служебных контейнеров (единый владелец карточки).
|
||||
/// Реестр коротких id модуля Cards и служебных контейнеров
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Единый префикс карточек <c>c_</c> приходит на смену <c>l_</c> (канбан) и <c>pr_</c> (проекты) — при
|
||||
/// слиянии таблиц у карточки один id, не зависящий от пространства. Служебные контейнеры
|
||||
/// (<c>inbox</c>/<c>archive</c>/<c>trash</c>) — фиксированные зоны любого пространства-дашборда.
|
||||
/// Контейнеры-доски (<c>b_…</c>) создаёт пользователь/ИИ; контейнеры-стадии — предзаданный каталог
|
||||
/// (см. CardsDefaultContainers). Id генерирует модуль (PrefixId), хранилище получает готовые.
|
||||
/// </remarks>
|
||||
public static class CardIds
|
||||
{
|
||||
/// <summary>
|
||||
/// Префикс id карточки (единый для всех дашбордов).
|
||||
/// Префикс id карточки
|
||||
/// </summary>
|
||||
public const string CardPrefix = "c_";
|
||||
|
||||
/// <summary>
|
||||
/// Контейнер «Неразобранное»: новые карточки пайплайна до раскладки по колонкам.
|
||||
/// Контейнер «Неразобранное»
|
||||
/// </summary>
|
||||
public const string Inbox = "inbox";
|
||||
|
||||
/// <summary>
|
||||
/// Контейнер «Архив»: карточки старше срока архивации (автоочистка по политике).
|
||||
/// Контейнер «Архив»
|
||||
/// </summary>
|
||||
public const string Archive = "archive";
|
||||
|
||||
/// <summary>
|
||||
/// Контейнер «Корзина»: удалённые карточки (автоочистка по политике).
|
||||
/// Контейнер «Корзина»
|
||||
/// </summary>
|
||||
public const string Trash = "trash";
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ public sealed record CardLink
|
||||
public string Id { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Подпись ссылки (пусто — url как подпись).
|
||||
/// Подпись ссылки
|
||||
/// </summary>
|
||||
public string Name { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Адрес ссылки (http/https).
|
||||
/// Адрес ссылки
|
||||
/// </summary>
|
||||
public string Url { get; init; } = string.Empty;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Напоминание об «Отложено» (карточка в контейнере hold).
|
||||
/// Напоминание об «Отложено»
|
||||
/// </summary>
|
||||
public sealed record CardReminder
|
||||
{
|
||||
@@ -11,7 +11,7 @@ public sealed record CardReminder
|
||||
public long AtMs { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Признак «напоминание выстрелило» (повторно не срабатывает до переноса/переустановки).
|
||||
/// Признак «напоминание выстрелило»
|
||||
/// </summary>
|
||||
public bool Fired { get; init; }
|
||||
}
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Каталог контейнеров по умолчанию пространства «Выбранные» (стадии) и служебных зон.
|
||||
/// Каталог контейнеров по умолчанию пространства «Выбранные»
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Приходит на смену ProjectStages модуля Projects: стадии — это контейнеры kind=stage предзаданного
|
||||
/// каталога (терминальные — finished/rejected). Хранилище провижинит их тенанту как строки Containers;
|
||||
/// каталог — единственный источник имён/цветов/порядка (как ProjectStages.All). Служебные зоны
|
||||
/// (inbox/archive/trash) — фиксированные контейнеры CardIds. Доски (kind=board) каталогу не принадлежат:
|
||||
/// их создаёт пользователь/ИИ.
|
||||
/// </remarks>
|
||||
public static class CardsDefaultContainers
|
||||
{
|
||||
/// <summary>
|
||||
/// Id стадии «Запланировано» (цель перехода «взять в работу»).
|
||||
/// Id стадии «Запланировано»
|
||||
/// </summary>
|
||||
public const string Planned = "planned";
|
||||
|
||||
@@ -43,7 +36,7 @@ public static class CardsDefaultContainers
|
||||
public const string Ready = "ready";
|
||||
|
||||
/// <summary>
|
||||
/// Id стадии «Отложено» (напоминания сбрасываются переносом).
|
||||
/// Id стадии «Отложено»
|
||||
/// </summary>
|
||||
public const string Hold = "hold";
|
||||
|
||||
@@ -53,12 +46,12 @@ public static class CardsDefaultContainers
|
||||
public const string Finished = "finished";
|
||||
|
||||
/// <summary>
|
||||
/// Id терминальной стадии «Отклонено» (очистка вручную, без возврата).
|
||||
/// Id терминальной стадии «Отклонено»
|
||||
/// </summary>
|
||||
public const string Rejected = "rejected";
|
||||
|
||||
/// <summary>
|
||||
/// Все контейнеры по умолчанию (стадии пространства «Выбранные»), порядок канбана.
|
||||
/// Все контейнеры по умолчанию
|
||||
/// </summary>
|
||||
public static IReadOnlyList<DefaultContainer> All { get; } = new List<DefaultContainer>
|
||||
{
|
||||
@@ -74,12 +67,12 @@ public static class CardsDefaultContainers
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Id всех контейнеров-стадий «Выбранных» (для фильтра пространства в выборках хранилища).
|
||||
/// Id всех контейнеров-стадий «Выбранных»
|
||||
/// </summary>
|
||||
public static IReadOnlyList<string> Ids { get; } = All.Select(container => container.Id).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Проверка: контейнер с таким id есть в каталоге (валидация move/ручного создания).
|
||||
/// Проверка: контейнер с таким id есть в каталоге
|
||||
/// </summary>
|
||||
/// <param name="containerId">Проверяемый id.</param>
|
||||
/// <returns>True — контейнер известен каталогу.</returns>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Описание контейнера по умолчанию (запись каталога CardsDefaultContainers).
|
||||
/// Описание контейнера по умолчанию
|
||||
/// </summary>
|
||||
public sealed record DefaultContainer
|
||||
{
|
||||
|
||||
@@ -3,15 +3,12 @@ using Deal.Modules.Cards.Application.Abstractions;
|
||||
namespace Deal.Modules.Cards.Application.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Контекст перехода карточки: кто инициировал и что делать с обучением.
|
||||
/// Контекст перехода карточки
|
||||
/// </summary>
|
||||
/// <remarks>Переход — единый механизм (<see cref="ICardMover"/>); контекст отличает действие пользователя
|
||||
/// (обучать ML), системы (автоархив/очистка) и ИИ/ML (классификация). Reason — для возвратов из отсева
|
||||
/// и ручных исключений, чтобы ML/ИИ учились на решении.</remarks>
|
||||
public sealed record TransitionContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Инициатор перехода: <c>user</c>|<c>system</c>|<c>ai</c>|<c>ml</c>.
|
||||
/// Инициатор перехода
|
||||
/// </summary>
|
||||
public required string Actor { get; init; }
|
||||
|
||||
@@ -21,7 +18,7 @@ public sealed record TransitionContext
|
||||
public string? Reason { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Обучать ML на этом действии (действия пользователя — да; системные — нет).
|
||||
/// Обучать ML на этом действии
|
||||
/// </summary>
|
||||
public bool Learn { get; init; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user