fix: make backend local verification safe
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -21,16 +21,31 @@
|
||||
<!--[](https://opencollective.com/nest#backer)
|
||||
[](https://opencollective.com/nest#sponsor)-->
|
||||
|
||||
## 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
|
||||
|
||||
+8
-1
@@ -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",
|
||||
|
||||
@@ -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<Pick<TbankClient, 'validateToken'>> = {
|
||||
validateToken: jest.fn(),
|
||||
};
|
||||
const portfolio = { invalidate: jest.fn() };
|
||||
const service = new TbankConnectionService(
|
||||
prisma as never,
|
||||
|
||||
@@ -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<TbankClient, 'validateToken'>;
|
||||
|
||||
@Injectable()
|
||||
export class TbankConnectionService {
|
||||
private readonly crypto: TbankCrypto;
|
||||
@@ -13,7 +15,7 @@ export class TbankConnectionService {
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
config: ConfigService<Environment, true>,
|
||||
private readonly tbank: TbankClient,
|
||||
@Inject(TbankClient) private readonly tbank: TbankTokenValidator,
|
||||
private readonly portfolio: PortfolioService,
|
||||
) {
|
||||
this.crypto = TbankCrypto.fromBase64(
|
||||
|
||||
@@ -37,7 +37,10 @@ const instrumentCacheTtlMs = 24 * 60 * 60_000;
|
||||
@Injectable()
|
||||
export class UpcomingEventsService {
|
||||
private readonly crypto: TbankCrypto;
|
||||
private readonly dividendCache = new Map<string, CachedEntry<TbankDividend[]>>();
|
||||
private readonly dividendCache = new Map<
|
||||
string,
|
||||
CachedEntry<TbankDividend[]>
|
||||
>();
|
||||
private readonly instrumentCache = new Map<
|
||||
string,
|
||||
CachedEntry<TbankInstrument | null>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"incremental": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/**/*.spec.ts", "test", "node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"incremental": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "test/**/*.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user