feat: add hourly portfolio sync history
Backend verify / commits (pull_request) Successful in 33s
Backend verify / security (pull_request) Failing after 12s
Backend verify / verify (pull_request) Skipped

This commit is contained in:
2026-10-09 09:04:41 +03:00
parent 03e75f8d2b
commit 0057925888
49 changed files with 1674 additions and 1870 deletions
+25 -18
View File
@@ -263,6 +263,26 @@ describe('T-Bank persisted read budget', () => {
historyBoundary: 'openedOn',
},
});
await prisma.tbankPortfolio.create({
data: {
...scope,
payload: {
lastSuccessfulAt: now.toISOString(),
isStale: false,
positions: [{
instrumentUid: instruments[0].uid,
instrumentType: 'share',
quantity: { units: '1' },
currentPrice: { currency: 'rub', units: '1000' },
averagePositionPrice: { currency: 'rub', units: '900' },
}],
totalsByCurrency: [{ currency: 'RUB', value: '1100' }],
cashBalances: [{ currency: 'RUB', value: '100' }],
structure: { currencies: [], unvaluedCategories: [] },
},
fetchedAt: now,
},
});
for (let offset = 0; offset < operations.length; offset += 1000) {
await prisma.tbankOperation.createMany({
data: operations.slice(offset, offset + 1000).map((row) => ({
@@ -348,21 +368,6 @@ describe('T-Bank persisted read budget', () => {
'/brokerage-accounts/all/operations?from=2026-08-01&to=2026-08-31&limit=50',
'/brokerage-accounts/baseline-0/income-analytics?from=2026-08-01&to=2026-08-31',
'/brokerage-accounts/all/income-analytics?from=2026-08-01&to=2026-08-31',
'/brokerage-accounts/baseline-0/events?from=2026-09-01&to=2026-10-31',
'/brokerage-accounts/all/events?from=2026-09-01&to=2026-10-31',
'/stocks?query=SYNTH',
'/bonds?query=SYNTH',
...[
['stocks', instruments[0].uid, 'dividends'],
['bonds', instruments[1].uid, 'coupons'],
].flatMap(([kind, uid, payout]) => [
`/${kind}/${uid}`,
`/${kind}/${uid}/quote`,
`/${kind}/${uid}/${kind === 'stocks' ? 'company' : 'metrics'}`,
`/${kind}/${uid}/candles?period=year`,
`/${kind}/${uid}/candles?period=all`,
`/${kind}/${uid}/${payout}`,
]),
];
async function settled() {
for (let index = 0; index < 6000; index++) {
@@ -395,7 +400,9 @@ describe('T-Bank persisted read budget', () => {
await request(app.getHttpServer())
.get(`/api/v1${route}`)
.set('Authorization', `Bearer ${token}`)
.expect(200);
.expect((response) => {
if (response.status !== 200) throw new Error(`${route}: ${JSON.stringify(response.body)}`);
});
await settled();
}
await fresh();
@@ -560,8 +567,8 @@ describe('T-Bank persisted read budget', () => {
}
const staleResponsesMs = performance.now() - startStale;
await settled();
expect(rpc.portfolio - beforeStale.portfolio).toBe(1);
expect(rpc.positions - beforeStale.positions).toBe(1);
expect((rpc.portfolio ?? 0) - (beforeStale.portfolio ?? 0)).toBe(0);
expect((rpc.positions ?? 0) - (beforeStale.positions ?? 0)).toBe(0);
await app
.get(PrismaService)
.tbankPortfolio.deleteMany({ where: { accountId: 'baseline-0' } });