refactor: retire legacy tbank-sync status and sync=observe (WealthLedger/backend#196)
Backend verify / commits (pull_request) Successful in 1m25s
Backend verify / security (pull_request) Successful in 1m8s
Backend verify / verify (pull_request) Successful in 6m20s

This commit is contained in:
2026-11-05 22:22:48 +03:00
parent 83b515a453
commit d1c5f575cf
36 changed files with 182 additions and 832 deletions
+21 -18
View File
@@ -73,13 +73,12 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
.set('Authorization', `Bearer ${auth(userId)}`)
.timeout(1500);
const events = (
observe = true,
scope = 'account',
userId = 'owner',
range = window,
) =>
get(
`brokerage-accounts/${scope}/events?from=${range.from}&to=${range.to}${observe ? '&sync=observe' : ''}`,
`brokerage-accounts/${scope}/events?from=${range.from}&to=${range.to}`,
userId,
);
const refresh = async (
@@ -278,7 +277,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
{ currency: 'RUB', value: '6' },
{ currency: 'USD', value: '20.000000002' },
]);
const all = (await events(true, 'all').expect(200))
const all = (await events('all').expect(200))
.body as UpcomingEventsResourceDto;
expect(
all.data?.events.every((event) => event.account?.id === 'account'),
@@ -327,7 +326,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
const saved = (await events().expect(200))
.body as UpcomingEventsResourceDto;
const newRange = (
await events(true, 'account', 'owner', {
await events('account', 'owner', {
from: '2099-03-01',
to: '2099-03-31',
}).expect(200)
@@ -346,7 +345,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
expect(
((await events().expect(200)).body as UpcomingEventsResourceDto).data,
).toBeNull();
await events(true, 'foreign').expect(404);
await events('foreign').expect(404);
expect(upstream.getOpenAccounts).not.toHaveBeenCalled();
});
@@ -389,7 +388,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await get(`stocks/${shareUid}/dividends`).expect(200);
await settled();
const before = (
await get(`stocks/${shareUid}/dividends?sync=observe`).expect(200)
await get(`stocks/${shareUid}/dividends`).expect(200)
).body as StockDividendsResourceDto;
expect(before.data?.dividends[0].estimatedAmount).toEqual({
currency: 'RUB',
@@ -418,7 +417,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await settled();
expect(
(
(await get(`stocks/${shareUid}/dividends?sync=observe`).expect(200))
(await get(`stocks/${shareUid}/dividends`).expect(200))
.body as StockDividendsResourceDto
).data,
).toEqual(before.data);
@@ -433,7 +432,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await get(`bonds/${bondUid}/coupons`).expect(200);
await settled();
const coupons = (
await get(`bonds/${bondUid}/coupons?sync=observe`).expect(200)
await get(`bonds/${bondUid}/coupons`).expect(200)
).body as BondCouponsResourceDto;
expect(coupons.data?.coupons[0].estimatedAmount).toEqual({
currency: 'RUB',
@@ -467,7 +466,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await portfolio([position(uid, '3', type)]);
const path = `${kind}/${uid}/${payout}`;
const read = async () =>
(await get(`${path}?sync=observe`).expect(200)).body as
(await get(`${path}`).expect(200)).body as
BondCouponsResourceDto | StockDividendsResourceDto;
await get(path).expect(200);
await settled();
@@ -614,7 +613,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await settled();
const result = (
await get(
'brokerage-accounts/account/events?from=2099-02-01&sync=observe',
'brokerage-accounts/account/events?from=2099-02-01',
).expect(200)
).body as UpcomingEventsResourceDto;
expect(result.data?.events.map((event) => event.date)).toEqual([
@@ -636,7 +635,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
const calculatedAt = full.data?.calculatedAt;
jest.clearAllMocks();
const narrow = (await events(false, 'account', 'owner', {
const narrow = (await events('account', 'owner', {
from: '2099-02-01',
to: '2099-02-10',
}).expect(200)).body as UpcomingEventsResourceDto;
@@ -656,7 +655,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
const narrowRange = { from: '2099-02-01', to: '2099-02-10' };
await refresh(narrowRange);
const narrow = (await events(true, 'account', 'owner', narrowRange).expect(
const narrow = (await events('account', 'owner', narrowRange).expect(
200,
)).body as UpcomingEventsResourceDto;
@@ -679,7 +678,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
dividendNet: { units: '10', nano: 1, currency: 'usd' },
});
const defaultEvents = async () =>
(await get('brokerage-accounts/account/events?sync=observe').expect(200))
(await get('brokerage-accounts/account/events').expect(200))
.body as UpcomingEventsResourceDto;
// Only Date is faked: the app and SQLite helpers need real timers.
const clock = (date: string) => {
@@ -724,12 +723,12 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
expect(second.data?.incomeTotalsByCurrency).toEqual([
{ currency: 'USD', value: '100.00000001' },
]);
const stale = (await events(true, 'account', 'owner', w0).expect(200))
const stale = (await events('account', 'owner', w0).expect(200))
.body as UpcomingEventsResourceDto;
expect(stale.data?.calculatedAt).toBe(second.data?.calculatedAt);
expect(stale.data?.window).toEqual(w1);
const disjoint = (
await events(true, 'account', 'owner', {
await events('account', 'owner', {
from: '2100-01-01',
to: '2100-01-31',
}).expect(200)
@@ -794,7 +793,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
await settled();
};
const latest = async () =>
(await get('brokerage-accounts/account/events?sync=observe').expect(200))
(await get('brokerage-accounts/account/events').expect(200))
.body as UpcomingEventsResourceDto;
const dividendRow = () =>
prisma.tbankInstrumentSource.findFirstOrThrow({
@@ -924,12 +923,16 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
'to=2099-13-01',
'from=2099-02-01T00:00:00Z',
'from=2099-02-28&to=2099-02-01',
'sync=invalid',
])('rejects invalid query before source reads: %s', async (query) => {
await get(`brokerage-accounts/account/events?${query}`).expect(400);
expect(upstream.getDividends).not.toHaveBeenCalled();
});
it('ignores the retired sync query parameter', async () => {
const response = await get(`brokerage-accounts/account/events?from=2099-02-01&to=2099-02-28&sync=invalid`).expect(200);
expect(response.body).toHaveProperty('meta');
});
it('uses UTC today for an end-only range and includes the entire leap day', async () => {
const today = new Date().toISOString().slice(0, 10);
await refresh({ from: today, to: '2096-02-29' });
@@ -954,7 +957,7 @@ describe('saved payout calendars and complete forecasts (SQLite HTTP)', () => {
const range = { from: '2096-02-29', to: '2096-02-29' };
await refresh(range);
jest.clearAllMocks();
const result = (await events(true, 'account', 'owner', range).expect(200))
const result = (await events('account', 'owner', range).expect(200))
.body as UpcomingEventsResourceDto;
expect(result.data?.events).toHaveLength(1);
expect(result.data?.events[0]).toMatchObject({