8.0 KiB
Backend Architecture Refactor
Дата: 2026-06-25 Статус: draft
Контекст
После аудита 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 логируются, но
500response не раскрывает внутренний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/ApiResponsecontract. - Backend docs обновлены и не ссылаются на удалённый
MoexClientServiceкак primary abstraction, устаревший/operations/refreshendpoint или 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.mddocs/features/backend-architecture-improvements/spec.mddocs/features/moex-client-split/spec.mddocs/features/api-envelope-contract/spec.mddocs/inbox.md— раздел «Технический долг — кандидат на следующую итерацию»