From 71d57d60bcf2186d4f8f02169d1bea4ea4d672e3 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 23 Aug 2026 21:21:17 +0300 Subject: [PATCH] fix: make backend local verification safe --- .nvmrc | 1 + AGENTS.md | 13 +++++++++-- README.md | 25 +++++++++++++++++----- package.json | 9 +++++++- src/tbank/tbank-connection.service.spec.ts | 5 ++++- src/tbank/tbank-connection.service.ts | 6 ++++-- src/tbank/upcoming-events.service.ts | 5 ++++- tsconfig.typecheck.app.json | 9 ++++++++ tsconfig.typecheck.test.json | 9 ++++++++ 9 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 .nvmrc create mode 100644 tsconfig.typecheck.app.json create mode 100644 tsconfig.typecheck.test.json diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/AGENTS.md b/AGENTS.md index ebca55b..b561cce 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,11 +7,20 @@ NestJS API WealthLedger. Все функциональные изменения ## Проверка ```bash +npm ci npm run lint -npm test -npm run build +npm run typecheck:app +npm run typecheck:test ``` +Node 22 обязателен. `npm run lint` и `npm run lint:check` не изменяют +versioned-файлы; `npm run lint:fix` — явная записывающая команда. Текущий +`npm run test:e2e` временно не является надёжным gate: WL-P2-05 отложен из-за +Prisma schema-engine failure; статус и trigger пересмотра указаны в +`../docs/development/audit-remediation.md`. +Для read-only сверки runtime OpenAPI с frontend snapshot под Node 22 запускать +из workspace `bash specs/scripts/verify-runtime-openapi.sh`. + ## Границы - Публичный HTTP API версионируется как `/api/v1`; OpenAPI из backend - источник контракта для frontend. diff --git a/README.md b/README.md index 8f0f65f..9f1d965 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,31 @@ -## Description +## WealthLedger backend -[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. - -## Project setup +NestJS API WealthLedger. Требуется Node 22. Перед первой локальной проверкой +установите зависимости строго из lockfile: ```bash -$ npm install +npm ci ``` +Проверки, не изменяющие исходники: + +```bash +npm run lint +npm run typecheck:app +npm run typecheck:test +``` + +Для явного исправления форматирования используйте `npm run lint:fix`. +`npm run test:e2e` пока не является надёжным local gate: Prisma 7.9.1 +останавливает migration до Jest; запись WL-P2-05 в +`../docs/development/audit-remediation.md` фиксирует rationale и trigger +пересмотра. + +## Запуск приложения + ## Compile and run the project ```bash diff --git a/package.json b/package.json index df8fa3a..a40108a 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "author": "", "private": true, "license": "UNLICENSED", + "engines": { + "node": "22.x" + }, "scripts": { "build": "prisma generate && nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", @@ -12,7 +15,11 @@ "start:dev": "NODE_ENV=development nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/src/main.js", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "lint": "npm run lint:check", + "lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --max-warnings=0", + "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "typecheck:app": "tsc --project tsconfig.typecheck.app.json", + "typecheck:test": "tsc --project tsconfig.typecheck.test.json", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", diff --git a/src/tbank/tbank-connection.service.spec.ts b/src/tbank/tbank-connection.service.spec.ts index 3f518ff..4a4cb83 100644 --- a/src/tbank/tbank-connection.service.spec.ts +++ b/src/tbank/tbank-connection.service.spec.ts @@ -5,6 +5,7 @@ jest.mock('../prisma/prisma.service', () => ({ })); import { TbankConnectionService } from './tbank-connection.service'; +import type { TbankClient } from './tbank.client'; describe('TbankConnectionService', () => { const prisma = { @@ -17,7 +18,9 @@ describe('TbankConnectionService', () => { const config = { getOrThrow: jest.fn(() => 'MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY='), }; - const tbank = { validateToken: jest.fn() }; + const tbank: jest.Mocked> = { + validateToken: jest.fn(), + }; const portfolio = { invalidate: jest.fn() }; const service = new TbankConnectionService( prisma as never, diff --git a/src/tbank/tbank-connection.service.ts b/src/tbank/tbank-connection.service.ts index baca1fe..8c5cfd6 100644 --- a/src/tbank/tbank-connection.service.ts +++ b/src/tbank/tbank-connection.service.ts @@ -1,4 +1,4 @@ -import { BadRequestException, Injectable } from '@nestjs/common'; +import { BadRequestException, Inject, Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Environment } from '../config/env.validation'; import { PrismaService } from '../prisma/prisma.service'; @@ -6,6 +6,8 @@ import { TbankClient } from './tbank.client'; import { TbankCrypto } from './tbank.crypto'; import { PortfolioService } from './portfolio.service'; +type TbankTokenValidator = Pick; + @Injectable() export class TbankConnectionService { private readonly crypto: TbankCrypto; @@ -13,7 +15,7 @@ export class TbankConnectionService { constructor( private readonly prisma: PrismaService, config: ConfigService, - private readonly tbank: TbankClient, + @Inject(TbankClient) private readonly tbank: TbankTokenValidator, private readonly portfolio: PortfolioService, ) { this.crypto = TbankCrypto.fromBase64( diff --git a/src/tbank/upcoming-events.service.ts b/src/tbank/upcoming-events.service.ts index 1599458..38d725d 100644 --- a/src/tbank/upcoming-events.service.ts +++ b/src/tbank/upcoming-events.service.ts @@ -37,7 +37,10 @@ const instrumentCacheTtlMs = 24 * 60 * 60_000; @Injectable() export class UpcomingEventsService { private readonly crypto: TbankCrypto; - private readonly dividendCache = new Map>(); + private readonly dividendCache = new Map< + string, + CachedEntry + >(); private readonly instrumentCache = new Map< string, CachedEntry diff --git a/tsconfig.typecheck.app.json b/tsconfig.typecheck.app.json new file mode 100644 index 0000000..98fb876 --- /dev/null +++ b/tsconfig.typecheck.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "incremental": false, + "noEmit": true + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "test", "node_modules", "dist"] +} diff --git a/tsconfig.typecheck.test.json b/tsconfig.typecheck.test.json new file mode 100644 index 0000000..1f6cc5b --- /dev/null +++ b/tsconfig.typecheck.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "incremental": false, + "noEmit": true + }, + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": ["node_modules", "dist"] +}