chore: strengthen backend eslint profile
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { isDeepStrictEqual } from 'node:util';
|
||||
|
||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
||||
|
||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
||||
|
||||
export type ForecastSourceVersion = {
|
||||
instrumentUid: string;
|
||||
source: string;
|
||||
kind: string;
|
||||
rangeKey: string;
|
||||
dataRevision: number;
|
||||
fetchedAt: Date;
|
||||
instrumentUid: string;
|
||||
kind: string;
|
||||
rangeKey: string;
|
||||
source: string;
|
||||
};
|
||||
const forecastSourceReadBatchSize = 100;
|
||||
|
||||
@@ -18,15 +20,15 @@ export class ForecastRepository {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
resolve(input: {
|
||||
userId: string;
|
||||
revision: string;
|
||||
membershipRevision: number;
|
||||
scopeKey: string;
|
||||
candidate?: object;
|
||||
membershipRevision: number;
|
||||
portfolioProjection: string;
|
||||
portfolios: { accountId: string; dataRevision: number }[];
|
||||
revision: string;
|
||||
scopeKey: string;
|
||||
sources: ForecastSourceVersion[];
|
||||
timestamps: { resourceKey: string; at: string }[];
|
||||
timestamps: { at: string; resourceKey: string }[];
|
||||
userId: string;
|
||||
}) {
|
||||
return this.prisma.$transaction(async (tx) => {
|
||||
const owner = { userId: input.userId, revision: input.revision };
|
||||
@@ -54,9 +56,9 @@ export class ForecastRepository {
|
||||
where: { userId_revision_scopeKey: key },
|
||||
});
|
||||
const fallback =
|
||||
previous?.membershipRevision === input.membershipRevision
|
||||
? previous
|
||||
: null;
|
||||
previous?.membershipRevision === input.membershipRevision ?
|
||||
previous :
|
||||
null;
|
||||
if (!input.candidate) return fallback;
|
||||
const portfolios = await tx.tbankPortfolio.findMany({
|
||||
where: {
|
||||
@@ -74,15 +76,16 @@ export class ForecastRepository {
|
||||
row.dataRevision === expected.dataRevision,
|
||||
),
|
||||
)
|
||||
)
|
||||
) {
|
||||
return fallback;
|
||||
}
|
||||
// Four identity parameters per source: stay below SQLite's parameter limit.
|
||||
const sources: ForecastSourceVersion[] = [];
|
||||
for (
|
||||
let offset = 0;
|
||||
offset < input.sources.length;
|
||||
offset += forecastSourceReadBatchSize
|
||||
)
|
||||
) {
|
||||
sources.push(
|
||||
...(await tx.tbankInstrumentSource.findMany({
|
||||
where: {
|
||||
@@ -106,6 +109,7 @@ export class ForecastRepository {
|
||||
},
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (
|
||||
input.sources.some(
|
||||
(expected) =>
|
||||
@@ -119,8 +123,9 @@ export class ForecastRepository {
|
||||
row.fetchedAt.valueOf() === expected.fetchedAt.valueOf(),
|
||||
),
|
||||
)
|
||||
)
|
||||
) {
|
||||
return fallback;
|
||||
}
|
||||
const revisions = JSON.parse(
|
||||
JSON.stringify({
|
||||
portfolioProjection: input.portfolioProjection,
|
||||
@@ -133,8 +138,9 @@ export class ForecastRepository {
|
||||
fallback &&
|
||||
isDeepStrictEqual(fallback.dependencyRevisions, revisions) &&
|
||||
isDeepStrictEqual(fallback.sourceTimestamps, timestamps)
|
||||
)
|
||||
) {
|
||||
return fallback;
|
||||
}
|
||||
const data = {
|
||||
membershipRevision: input.membershipRevision,
|
||||
payload: JSON.parse(
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import {
|
||||
tbankSourceTtlMs,
|
||||
tbankSourceNeedsRefresh,
|
||||
} from '../../../../integrations/tbank/tbank.api';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
||||
|
||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
||||
import type { PortfolioDto } from '../presentation/portfolio.dto';
|
||||
|
||||
import {
|
||||
tbankSourceNeedsRefresh,
|
||||
tbankSourceTtlMs,
|
||||
} from '../../../../integrations/tbank/tbank.api';
|
||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
||||
|
||||
type PortfolioAttempt = {
|
||||
id: string;
|
||||
attemptId: string;
|
||||
userId: string;
|
||||
id: string;
|
||||
revision: string;
|
||||
userId: string;
|
||||
};
|
||||
export const portfolioFreshForMs = tbankSourceTtlMs.portfolio;
|
||||
|
||||
@@ -71,8 +73,9 @@ export class PortfolioRepository {
|
||||
!force &&
|
||||
snapshot &&
|
||||
!tbankSourceNeedsRefresh('portfolio', snapshot.fetchedAt, new Date())
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const scope = { userId, revision, scopeKey: portfolioWorkKey(accountId) };
|
||||
const previous = await tx.tbankSyncWork.findUnique({
|
||||
where: { userId_revision_scopeKey: scope },
|
||||
@@ -81,8 +84,9 @@ export class PortfolioRepository {
|
||||
previous?.state === 'running' &&
|
||||
previous.processRunId === processRunId &&
|
||||
active.has(previous.attemptId)
|
||||
)
|
||||
) {
|
||||
return { work: previous, launch: false };
|
||||
}
|
||||
const data = {
|
||||
state: 'running',
|
||||
attemptId: randomUUID(),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { Money } from '../../../../common/money.types';
|
||||
|
||||
import {
|
||||
add,
|
||||
formatDecimal,
|
||||
isZero,
|
||||
multiply,
|
||||
} from '../../../../common/decimal';
|
||||
import type { Money } from '../../../../common/money.types';
|
||||
import { decimal } from '../../../../integrations/tbank/decimal';
|
||||
|
||||
import {
|
||||
TbankPortfolio,
|
||||
TbankPositions,
|
||||
|
||||
Reference in New Issue
Block a user