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

Правила Backend Разработки

Принципы

  • Выбор между rich model и anemic model делается по DDD И Rich Model: Правила И Практика, а не по локальному удобству реализации.
  • Используй rich domain model там, где есть lifecycle, инварианты, финансовые или audit-sensitive решения.
  • Используй простые CRUD/application services там, где домен является стабильным справочником или admin-only dictionary.
  • Следуй SOLID, GRASP, KISS, DRY.
  • Не протаскивай infrastructure concerns в domain objects.
  • Provider DTO не должны попадать в Application и Domain.
  • Все risky behavior покрывается tests: деньги, callbacks, identity, KYC, payout, incentive redemption.

Структура Сервиса

src/services/accounting/
Pin.Accounting.Api/
Pin.Accounting.Application/
Pin.Accounting.Domain/
Pin.Accounting.Infrastructure/
Pin.Accounting.Migrator/
Pin.Accounting.Background/
Pin.Accounting.Contracts/
docker-compose.yml
run-accounting-stack.bat

Слои

  • Api: controllers, auth policies, request/response DTO, filters, OpenAPI.
  • Application: feature slices, commands, queries, handlers, validators, result mapping, orchestration, ports.
  • Domain: aggregates, entities, value objects, domain events, domain services, specifications.
  • Infrastructure: EF DbContext, configurations, repositories, integrations, Redis, Elasticsearch, Kafka, ClickHouse adapters, options.
  • Migrator: применение EF migrations и SQL migrations, затем завершение процесса.
  • Background: consumers, delivery/inbox background services, scheduled synchronization, reconciliation jobs.
  • Contracts: event models и public DTO, которые безопасно шарить.

Application Feature Slice

Application структурируется по FeatureGroup/Feature, а не по root-level техническим папкам Commands, Queries, Validators.

Контракты Методов

  • Find* возвращает nullable и не бросает исключение при отсутствии значения.
  • Get* возвращает значение или typed exception/result failure.
  • List* возвращает страницу или коллекцию и не возвращает nullable.
  • Exists*, Can*, Is*, Has* возвращают boolean.
  • Backend методы не используют suffix Async.
  • Все I/O методы принимают CancellationToken.

CQRS

  • Каждый HTTP action, callback, consumer и background job маппится в Command или Query.
  • Commands изменяют состояние только owning service и проходят через handler, validator, transaction boundary, audit/idempotency и outbox.
  • Queries не меняют operational state и читают source of truth или documented read model/projection с явным freshness SLA.
  • Controllers остаются тонкими.
  • Cross-service consistency строится через events, inbox/outbox, saga/compensation и reconciliation, а не через distributed transaction.

DDD И Rich Model

Нормативные правила, критерии выбора, anti-patterns и практические рекомендации вынесены в DDD И Rich Model: Правила И Практика. Подробные примеры реализации см. в DDD и Domain Model: Практическое Руководство.

Persistence И Side Effects

  • Каждая таблица имеет явный ownership и documented purpose.
  • Финансовые и критичные учетные таблицы используют append-only подход там, где это требуется доменом.
  • jsonb допустим только с typed model, versioning и documentation.
  • Каждая mutation перечисляет side effects: events, external calls, cache invalidation, read model updates, notifications и audit.

Testing И Observability

  • Unit tests покрывают domain invariants и handler decisions.
  • Integration tests покрывают persistence, messaging и adapters по риску изменения.
  • Structured logs, metrics и traces обязательны для runtime-critical paths.

Детальные требования вынесены в:

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

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