feat: enrich ledger events with logo metadata

This commit is contained in:
2026-08-26 15:03:48 +03:00
parent f1df104462
commit 84fabd264f
9 changed files with 294 additions and 69 deletions
+41 -7
View File
@@ -9,6 +9,7 @@ import {
mapBrokerageOperation,
operationCategory,
} from './brokerage-operation.mapper';
import { InstrumentMetadataService } from './instrument-metadata.service';
import { TbankAccessService } from './tbank-access.service';
import { TbankClient } from './tbank.client';
@@ -27,6 +28,7 @@ export class BrokerageOperationsService {
private readonly access: TbankAccessService,
private readonly tbank: TbankClient,
private readonly requestContext: RequestContextService,
private readonly metadata: InstrumentMetadataService,
) {}
async get(
@@ -56,15 +58,25 @@ export class BrokerageOperationsService {
limit: query.limit ?? 100,
state: 'OPERATION_STATE_EXECUTED',
});
const items = (response.items ?? []).filter(
(item) =>
!query.categories?.length ||
query.categories.includes(operationCategory(item.type)),
);
const logoNames = new Map<string, Promise<string | null>>();
const page = {
accountId,
items: (response.items ?? [])
.filter(
(item) =>
!query.categories?.length ||
query.categories.includes(operationCategory(item.type)),
)
.map(mapBrokerageOperation),
items: await Promise.all(
items.map(async (item) => ({
...mapBrokerageOperation(item),
logoName: await this.logoName(
token,
item.instrumentUid,
item.figi,
logoNames,
),
})),
),
nextCursor: response.nextCursor || null,
hasNext: Boolean(response.hasNext),
observedAt: new Date().toISOString(),
@@ -83,6 +95,28 @@ export class BrokerageOperationsService {
to: dateBoundary(query.to, true) ?? now,
};
}
private async logoName(
token: string,
instrumentUid: string | undefined,
figi: string | undefined,
logoNames: Map<string, Promise<string | null>>,
): Promise<string | null> {
const uid = instrumentUid?.trim() || null;
const instrumentFigi = figi?.trim() || null;
const key =
uid || instrumentFigi
? JSON.stringify({ uid, figi: instrumentFigi })
: null;
if (!key) return Promise.resolve(null);
const existing = logoNames.get(key);
if (existing) return existing;
const logoName = this.metadata
.resolve(token, uid, instrumentFigi)
.then((instrument) => instrument?.brand?.logoName?.trim() || null);
logoNames.set(key, logoName);
return logoName;
}
}
function cacheKey(