Перейти к основному содержимому

DELETE /api/developers/v1/ranking-rules/{ruleId} — Удаление правила ранжирования

Назначение

Soft-delete правила ранжирования (ranking-rule.md, stateDiagram: Active|Disabled → SoftDelete): правило исчезает из списка застройщика, история настроек сохраняется (DeletedAt/DeletedByUserId), карточки пересчитываются по каскаду INV-5 без этого правила в той же транзакции (INV-4). Отличие от Disable: удалённое правило нельзя включить обратно — для той же цели создаётся новое (unique-индекс с фильтром deleted_at is null освобождает цель).

Metadata

ПолеЗначение
Сервис/контекстcatalog
API areadevelopers
Feature groupranking
Статусdraft
Документdocs/06-services/catalog/api/developers/delete-ranking-rule.md

Актор и доступ

ПроверкаЗначение
Actor typeUser (менеджер застройщика — JWT identity)
Auth policy / Permissionspermission catalog.ranking.manage в scope организации/группы проектов/проекта
Scope (RBAC)организация и ниже
Tenant isolationTenantId = CompanyId (ADR-0052); чужое правило невидимо
Auditsoft-delete: DeletedAt/DeletedByUserId + Version++ (история приоритетов — требование аудита ranking-rule.md)

HTTP-контракт

ПолеЗначение
MethodDELETE
Route/api/developers/v1/ranking-rules/{ruleId}
Success status200
Idempotency headerне применяется (повтор → 404 — запись уже снята)
Correlationсквозной trace через traceparent

Входные данные / параметры запроса

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
TenantIdidentity claimsGuidДаRequiredtenant isolation
RuleIdrouteGuidДа!= Guid.Empty; существование — шаг 2

Модель ответа RankingRuleResult

Модель — дом create-ranking-rule.md. Дельта: Status — статус на момент удаления; CardsRecomputed — карточки, вернувшиеся к каскадному приоритету (для удаления Disabled-правила — 0, карточки уже без него).

Алгоритм

  1. Контекст и доступ. Актор — менеджер застройщика (JWT + catalog.ranking.manage); TenantId из claims.
  2. Проверка входа. RuleId != Guid.EmptyValidationError. Существование: правило (в рамках своего tenant, не удалённое) найдено; нет → CATALOG_RANKING_RULE_NOT_FOUND (404). Состояние: Active и Disabled — оба допускают удаление.
  3. Что читаем. Только при Status == Active (иначе пересчёт не нужен): каскадные данные — как в create-ranking-rule.md шаг 3; для TargetKind=PropertyObject дополнительно активное проектное правило (для приоритета отката).
  4. Правила и переходы. Active|Disabled → SoftDelete: DeletedAt = now, DeletedByUserId = актор, Version++; фиксируется RankingRuleChangedEvent. Каскад INV-5 без правила (только если был Active): TargetKind=PropertyObject → объект недвижимости получает DeveloperPriority = активное проектное правило?.Priority ?? 0; TargetKind=Project → карточка проекта DeveloperPriority = 0, объекты недвижимости проекта без собственного Active-правила → 0.
  5. Что меняется. Правило переводится в soft-delete (мутация, не физическое удаление); обновляются затронутые карточки (счётчик → CardsRecomputed). Snapshot-эффект: soft-delete сразу освобождает цель (partial unique index deleted_at is null) — на ту же цель можно создать новое правило в следующем запросе. Правка не должна затирать чужую (конкурентный доступ): два параллельных DELETE одного правила → один переводит в soft-delete, второй видит уже снятое правило и получает CATALOG_RANKING_RULE_NOT_FOUND (404); гонка DELETE с enable/update-priority → проигравший по версии получает CONCURRENCY_CONFLICT (409) и перечитывает состояние.
  6. События. Только доменное RankingRuleChangedEvent; интеграционных нет.
  7. Согласованность. Правило + карточки — в одном согласованном изменении (INV-4).
  8. Результат. RankingRuleResult (200); отказ → ProblemDetails.

Диаграмма

Побочные эффекты

ТипДетали
Проекции / поискоткат DeveloperPriority карточек (индекс ix_*_feed)

Интеграционные события не публикуются; внешних вызовов и уведомлений нет.

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
ValidationError400Пустой RuleIdОшибка валидации запросаno retry
UNAUTHORIZED401Нет/просрочен JWTТребуется авторизацияno retry
FORBIDDEN403Нет permission в scopeДоступ запрещёнno retry
CATALOG_RANKING_RULE_NOT_FOUND404Правило не существует / чужой tenant / уже удаленоПравило не найденоno retry
CONCURRENCY_CONFLICT409Гонка версийПовторите операциюretry

Совместимость и наблюдаемость

  • Новые optional поля — additive; удаление/переименование — breaking.
  • Logs: ranking-rule-deleted (ruleId, tenantId, status-на-момент, cardsRecomputed); metrics: catalog_developers_operations_total{operation="delete-ranking-rule"}; traces + correlation — сквозной trace через traceparent. Dashboard catalog-overview.

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы