refactor!: simplify runtime coordination #7
Backend verify / commits (pull_request) Successful in 29s
Backend verify / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 9m36s

Keep financial ownership, atomic publication and refresh CAS.
Failed refresh leaves cookies untouched; logout still clears them.

Remove full-history candle prefetch and special metadata retries.
Use native Pino request context instead of parallel middleware.

BREAKING CHANGE: remove investment stateVersion, queued sync state,
and tbank-sync status progress/resources. Consumers must observe
resources through sync=observe with the updated frontend contract.
This commit is contained in:
2026-10-03 11:38:08 +03:00
parent 0f27da9fd1
commit d698ed9425
48 changed files with 185 additions and 925 deletions
@@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
import type { InvestmentResourceMetaDto } from '../../investment-resource.dto';
import { tbankSourceNeedsRefresh } from '../../../../integrations/tbank/tbank.api';
import { investmentResourceMeta } from '../../investment-resource.mapper';
import {
ForecastRepository,
@@ -10,7 +9,6 @@ import {
} from '../infrastructure/forecast.repository';
const MISSING_DATA_REVISION = 0;
const STALE_FRESHNESS_MS = 0;
@Injectable()
export class ForecastService {
@@ -73,23 +71,8 @@ export class ForecastService {
dependencies
.map((dependency) => dependency.sync)
.find((sync) => sync.state === 'failed');
const payload = stored ? (stored.payload as T) : null;
const data =
payload &&
'positionIsStale' in payload &&
'positionAt' in payload &&
typeof payload.positionAt === 'string'
? {
...payload,
positionIsStale: tbankSourceNeedsRefresh(
'portfolio',
new Date(payload.positionAt),
new Date(Date.now()),
),
}
: payload;
return {
data,
data: stored ? (stored.payload as T) : null,
meta: investmentResourceMeta({
resourceKey: input.scopeKey,
dataRevision: String(stored?.dataRevision ?? MISSING_DATA_REVISION),
@@ -101,10 +84,7 @@ export class ForecastService {
? 'partial'
: 'missing',
fetchedAt: first ? new Date(first) : null,
freshForMs:
data && 'positionIsStale' in data && data.positionIsStale === true
? STALE_FRESHNESS_MS
: Number.POSITIVE_INFINITY,
freshForMs: Number.POSITIVE_INFINITY,
work: work?.id ? { ...work, id: work.id } : null,
dependencies,
}),