8.0 KiB
Raw Blame History

Backend Architecture Refactor

Дата: 2026-06-25 Статус: выполнено

Контекст

После аудита backend-архитектуры от 2026-06-25 и последующей фичи backend-architecture-improvements большая часть первого слоя долга закрыта: общий envelope DTO, domain exceptions, dependency-aware health checks, DI-подключение middleware и разделение MoexClientService.

Оставшийся долг неоднороден. Часть пунктов требует новых продуктовых или доменных решений (T-Bank multi-tenancy, локальный read-path истории операций, device sessions, ledger-модель). Эти изменения не должны попадать в локальный рефакторинг без отдельной спецификации, потому что меняют поведение, модель данных или threat model.

Текущая фича фиксирует только refactor-only итерацию: привести существующий backend к более правильным архитектурным границам без добавления новых пользовательских возможностей и без изменения публичной формы API, кроме уточнения валидации некорректных входных данных.

Цель

Снизить backend technical debt в существующем поведении за счёт точечных архитектурных правок: безопаснее обрабатывать ошибки, формализовать production-конфигурацию, усилить DTO-валидацию, сузить any на границе T-Bank gRPC, улучшить cache metadata и синхронизировать опубликованную backend-документацию с текущим кодом.

Требования

1. Error masking для необработанных исключений

Backend не должен возвращать клиенту внутренние сообщения необработанных Error в ответах 500. Подробности должны оставаться в backend-логах. Публичный ответ для unknown/internal errors должен быть стабильным и безопасным.

2. Production configuration hardening

Backend должен явно отделять dev defaults от production-конфигурации:

  • production-запуск не должен молча использовать дефолтные JWT access/refresh secrets;
  • CORS с credentials не должен отражать произвольный origin в production;
  • список допустимых origins должен задаваться конфигурацией окружения.

3. DTO validation hardening

Существующие DTO должны отсеивать заведомо некорректные значения до попадания в service-layer:

  • даты покупки позиции должны валидироваться как ISO/date строки;
  • количество позиции не должно допускать 0 там, где service-layer уже трактует это как ошибку;
  • изменения должны сохранять существующий успешный пользовательский сценарий для валидных данных.

4. T-Bank gRPC typed boundary

Динамическая природа protobuf/gRPC клиента должна быть локализована в одном typed boundary, чтобы доменные broker-сервисы не приводили service clients к any напрямую. Цель — улучшить compile-time границы без переписывания vendored proto contract и без изменения внешнего T-Bank API behavior.

5. Cache metadata consistency

Cache helper должен сохранять полезность meta.cachedAt: cache hit не должен выглядеть как состояние без времени кеширования, если timestamp уже можно сохранить вместе с cached payload.

6. Backend documentation sync

Опубликованные docs в apps/docs/docs/backend/ должны отражать текущее состояние backend после закрытых refactor-работ:

  • split MOEX clients вместо устаревшего MoexClientService как единого God Service;
  • актуальный envelope contract;
  • актуальные health response и broker operations sync endpoint.

Ограничения

  • Не добавлять новые user-facing возможности.
  • Не менять публичный API shape для успешных ответов.
  • Не вводить multi-tenancy или пользовательские T-Bank connections в рамках этой фичи.
  • Не переводить операции T-Bank на локальный read-path в рамках этой фичи.
  • Не менять модель сессий на device/session table в рамках этой фичи.
  • Не менять финансовую модель хранения (Float, Int, JSON/string fields) и не создавать ledger ADR в рамках этой фичи.
  • Не выполнять механическое дробление больших сервисов без проверяемой архитектурной цели.
  • Не редактировать Prisma migrations вручную.

Acceptance Criteria

  • Необработанные backend exceptions логируются, но 500 response не раскрывает внутренний Error.message.
  • Production-конфигурация не стартует с дефолтными JWT secrets и не использует wildcard/reflected CORS для credentialed requests.
  • DTO портфельных позиций валидируют даты и количество на boundary-уровне; добавлены regression tests.
  • Production-код broker-сервисов не содержит прямых as any для получения T-Bank gRPC service clients; небезопасное приведение, если оно необходимо, локализовано и покрыто типом/facade.
  • Cache metadata на hit/miss согласована тестами и не ломает ApiEnvelopePayload/ApiResponse contract.
  • Backend docs обновлены и не ссылаются на удалённый MoexClientService как primary abstraction, устаревший /operations/refresh endpoint или raw health response без envelope.
  • Затронутые backend tests проходят.
  • Backend build проходит.
  • OpenAPI/types обновляются только если реально меняется Swagger contract; apps/frontend/src/api/types.ts не редактируется вручную.

Out Of Scope

  • T-Bank data isolation and multi-tenancy.
  • Local T-Bank operations read-path.
  • Device-level sessions, refresh-token rotation и reuse detection.
  • Ledger/financial data model migration.
  • Rate limiting, CSRF и security headers, если они требуют отдельной threat model или middleware policy.
  • Декомпозиция PortfolioService или tbank/ на новые модули без отдельного плана.

Источники

  • docs/research/2026-06-25-backend-audit.md
  • docs/features/backend-architecture-improvements/spec.md
  • docs/features/moex-client-split/spec.md
  • docs/features/api-envelope-contract/spec.md
  • docs/inbox.md — раздел «Технический долг — кандидат на следующую итерацию»