codex/backend-architecture-improvements #47

Merged
ksv741 merged 9 commits from codex/backend-architecture-improvements into main 2026-06-25 21:09:15 +03:00
3 changed files with 30 additions and 14 deletions
Showing only changes of commit 3b919ecdc6 - Show all commits

View File

@ -29,6 +29,7 @@ export default registerAs('app', () => ({
candlesTtl: parseInt(process.env.CACHE_CANDLES_TTL || '3600', 10),
securityTtl: parseInt(process.env.CACHE_SECURITY_TTL || '86400', 10),
searchTtl: parseInt(process.env.CACHE_SEARCH_TTL || '3600', 10),
screenerTtl: parseInt(process.env.CACHE_SCREENER_TTL || '900', 10),
dividendsTtl: parseInt(process.env.CACHE_DIVIDENDS_TTL || '86400', 10),
tbankAccountsTtl: parseInt(process.env.CACHE_TBANK_ACCOUNTS_TTL || '3600', 10),
tbankPortfolioTtl: parseInt(process.env.CACHE_TBANK_PORTFOLIO_TTL || '60', 10),

View File

@ -7,24 +7,15 @@ import { ScreenerType } from './dto/screener-query.dto';
describe('ScreenerService', () => {
let service: ScreenerService;
let cache: CacheService;
const moexClient = { getShareMarketDataBatch: vi.fn(), getBondPositionDataBatch: vi.fn() };
beforeEach(async () => {
vi.clearAllMocks();
const module: TestingModule = await Test.createTestingModule({
providers: [
ScreenerService,
{
provide: MoexClientService,
useValue: {
getShareMarketDataBatch: vi.fn(),
getBondPositionDataBatch: vi.fn(),
},
},
{
provide: CacheService,
useValue: {
getOrFetch: vi.fn(),
},
},
{ provide: MoexClientService, useValue: moexClient },
{ provide: CacheService, useValue: { getOrFetch: vi.fn() } },
],
}).compile();
@ -37,6 +28,30 @@ describe('ScreenerService', () => {
});
describe('screen', () => {
it('should cache full dataset with screenerTtl config', async () => {
const mockShares = [{
secid: 'SBER', shortName: 'Sberbank', last: 250, volume: 1000000,
lastChange: 5, lastChangePrcnt: 2, issueCapitalization: 1e9,
}];
moexClient.getShareMarketDataBatch.mockResolvedValue(mockShares);
vi.mocked(cache.getOrFetch).mockImplementation(async (_prefix, _keys, fetchFn) => ({
data: await fetchFn(),
fromCache: false,
cachedAt: null,
}));
await service.screen({ type: ScreenerType.SHARE });
expect(cache.getOrFetch).toHaveBeenCalledWith(
'screener',
[ScreenerType.SHARE],
expect.any(Function),
'screenerTtl',
);
});
it('should filter and sort shares', async () => {
const mockShares = [
{

View File

@ -85,7 +85,7 @@ export class ScreenerService {
);
}
},
'marketDataTtl',
'screenerTtl',
);
return data;