This commit was merged in pull request #154.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
jest.mock('../../../prisma/prisma.service', () => ({
|
||||
PrismaService: class {},
|
||||
}));
|
||||
|
||||
import { screenIntent } from './tbank-sync.repository';
|
||||
|
||||
describe('screen sync intent', () => {
|
||||
it('restores a persisted intent and rejects a corrupted one', () => {
|
||||
const intent = { now: '2026-11-02T00:00:00.000Z', scope: { screen: 'accounts' } };
|
||||
expect(screenIntent(intent)).toEqual(intent);
|
||||
expect(() => screenIntent({ source: 'hourly' })).toThrow('Corrupted screen sync intent');
|
||||
expect(() => screenIntent(null)).toThrow('Corrupted screen sync intent');
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,15 @@ import type { InvestmentScreenDto } from './tbank-sync.dto';
|
||||
|
||||
import { PrismaService } from '../../../prisma/prisma.service';
|
||||
export type ScreenIntent = { now: string; scope: InvestmentScreenDto };
|
||||
|
||||
// Json columns are written only by this repository; a shape check turns corruption into an explicit 500.
|
||||
export function screenIntent(value: Prisma.JsonValue): ScreenIntent {
|
||||
const intent = value as null | Partial<ScreenIntent>;
|
||||
if (typeof intent?.now !== 'string' || typeof intent.scope?.screen !== 'string') {
|
||||
throw new Error('Corrupted screen sync intent');
|
||||
}
|
||||
return intent as ScreenIntent;
|
||||
}
|
||||
export type ScreenProgress = {
|
||||
attempts?: Record<string, string>;
|
||||
children: string[];
|
||||
@@ -226,10 +235,8 @@ export class TbankSyncRepository {
|
||||
processRunId: runId,
|
||||
state: 'running',
|
||||
priority: 0,
|
||||
intent: JSON.parse(
|
||||
JSON.stringify({ source: 'hourly' }),
|
||||
) as Prisma.InputJsonObject,
|
||||
progress: { sections: [] } as unknown as Prisma.InputJsonValue,
|
||||
intent: { source: 'hourly' },
|
||||
progress: { sections: [] },
|
||||
errorCode: null,
|
||||
};
|
||||
const work = await tx.tbankSyncWork.upsert({
|
||||
|
||||
@@ -8,10 +8,7 @@ import { randomUUID } from 'node:crypto';
|
||||
import { TbankAccessService } from '../../../integrations/tbank/tbank.api';
|
||||
import { BrokerageOperationsSyncService } from '../operations/operations.api';
|
||||
import { TbankSyncStatusDto } from './tbank-sync.dto';
|
||||
import {
|
||||
type ScreenIntent,
|
||||
TbankSyncRepository,
|
||||
} from './tbank-sync.repository';
|
||||
import { screenIntent, TbankSyncRepository } from './tbank-sync.repository';
|
||||
|
||||
@Injectable()
|
||||
export class TbankSyncService {
|
||||
@@ -35,7 +32,7 @@ export class TbankSyncService {
|
||||
if (!saved.work.scopeKey.startsWith('screen:')) {
|
||||
return this.sourceStatus(userId, saved.work);
|
||||
}
|
||||
const intent = saved.work.intent as unknown as ScreenIntent;
|
||||
const intent = screenIntent(saved.work.intent);
|
||||
await this.access.local(userId, intent.scope.accountId);
|
||||
const children = await Promise.all(
|
||||
saved.children.map((child) =>
|
||||
|
||||
Reference in New Issue
Block a user