feat: expose logos and ISINs for upcoming events

This commit is contained in:
2026-09-09 17:57:54 +03:00
parent a83e26e5ef
commit 33f703d9a3
3 changed files with 57 additions and 4 deletions
+6
View File
@@ -23,6 +23,12 @@ export class UpcomingEventDto {
@ApiProperty() @ApiProperty()
displayName: string; displayName: string;
@ApiProperty({ type: String, nullable: true })
isin: string | null;
@ApiProperty({ type: String, nullable: true })
logoName: string | null;
@ApiProperty({ type: MoneyDto, nullable: true }) @ApiProperty({ type: MoneyDto, nullable: true })
projectedAmount: MoneyDto | null; projectedAmount: MoneyDto | null;
} }
+47 -2
View File
@@ -62,6 +62,11 @@ describe('UpcomingEventsService', () => {
) )
.toISOString() .toISOString()
.slice(0, 10); .slice(0, 10);
tbank.getInstrumentByFigi.mockResolvedValue({
name: 'Бумага',
isin: ' RU000A0JX0J2 ',
brand: { logoName: ' instrument-logo.png ' },
});
tbank.getPortfolio.mockResolvedValue({ tbank.getPortfolio.mockResolvedValue({
positions: [ positions: [
{ {
@@ -99,17 +104,52 @@ describe('UpcomingEventsService', () => {
type: 'coupon', type: 'coupon',
projectedAmount: { currency: 'RUB', value: '7.5' }, projectedAmount: { currency: 'RUB', value: '7.5' },
dateKind: 'event', dateKind: 'event',
isin: 'RU000A0JX0J2',
logoName: 'instrument-logo.png',
}, },
{ {
type: 'dividend', type: 'dividend',
projectedAmount: { currency: 'RUB', value: '2.5' }, projectedAmount: { currency: 'RUB', value: '2.5' },
dateKind: 'registry', dateKind: 'registry',
isin: 'RU000A0JX0J2',
logoName: 'instrument-logo.png',
},
{
type: 'offer',
projectedAmount: null,
isin: 'RU000A0JX0J2',
logoName: 'instrument-logo.png',
}, },
{ type: 'offer', projectedAmount: null },
], ],
}); });
}); });
it.each([undefined, ' '])(
'keeps events without optional metadata when it is %s',
async (metadata) => {
const today = new Date().toISOString().slice(0, 10);
tbank.getPortfolio.mockResolvedValue({
positions: [
{
instrumentUid: 'bond-uid',
ticker: 'BOND',
instrumentType: 'bond',
quantity: { units: 1 },
},
],
});
tbank.getInstrumentByUid.mockResolvedValue({
name: 'Bond',
isin: metadata,
brand: { logoName: metadata },
});
moex.bondEvents.mockResolvedValue([{ type: 'offer', date: today }]);
await expect(service.get('user', 'account')).resolves.toMatchObject({
events: [{ type: 'offer', isin: null, logoName: null }],
});
},
);
it('does not read upstream data for inaccessible accounts', async () => { it('does not read upstream data for inaccessible accounts', async () => {
access.withAccount.mockRejectedValueOnce(new NotFoundException()); access.withAccount.mockRejectedValueOnce(new NotFoundException());
await expect(service.get('user', 'account')).rejects.toEqual( await expect(service.get('user', 'account')).rejects.toEqual(
@@ -145,7 +185,12 @@ describe('UpcomingEventsService', () => {
await expect(service.get('user', 'account')).resolves.toMatchObject({ await expect(service.get('user', 'account')).resolves.toMatchObject({
events: [ events: [
{ ticker: 'SBER', projectedAmount: { currency: 'RUB', value: '1' } }, {
ticker: 'SBER',
projectedAmount: { currency: 'RUB', value: '1' },
isin: null,
logoName: null,
},
], ],
}); });
expect(tbank.getInstrumentByFigi).toHaveBeenCalledWith('token', 'S'); expect(tbank.getInstrumentByFigi).toHaveBeenCalledWith('token', 'S');
+4 -2
View File
@@ -108,6 +108,8 @@ export class UpcomingEventsService {
instrumentUid: position.instrumentUid?.trim() || null, instrumentUid: position.instrumentUid?.trim() || null,
ticker: resolvedTicker, ticker: resolvedTicker,
displayName: instrument?.name?.trim() || resolvedTicker, displayName: instrument?.name?.trim() || resolvedTicker,
isin: instrument?.isin?.trim() || null,
logoName: instrument?.brand?.logoName?.trim() || null,
}; };
const quantity = decimal(position.quantity ?? {}); const quantity = decimal(position.quantity ?? {});
if (position.instrumentType?.toLowerCase() === 'share') { if (position.instrumentType?.toLowerCase() === 'share') {
@@ -181,7 +183,7 @@ export class UpcomingEventsService {
private dividend( private dividend(
metadata: Pick< metadata: Pick<
UpcomingEventDto, UpcomingEventDto,
'figi' | 'instrumentUid' | 'ticker' | 'displayName' 'figi' | 'instrumentUid' | 'ticker' | 'displayName' | 'isin' | 'logoName'
>, >,
quantity: ReturnType<typeof decimal>, quantity: ReturnType<typeof decimal>,
event: TbankDividend, event: TbankDividend,
@@ -206,7 +208,7 @@ export class UpcomingEventsService {
private bond( private bond(
metadata: Pick< metadata: Pick<
UpcomingEventDto, UpcomingEventDto,
'figi' | 'instrumentUid' | 'ticker' | 'displayName' 'figi' | 'instrumentUid' | 'ticker' | 'displayName' | 'isin' | 'logoName'
>, >,
quantity: ReturnType<typeof decimal>, quantity: ReturnType<typeof decimal>,
event: MoexBondEvent, event: MoexBondEvent,