From b092caf8d6e8ab46c1416f1ab2e295a21133de9d Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 24 Jun 2026 19:39:30 +0300 Subject: [PATCH] feat: migrate services to ApiEnvelopePayload, controllers to plain returns --- .../src/modules/auth/auth.controller.ts | 41 +++---------------- .../src/modules/bonds/bonds.service.ts | 28 +++++++------ .../src/modules/candles/candles.service.ts | 10 +++-- .../modules/portfolio/portfolio.controller.ts | 33 +++++---------- .../securities/securities.controller.ts | 6 +-- .../src/modules/shares/shares.controller.ts | 3 +- .../src/modules/shares/shares.service.ts | 28 +++++++------ .../tbank/services/broker-accounts.service.ts | 11 ++--- .../services/broker-analytics.service.ts | 11 ++--- .../tbank/services/broker-events.service.ts | 11 ++--- .../services/broker-operations.service.ts | 11 ++--- .../services/broker-portfolio.service.ts | 21 +++------- .../src/modules/tbank/tbank.controller.ts | 22 ++++------ 13 files changed, 82 insertions(+), 154 deletions(-) diff --git a/apps/backend/src/modules/auth/auth.controller.ts b/apps/backend/src/modules/auth/auth.controller.ts index d933b34..035441b 100644 --- a/apps/backend/src/modules/auth/auth.controller.ts +++ b/apps/backend/src/modules/auth/auth.controller.ts @@ -41,13 +41,7 @@ export class AuthController { async register(@Body() dto: RegisterDto, @Res({ passthrough: true }) res: Response) { const result = await this.authService.register(dto); res.cookie(REFRESH_COOKIE, result.refreshToken, COOKIE_OPTIONS); - return { - data: { - user: result.user, - accessToken: result.accessToken, - }, - meta: { fromCache: false, cachedAt: null }, - }; + return { user: result.user, accessToken: result.accessToken }; } @Public() @@ -57,13 +51,7 @@ export class AuthController { async login(@Body() dto: LoginDto, @Res({ passthrough: true }) res: Response) { const result = await this.authService.login(dto); res.cookie(REFRESH_COOKIE, result.refreshToken, COOKIE_OPTIONS); - return { - data: { - user: result.user, - accessToken: result.accessToken, - }, - meta: { fromCache: false, cachedAt: null }, - }; + return { user: result.user, accessToken: result.accessToken }; } @Public() @@ -75,13 +63,7 @@ export class AuthController { const token = req.cookies?.[REFRESH_COOKIE]; const result = await this.authService.refresh(token); res.cookie(REFRESH_COOKIE, result.refreshToken, COOKIE_OPTIONS); - return { - data: { - user: result.user, - accessToken: result.accessToken, - }, - meta: { fromCache: false, cachedAt: null }, - }; + return { user: result.user, accessToken: result.accessToken }; } @Post('logout') @@ -92,10 +74,7 @@ export class AuthController { async logout(@CurrentUser() user: JwtPayload, @Res({ passthrough: true }) res: Response) { await this.authService.logout(user.sub); res.clearCookie(REFRESH_COOKIE, { path: '/api/v1/auth' }); - return { - data: { message: 'Logged out successfully' }, - meta: { fromCache: false, cachedAt: null }, - }; + return { message: 'Logged out successfully' }; } @Get('me') @@ -103,11 +82,7 @@ export class AuthController { @ApiOperation({ summary: 'Get current user profile' }) @ApiOkResponse({ type: AuthProfileResponseDto }) async getProfile(@CurrentUser() user: JwtPayload) { - const profile = await this.authService.getProfile(user.sub); - return { - data: profile, - meta: { fromCache: false, cachedAt: null }, - }; + return this.authService.getProfile(user.sub); } @Patch('me') @@ -115,10 +90,6 @@ export class AuthController { @ApiOperation({ summary: 'Update current user profile' }) @ApiOkResponse({ type: AuthProfileResponseDto }) async updateProfile(@CurrentUser() user: JwtPayload, @Body() dto: UpdateProfileDto) { - const profile = await this.authService.updateProfile(user.sub, dto); - return { - data: profile, - meta: { fromCache: false, cachedAt: null }, - }; + return this.authService.updateProfile(user.sub, dto); } } diff --git a/apps/backend/src/modules/bonds/bonds.service.ts b/apps/backend/src/modules/bonds/bonds.service.ts index 6ccd3f7..407451b 100644 --- a/apps/backend/src/modules/bonds/bonds.service.ts +++ b/apps/backend/src/modules/bonds/bonds.service.ts @@ -1,6 +1,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { MoexClientService } from '../moex-client/moex-client.service'; import { CacheService } from '../cache/cache.service'; +import { ApiEnvelopePayload } from '../../common/dto/api-response.dto'; @Injectable() export class BondsService { @@ -32,8 +33,8 @@ export class BondsService { 'marketDataTtl', ); - return { - data: { + return new ApiEnvelopePayload( + { secid: bond.secid, isin: bond.isin, name: bond.shortName, @@ -70,8 +71,9 @@ export class BondsService { : new Date().toISOString(), }, }, - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } async getMarketData(secid: string) { @@ -90,8 +92,8 @@ export class BondsService { throw new NotFoundException(`Market data for bond ${secid} not found`); } - return { - data: { + return new ApiEnvelopePayload( + { price: mkt.last ?? 0, yieldToMaturity: mkt.yield ?? null, duration: mkt.duration ?? null, @@ -107,8 +109,9 @@ export class BondsService { ? new Date().toISOString().split('T')[0] + 'T' + mkt.updateTime : new Date().toISOString(), }, - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } async getHistory(secid: string, from: string, till: string) { @@ -119,14 +122,15 @@ export class BondsService { 'historyTtl', ); - return { - data: data.map((h) => ({ + return new ApiEnvelopePayload( + data.map((h) => ({ date: h.tradeDate, closePrice: h.legalClosePrice ?? h.close ?? 0, yieldClose: h.yieldClose ?? null, duration: h.duration ?? null, })), - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } } diff --git a/apps/backend/src/modules/candles/candles.service.ts b/apps/backend/src/modules/candles/candles.service.ts index 0cb4ae4..15feada 100644 --- a/apps/backend/src/modules/candles/candles.service.ts +++ b/apps/backend/src/modules/candles/candles.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { MoexClientService } from '../moex-client/moex-client.service'; import { CacheService } from '../cache/cache.service'; import { CandleInterval } from './dto/candles-query.dto'; +import { ApiEnvelopePayload } from '../../common/dto/api-response.dto'; @Injectable() export class CandlesService { @@ -29,8 +30,8 @@ export class CandlesService { 'candlesTtl', ); - return { - data: data.map((c) => ({ + return new ApiEnvelopePayload( + data.map((c) => ({ open: c.open, high: c.high, low: c.low, @@ -40,7 +41,8 @@ export class CandlesService { begin: c.begin, end: c.end, })), - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } } diff --git a/apps/backend/src/modules/portfolio/portfolio.controller.ts b/apps/backend/src/modules/portfolio/portfolio.controller.ts index 9632fe6..c9badd4 100644 --- a/apps/backend/src/modules/portfolio/portfolio.controller.ts +++ b/apps/backend/src/modules/portfolio/portfolio.controller.ts @@ -26,12 +26,8 @@ import { const nullDataEnvelopeSchema = { type: 'object', properties: { - data: { - type: 'null', - }, - meta: { - $ref: getSchemaPath(PortfolioResponseMetaDto), - }, + data: { type: 'null' }, + meta: { $ref: getSchemaPath(PortfolioResponseMetaDto) }, }, required: ['data', 'meta'], }; @@ -47,24 +43,21 @@ export class PortfolioController { @ApiOperation({ summary: 'Get all portfolios for current user' }) @ApiOkResponse({ type: PortfolioListEnvelopeDto }) async findAll(@CurrentUser() user: { sub: number }) { - const portfolios = await this.portfolioService.findAll(user.sub); - return { data: portfolios, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.findAll(user.sub); } @Post() @ApiOperation({ summary: 'Create a new portfolio' }) @ApiCreatedResponse({ type: PortfolioEnvelopeDto }) async create(@CurrentUser() user: { sub: number }, @Body() dto: CreatePortfolioDto) { - const portfolio = await this.portfolioService.create(user.sub, dto); - return { data: portfolio, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.create(user.sub, dto); } @Get(':id') @ApiOperation({ summary: 'Get portfolio details with positions and prices' }) @ApiOkResponse({ type: PortfolioDetailEnvelopeDto }) async findOne(@CurrentUser() user: { sub: number }, @Param('id', ParseIntPipe) id: number) { - const portfolio = await this.portfolioService.findOne(user.sub, id); - return { data: portfolio, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.findOne(user.sub, id); } @Patch(':id') @@ -75,8 +68,7 @@ export class PortfolioController { @Param('id', ParseIntPipe) id: number, @Body() dto: UpdatePortfolioDto, ) { - const portfolio = await this.portfolioService.update(user.sub, id, dto); - return { data: portfolio, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.update(user.sub, id, dto); } @Delete(':id') @@ -84,7 +76,7 @@ export class PortfolioController { @ApiOkResponse({ schema: nullDataEnvelopeSchema }) async remove(@CurrentUser() user: { sub: number }, @Param('id', ParseIntPipe) id: number) { await this.portfolioService.remove(user.sub, id); - return { data: null, meta: { cachedAt: null, fromCache: false } }; + return null; } @Post(':id/positions') @@ -95,8 +87,7 @@ export class PortfolioController { @Param('id', ParseIntPipe) id: number, @Body() dto: AddPositionDto, ) { - const position = await this.portfolioService.addPosition(user.sub, id, dto); - return { data: position, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.addPosition(user.sub, id, dto); } @Patch(':id/positions/:positionId') @@ -108,16 +99,14 @@ export class PortfolioController { @Param('positionId', ParseIntPipe) positionId: number, @Body() dto: UpdatePositionDto, ) { - const position = await this.portfolioService.updatePosition(user.sub, id, positionId, dto); - return { data: position, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.updatePosition(user.sub, id, positionId, dto); } @Get(':id/analytics') @ApiOperation({ summary: 'Get portfolio analytics with PnL' }) @ApiOkResponse({ type: AnalyticsEnvelopeDto }) async getAnalytics(@CurrentUser() user: { sub: number }, @Param('id', ParseIntPipe) id: number) { - const result = await this.portfolioService.getAnalytics(user.sub, id); - return { data: result, meta: { cachedAt: null, fromCache: false } }; + return this.portfolioService.getAnalytics(user.sub, id); } @Delete(':id/positions/:positionId') @@ -129,6 +118,6 @@ export class PortfolioController { @Param('positionId', ParseIntPipe) positionId: number, ) { await this.portfolioService.removePosition(user.sub, id, positionId); - return { data: null, meta: { cachedAt: null, fromCache: false } }; + return null; } } diff --git a/apps/backend/src/modules/securities/securities.controller.ts b/apps/backend/src/modules/securities/securities.controller.ts index 5f17949..b1a542d 100644 --- a/apps/backend/src/modules/securities/securities.controller.ts +++ b/apps/backend/src/modules/securities/securities.controller.ts @@ -21,19 +21,17 @@ export class SecuritiesController { @ApiOperation({ summary: 'Поиск по инструментам' }) @ApiOkResponse({ type: SearchEnvelopeDto }) async search(@Query(ValidationPipe) query: SearchQueryDto) { - const results = await this.securitiesService.search( + return this.securitiesService.search( query.q, query.type || SecurityType.ALL, query.limit || 20, ); - return { data: results, meta: { cachedAt: null, fromCache: false } }; } @Get('screener') @ApiOperation({ summary: 'Фильтр ценных бумаг по параметрам' }) @ApiOkResponse({ type: ScreenerResponseDto }) async screener(@Query(ValidationPipe) query: ScreenerQueryDto) { - const result = await this.screenerService.screen(query); - return { data: result, meta: { cachedAt: null, fromCache: false } }; + return this.screenerService.screen(query); } } diff --git a/apps/backend/src/modules/shares/shares.controller.ts b/apps/backend/src/modules/shares/shares.controller.ts index 1f082c8..1b37890 100644 --- a/apps/backend/src/modules/shares/shares.controller.ts +++ b/apps/backend/src/modules/shares/shares.controller.ts @@ -19,8 +19,7 @@ export class SharesController { @ApiOperation({ summary: 'Получить спецификацию акции' }) @ApiOkResponse({ type: ShareEnvelopeDto }) async getShare(@Param('secid') secid: string) { - const share = await this.sharesService.getShare(secid); - return { data: share, meta: { cachedAt: null, fromCache: false } }; + return this.sharesService.getShare(secid); } @Get(':secid/marketdata') diff --git a/apps/backend/src/modules/shares/shares.service.ts b/apps/backend/src/modules/shares/shares.service.ts index 85e260b..e565d9e 100644 --- a/apps/backend/src/modules/shares/shares.service.ts +++ b/apps/backend/src/modules/shares/shares.service.ts @@ -1,6 +1,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { MoexClientService } from '../moex-client/moex-client.service'; import { CacheService } from '../cache/cache.service'; +import { ApiEnvelopePayload } from '../../common/dto/api-response.dto'; @Injectable() export class SharesService { @@ -77,8 +78,8 @@ export class SharesService { throw new NotFoundException(`Market data for ${secid} not found`); } - return { - data: { + return new ApiEnvelopePayload( + { price: marketData.last ?? 0, change: marketData.lastChange ?? 0, changePercent: marketData.lastChangePrcnt ?? 0, @@ -92,8 +93,9 @@ export class SharesService { ? new Date().toISOString().split('T')[0] + 'T' + marketData.updateTime : new Date().toISOString(), }, - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } async getDividends(secid: string) { @@ -104,14 +106,15 @@ export class SharesService { 'dividendsTtl', ); - return { - data: data.map((d) => ({ + return new ApiEnvelopePayload( + data.map((d) => ({ registryCloseDate: d.registryCloseDate, value: d.value, currency: d.currencyId, })), - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } async getHistory(secid: string, from: string, till: string) { @@ -122,8 +125,8 @@ export class SharesService { 'historyTtl', ); - return { - data: data.map((h) => ({ + return new ApiEnvelopePayload( + data.map((h) => ({ date: h.tradeDate, open: h.open ?? 0, high: h.high ?? 0, @@ -132,7 +135,8 @@ export class SharesService { volume: h.volume, value: h.value, })), - meta: { fromCache, cachedAt }, - }; + fromCache, + cachedAt, + ); } } diff --git a/apps/backend/src/modules/tbank/services/broker-accounts.service.ts b/apps/backend/src/modules/tbank/services/broker-accounts.service.ts index 63a03fd..4c6191d 100644 --- a/apps/backend/src/modules/tbank/services/broker-accounts.service.ts +++ b/apps/backend/src/modules/tbank/services/broker-accounts.service.ts @@ -5,6 +5,7 @@ import { TBANK_CACHE_KEYS } from '../tbank.config'; import type { BrokerAccount } from '../types/broker.types'; import type { TBankAccountsResponse } from '../types/tbank-proto.types'; import { TBankClientService } from './tbank-client.service'; +import { ApiEnvelopePayload } from '../../../common/dto/api-response.dto'; @Injectable() export class BrokerAccountsService { @@ -13,10 +14,7 @@ export class BrokerAccountsService { private readonly cacheService: CacheService, ) {} - async findAll(): Promise<{ - data: BrokerAccount[]; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + async findAll(): Promise> { const result = await this.cacheService.getOrFetch( TBANK_CACHE_KEYS.accounts, ['open-brokerage-iis'], @@ -24,10 +22,7 @@ export class BrokerAccountsService { 'tbankAccountsTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } async findById(accountId: string): Promise { diff --git a/apps/backend/src/modules/tbank/services/broker-analytics.service.ts b/apps/backend/src/modules/tbank/services/broker-analytics.service.ts index 4380b81..d21bb03 100644 --- a/apps/backend/src/modules/tbank/services/broker-analytics.service.ts +++ b/apps/backend/src/modules/tbank/services/broker-analytics.service.ts @@ -1,6 +1,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../../prisma/prisma.service'; import { CacheService } from '../../cache/cache.service'; +import { ApiEnvelopePayload } from '../../../common/dto/api-response.dto'; import { BrokerAnalyticsDto } from '../dto/broker-analytics-response.dto'; import { BrokerAccountsService } from './broker-accounts.service'; import { TBANK_CACHE_KEYS } from '../tbank.config'; @@ -41,10 +42,7 @@ export class BrokerAnalyticsService { private readonly cacheService: CacheService, ) {} - async getAnalytics(accountId: string): Promise<{ - data: BrokerAnalyticsDto; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + async getAnalytics(accountId: string): Promise> { const account = await this.accountsService.findById(accountId); if (!account) throw new NotFoundException('Broker account not found'); @@ -55,10 +53,7 @@ export class BrokerAnalyticsService { 'tbankAnalyticsTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } private async computeAnalytics(accountId: string): Promise { diff --git a/apps/backend/src/modules/tbank/services/broker-events.service.ts b/apps/backend/src/modules/tbank/services/broker-events.service.ts index ef60b52..8c3b7d4 100644 --- a/apps/backend/src/modules/tbank/services/broker-events.service.ts +++ b/apps/backend/src/modules/tbank/services/broker-events.service.ts @@ -1,6 +1,7 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { CacheService } from '../../cache/cache.service'; import { MoexClientService } from '../../moex-client/moex-client.service'; +import { ApiEnvelopePayload } from '../../../common/dto/api-response.dto'; import { TBANK_CACHE_KEYS } from '../tbank.config'; import { mapQuotationToNumber } from '../mappers/money.mapper'; import type { @@ -52,10 +53,7 @@ export class BrokerEventsService { async getEvents( accountId: string, query: BrokerEventsQuery, - ): Promise<{ - data: BrokerEventsData; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + ): Promise> { const account = await this.accountsService.findById(accountId); if (!account) throw new NotFoundException('Broker account not found'); @@ -68,10 +66,7 @@ export class BrokerEventsService { 'tbankPortfolioTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } private async buildEvents( diff --git a/apps/backend/src/modules/tbank/services/broker-operations.service.ts b/apps/backend/src/modules/tbank/services/broker-operations.service.ts index eee1792..5ab575f 100644 --- a/apps/backend/src/modules/tbank/services/broker-operations.service.ts +++ b/apps/backend/src/modules/tbank/services/broker-operations.service.ts @@ -1,5 +1,6 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { CacheService } from '../../cache/cache.service'; +import { ApiEnvelopePayload } from '../../../common/dto/api-response.dto'; import type { BrokerOperationQueryDto } from '../dto/broker-operation-query.dto'; import { mapOperationsPage } from '../mappers/operation.mapper'; import { TBANK_CACHE_KEYS } from '../tbank.config'; @@ -19,10 +20,7 @@ export class BrokerOperationsService { async getOperations( accountId: string, query: BrokerOperationQueryDto, - ): Promise<{ - data: BrokerOperationsPage; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + ): Promise> { const account = await this.accountsService.findById(accountId); if (!account) throw new NotFoundException('Broker account not found'); @@ -34,10 +32,7 @@ export class BrokerOperationsService { 'tbankOperationsTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } private buildRequest(accountId: string, query: BrokerOperationQueryDto): Record { diff --git a/apps/backend/src/modules/tbank/services/broker-portfolio.service.ts b/apps/backend/src/modules/tbank/services/broker-portfolio.service.ts index 2f6f927..7559b44 100644 --- a/apps/backend/src/modules/tbank/services/broker-portfolio.service.ts +++ b/apps/backend/src/modules/tbank/services/broker-portfolio.service.ts @@ -12,6 +12,7 @@ import type { import { BrokerAccountsService } from './broker-accounts.service'; import { BrokerInstrumentsService } from './broker-instruments.service'; import { TBankClientService } from './tbank-client.service'; +import { ApiEnvelopePayload } from '../../../common/dto/api-response.dto'; @Injectable() export class BrokerPortfolioService { @@ -22,10 +23,7 @@ export class BrokerPortfolioService { private readonly cacheService: CacheService, ) {} - async getPortfolio(accountId: string): Promise<{ - data: BrokerPortfolio; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + async getPortfolio(accountId: string): Promise> { const account = await this.accountsService.findById(accountId); if (!account) throw new NotFoundException('Broker account not found'); @@ -43,10 +41,7 @@ export class BrokerPortfolioService { 'tbankPortfolioTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } async getPositions( @@ -54,10 +49,7 @@ export class BrokerPortfolioService { cursor?: string, limit = 10, type?: string, - ): Promise<{ - data: BrokerPositionsPage; - meta: { fromCache: boolean; cachedAt: string | null }; - }> { + ): Promise> { const account = await this.accountsService.findById(accountId); if (!account) throw new NotFoundException('Broker account not found'); @@ -87,10 +79,7 @@ export class BrokerPortfolioService { 'tbankPositionsTtl', ); - return { - data: result.data, - meta: { fromCache: result.fromCache, cachedAt: result.cachedAt }, - }; + return new ApiEnvelopePayload(result.data, result.fromCache, result.cachedAt); } private async buildInstrumentMap( diff --git a/apps/backend/src/modules/tbank/tbank.controller.ts b/apps/backend/src/modules/tbank/tbank.controller.ts index 95526a0..5d3a54c 100644 --- a/apps/backend/src/modules/tbank/tbank.controller.ts +++ b/apps/backend/src/modules/tbank/tbank.controller.ts @@ -1,6 +1,5 @@ import { Controller, Get, Param, Post, Query } from '@nestjs/common'; import { ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; -import { ApiResponse } from '../../common/dto/api-response.dto'; import { Roles } from '../auth/decorators/roles.decorator'; import { BrokerAccountsEnvelopeDto, @@ -40,16 +39,14 @@ export class TBankController { @ApiOperation({ summary: 'Get open T-Bank brokerage and IIS accounts' }) @ApiOkResponse({ type: BrokerAccountsEnvelopeDto }) async getAccounts() { - const result = await this.brokerAccountsService.findAll(); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); + return this.brokerAccountsService.findAll(); } @Get('accounts/:accountId/portfolio') @ApiOperation({ summary: 'Get T-Bank broker account portfolio with cash and positions' }) @ApiOkResponse({ type: BrokerPortfolioEnvelopeDto }) async getPortfolio(@Param('accountId') accountId: string) { - const result = await this.brokerPortfolioService.getPortfolio(accountId); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); + return this.brokerPortfolioService.getPortfolio(accountId); } @Get('accounts/:accountId/positions') @@ -59,13 +56,12 @@ export class TBankController { @Param('accountId') accountId: string, @Query() query: BrokerPositionQueryDto, ) { - const result = await this.brokerPortfolioService.getPositions( + return this.brokerPortfolioService.getPositions( accountId, query.cursor, query.limit, query.type, ); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); } @Get('accounts/:accountId/operations') @@ -75,24 +71,21 @@ export class TBankController { @Param('accountId') accountId: string, @Query() query: BrokerOperationQueryDto, ) { - const result = await this.brokerOperationsService.getOperations(accountId, query); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); + return this.brokerOperationsService.getOperations(accountId, query); } @Get('accounts/:accountId/events') @ApiOperation({ summary: 'Get broker account calendar events and cashflow' }) @ApiOkResponse({ type: BrokerEventsEnvelopeDto }) async getEvents(@Param('accountId') accountId: string, @Query() query: BrokerEventsQueryDto) { - const result = await this.brokerEventsService.getEvents(accountId, query); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); + return this.brokerEventsService.getEvents(accountId, query); } @Get('accounts/:accountId/analytics') @ApiOperation({ summary: 'Get broker account profitability analytics' }) @ApiOkResponse({ type: BrokerAnalyticsEnvelopeDto }) async getAnalytics(@Param('accountId') accountId: string) { - const result = await this.brokerAnalyticsService.getAnalytics(accountId); - return new ApiResponse(result.data, result.meta.fromCache, result.meta.cachedAt); + return this.brokerAnalyticsService.getAnalytics(accountId); } @Post('accounts/:accountId/operations/sync') @@ -102,7 +95,6 @@ export class TBankController { @Param('accountId') accountId: string, @Query() query: BrokerOperationSyncQueryDto, ) { - const result = await this.brokerOperationSyncService.syncAccount(accountId, query); - return new ApiResponse(result); + return this.brokerOperationSyncService.syncAccount(accountId, query); } }