Внутренняя операция: <НазваниеОперации>
Шаблон чисто-внутренней операции — той, что не выставлена наружу как HTTP-эндпоинт и не запускается Kafka-consumer'ом (для них — api-method-template и consumer-template). Применяй его для операций, которые запускает фоновое задание, доменное событие или realtime-вызов (SignalR). Уровень изложения — по Уровню изложения ТЗ.
Назначение
2–4 предложения: бизнес-цель операции, кто/что её запускает (фоновое задание, доменное событие, realtime-вызов) и что она делает/возвращает на выходе. Читатель за 10 секунд должен понять, зачем эта операция существует.
Классификация
| Поле | Значение |
|---|---|
| Тип | Изменяет данные (запись) / Только чтение |
| Триггер | Фоновое задание (расписание) / Доменное событие <event> / Realtime-вызов (SignalR) |
| Агрегат / граница | <AggregateName> (для записи) или не применяется |
| Источник данных | <source of truth / read-модель / проекция> |
| Доступ | <актор/система, scope, tenant, record-level — каждый пункт только если применим> |
Входные данные (модель <НазваниеОперации>)
| Поле | Тип | Обязательность | Источник | Ограничения | Безопасность |
|---|---|---|---|---|---|
TenantId | Guid | Да/Нет | scope задания / контекст события | Required | Изоляция по tenant |
<FieldName> | <TypedValue> | Да/Нет | <источник> | <формат / диапазон / enum / ссылка> | <mask/exclude> |
Результат (модель <ResultModelName>)
Для операции записи без результата — опиши эффект (какие сущности изменились, какие события зафиксированы). Для чтения или записи с результатом — таблица полей.
| Поле | Тип | Обязательность | Источник | Описание |
|---|---|---|---|---|
<FieldName> | <Type> | Да/Нет | <сущность / проекция / вычисление> | <описание> |
Алгоритм
Нумерованные бизнес-шаги (happy path + negative paths) по структуре «Алгоритм». Для каждого шага — какую сущность по каким условиям получаем и что решаем; при отказе — какой код ошибки (коды дублируются в таблице «Ошибки»). Шаги записи (мутации, события, согласованность) пиши только для операций записи; для чтения — опусти. Тривиальный CRUD — один абзац без нумерации.
- Контекст и доступ. Кто/что запускает операцию (актор/система), scope/tenant, требуемые права.
- Проверка входа и предусловий. Формат/диапазоны/enum полей; существование сущностей по бизнес-ключу; допустимость состояния (перечислить допустимые статусы); принадлежность/scope. При нарушении — какой код ошибки.
- Что читаем. Какие сущности и по каким условиям загружаем и зачем; списки/поиск — по каким фильтрам, сортировке и страницам.
- Бизнес-правила и переходы. Инварианты (
INV-*), переходы статусаFrom → Toс условием, расчёты; маппинг поле-в-поле (для каждого выходного/сохраняемого поля — источник). - Что меняется (только запись). Какие сущности создаются/обновляются/удаляются и в каком порядке; правило конкурентного доступа — как бизнес-условие («правка не должна затирать чужую»).
- Какие факты/события фиксируются (только если есть). Имя события, топик, из каких полей снапшот, потребители.
- Согласованность (только запись). Что меняется в одном согласованном изменении (атомарно) — бизнес-формулировкой.
- Результат. Что возвращает операция; для чтения — актуальность (freshness) и маскирование чувствительных полей.
Диаграмма
Опционально; рисуй, только если поведение нетривиально. Участники — бизнес/доменные роли. Для тривиального CRUD диаграмму не рисуй.
Побочные эффекты
Только реальные эффекты; если их нет — секцию опусти.
| Тип | Детали |
|---|---|
| События | <имя события / топик / ключ> |
| Внешние вызовы | <адаптер / таймаут / retry> |
| Проекции / кэш / поиск | <индексы / ключи> |
| Уведомления | <канал / шаблон> |
Идемпотентность и повторы
Только для операций записи. Опиши бизнес-условиями: как распознаётся повторный запуск/дубль (по какому ключу), что происходит при повторе (пропуск / обновление), политика повторов и поведение «ядовитой» записи.
| Сценарий | Правило |
|---|---|
| Повторный запуск | <продолжить с контрольной точки / пропустить дубль> |
| Дубль по ключу | <ключ дедупликации и поведение> |
| Повторяемая ошибка | <политика повторов> |
| Неустранимая ошибка | <карантин / ручной разбор> |
Чтение: источник и актуальность
Только для операций чтения. Опусти для записи.
| Аспект | Значение |
|---|---|
| Источник | <source of truth / read-модель / проекция> |
| Freshness SLA | <допустимая задержка> |
| Фильтры / сортировка / страницы | <по каким полям> |
| Маскирование | <правило маскирования по правам> |
Ошибки
| Код | Условие | Повторяемость | Audit |
|---|---|---|---|
<ErrorCode> | <condition> | Да/Нет | Да/Нет |
Наблюдаемость
- Logs:
<запуск / обработано / пропущено-дубль / ошибка / завершено>. - Metrics:
<длительность / обработано записей / ошибки / backlog>. - Traces: correlation id, tenant, id запуска операции.
- Alerts:
<застревание / рост ошибок / backlog>.
Проверяемость
| Проверка | Ожидание |
|---|---|
<успех> | <результат / изменённое состояние> |
<нарушение предусловия> | <код ошибки> |
<повторный запуск> | <идемпотентный результат> |
<конкурентная правка> | <правка не затирает чужую> |
Обратные ссылки
Автоссылки: где используется этот документ.
- API (2): Identity Admin API — реестр методов и общие правила области, Identity Agent API — реестр методов и общие правила области
- documentation-file-templates.md (1): Индекс Шаблонов Документации
- index.md (1): Шаблоны Документации
Связанные документы
- Уровень изложения: spec-authoring-altitude-rules.md.
- Структура алгоритма: algorithm-documentation-rules.md.
- Сущности/агрегаты:
<links>; события:<event-contract links>; use case:<UC link>.