Контекст: видимость данных
NOTE
Статус: Target design. Документ описывает целевую доменную модель. Соответствующий код реализован частично (см.
backend/internal/core/) или пока не начат. Правила маркировки — в50-processes/documentation-standard.md.
Назначение
В P1 proposal pipeline (
search-proposal.md) visibility поддерживается только как deny на Discovery (Layer 1). Transforms (price_to_range,hide_warehouse, response-shaping) — P5 (Layer 3d post-ranking). До P5 leaf resolvers не модифицируют цену/остаток/склад на основании visibility.
Единый движок управления видимостью данных. Применяется на всех точках выдачи: search, pricing, estimate, public/admin API, analytics, webhooks, media. Вместо рассеянных проверок «кому что показать» — декларативные DataVisibilityPolicy.
Главный смысл
Visibility — поперечный (cross-cutting) BC. Он не владеет товарными или клиентскими данными — он фильтрует/трансформирует выдачу для конкретного
Subject. Дефолт системы: allow (явноеdenyнужно завести).
Агрегаты / сущности / value objects
| Имя | Тип | Назначение |
|---|---|---|
DataVisibilityPolicy | 🟨 Aggregate | Правило видимости. |
Subject | VO | default / customer / customer_group / customer_pricing_group / role. Shared Kernel. |
TargetKind | VO enum | catalog / offer / observation / price / characteristic / analytics / media. |
Effect | VO enum | allow / deny / transform. |
Predicate | VO | JSONB-дерево. |
TransformSpec | VO | redact_field / price_to_range / round_value / hide_warehouse / … |
CompiledPolicy | 🟩 Read model | Кэшированное исполнимое представление per-subject. |
PolicySimulation | VO | Diff-режим: «что увидит X». |
Predicate DSL: операции
- Логические:
and,or,not. - Сравнения:
eq,neq,in,not_in,any_in,between,gt,gte,lt,lte. - Спец:
matches_tag,characteristic_eq,characteristic_in_range,manufacturer_in_group,belongs_to_identity_profile. - По supply chain:
real_manufacturer_in,chain_includes_supplier,has_warehouse_operator,chain_depth_gt,trust_level_in.
Доменные события
| Событие | Причина |
|---|---|
ПолитикаВидимостиСоздана (VisibilityPolicyCreated) | Operator |
ПолитикаВидимостиИзменена (VisibilityPolicyChanged) | Operator |
ПолитикаВидимостиОтключена (VisibilityPolicyDisabled) | Operator |
КомпиляцияПолитикиВыполнена (PolicyCompiled) | Cache miss → compile |
КомпиляцияПолитикиСброшена (PolicyCacheInvalidated) | Изменение policy / subject membership |
НарушениеSLAПолитики (PolicyEvaluationPerfViolation) | Hard limit пробит |
ПолитикаВDryRun (PolicyDryRunObservation) | Pre-prod observation |
Команды
| Команда | Актор | Целевой агрегат | Результат |
|---|---|---|---|
СоздатьПолитику (CreatePolicy) | Operator | DataVisibilityPolicy | VisibilityPolicyCreated |
ИзменитьПолитику (UpdatePolicy) | Operator | DataVisibilityPolicy | VisibilityPolicyChanged |
СкомпилироватьПолитики (CompileForSubject) | Engine | — | PolicyCompiled |
СимулироватьПолитику (Simulate) | Operator | — | PolicySimulation |
ВключитьDryRun (EnableDryRun) | Operator | DataVisibilityPolicy | — |
Политики
| Триггер | Реакция |
|---|---|
VisibilityPolicyCreated/Changed/Disabled | → PolicyCacheInvalidated для затронутых subjects |
CustomerPricingGroupChanged (Customer) | → invalidate cache subject=customer |
PolicyEvaluationPerfViolation | → alert + запись policy_evaluation_audit |
| Создание новой policy | → автоматический EnableDryRun (опция, по умолчанию on) |
Read-модели
- 🟩
compiled_policy_cache(Redis) per-subject. TTL 5 мин (configurable). - 🟩
policy_evaluation_audit(CH) — для аудита нарушений и расследования. - 🟩
policy_simulation_runs(PG) — история симуляций.
Инварианты
- Дефолт системы — allow. Чтобы что-то скрыть — нужна явная
deny-policy. - Алгоритм применения детерминирован: при тех же
(subject, target, candidate)— тот же effect. - Performance budget (см.
data-visibility-policy.mdраньше — теперь здесь):- compile p95 < 20 мс (cache miss).
- evaluate p95 < 0.5 мс (cache hit).
- overhead на 10 policies p95 < 5 мс.
- Privacy: policy не утечёт данных другого клиента; сама policy запрещена цитировать конкретные customer_id из другой группы (валидируется при сохранении).
- Cyclic policy references — hard error.
Точки применения
| BC | Что фильтрует |
|---|---|
| Search | Результаты поиска catalog/offers |
| Pricing | Observations (выбор), price (transform) |
| Estimate | Какие offers разрешены в смете |
| API response shaping | Redact полей в ответах |
| Analytics | Какие агрегаты доступны |
| Webhooks | Какие события push’ить |
| Media serving | Какие изображения / сертификаты разрешены |
Интеграционные события (публикуем)
Топик: visibility.events.v1. Partition key: policy_id.
| Имя | Когда |
|---|---|
VisibilityPolicyCreated, VisibilityPolicyChanged, VisibilityPolicyDisabled | Изменения справочника |
PolicyCacheInvalidated | Для всех потребителей кэша |
Подписанные интеграционные события
| Источник | Событие | Реакция |
|---|---|---|
| Customer | CustomerPricingGroupChanged | Invalidate cache subject=customer |
| Customer | CustomerGroupMembershipChanged | Invalidate per-subject |
| Supplier Network | SupplyChainTraceRecomputed | (опционально) Re-evaluate где predicate использует chain |
Связи в context map
| BC | Паттерн | Назначение |
|---|---|---|
| Pricing | SK (Visibility filter применяется внутри) | — |
| Search | SK | — |
| Estimate | SK | — |
| Customer | SK (Subject shared) | — |
| Supplier Network | SK (SupplyChainTrace для chain-предикатов) | — |
Мини event storming
flowchart LR subgraph OPS["Actor"] OP["🟫 Operator"] end subgraph V["Visibility"] CMD["🟦 CreatePolicy"] DVP["🟨 DataVisibilityPolicy"] EV["🟧 VisibilityPolicyCreated"] DR["🟧 PolicyDryRunObservation"] COMP["🟦 CompileForSubject"] EC["🟧 PolicyCompiled"] CACHE["🟩 compiled_policy_cache"] end subgraph CONS["Pricing / Search / Estimate"] REQ["🟦 Evaluate(subject, target, candidate)"] end subgraph C["Customer"] CC["🟧 CustomerPricingGroupChanged"] end OP --> CMD --> DVP --> EV --> DR EV --> COMP --> EC --> CACHE REQ -. read .-> CACHE CC -.invalidate.-> CACHE
Связанные файлы
pricing.md,search.md,estimate.md,customer.md,supplier-network.md.- ADR-0014 (граничный SLA).