Sergey Krylov ccb1082535 refactor(backend): unify envelope DTOs and fix shares/bonds inconsistency
- Replace 4 duplicate meta DTOs (AuthResponseMetaDto, PortfolioResponseMetaDto,
  BrokerResponseMetaDto, ScreenerResponseMetaDto) with shared ApiResponseMeta
- Wrap shares getShare() in ApiEnvelopePayload (was raw object, unlike bonds)
- Remove unnecessary CacheModule import from securities module
- Update portfolio controller nullDataEnvelopeSchema to use shared ApiResponseMeta
- All 116 tests pass
2026-06-25 20:20:59 +03:00

2.6 KiB
Raw Blame History

Backend Architecture Improvements — Plan

Подход

Разбиваем на итерации от самых безопасных (только DTO/косметика) к самым рискованным (сплит сервисов). Каждая итерация — отдельная задача с отдельным commit'ом.

Итерации

Итерация 1: Shared envelope DTO + fixes

  1. Вынести ApiResponseMeta в common/dto/api-response.dto.ts как единый класс, убрать дубликаты *ResponseMetaDto в модулях.
  2. Убрать AuthResponseMetaDto → заменить на ApiResponseMeta.
  3. Поправить shares/shares.service.ts:getShare() — обернуть результат в ApiEnvelopePayload.
  4. Убрать лишний импорт CacheModule из securities/securities.module.ts.
  5. Убрать PortfolioResponseMetaDto и BrokerResponseMetaDto — заменить на ApiResponseMeta.

Итерация 2: Screener caching + server-side пагинация

  1. Добавить кеширование полного screener-датасета при пустом фильтре.
  2. Ключ кеша: 'screener:full' с TTL из app.cache.marketDataTtl.

Итерация 3: Domain exception hierarchy

  1. Создать common/exceptions/ с базой DomainException и конкретными классами.
  2. Обновить HttpExceptionFilter для map'инга доменных → HTTP исключений.
  3. Заменить NotFoundException на EntityNotFoundException в сервисах.

Итерация 4: Health check improvement

  1. Добавить проверки: Prisma ping, MOEX /health, T-Bank gRPC connectivity.
  2. Обновить HealthResponseDto с полем checks.

Итерация 5: RequestLoggingMiddleware через DI

  1. Перенести middleware в корректный DI-контекст через configure() в AppModule.

Итерация 6 (отдельный эпик): MoexClientService split

  1. Выделить MoexSecuritiesClient, MoexMarketDataClient, MoexCandlesClient.
  2. Общий rate limiter + circuit breaker в shared utils.

Data Flow

Controller → Service → [CacheService.getOrFetch] → [MoexClient* или TBank*] → Внешнее API
                         ↓
                    ApiEnvelopePayload<T>
                         ↓
                    TransformInterceptor → ApiResponse<T>

После итерации 1 все модули следуют этому потоку единообразно.