feat: reconcile hourly investment resource states
This commit is contained in:
@@ -17,6 +17,10 @@ import {
|
||||
tbankSourceTtlMs,
|
||||
} from '../../../../integrations/tbank/tbank.api';
|
||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||
import {
|
||||
hourlyAttempt,
|
||||
TbankSyncRepository,
|
||||
} from '../../tbank-sync/tbank-sync.repository';
|
||||
import { portfolioStructure } from '../domain/portfolio-structure';
|
||||
import { sumMoneyByCurrency } from '../domain/portfolio-totals';
|
||||
import {
|
||||
@@ -44,12 +48,14 @@ export class PortfolioService {
|
||||
private readonly repository: PortfolioRepository,
|
||||
private readonly membership: TbankMembershipService,
|
||||
private readonly logger: StructuredLogger,
|
||||
private readonly sync: TbankSyncRepository,
|
||||
) {}
|
||||
|
||||
// Local reads never start upstream work; the hourly walk owns refreshes.
|
||||
async saved(userId: string, accountId: string) {
|
||||
const connection = await this.access.local(userId, accountId);
|
||||
const saved = await this.repository.read(userId, connection.revision);
|
||||
const hourly = await this.sync.hourly(userId);
|
||||
if (
|
||||
saved?.membershipAt &&
|
||||
accountId !== 'all' &&
|
||||
@@ -64,8 +70,10 @@ export class PortfolioService {
|
||||
fetchedAt: saved?.membershipAt ?? null,
|
||||
freshForMs: membershipFreshForMs,
|
||||
work: saved?.work.find((work) => work.scopeKey === 'membership') ?? null,
|
||||
lastAttempt: hourlyAttempt(hourly, 'membership'),
|
||||
});
|
||||
return {
|
||||
hourly,
|
||||
membership: membershipMeta,
|
||||
accounts: (saved?.accounts ?? [])
|
||||
.filter(
|
||||
@@ -95,15 +103,16 @@ export class PortfolioService {
|
||||
saved?.work.find(
|
||||
(work) => work.scopeKey === portfolioWorkKey(account.accountId),
|
||||
) ?? null,
|
||||
lastAttempt: hourlyAttempt(hourly, 'portfolio', account.accountId),
|
||||
}),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
async read(userId: string, accountId: string) {
|
||||
const saved = await this.saved(userId, accountId);
|
||||
const { hourly, ...saved } = await this.saved(userId, accountId);
|
||||
const missing =
|
||||
saved.membership.availability === 'missing' ||
|
||||
saved.membership.completeness === 'incomplete' ||
|
||||
saved.accounts.some((account) => !account.snapshot);
|
||||
const metadata = await this.metadata.savedMany(
|
||||
saved.accounts.flatMap((account) => account.snapshot?.positions ?? []),
|
||||
@@ -206,6 +215,7 @@ export class PortfolioService {
|
||||
? portfolioFreshForMs
|
||||
: membershipFreshForMs,
|
||||
work: work.id ? { ...work, id: work.id } : null,
|
||||
lastAttempt: hourlyAttempt(hourly, 'portfolio', accountId === 'all' ? undefined : accountId),
|
||||
dependencies: [
|
||||
saved.membership,
|
||||
...saved.accounts.map((account) => account.meta),
|
||||
|
||||
Reference in New Issue
Block a user