refactor: share tbank-sync claim and generation lock (WealthLedger/backend#166) (#188)
Backend verify / commits (push) Skipped
Backend verify / security (push) Successful in 1m9s
Backend verify / verify (push) Failing after 7m40s

This commit was merged in pull request #188.
This commit is contained in:
2026-11-04 20:47:50 +03:00
parent c5ccfeadea
commit 5d31b3e6dd
8 changed files with 167 additions and 206 deletions
@@ -12,6 +12,7 @@ import type { TbankInstrument } from './tbank.client';
import { PrismaService } from '../../prisma/prisma.service';
import { isJoinableRunningAttempt, type TbankSyncAttempt } from './tbank-access.service';
import { TbankErrorCode } from './tbank-error-code';
import { claimSyncWork, lockConnectionGeneration } from './tbank-sync-claim';
const FIRST_BATCH_OFFSET = 0;
const UNCHANGED_REVISION_INCREMENT = 0;
@@ -119,11 +120,8 @@ export class InstrumentMetadataRepository {
active: ReadonlySet<string>,
) {
return this.prisma.$transaction(async (tx) => {
const valid = await tx.tbankConnection.updateMany({
where: { ...attemptOwner, invalidToken: false },
data: { membershipRevision: { increment: 0 } },
});
if (!valid.count) return null;
const valid = await lockConnectionGeneration(tx, attemptOwner);
if (!valid) return null;
const scope = {
...attemptOwner,
scopeKey: `metadata:${metadataKey(identity)}`,
@@ -167,15 +165,11 @@ export class InstrumentMetadataRepository {
publish(attempt: TbankSyncAttempt, results: MetadataLookup[], now: Date) {
return this.prisma.$transaction(async (tx) => {
const claimed = await tx.tbankSyncWork.updateMany({
where: {
...attempt,
state: 'running',
connection: { invalidToken: false },
},
data: { state: 'complete', progress: {} },
const claimed = await claimSyncWork(tx, attempt, {
state: 'complete',
progress: {},
});
if (!claimed.count) return false;
if (!claimed) return false;
const aliases = new Map(
results.map((result) => [`${result.type}:${result.id}`, result]),
);
@@ -264,18 +258,17 @@ export class InstrumentMetadataRepository {
}
async finishObserver(attempt: TbankSyncAttempt, success: boolean) {
await this.prisma.tbankSyncWork.updateMany({
where: {
...attempt,
state: 'running',
...(success ? { connection: { invalidToken: false } } : {}),
},
data: {
await claimSyncWork(
this.prisma,
attempt,
{
state: success ? 'complete' : 'failed',
errorCode: success ? null : TbankErrorCode.Unavailable,
},
});
{ withoutConnectionFence: !success },
);
if (success) {
// Fails sibling attempts whose connection was invalidated mid-flight.
await this.prisma.tbankSyncWork.updateMany({
where: {
...attempt,