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

Data Ownership И Data Lineage

Назначение

Документ задает единые правила владения данными, происхождения данных и согласования между source of truth, replicas, snapshots, Elasticsearch projections, ClickHouse facts и cache.

Правила обязательны для backend services, gateway, frontend view models, analytics, exports и background jobs. Детальные entity, replica, search document и ClickHouse fact models описываются в service docs рядом с owning service.

Термины

ТерминЗначение
SourceOfTruthЕдинственное место, где принимается бизнес-решение и хранится authoritative state.
ForeignIdТолько id чужой сущности без копирования ее атрибутов.
SnapshotImmutable снимок данных в событии, audit, ledger decision или evidence package.
ReplicaЛокальная eventually consistent копия части чужих данных для проверок или UX.
ProjectionПроизводная read model для поиска, отчетов или dashboard.
LineageПрослеживаемая цепочка: источник, событие, consumer, transform, target model, freshness.
WatermarkEvent offset/id, batch id или timestamp, до которого projection считается построенной.

Базовое Правило

Каждое поле в runtime contract имеет владельца. Сервис-владелец определяет инварианты, схему, допустимые состояния, lifecycle, PII classification, retention и события изменения.

Чужой сервис не меняет owned state напрямую, не пишет в чужую schema/database и не считает replica источником истины. Cross-service согласованность строится через owner API, Kafka events, MassTransit Inbox/Outbox, reconciliation и явно описанные freshness SLA.

Source Of Truth

ДанныеSource of TruthПравило
Пользователи, сессии, роли, permissionsIdentity PostgreSQLAuthorization decisions читают Identity или разрешенную projection с fail closed.
Профиль, KYC, документы проверкиProfile/KYC PostgreSQL и File Storage для файловKYC decision фиксируется snapshot-ом в зависимых financial/security decisions.
Валюты, страны, регионы, города, языкиpin.handbook PostgreSQL (реплика Talent Handbook, ADR-0063)В контрактах используются CurrencyId (short), CountryId (short), RegionId/CityId (long), LanguageId (short).
Ledger, balances, holds, paymentsAccounting PostgreSQL ledgerДеньги меняются только через double-entry postings и ledger transactions.
Catalog data, providers, restrictionsCatalog PostgreSQLElasticsearch index rebuildable и не является owner-ом каталога.
Game sessions, rounds, provider callbacksExecution Gateway PostgreSQLProvider input недоверенный и проходит idempotency/reconciliation.
Incentivees, rewards, cashback rulesIncentive Store PostgreSQLAccounting events не заменяют Incentive source state.
Partner, promo, referrals, commissionsPromo/Partner PostgreSQLPayout decisions фиксируют snapshot ставок и attribution.
AML, risk, safety decisionsCompliance/Anti-Fraud/User Safety PostgreSQLHigh-impact flows используют свежие decisions или fail closed.
Notifications delivery stateNotification PostgreSQLDelivery provider status хранится как adapter-specific typed model.
Analytics reportsClickHouse projectionsНе используются как operational source of truth.

Replicas И Snapshots

Replica создается только когда синхронный owner API lookup неприемлем по latency, availability или объему. Replica описывает owner service, source events, consumer, target model, allowed fields, prohibited fields, freshness SLA, rebuild strategy и fail behavior.

Snapshot используется для воспроизводимости прошлого решения: ledger posting, KYC decision, risk decision, payout approval, audit/evidence, event payload. Snapshot не обновляется после записи и содержит SnapshotVersion, CapturedAt, SourceService, SourceEntityId и typed fields.

Разрешено хранить:

  • display fields, статусы, ids справочников и короткие typed summaries;
  • маскированные или классифицированные PII только при явном разрешении;
  • provider-specific поля только внутри adapter-owned typed models.

Запрещено хранить:

  • secrets, access tokens, refresh tokens, raw provider credentials;
  • полные платежные реквизиты и KYC images вне owner storage;
  • произвольные object/json/jsonb/payload/metadata без named typed model.

Elasticsearch Projections

Elasticsearch является rebuildable search projection. Для каждого index document указывается owner, source events, transform, document id, routing key, tenant/brand trimming, PII fields, freshness SLA, rebuild job и delete/tombstone behavior.

Elasticsearch query возвращает FreshnessView, если результат влияет на admin decision, decision check или support action. Security trimming выполняется до query execution, а не после получения результата.

ClickHouse Projections

ClickHouse хранит append-only facts и агрегаты для аналитики. Каждая таблица описывает source event fields, transform version, deduplication key, partition/order keys, TTL, retention и rebuild/backfill process.

ClickHouse не участвует в command validation для денег, KYC, AML, fraud, withdrawal, game settlement и partner payout. Исключение требует отдельного ADR и fail-closed fallback.

Lineage Contract

Любая replica, projection, export или report описывает lineage:

ПолеОписание
LineageIdСтабильное имя lineage chain.
SourceServiceOwning service.
SourceModelEntity/event/API model источник.
SourceEventTypesСписок events и версий.
ConsumerNameConsumer/job, который строит target.
TransformVersionВерсия transform logic.
TargetModelReplica/search/fact/export model.
FreshnessSlaКатегория из Data Freshness Standard.
WatermarkПоследний обработанный offset/event/batch.
RebuildStrategyКак восстановить target с нуля.

Lineage должен попадать в observability: lag, last successful watermark, failed transform count, poison records, rebuild status.

Freshness И Fail Behavior

Read models возвращают FreshnessView по стандарту docs/02-architecture/data-freshness-standard.md.

High-impact flows fail closed при stale/unknown data:

  • withdrawal decision check;
  • game launch decision check;
  • incentive redemption;
  • AML/KYC/safety checks;
  • partner payout approval;
  • provider callback settlement.

Read-only UX может использовать stale data только с явным stale marker. Command не принимает irreversible decision на stale replica без documented exception и audit reason.

Reconciliation

Reconciliation обязателен, если данные приходят из внешнего провайдера, Kafka consumer может отстать, projection rebuildable или есть cross-service saga.

Каждый reconciliation job описывает owner, source of truth, compared target, matching key, period, допустимый drift, correction command, audit record, published events и alert thresholds.

Для financial и provider flows reconciliation не исправляет ledger напрямую. Исправление выполняется через typed command, который создает компенсирующие ledger postings или state transition.

Ownership Matrix

ArtifactOwnerМожет ЧитатьМожет Писать
Service PostgreSQL schemaOwning serviceOwning serviceOwning service migrations/commands
Kafka event contractProducer serviceConsumersProducer service через governance review
Event snapshotProducer serviceConsumersImmutable после publish
Replica tableConsumer serviceConsumer serviceConsumer через inbox/rebuild job
Elasticsearch indexProjection ownerAuthorized API/query layerProjection consumer/rebuild job
ClickHouse factAnalytics ownerAnalytics/reportingAnalytics consumers/backfill jobs
Redis cacheService using cacheSame serviceSame service with TTL
Export fileExport ownerAuthorized actorsExport job only

Forbidden Patterns

  • Cross-service SQL joins, foreign keys, migrations или direct writes.
  • Использование Elasticsearch, ClickHouse, Redis или frontend state как source of truth.
  • Consumer, который вызывает producer API для каждого события без documented backpressure и fallback.
  • Stale replica для financial/security-critical command без fail closed.
  • Event payload с необъявленным payload, metadata, settings, attributes.
  • Rebuild projection без tombstones/delete handling.
  • Snapshot, который содержит secrets, raw tokens, raw PII или полные платежные реквизиты.
  • Silent schema drift между entity docs, event docs, search docs и ClickHouse docs.

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

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