moex-vibe/apps/backend/src/modules/tbank/services/broker-accounts.service.ts
Sergey Krylov feaff2103e perf(broker): parallel instrument name loading with per-service rate limit queues
- Split single p-queue (5 req/s) into 3 isolated queues:
  operations (5/s), instruments (20/s), users (5/s)
- Removed dead instruments param from mapBrokerPortfolio
- portfolio/positions endpoints share raw GetPortfolio cache
- Docs: T_BANK_INSTRUMENTS_RATE_LIMIT, CACHE_TBANK_POSITIONS_TTL,
  rate limiting section in tbank-invest.md
2026-06-18 06:34:55 +03:00

56 lines
1.7 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { CacheService } from '../../cache/cache.service';
import { isSupportedBrokerAccount, mapAccount } from '../mappers/account.mapper';
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';
@Injectable()
export class BrokerAccountsService {
constructor(
private readonly tbankClient: TBankClientService,
private readonly cacheService: CacheService,
) {}
async findAll(): Promise<{
data: BrokerAccount[];
meta: { fromCache: boolean; cachedAt: string | null };
}> {
const result = await this.cacheService.getOrFetch(
TBANK_CACHE_KEYS.accounts,
['open-brokerage-iis'],
() => this.fetchAccounts(),
'tbankAccountsTtl',
);
return {
data: result.data,
meta: { fromCache: result.fromCache, cachedAt: result.cachedAt },
};
}
async findById(accountId: string): Promise<BrokerAccount | null> {
const accounts = await this.findAll();
return accounts.data.find((account) => account.id === accountId) ?? null;
}
private async fetchAccounts(): Promise<BrokerAccount[]> {
const usersClient = this.tbankClient.getServiceClient('UsersService') as any;
const response = await this.tbankClient.callUnary<
Record<string, string>,
TBankAccountsResponse
>(
'UsersService/GetAccounts',
usersClient.getAccounts.bind(usersClient),
{
status: 'ACCOUNT_STATUS_OPEN',
},
'users',
);
return (response.accounts ?? []).filter(isSupportedBrokerAccount).map(mapAccount);
}
}