refactor: centralize domain values and enforce numeric lint

This commit is contained in:
2026-09-13 14:37:39 +03:00
parent 8ba005346d
commit 8637ad2f34
44 changed files with 543 additions and 174 deletions
@@ -1,10 +1,18 @@
import { BankOperationKind } from '../domain/bank-operation-kind';
import { Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import { Prisma } from '../../../../../generated/prisma/client';
import { PrismaService } from '../../../../prisma/prisma.service';
import { conflict, missing } from '../application/bank-card-input';
import {
BankErrorCode,
conflict,
missing,
} from '../application/bank-card-input';
type Tx = Prisma.TransactionClient;
const TRANSACTION_MAX_WAIT_MS = 10_000;
const TRANSACTION_TIMEOUT_MS = 15_000;
const MAX_WRITE_RETRY_COUNT = 2;
const seeds = [
'Продукты',
'Кафе',
@@ -23,8 +31,8 @@ export class BankCardsRepository {
for (let attempt = 0; ; attempt++) {
try {
return await this.prisma.$transaction(run, {
maxWait: 10000,
timeout: 15000,
maxWait: TRANSACTION_MAX_WAIT_MS,
timeout: TRANSACTION_TIMEOUT_MS,
});
} catch (error) {
const code =
@@ -36,9 +44,10 @@ export class BankCardsRepository {
code === 'P2028' ||
(error instanceof Error &&
/SQLITE_BUSY|database is locked/.test(error.message));
if ((busy || code === 'P2002') && attempt < 2) continue;
if (busy) conflict('BANK_WRITE_CONFLICT');
if (code === 'P2002') conflict('BANK_DUPLICATE_CATEGORY');
if ((busy || code === 'P2002') && attempt < MAX_WRITE_RETRY_COUNT)
continue;
if (busy) conflict(BankErrorCode.WriteConflict);
if (code === 'P2002') conflict(BankErrorCode.DuplicateCategory);
throw error;
}
}
@@ -46,7 +55,7 @@ export class BankCardsRepository {
async card(tx: Tx, userId: string, id: string, active = false) {
const card = await tx.bankCard.findFirst({ where: { id, userId } });
if (!card) return missing();
if (active && card.archivedAt) conflict('BANK_CARD_ARCHIVED');
if (active && card.archivedAt) conflict(BankErrorCode.CardArchived);
return card;
}
async operation(tx: Tx, userId: string, id: string) {
@@ -56,7 +65,7 @@ export class BankCardsRepository {
}
async seed(tx: Tx, userId: string) {
for (const [index, label] of seeds.entries()) {
const seedKey = index === 8 ? 'other' : String(index);
const seedKey = index === seeds.length - 1 ? 'other' : String(index);
if (
!(await tx.expenseCategory.findUnique({
where: { userId_seedKey: { userId, seedKey } },
@@ -85,7 +94,7 @@ export class BankCardsRepository {
userId,
deletedAt: null,
date: { gte: period.from, lte: period.to },
kind: { in: ['expense', 'refund'] },
kind: { in: [BankOperationKind.Expense, BankOperationKind.Refund] },
...(cardId ? { cardId } : {}),
},
include: { originalExpense: { select: { categoryId: true } } },