53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
import type { MoexIndexClose } from '#src/integrations/moex/moex.client';
|
|
|
|
import { PrismaService } from '#src/prisma/prisma.service';
|
|
|
|
@Injectable()
|
|
export class MarketIndexRepository {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async read(secid: 'IMOEX' | 'MCFTRR', from: string, to: string) {
|
|
const [closes, state] = await Promise.all([
|
|
this.prisma.marketIndexDailyClose.findMany({
|
|
where: { secid, tradeDate: { gte: from, lte: to } },
|
|
orderBy: { tradeDate: 'asc' },
|
|
}),
|
|
this.prisma.marketIndexSyncState.findUnique({ where: { secid } }),
|
|
]);
|
|
return { closes, state };
|
|
}
|
|
|
|
async attempt(secid: 'IMOEX' | 'MCFTRR', at: Date) {
|
|
await this.prisma.marketIndexSyncState.upsert({
|
|
where: { secid }, create: { secid, lastAttemptAt: at }, update: { lastAttemptAt: at },
|
|
});
|
|
}
|
|
|
|
// coveredTo is the `till` MOEX answered for: a close for today that is not
|
|
// published yet is re-checked by the service while the last close < to.
|
|
async save(secid: 'IMOEX' | 'MCFTRR', closes: MoexIndexClose[], from: string, to: string, at: Date) {
|
|
await this.prisma.$transaction(async (tx) => {
|
|
for (const close of closes) {
|
|
await tx.marketIndexDailyClose.upsert({
|
|
where: { secid_tradeDate: { secid, tradeDate: close.tradeDate } },
|
|
create: { secid, ...close },
|
|
update: { close: close.close },
|
|
});
|
|
}
|
|
const state = await tx.marketIndexSyncState.findUniqueOrThrow({ where: { secid } });
|
|
const joined = Boolean(state.coveredFrom && state.coveredTo &&
|
|
from <= state.coveredTo && to >= state.coveredFrom);
|
|
await tx.marketIndexSyncState.update({
|
|
where: { secid },
|
|
data: {
|
|
lastSuccessAt: at,
|
|
coveredFrom: joined && state.coveredFrom && state.coveredFrom < from ? state.coveredFrom : from,
|
|
coveredTo: joined && state.coveredTo && state.coveredTo > to ? state.coveredTo : to,
|
|
},
|
|
});
|
|
});
|
|
}
|
|
}
|