refactor!: support RUB only (WealthLedger/main#55)

Filter non-RUB data at ingest, collapse per-currency collections into single RUB Money, drop currency from TbankPortfolioValuePoint, remove NON_RUB_ACTIVITY and screener currency filter.

BREAKING CHANGE: per-currency API fields replaced with single RUB Money; stock screener currency param removed.
This commit is contained in:
2026-11-11 08:22:16 +03:00
parent fee61537b6
commit 3b55b611b5
60 changed files with 624 additions and 736 deletions
+17 -25
View File
@@ -218,32 +218,27 @@ describe('local accounts and portfolio HTTP (SQLite)', () => {
bondPositionCount: 0,
fundPositionCount: 0,
totalPositionCount: 1,
totalsByCurrency: [{ currency: 'RUB', value: '21.100000002' }],
cashBalances: [{ currency: 'RUB', value: '1.1' }],
totals: { currency: 'RUB', value: '21.100000002' },
cash: { currency: 'RUB', value: '1.1' },
structure: {
currencies: [{
currency: 'RUB',
totalValue: '21.100000002',
hasNegativeValues: false,
categories: [
{ type: 'STOCK', value: '20.000000002', sharePercent: '94.78673' },
{ type: 'BOND', value: '0', sharePercent: '0' },
{ type: 'OTHER', value: '0', sharePercent: '0' },
{ type: 'CASH', value: '1.1', sharePercent: '5.21327' },
],
}],
totalValue: '21.100000002',
hasNegativeValues: false,
categories: [
{ type: 'STOCK', value: '20.000000002', sharePercent: '94.78673' },
{ type: 'BOND', value: '0', sharePercent: '0' },
{ type: 'OTHER', value: '0', sharePercent: '0' },
{ type: 'CASH', value: '1.1', sharePercent: '5.21327' },
],
unvaluedCategories: [],
},
unrealizedReturnByCurrency: [
{ currency: 'RUB', absolute: '0', costBasis: '0', percent: null, partial: true },
],
unrealizedReturn: { absolute: '0', costBasis: '0', percent: null, partial: true },
});
const portfolio = await get('brokerage-accounts/account/portfolio').expect(
200,
);
expect(
(portfolio.body as PortfolioResourceDto).data?.totalsByCurrency,
).toEqual([{ currency: 'RUB', value: '21.100000002' }]);
(portfolio.body as PortfolioResourceDto).data?.totals,
).toEqual({ currency: 'RUB', value: '21.100000002' });
expect(upstream.getOpenAccounts).not.toHaveBeenCalled();
expect(upstream.getPortfolio).toHaveBeenCalledTimes(1);
expect(upstream.getInstrumentByFigi).not.toHaveBeenCalled();
@@ -315,7 +310,7 @@ describe('local accounts and portfolio HTTP (SQLite)', () => {
logoName: 'enriched.png',
quantity: '2',
});
expect(after.data?.totalsByCurrency).toEqual(before.data?.totalsByCurrency);
expect(after.data?.totals).toEqual(before.data?.totals);
expect(after.data?.lastSuccessfulAt).toBe(before.data?.lastSuccessfulAt);
expect(after.meta.dataRevision).not.toBe(before.meta.dataRevision);
expect(upstream.getPortfolio).toHaveBeenCalledTimes(1);
@@ -513,12 +508,9 @@ describe('local accounts and portfolio HTTP (SQLite)', () => {
const summaries = (await get('brokerage-accounts').expect(200))
.body as BrokerageAccountsResourceDto;
expect(summaries.data?.[0].portfolioSummary).toMatchObject({
totalsByCurrency: [{ currency: 'RUB', value: '21.1' }],
cashBalances: [{ currency: 'RUB', value: '1.1' }],
structure: { currencies: [{ currency: 'RUB' }] },
unrealizedReturnByCurrency: [
{ currency: 'RUB', absolute: '0', costBasis: '0', percent: null, partial: true },
],
totals: { currency: 'RUB', value: '21.1' },
cash: { currency: 'RUB', value: '1.1' },
unrealizedReturn: { absolute: '0', costBasis: '0', percent: null, partial: true },
stockPositionCount: 1,
bondPositionCount: 0,
fundPositionCount: 0,