Архитектура Данных
PostgreSQL
PostgreSQL is OLTP source of truth.
Rules:
- Each service owns its own schema and migrations.
- No cross-service foreign keys.
- Tenant-scoped tables include
tenant_id. - Critical tables include idempotency unique constraints.
- Use optimistic concurrency for mutable aggregates.
- Use append-only patterns for ledger, audit, provider callbacks and security logs.
- JSONB используется только для bounded document models с явной typed моделью,
SchemaVersion, validator и backward-compatible reader. - JSONB не используется для обычных связей 1:1, 1:N и M:N; такие связи моделируются таблицами связи.
- Audit, idempotency records и MassTransit outbox publish/send, относящиеся к одной mutation, участвуют в той же transaction boundary, что и aggregate state.
- State transitions сохраняют текущий status, новый status, actor/system initiator и correlationId в audit trail для критичных доменов.
- Страны, регионы, города, валюты и языки хранятся как ссылки на справочники
pin.handbook:CountryId(short),RegionId/CityId(long),CurrencyId(short),LanguageId(short) + денормализованное display-имя, снятое при записи. ISO-коды — атрибуты записей справочника, а не доменные ключи контрактов; единственное легитимноеchar(3)—Currency.IsoCode(ADR-0063). - Untyped
object/json/jsonbв таблицах и контрактах запрещены. Любой гибкий документ имеет typed model, schema version, validator, bounded size и compatibility reader.
Подробные правила: PostgreSQL JSONB document models. Границы транзакций: Transaction Boundaries, Side Effects И Sagas. Inbox/MassTransit outbox: MassTransit Inbox/Outbox.
Recommended service schemas:
| Schema | Owner |
|---|---|
identity | Identity |
handbook | Handbook (реплика Talent Handbook, ADR-0063) |
profile_kyc | Profile/KYC |
accounting | Accounting/Payments |
game_catalog | Catalog |
game_host | Execution Gateway |
incentive | Incentive/Store |
engagement | Tasks/Achievements/User Statistics |
messages | Messages |
saved-items | SavedItems |
connections | Connections |
competitions | Competitions |
promo_partner | Promo/Partners |
notifications | Notifications |
files | File Storage |
ClickHouse
ClickHouse is OLAP storage for analytics.
Rules:
- Store raw facts from Kafka events.
- Use materialized views for dashboard metrics.
- Partition by month or day depending on volume.
- Order keys must start with common filters: tenant, event type/domain, time.
- Do not use ClickHouse as operational source of truth.
- Insert data in batches from Analytics consumers; small synchronous inserts from request handlers are prohibited.
- Use
MergeTreefor raw append-only facts,ReplacingMergeTreeonly where producer deduplication is required, andAggregatingMergeTreefor pre-aggregated dashboards. - Every ClickHouse table is documented as a typed model: column, ClickHouse type, source event field, nullable behavior, partition key, order key, TTL, retention and PII classification.
- Materialized views are documented with source table, target table, aggregation functions, freshness SLA and rebuild strategy.
- Queries must select explicit columns, use partition/order key filters first, avoid
FINALin online dashboards and cap result size by bucketed paging.
Core tables:
fact_eventsfact_paymentsfact_betsfact_winsfact_game_sessionsagg_user_activityagg_paymentsagg_game_popularityagg_partner_performance
Elasticsearch
Elasticsearch is a rebuildable search projection.
Indexes:
| Index | Owner | Purpose |
|---|---|---|
games-v1 | Catalog | Fuzzy, aliases, transliteration game search. |
game-providers-v1 | Catalog | Provider search. |
users-admin-v1 | Profile/KYC + Identity projections | Admin user search with masked/allowed fields. |
users-public-v1 | Profile/Connections | DisplayName-only user search. |
partners-admin-v1 | Partners | Partner search. |
promocodes-admin-v1 | Promo | Promo search. |
Rules:
- Source of truth remains PostgreSQL.
- Index updates come from events.
- Rebuild jobs must exist for every index.
- Security trimming must happen before query execution.
- PII indexes require explicit review.
- Справочники
handbookне индексируются: lookup и internal resolve работают на PostgreSQL (ADR-0056, ADR-0063).
Redis
Redis is used for:
- short-lived cache;
- distributed locks;
- rate limiting counters;
- SignalR backplane;
- nonce/timestamp callback replay protection;
- idempotency short cache where DB unique constraint is still source of truth.
Rules:
- Do not store permanent source-of-truth data in Redis.
- Use TTL for cache keys.
- Locks must have expiration and owner tokens.
Object Storage
S3-compatible storage stores:
- KYC documents;
- avatars/backgrounds/cosmetics;
- game images;
- partner creatives;
- generated reports.
Path convention:
tenants/{tenantId}/{purpose}/{ownerType}/{ownerId}/{fileId}
shared/{purpose}/{fileId}
Files are private by default. Public assets require explicit visibility metadata.
Обратные ссылки
Автоссылки: где используется этот документ.