refactor: replace deep imports with native node aliases (WealthLedger/backend#165) #193
+16
-2
@@ -4,6 +4,16 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"imports": {
|
||||||
|
"#generated/*": {
|
||||||
|
"development": "./dist-dev/generated/*",
|
||||||
|
"default": "./dist/generated/*"
|
||||||
|
},
|
||||||
|
"#src/*": {
|
||||||
|
"development": "./dist-dev/src/*",
|
||||||
|
"default": "./dist/src/*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "v24.22.1"
|
"node": "v24.22.1"
|
||||||
@@ -14,8 +24,8 @@
|
|||||||
"openapi:check": "npm run build && node scripts/generate-openapi.cjs --check",
|
"openapi:check": "npm run build && node scripts/generate-openapi.cjs --check",
|
||||||
"format": "npm run lint:fix",
|
"format": "npm run lint:fix",
|
||||||
"start": "nest start",
|
"start": "nest start",
|
||||||
"start:dev": "NODE_ENV=development nest start --watch --path tsconfig.dev.json",
|
"start:dev": "NODE_ENV=development NODE_OPTIONS=--conditions=development nest start --watch --path tsconfig.dev.json",
|
||||||
"start:debug": "NODE_ENV=development nest start --debug --watch --path tsconfig.dev.json",
|
"start:debug": "NODE_ENV=development NODE_OPTIONS=--conditions=development nest start --debug --watch --path tsconfig.dev.json",
|
||||||
"start:prod": "node dist/src/main.js",
|
"start:prod": "node dist/src/main.js",
|
||||||
"lint": "npm run lint:check",
|
"lint": "npm run lint:check",
|
||||||
"lint:check": "eslint . --max-warnings=0",
|
"lint:check": "eslint . --max-warnings=0",
|
||||||
@@ -131,6 +141,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"moduleNameMapper": {
|
||||||
|
"^#generated/(.*)$": "<rootDir>/../generated/$1",
|
||||||
|
"^#src/(.*)$": "<rootDir>/$1"
|
||||||
|
},
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
"js",
|
"js",
|
||||||
"json",
|
"json",
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { isDeepStrictEqual } from 'node:util';
|
|||||||
import type {
|
import type {
|
||||||
TbankInstrumentLookup as MetadataLookupRow,
|
TbankInstrumentLookup as MetadataLookupRow,
|
||||||
TbankInstrument as MetadataRow,
|
TbankInstrument as MetadataRow,
|
||||||
} from '../../../generated/prisma/client';
|
} from '#generated/prisma/client';
|
||||||
|
|
||||||
import type { TbankInstrument } from './tbank.client';
|
import type { TbankInstrument } from './tbank.client';
|
||||||
|
|
||||||
import { PrismaService } from '../../prisma/prisma.service';
|
import { PrismaService } from '../../prisma/prisma.service';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Prisma } from '../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import type { TbankSyncAttempt } from './tbank-access.service';
|
import type { TbankSyncAttempt } from './tbank-access.service';
|
||||||
|
|
||||||
const NO_UPDATED_ROWS = 0;
|
const NO_UPDATED_ROWS = 0;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jest.mock('bcrypt', () => ({
|
|||||||
compare: jest.fn(() => Promise.resolve(true)),
|
compare: jest.fn(() => Promise.resolve(true)),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class PrismaService {},
|
PrismaService: class PrismaService {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import { JwtService } from '@nestjs/jwt';
|
|||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { createHash, randomUUID } from 'crypto';
|
import { createHash, randomUUID } from 'crypto';
|
||||||
|
|
||||||
import type { Session, User } from '../../../../generated/prisma/client';
|
import type { Session, User } from '#generated/prisma/client';
|
||||||
|
|
||||||
|
import { HttpErrorCode } from '#src/common/error-code';
|
||||||
|
|
||||||
import { HttpErrorCode } from '../../../common/error-code';
|
|
||||||
import { AuthRepository } from '../infrastructure/auth.repository';
|
import { AuthRepository } from '../infrastructure/auth.repository';
|
||||||
import { AuthErrorCode } from './auth-error-code';
|
import { AuthErrorCode } from './auth-error-code';
|
||||||
import { AuthenticationResult, AuthUser, RefreshPayload } from './auth.types';
|
import { AuthenticationResult, AuthUser, RefreshPayload } from './auth.types';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { isPrismaErrorCode, PrismaErrorCode } from '../../../prisma/prisma-error-code';
|
import { isPrismaErrorCode, PrismaErrorCode } from '#src/prisma/prisma-error-code';
|
||||||
import { PrismaService } from '../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
const EXPECTED_ROTATED_SESSIONS = 1;
|
const EXPECTED_ROTATED_SESSIONS = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import { ConfigService } from '@nestjs/config';
|
|||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||||
|
|
||||||
import { HttpErrorCode } from '../../../common/error-code';
|
import { HttpErrorCode } from '#src/common/error-code';
|
||||||
import { Environment } from '../../../config/env.validation';
|
import { Environment } from '#src/config/env.validation';
|
||||||
|
|
||||||
import { AccessPayload } from '../application/auth.types';
|
import { AccessPayload } from '../application/auth.types';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import {
|
|||||||
ApiTags,
|
ApiTags,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { HttpErrorCode } from '../../../common/error-code';
|
import { HttpErrorCode } from '#src/common/error-code';
|
||||||
|
|
||||||
import { AuthService, REFRESH_TTL_MS } from '../application/auth.service';
|
import { AuthService, REFRESH_TTL_MS } from '../application/auth.service';
|
||||||
import { AccessPayload, AuthenticationResult } from '../application/auth.types';
|
import { AccessPayload, AuthenticationResult } from '../application/auth.types';
|
||||||
import { LoginDto, RegisterDto } from './auth.dto';
|
import { LoginDto, RegisterDto } from './auth.dto';
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { createHash } from 'node:crypto';
|
import { createHash } from 'node:crypto';
|
||||||
|
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MAX_CARD_NAME_LENGTH,
|
MAX_CARD_NAME_LENGTH,
|
||||||
MAX_OPERATION_DESCRIPTION_LENGTH,
|
MAX_OPERATION_DESCRIPTION_LENGTH,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import type { BankCard, Prisma } from '../../../../../generated/prisma/client';
|
import type { BankCard, Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import { bankBalance } from '../domain/bank-card.calculations';
|
import { bankBalance } from '../domain/bank-card.calculations';
|
||||||
import { rubMoney } from '../domain/rub-money';
|
import { rubMoney } from '../domain/rub-money';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { GoneException, Injectable } from '@nestjs/common';
|
|||||||
import type {
|
import type {
|
||||||
BankCardOperation,
|
BankCardOperation,
|
||||||
Prisma,
|
Prisma,
|
||||||
} from '../../../../../generated/prisma/client';
|
} from '#generated/prisma/client';
|
||||||
|
|
||||||
import { FIRST_PAGE } from '../domain/bank-card-limits';
|
import { FIRST_PAGE } from '../domain/bank-card-limits';
|
||||||
import { BankOperationKind } from '../domain/bank-operation-kind';
|
import { BankOperationKind } from '../domain/bank-operation-kind';
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
jest.mock('../../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
jest.mock('../../../../../generated/prisma/client', () => ({ Prisma: {} }));
|
jest.mock('#generated/prisma/client', () => ({ Prisma: {} }));
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
import { BankCardsRepository } from '../infrastructure/bank-cards.repository';
|
import { BankCardsRepository } from '../infrastructure/bank-cards.repository';
|
||||||
import { GetBankSummaryUseCase } from './get-bank-summary.use-case';
|
import { GetBankSummaryUseCase } from './get-bank-summary.use-case';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
|
|
||||||
import { BankOperationKind } from './bank-operation-kind';
|
import { BankOperationKind } from './bank-operation-kind';
|
||||||
import { ZERO_KOPECKS } from './rub-money';
|
import { ZERO_KOPECKS } from './rub-money';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Money } from '../../../../common/money.types';
|
import type { Money } from '#src/common/money.types';
|
||||||
|
|
||||||
import { DECIMAL_RADIX, decimalFromString, formatDecimal } from '../../../../common/decimal';
|
import { DECIMAL_RADIX, decimalFromString, formatDecimal } from '#src/common/decimal';
|
||||||
|
|
||||||
export const ZERO_KOPECKS = 0n;
|
export const ZERO_KOPECKS = 0n;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { BankCard, BankCardOperation, Prisma } from '../../../../../generated/prisma/client';
|
import { BankCard, BankCardOperation, Prisma } from '#generated/prisma/client';
|
||||||
import { isPrismaErrorCode, PrismaErrorCode } from '../../../../prisma/prisma-error-code';
|
import { isPrismaErrorCode, PrismaErrorCode } from '#src/prisma/prisma-error-code';
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BankErrorCode,
|
BankErrorCode,
|
||||||
conflict,
|
conflict,
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import {
|
|||||||
ValidateNested,
|
ValidateNested,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FIRST_PAGE,
|
FIRST_PAGE,
|
||||||
MAX_CARD_NAME_LENGTH,
|
MAX_CARD_NAME_LENGTH,
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
ApiProblemResponses,
|
ApiProblemResponses,
|
||||||
ProblemDetailsDto,
|
ProblemDetailsDto,
|
||||||
} from '../../../../common/decorators/api-safe-error-response.decorator';
|
} from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '#src/modules/auth/auth.api';
|
||||||
|
|
||||||
import { BankCardsService } from '../application/bank-cards.service';
|
import { BankCardsService } from '../application/bank-cards.service';
|
||||||
import { BankOperationsService } from '../application/bank-operations.service';
|
import { BankOperationsService } from '../application/bank-operations.service';
|
||||||
import { ExpenseCategoriesService } from '../application/expense-categories.service';
|
import { ExpenseCategoriesService } from '../application/expense-categories.service';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import { InvestmentResourceMetaDto } from '../investment-resource.dto';
|
import { InvestmentResourceMetaDto } from '../investment-resource.dto';
|
||||||
import { PortfolioStructureDto } from '../portfolio/portfolio.api';
|
import { PortfolioStructureDto } from '../portfolio/portfolio.api';
|
||||||
import { HourlySyncStatusDto } from '../tbank-sync/tbank-sync.dto';
|
import { HourlySyncStatusDto } from '../tbank-sync/tbank-sync.dto';
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import type { Request } from 'express';
|
|||||||
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
|
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
||||||
import { BrokerageAccountsResourceDto } from './brokerage-account.dto';
|
import { BrokerageAccountsResourceDto } from './brokerage-account.dto';
|
||||||
import { BrokerageAccountsService } from './brokerage-accounts.service';
|
import { BrokerageAccountsService } from './brokerage-accounts.service';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { PortfolioModule } from '../portfolio/portfolio.module';
|
import { PortfolioModule } from '../portfolio/portfolio.module';
|
||||||
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
import { investmentResourceMeta } from '../investment-resource.mapper';
|
import { investmentResourceMeta } from '../investment-resource.mapper';
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import {
|
|||||||
formatDecimal,
|
formatDecimal,
|
||||||
isZero,
|
isZero,
|
||||||
multiply,
|
multiply,
|
||||||
} from '../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
|
|
||||||
import { investmentResourceMeta } from '../investment-resource.mapper';
|
import { investmentResourceMeta } from '../investment-resource.mapper';
|
||||||
import { sumMoneyByCurrency } from '../portfolio/domain/portfolio-totals';
|
import { sumMoneyByCurrency } from '../portfolio/domain/portfolio-totals';
|
||||||
import { PortfolioPositionDto, PortfolioService } from '../portfolio/portfolio.api';
|
import { PortfolioPositionDto, PortfolioService } from '../portfolio/portfolio.api';
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import type { Request } from 'express';
|
|||||||
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
|
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
||||||
import { InvestmentReadQueryDto } from '../investment-resource.dto';
|
import { InvestmentReadQueryDto } from '../investment-resource.dto';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsOptional, Matches } from 'class-validator';
|
import { IsOptional, Matches } from 'class-validator';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InvestmentDependencyDto,
|
InvestmentDependencyDto,
|
||||||
InvestmentReadQueryDto,
|
InvestmentReadQueryDto,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
jest.mock('../operations/application/brokerage-operations.service', () => ({
|
jest.mock('../operations/application/brokerage-operations.service', () => ({
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import {
|
|||||||
compare,
|
compare,
|
||||||
decimalFromString,
|
decimalFromString,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
} from '../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { isTbankProtocolValue, TbankOperationType } from '../../../integrations/tbank/tbank-protocol';
|
import { isTbankProtocolValue, TbankOperationType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
|
|
||||||
import { DateOnlyRange, moscowDate } from '../investment-calendar';
|
import { DateOnlyRange, moscowDate } from '../investment-calendar';
|
||||||
import { investmentResourceMeta } from '../investment-resource.mapper';
|
import { investmentResourceMeta } from '../investment-resource.mapper';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
|
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_DAY } from '../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_DAY } from '#src/common/time';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DateOnlyRange,
|
DateOnlyRange,
|
||||||
dateParts,
|
dateParts,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ jest.mock('../infrastructure/candle.repository', () => ({
|
|||||||
jest.mock('./catalog-enrichment.service', () => ({
|
jest.mock('./catalog-enrichment.service', () => ({
|
||||||
CatalogEnrichmentService: class {},
|
CatalogEnrichmentService: class {},
|
||||||
}));
|
}));
|
||||||
jest.mock('../../../../integrations/tbank/tbank.api', () => ({
|
jest.mock('#src/integrations/tbank/tbank.api', () => ({
|
||||||
TbankAccessService: class {},
|
TbankAccessService: class {},
|
||||||
TbankClient: class {},
|
TbankClient: class {},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,15 +5,16 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { MILLISECONDS_PER_DAY } from '../../../../common/time';
|
import { MILLISECONDS_PER_DAY } from '#src/common/time';
|
||||||
import { isTbankErrorCode, TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { isTbankErrorCode, TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import {
|
import {
|
||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
TbankClient,
|
TbankClient,
|
||||||
type TbankShare,
|
type TbankShare,
|
||||||
type TbankSyncAttempt,
|
type TbankSyncAttempt,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import {
|
import {
|
||||||
candleGaps,
|
candleGaps,
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
TbankClient,
|
TbankClient,
|
||||||
tbankSourceTtlMs,
|
tbankSourceTtlMs,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import { InstrumentErrorCode } from '../domain/instrument-error-code';
|
import { InstrumentErrorCode } from '../domain/instrument-error-code';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { isTbankErrorCode, TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { isTbankErrorCode, TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import {
|
import {
|
||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
TbankClient,
|
TbankClient,
|
||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
tbankSourceNeedsRefresh,
|
tbankSourceNeedsRefresh,
|
||||||
tbankSourceTtlMs,
|
tbankSourceTtlMs,
|
||||||
type TbankSyncAttempt,
|
type TbankSyncAttempt,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import {
|
import {
|
||||||
CatalogDiscoveryRepository,
|
CatalogDiscoveryRepository,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { TbankShare } from '../../../../integrations/tbank/tbank.api';
|
import type { TbankShare } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { TbankInstrumentType } from '../../../../integrations/tbank/tbank-protocol';
|
import { TbankInstrumentType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
|
|
||||||
export const catalogSearchLimit = 30;
|
export const catalogSearchLimit = 30;
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import {
|
import {
|
||||||
decimalFromString,
|
decimalFromString,
|
||||||
divide,
|
divide,
|
||||||
} from '../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import {
|
import {
|
||||||
MILLISECONDS_PER_DAY,
|
MILLISECONDS_PER_DAY,
|
||||||
MILLISECONDS_PER_SECOND,
|
MILLISECONDS_PER_SECOND,
|
||||||
} from '../../../../common/time';
|
} from '#src/common/time';
|
||||||
import { type MoexBondEvent, MoexClient } from '../../../../integrations/moex/moex.api';
|
import { type MoexBondEvent, MoexClient } from '#src/integrations/moex/moex.api';
|
||||||
import { NcrRatingsClient } from '../../../../integrations/ncr/ncr.api';
|
import { NcrRatingsClient } from '#src/integrations/ncr/ncr.api';
|
||||||
import {
|
import {
|
||||||
type TbankBond,
|
type TbankBond,
|
||||||
type TbankCandle,
|
type TbankCandle,
|
||||||
@@ -20,7 +20,8 @@ import {
|
|||||||
type TbankLastPrice,
|
type TbankLastPrice,
|
||||||
type TbankShare,
|
type TbankShare,
|
||||||
type TbankSyncAttempt,
|
type TbankSyncAttempt,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { candleGaps, utcDay } from '../domain/candle-coverage';
|
import { candleGaps, utcDay } from '../domain/candle-coverage';
|
||||||
import { CandleRepository } from '../infrastructure/candle.repository';
|
import { CandleRepository } from '../infrastructure/candle.repository';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type {
|
import type {
|
||||||
TbankCandle,
|
TbankCandle,
|
||||||
TbankTimestamp,
|
TbankTimestamp,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_SECOND } from '../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_SECOND } from '#src/common/time';
|
||||||
|
|
||||||
const MIN_TIMESTAMP_SECONDS_EXCLUSIVE = 0;
|
const MIN_TIMESTAMP_SECONDS_EXCLUSIVE = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import {
|
|||||||
divide,
|
divide,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
} from '../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { MoneyDto } from '../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PortfolioDto,
|
PortfolioDto,
|
||||||
PortfolioPositionDto,
|
PortfolioPositionDto,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
TbankBond,
|
TbankBond,
|
||||||
TbankShare,
|
TbankShare,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { publicInstrument } from './public-instrument';
|
import { publicInstrument } from './public-instrument';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
TbankBond,
|
TbankBond,
|
||||||
TbankShare,
|
TbankShare,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
export function publicInstrument(value: TbankBond | TbankShare) {
|
export function publicInstrument(value: TbankBond | TbankShare) {
|
||||||
const bond = value as TbankBond;
|
const bond = value as TbankBond;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import type { TbankBond } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankBond } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
|
import { formatDecimal } from '#src/common/decimal';
|
||||||
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import { formatDecimal } from '../../../../../common/decimal';
|
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
|
||||||
import { CatalogDiscoveryService } from '../../application/catalog-discovery.service';
|
import { CatalogDiscoveryService } from '../../application/catalog-discovery.service';
|
||||||
import { timestamp } from '../../application/instrument-market';
|
import { timestamp } from '../../application/instrument-market';
|
||||||
import {
|
import {
|
||||||
@@ -14,7 +15,8 @@ import {
|
|||||||
|
|
||||||
type IdentifiedBond = TbankBond & { uid: string };
|
type IdentifiedBond = TbankBond & { uid: string };
|
||||||
|
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
|
|
||||||
import { money } from '../infrastructure/bond-money.mapper';
|
import { money } from '../infrastructure/bond-money.mapper';
|
||||||
|
|
||||||
const MIN_LOT_EXCLUSIVE = 0;
|
const MIN_LOT_EXCLUSIVE = 0;
|
||||||
|
|||||||
@@ -5,19 +5,20 @@ import {
|
|||||||
divide,
|
divide,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
} from '../../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
import { isTbankProtocolValue, TbankCouponType } from '../../../../../integrations/tbank/tbank-protocol';
|
import { isTbankProtocolValue, TbankCouponType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
import {
|
import {
|
||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
type TbankBond,
|
type TbankBond,
|
||||||
type TbankCoupon,
|
type TbankCoupon,
|
||||||
tbankSourceNeedsRefresh,
|
tbankSourceNeedsRefresh,
|
||||||
} from '../../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import {
|
import {
|
||||||
ForecastService,
|
ForecastService,
|
||||||
PortfolioService,
|
PortfolioService,
|
||||||
} from '../../../portfolio/portfolio.api';
|
} from '#src/modules/investments/portfolio/portfolio.api';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CatalogEnrichmentService,
|
CatalogEnrichmentService,
|
||||||
type CatalogPayload,
|
type CatalogPayload,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import type { TbankBond } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankBond } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
@@ -9,9 +9,10 @@ import {
|
|||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
subtract,
|
subtract,
|
||||||
} from '../../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import { CandleService } from '../../application/candle.service';
|
import { CandleService } from '../../application/candle.service';
|
||||||
import {
|
import {
|
||||||
CatalogEnrichmentService,
|
CatalogEnrichmentService,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { PortfolioDto } from '../../../portfolio/portfolio.api';
|
import type { PortfolioDto } from '#src/modules/investments/portfolio/portfolio.api';
|
||||||
|
|
||||||
import { instrumentPosition } from '../../application/instrument-position';
|
import { instrumentPosition } from '../../application/instrument-position';
|
||||||
import { bondCoupons, bondMetrics } from './bond-income.service';
|
import { bondCoupons, bondMetrics } from './bond-income.service';
|
||||||
import { bondQuote } from './bond-market.service';
|
import { bondQuote } from './bond-market.service';
|
||||||
jest.mock('../../../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
const time = (value: string) => ({ seconds: String(Date.parse(value) / 1000) });
|
const time = (value: string) => ({ seconds: String(Date.parse(value) / 1000) });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { formatDecimal } from '../../../../../common/decimal';
|
import { formatDecimal } from '#src/common/decimal';
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
import { type TbankMoney } from '../../../../../integrations/tbank/tbank.api';
|
import { type TbankMoney } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
export function money(value?: TbankMoney) {
|
export function money(value?: TbankMoney) {
|
||||||
const currency = value?.currency?.toUpperCase();
|
const currency = value?.currency?.toUpperCase();
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '#src/modules/auth/auth.api';
|
||||||
import { InvestmentReadQueryDto } from '../../../investment-resource.dto';
|
import { InvestmentReadQueryDto } from '#src/modules/investments/investment-resource.dto';
|
||||||
|
|
||||||
import { BondCatalogService } from '../application/bond-catalog.service';
|
import { BondCatalogService } from '../application/bond-catalog.service';
|
||||||
import { BondIncomeService } from '../application/bond-income.service';
|
import { BondIncomeService } from '../application/bond-income.service';
|
||||||
import { BondMarketService } from '../application/bond-market.service';
|
import { BondMarketService } from '../application/bond-market.service';
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
import { InvestmentResourceMetaDto } from '../../../investment-resource.dto';
|
import { InvestmentResourceMetaDto } from '#src/modules/investments/investment-resource.dto';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StockCandlesDto,
|
StockCandlesDto,
|
||||||
StockCandlesQueryDto,
|
StockCandlesQueryDto,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MILLISECONDS_PER_DAY } from '../../../../common/time';
|
import { MILLISECONDS_PER_DAY } from '#src/common/time';
|
||||||
|
|
||||||
const FIRST_RANGE_END_INDEX = 1;
|
const FIRST_RANGE_END_INDEX = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { createHash, randomUUID } from 'node:crypto';
|
import { createHash, randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
claimSyncWork,
|
claimSyncWork,
|
||||||
lockConnectionGeneration,
|
lockConnectionGeneration,
|
||||||
} from '../../../../integrations/tbank/tbank-sync-claim';
|
} from '#src/integrations/tbank/tbank-sync-claim';
|
||||||
import {
|
import {
|
||||||
isJoinableRunningAttempt,
|
isJoinableRunningAttempt,
|
||||||
type TbankSyncAttempt,
|
type TbankSyncAttempt,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
import { toJson } from '../../../../prisma/to-json';
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type CandleRange,
|
type CandleRange,
|
||||||
confirmedCandleCoverage,
|
confirmedCandleCoverage,
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { isDeepStrictEqual } from 'node:util';
|
import { isDeepStrictEqual } from 'node:util';
|
||||||
|
|
||||||
import { TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { claimSyncWork, lockConnectionGeneration } from '../../../../integrations/tbank/tbank-sync-claim';
|
import { claimSyncWork, lockConnectionGeneration } from '#src/integrations/tbank/tbank-sync-claim';
|
||||||
import { isJoinableRunningAttempt, type TbankBond, type TbankShare, type TbankSyncAttempt } from '../../../../integrations/tbank/tbank.api';
|
import { isJoinableRunningAttempt, type TbankBond, type TbankShare, type TbankSyncAttempt } from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
import { toJson } from '../../../../prisma/to-json';
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
const UNCHANGED_REVISION_INCREMENT = 0;
|
const UNCHANGED_REVISION_INCREMENT = 0;
|
||||||
const REVISION_INCREMENT = 1;
|
const REVISION_INCREMENT = 1;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import type { TbankCandle } from '../../../../integrations/tbank/tbank.api';
|
import type { TbankCandle } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
|
import { formatDecimal } from '#src/common/decimal';
|
||||||
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import type { SavedCandle } from '../domain/candle-coverage';
|
import type { SavedCandle } from '../domain/candle-coverage';
|
||||||
|
|
||||||
import { formatDecimal } from '../../../../common/decimal';
|
|
||||||
import { decimal } from '../../../../integrations/tbank/decimal';
|
|
||||||
import { timestamp } from '../application/instrument-market';
|
import { timestamp } from '../application/instrument-market';
|
||||||
|
|
||||||
function toSavedCandle(candle: TbankCandle): SavedCandle {
|
function toSavedCandle(candle: TbankCandle): SavedCandle {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { MoexModule } from '../../../integrations/moex/moex.module';
|
import { MoexModule } from '#src/integrations/moex/moex.module';
|
||||||
import { NcrModule } from '../../../integrations/ncr/ncr.module';
|
import { NcrModule } from '#src/integrations/ncr/ncr.module';
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { CandleService } from './application/candle.service';
|
import { CandleService } from './application/candle.service';
|
||||||
import { CatalogDiscoveryService } from './application/catalog-discovery.service';
|
import { CatalogDiscoveryService } from './application/catalog-discovery.service';
|
||||||
import { CatalogEnrichmentService } from './application/catalog-enrichment.service';
|
import { CatalogEnrichmentService } from './application/catalog-enrichment.service';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { PortfolioModule } from '../portfolio/portfolio.module';
|
import { PortfolioModule } from '../portfolio/portfolio.module';
|
||||||
import { BondCatalogService } from './bonds/application/bond-catalog.service';
|
import { BondCatalogService } from './bonds/application/bond-catalog.service';
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import type { TbankFundamentals } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankFundamentals } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { CatalogEnrichmentService } from '../../application/catalog-enrichment.service';
|
import { CatalogEnrichmentService } from '../../application/catalog-enrichment.service';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import type { TbankShare } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankShare } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
|
import { formatDecimal } from '#src/common/decimal';
|
||||||
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import { formatDecimal } from '../../../../../common/decimal';
|
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
|
||||||
import { CatalogDiscoveryService } from '../../application/catalog-discovery.service';
|
import { CatalogDiscoveryService } from '../../application/catalog-discovery.service';
|
||||||
import { timestamp } from '../../application/instrument-market';
|
import { timestamp } from '../../application/instrument-market';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -4,18 +4,19 @@ import {
|
|||||||
decimalFromString,
|
decimalFromString,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
} from '../../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
import {
|
import {
|
||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
type TbankDividend,
|
type TbankDividend,
|
||||||
tbankSourceNeedsRefresh,
|
tbankSourceNeedsRefresh,
|
||||||
} from '../../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import {
|
import {
|
||||||
ForecastService,
|
ForecastService,
|
||||||
PortfolioService,
|
PortfolioService,
|
||||||
} from '../../../portfolio/portfolio.api';
|
} from '#src/modules/investments/portfolio/portfolio.api';
|
||||||
|
|
||||||
import { CatalogEnrichmentService } from '../../application/catalog-enrichment.service';
|
import { CatalogEnrichmentService } from '../../application/catalog-enrichment.service';
|
||||||
import { moscowDay, timestamp } from '../../application/instrument-market';
|
import { moscowDay, timestamp } from '../../application/instrument-market';
|
||||||
import { instrumentPosition } from '../../application/instrument-position';
|
import { instrumentPosition } from '../../application/instrument-position';
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ import {
|
|||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
subtract,
|
subtract,
|
||||||
} from '../../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
import { decimal } from '../../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import { CandleService } from '../../application/candle.service';
|
import { CandleService } from '../../application/candle.service';
|
||||||
import {
|
import {
|
||||||
CatalogEnrichmentService,
|
CatalogEnrichmentService,
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
jest.mock('../../../../../integrations/tbank/tbank.api', () => ({
|
jest.mock('#src/integrations/tbank/tbank.api', () => ({
|
||||||
TbankAccessService: class {},
|
TbankAccessService: class {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { NotFoundException, ServiceUnavailableException } from '@nestjs/common';
|
import { NotFoundException, ServiceUnavailableException } from '@nestjs/common';
|
||||||
|
|
||||||
import type { TbankShare } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankShare } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { StockScreenerService } from './stock-screener.service';
|
import { StockScreenerService } from './stock-screener.service';
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import type { TbankShare } from '../../../../../integrations/tbank/tbank-market.types';
|
import type { TbankShare } from '#src/integrations/tbank/tbank-market.types';
|
||||||
|
|
||||||
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
|
import { TbankAccessService } from '#src/integrations/tbank/tbank.api';
|
||||||
|
import { TbankClient } from '#src/integrations/tbank/tbank.client';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../../../common/logging/structured-logger.service';
|
|
||||||
import { TbankAccessService } from '../../../../../integrations/tbank/tbank.api';
|
|
||||||
import { TbankClient } from '../../../../../integrations/tbank/tbank.client';
|
|
||||||
import {
|
import {
|
||||||
selectStockScreenerInstruments,
|
selectStockScreenerInstruments,
|
||||||
type StockScreenerConditions,
|
type StockScreenerConditions,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { previousClose } from '../../application/instrument-market';
|
|||||||
import { metrics } from './get-stock-company.use-case';
|
import { metrics } from './get-stock-company.use-case';
|
||||||
import { stockDividends } from './stock-income.service';
|
import { stockDividends } from './stock-income.service';
|
||||||
import { stockQuote } from './stock-market.service';
|
import { stockQuote } from './stock-market.service';
|
||||||
jest.mock('../../../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
const time = (value: string) => ({ seconds: String(Date.parse(value) / 1000) });
|
const time = (value: string) => ({ seconds: String(Date.parse(value) / 1000) });
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import type { TbankShare } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankShare } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { selectStockScreenerInstruments } from './stock-screener-selection.rules';
|
import { selectStockScreenerInstruments } from './stock-screener-selection.rules';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { TbankShare } from '../../../../../integrations/tbank/tbank.api';
|
import type { TbankShare } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
export type StockScreenerCatalog = {
|
export type StockScreenerCatalog = {
|
||||||
asOf: Date;
|
asOf: Date;
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '#src/modules/auth/auth.api';
|
||||||
import { InvestmentReadQueryDto } from '../../../investment-resource.dto';
|
import { InvestmentReadQueryDto } from '#src/modules/investments/investment-resource.dto';
|
||||||
|
|
||||||
import { GetStockCompanyUseCase } from '../application/get-stock-company.use-case';
|
import { GetStockCompanyUseCase } from '../application/get-stock-company.use-case';
|
||||||
import { StockCatalogService } from '../application/stock-catalog.service';
|
import { StockCatalogService } from '../application/stock-catalog.service';
|
||||||
import { StockIncomeService } from '../application/stock-income.service';
|
import { StockIncomeService } from '../application/stock-income.service';
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ import {
|
|||||||
MinLength,
|
MinLength,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
import {
|
import {
|
||||||
MAX_INSTRUMENT_QUERY_LENGTH,
|
MAX_INSTRUMENT_QUERY_LENGTH,
|
||||||
MIN_INSTRUMENT_QUERY_LENGTH,
|
MIN_INSTRUMENT_QUERY_LENGTH,
|
||||||
} from '../../../instrument-query';
|
} from '#src/modules/investments/instrument-query';
|
||||||
import {
|
import {
|
||||||
InvestmentReadQueryDto,
|
InvestmentReadQueryDto,
|
||||||
InvestmentResourceMetaDto,
|
InvestmentResourceMetaDto,
|
||||||
} from '../../../investment-resource.dto';
|
} from '#src/modules/investments/investment-resource.dto';
|
||||||
import { PortfolioPositionDto } from '../../../portfolio/portfolio.api';
|
import { PortfolioPositionDto } from '#src/modules/investments/portfolio/portfolio.api';
|
||||||
|
|
||||||
const MIN_TICKER_LENGTH = 1;
|
const MIN_TICKER_LENGTH = 1;
|
||||||
const MAX_SCREENER_QUERY_LENGTH = 80;
|
const MAX_SCREENER_QUERY_LENGTH = 80;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { MILLISECONDS_PER_SECOND } from '../../../../common/time';
|
import { MILLISECONDS_PER_SECOND } from '#src/common/time';
|
||||||
import { isTbankErrorCode, TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { isTbankErrorCode, TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { TbankOperationState } from '../../../../integrations/tbank/tbank-protocol';
|
import { TbankOperationState } from '#src/integrations/tbank/tbank-protocol';
|
||||||
import { TbankAccessService, TbankClient } from '../../../../integrations/tbank/tbank.api';
|
import { TbankAccessService, TbankClient } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type OperationInterval,
|
type OperationInterval,
|
||||||
operationIntervals,
|
operationIntervals,
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import {
|
|||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
type TbankOperationItem,
|
type TbankOperationItem,
|
||||||
tbankSourceTtlMs,
|
tbankSourceTtlMs,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { dateOnlyBounds, DateOnlyRange } from '../../investment-calendar';
|
import { dateOnlyBounds, DateOnlyRange } from '../../investment-calendar';
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import { ledgerRange } from '../../investment-sync-plan';
|
import { ledgerRange } from '../../investment-sync-plan';
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { formatDecimal } from '../../../../common/decimal';
|
import { formatDecimal } from '#src/common/decimal';
|
||||||
import { MILLISECONDS_PER_SECOND } from '../../../../common/time';
|
import { MILLISECONDS_PER_SECOND } from '#src/common/time';
|
||||||
import { decimal } from '../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
import { TbankOperationType } from '../../../../integrations/tbank/tbank-protocol';
|
import { TbankOperationType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
import { TbankMoney, TbankOperationItem } from '../../../../integrations/tbank/tbank.api';
|
import { TbankMoney, TbankOperationItem } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { type OperationCategory } from '../../operation-category';
|
import { type OperationCategory } from '../../operation-category';
|
||||||
import { BrokerageOperationDto } from '../presentation/brokerage-operation.dto';
|
import { BrokerageOperationDto } from '../presentation/brokerage-operation.dto';
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -5,7 +5,8 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { createHash } from 'node:crypto';
|
import { createHash } from 'node:crypto';
|
||||||
|
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
dateOnlyBounds,
|
dateOnlyBounds,
|
||||||
DateOnlyRange,
|
DateOnlyRange,
|
||||||
|
|||||||
+8
-7
@@ -2,17 +2,18 @@ import { Injectable, NotFoundException } from '@nestjs/common';
|
|||||||
import { createHash, randomUUID } from 'node:crypto';
|
import { createHash, randomUUID } from 'node:crypto';
|
||||||
import { isDeepStrictEqual } from 'node:util';
|
import { isDeepStrictEqual } from 'node:util';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import { TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { isTbankProtocolValue, TbankOperationState } from '../../../../integrations/tbank/tbank-protocol';
|
import { isTbankProtocolValue, TbankOperationState } from '#src/integrations/tbank/tbank-protocol';
|
||||||
import { claimSyncWork, lockConnectionGeneration } from '../../../../integrations/tbank/tbank-sync-claim';
|
import { claimSyncWork, lockConnectionGeneration } from '#src/integrations/tbank/tbank-sync-claim';
|
||||||
import {
|
import {
|
||||||
isJoinableRunningAttempt,
|
isJoinableRunningAttempt,
|
||||||
type TbankOperationItem, type TbankOperationsByCursorResponse,
|
type TbankOperationItem, type TbankOperationsByCursorResponse,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
import { toJson } from '../../../../prisma/to-json';
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
decodeInterval,
|
decodeInterval,
|
||||||
extendRunningIntent,
|
extendRunningIntent,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
||||||
import { BrokerageOperationsSyncService } from './application/brokerage-operations-sync.service';
|
import { BrokerageOperationsSyncService } from './application/brokerage-operations-sync.service';
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import {
|
|||||||
Min,
|
Min,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import { AccountReferenceDto } from '../../account-reference.dto';
|
import { AccountReferenceDto } from '../../account-reference.dto';
|
||||||
import { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
import { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
||||||
import { operationCategories, type OperationCategory } from '../../operation-category';
|
import { operationCategories, type OperationCategory } from '../../operation-category';
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
jest.mock('../../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class PrismaService {},
|
PrismaService: class PrismaService {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import type { Request } from 'express';
|
|||||||
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '#src/modules/auth/auth.api';
|
||||||
|
|
||||||
import { BrokerageOperationsService } from '../application/brokerage-operations.service';
|
import { BrokerageOperationsService } from '../application/brokerage-operations.service';
|
||||||
import {
|
import {
|
||||||
BrokerageOperationsQueryDto,
|
BrokerageOperationsQueryDto,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { add, decimalFromString, formatDecimal } from '#src/common/decimal';
|
||||||
|
|
||||||
import type { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
import type { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
||||||
|
|
||||||
import { add, decimalFromString, formatDecimal } from '../../../../common/decimal';
|
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import {
|
import {
|
||||||
ForecastRepository,
|
ForecastRepository,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
jest.mock('../../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
import { PortfolioDto } from '../presentation/portfolio.dto';
|
import { PortfolioDto } from '../presentation/portfolio.dto';
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { isTbankErrorCode, TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { isTbankErrorCode, TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import {
|
import {
|
||||||
InstrumentMetadataService,
|
InstrumentMetadataService,
|
||||||
metadataKey,
|
metadataKey,
|
||||||
@@ -17,7 +17,8 @@ import {
|
|||||||
type TbankMoney,
|
type TbankMoney,
|
||||||
type TbankPortfolio,
|
type TbankPortfolio,
|
||||||
tbankSourceTtlMs,
|
tbankSourceTtlMs,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
import { investmentResourceMeta } from '../../investment-resource.mapper';
|
||||||
import {
|
import {
|
||||||
hourlyAttempt,
|
hourlyAttempt,
|
||||||
|
|||||||
+4
-3
@@ -1,8 +1,9 @@
|
|||||||
import { NotFoundException } from '@nestjs/common';
|
import { NotFoundException } from '@nestjs/common';
|
||||||
|
|
||||||
jest.mock('../../../../prisma/prisma.service', () => ({ PrismaService: class {} }));
|
jest.mock('#src/prisma/prisma.service', () => ({ PrismaService: class {} }));
|
||||||
import { TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { InstrumentIdType } from '../../../../integrations/tbank/tbank-protocol';
|
import { InstrumentIdType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
|
|
||||||
import { PositionClassificationService } from './position-classification.service';
|
import { PositionClassificationService } from './position-classification.service';
|
||||||
|
|
||||||
describe('PositionClassificationService', () => {
|
describe('PositionClassificationService', () => {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
|
||||||
import { isZero } from '../../../../common/decimal';
|
import { isZero } from '#src/common/decimal';
|
||||||
import { StructuredLogger } from '../../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { MILLISECONDS_PER_DAY } from '../../../../common/time';
|
import { MILLISECONDS_PER_DAY } from '#src/common/time';
|
||||||
import { decimal } from '../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
import { isTbankErrorCode, TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { isTbankErrorCode, TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { InstrumentIdType } from '../../../../integrations/tbank/tbank-protocol';
|
import { InstrumentIdType } from '#src/integrations/tbank/tbank-protocol';
|
||||||
import { metadataKey, TbankClient, type TbankPortfolio } from '../../../../integrations/tbank/tbank.api';
|
import { metadataKey, TbankClient, type TbankPortfolio } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { PositionClassificationRepository } from '../infrastructure/position-classification.repository';
|
import { PositionClassificationRepository } from '../infrastructure/position-classification.repository';
|
||||||
|
|
||||||
export type Classification = { issuer: null | { id: string; name: string }; sector: null | string };
|
export type Classification = { issuer: null | { id: string; name: string }; sector: null | string };
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { Money } from '../../../../common/money.types';
|
import type { Money } from '#src/common/money.types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
DECIMAL_RADIX,
|
DECIMAL_RADIX,
|
||||||
decimalFromString,
|
decimalFromString,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
} from '../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
|
|
||||||
const ZERO_AMOUNT = 0n;
|
const ZERO_AMOUNT = 0n;
|
||||||
const INITIAL_UNVALUED_COUNT = 0;
|
const INITIAL_UNVALUED_COUNT = 0;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { Money } from '../../../../common/money.types';
|
import type { Money } from '#src/common/money.types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
decimalFromString,
|
decimalFromString,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
} from '../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
|
|
||||||
export function sumMoneyByCurrency(amounts: Money[]): Money[] {
|
export function sumMoneyByCurrency(amounts: Money[]): Money[] {
|
||||||
const totals = new Map<string, ReturnType<typeof decimalFromString>>();
|
const totals = new Map<string, ReturnType<typeof decimalFromString>>();
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { isDeepStrictEqual } from 'node:util';
|
import { isDeepStrictEqual } from 'node:util';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
|
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
import { toJson } from '../../../../prisma/to-json';
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
const FIRST_BATCH_OFFSET = 0;
|
const FIRST_BATCH_OFFSET = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
import type { PortfolioDto } from '../presentation/portfolio.dto';
|
|
||||||
|
|
||||||
import { TbankErrorCode } from '../../../../integrations/tbank/tbank-error-code';
|
import { TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import { lockConnectionGeneration } from '../../../../integrations/tbank/tbank-sync-claim';
|
import { lockConnectionGeneration } from '#src/integrations/tbank/tbank-sync-claim';
|
||||||
import { isJoinableRunningAttempt, tbankSourceNeedsRefresh, tbankSourceTtlMs } from '../../../../integrations/tbank/tbank.api';
|
import { isJoinableRunningAttempt, tbankSourceNeedsRefresh, tbankSourceTtlMs } from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
import { toJson } from '../../../../prisma/to-json';
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
|
import type { PortfolioDto } from '../presentation/portfolio.dto';
|
||||||
|
|
||||||
const EXPECTED_UPDATED_ACCOUNTS = 1;
|
const EXPECTED_UPDATED_ACCOUNTS = 1;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PositionClassificationRepository {
|
export class PositionClassificationRepository {
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import type { Money } from '../../../../common/money.types';
|
import type { Money } from '#src/common/money.types';
|
||||||
import type { Classification } from '../application/position-classification.service';
|
|
||||||
import type { PortfolioDto, PortfolioPositionDto } from '../presentation/portfolio.dto';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
@@ -9,15 +7,19 @@ import {
|
|||||||
isZero,
|
isZero,
|
||||||
multiply,
|
multiply,
|
||||||
subtract,
|
subtract,
|
||||||
} from '../../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { decimal } from '../../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
import {
|
import {
|
||||||
metadataKey,
|
metadataKey,
|
||||||
type TbankInstrument,
|
type TbankInstrument,
|
||||||
type TbankMoney,
|
type TbankMoney,
|
||||||
TbankPortfolio,
|
TbankPortfolio,
|
||||||
TbankPositions,
|
TbankPositions,
|
||||||
} from '../../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
|
import type { Classification } from '../application/position-classification.service';
|
||||||
|
import type { PortfolioDto, PortfolioPositionDto } from '../presentation/portfolio.dto';
|
||||||
|
|
||||||
import { portfolioStructure } from '../domain/portfolio-structure';
|
import { portfolioStructure } from '../domain/portfolio-structure';
|
||||||
|
|
||||||
const types: Record<string, string> = {
|
const types: Record<string, string> = {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
import { TbankSyncRepositoryModule } from '../tbank-sync/tbank-sync-repository.module';
|
||||||
import { ForecastService } from './application/forecast.service';
|
import { ForecastService } from './application/forecast.service';
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import type { Request } from 'express';
|
|||||||
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Param, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '#src/modules/auth/auth.api';
|
||||||
|
|
||||||
import { PortfolioService } from '../application/portfolio.service';
|
import { PortfolioService } from '../application/portfolio.service';
|
||||||
import { PortfolioResourceDto } from './portfolio.dto';
|
import { PortfolioResourceDto } from './portfolio.dto';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import { AccountReferenceDto } from '../../account-reference.dto';
|
import { AccountReferenceDto } from '../../account-reference.dto';
|
||||||
import { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
import { InvestmentResourceMetaDto } from '../../investment-resource.dto';
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ import {
|
|||||||
ApiTags,
|
ApiTags,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
|
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
||||||
import {
|
import {
|
||||||
PutTbankConnectionDto,
|
PutTbankConnectionDto,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { TbankSyncModule } from '../tbank-sync/tbank-sync.module';
|
import { TbankSyncModule } from '../tbank-sync/tbank-sync.module';
|
||||||
import { TbankConnectionController } from './tbank-connection.controller';
|
import { TbankConnectionController } from './tbank-connection.controller';
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { HttpErrorCode } from '../../../common/error-code';
|
import { HttpErrorCode } from '#src/common/error-code';
|
||||||
import {
|
import {
|
||||||
supportedTbankAccounts,
|
supportedTbankAccounts,
|
||||||
TbankClient,
|
TbankClient,
|
||||||
TbankTokenService,
|
TbankTokenService,
|
||||||
} from '../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
type TbankTokenValidator = Pick<TbankClient, 'validateToken'>;
|
type TbankTokenValidator = Pick<TbankClient, 'validateToken'>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { StructuredLogger } from '../../../common/logging/structured-logger.service';
|
import { StructuredLogger } from '#src/common/logging/structured-logger.service';
|
||||||
import { TbankErrorCode } from '../../../integrations/tbank/tbank-error-code';
|
import { TbankErrorCode } from '#src/integrations/tbank/tbank-error-code';
|
||||||
import {
|
import {
|
||||||
TbankAccessService,
|
TbankAccessService,
|
||||||
TbankMembershipService,
|
TbankMembershipService,
|
||||||
type TbankSyncAttempt,
|
type TbankSyncAttempt,
|
||||||
} from '../../../integrations/tbank/tbank.api';
|
} from '#src/integrations/tbank/tbank.api';
|
||||||
import { PrismaService } from '../../../prisma/prisma.service';
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
|
||||||
import { BrokerageOperationsSyncService } from '../operations/operations.api';
|
import { BrokerageOperationsSyncService } from '../operations/operations.api';
|
||||||
import { PortfolioService } from '../portfolio/portfolio.api';
|
import { PortfolioService } from '../portfolio/portfolio.api';
|
||||||
import { UpcomingEventsService } from '../upcoming-events/upcoming-events.service';
|
import { UpcomingEventsService } from '../upcoming-events/upcoming-events.service';
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { ISO_DATE_LENGTH, ISO_DATE_START } from '#src/common/time';
|
||||||
|
|
||||||
import type { InvestmentScreenDto } from './tbank-sync.dto';
|
import type { InvestmentScreenDto } from './tbank-sync.dto';
|
||||||
|
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START } from '../../../common/time';
|
|
||||||
import { MIN_INSTRUMENT_QUERY_LENGTH } from '../instrument-query';
|
import { MIN_INSTRUMENT_QUERY_LENGTH } from '../instrument-query';
|
||||||
|
|
||||||
// Reject fields from other screens before reserving any source work.
|
// Reject fields from other screens before reserving any source work.
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
ApiTags,
|
ApiTags,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
|
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
||||||
import {
|
import {
|
||||||
EventsInvestmentScreenDto,
|
EventsInvestmentScreenDto,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { InstrumentSourcesModule } from '../instruments/instrument-sources.module';
|
import { InstrumentSourcesModule } from '../instruments/instrument-sources.module';
|
||||||
import { OperationsModule } from '../operations/operations.module';
|
import { OperationsModule } from '../operations/operations.module';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import type { Prisma } from '../../../../generated/prisma/client';
|
import type { Prisma } from '#generated/prisma/client';
|
||||||
import type { TbankSyncAttempt } from '../../../integrations/tbank/tbank.api';
|
import type { TbankSyncAttempt } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
|
import { claimSyncWork, lockConnectionGeneration } from '#src/integrations/tbank/tbank-sync-claim';
|
||||||
|
import { PrismaService } from '#src/prisma/prisma.service';
|
||||||
|
import { toJson } from '#src/prisma/to-json';
|
||||||
|
|
||||||
import type { InvestmentAttemptDto } from '../investment-resource.dto';
|
import type { InvestmentAttemptDto } from '../investment-resource.dto';
|
||||||
import type { InvestmentScreenDto } from './tbank-sync.dto';
|
import type { InvestmentScreenDto } from './tbank-sync.dto';
|
||||||
|
|
||||||
import { claimSyncWork, lockConnectionGeneration } from '../../../integrations/tbank/tbank-sync-claim';
|
|
||||||
import { PrismaService } from '../../../prisma/prisma.service';
|
|
||||||
import { toJson } from '../../../prisma/to-json';
|
|
||||||
export type ScreenIntent = { now: string; scope: InvestmentScreenDto };
|
export type ScreenIntent = { now: string; scope: InvestmentScreenDto };
|
||||||
|
|
||||||
// Json columns are written only by this repository; a shape check turns corruption into an explicit 500.
|
// Json columns are written only by this repository; a shape check turns corruption into an explicit 500.
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
|
|
||||||
import { TbankAccessService } from '../../../integrations/tbank/tbank.api';
|
import { TbankAccessService } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import { BrokerageOperationsSyncService } from '../operations/operations.api';
|
import { BrokerageOperationsSyncService } from '../operations/operations.api';
|
||||||
import { TbankSyncStatusDto } from './tbank-sync.dto';
|
import { TbankSyncStatusDto } from './tbank-sync.dto';
|
||||||
import { screenIntent, TbankSyncRepository } from './tbank-sync.repository';
|
import { screenIntent, TbankSyncRepository } from './tbank-sync.repository';
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import type { MoexBondEvent } from '../../../integrations/moex/moex.api';
|
import type { MoexBondEvent } from '#src/integrations/moex/moex.api';
|
||||||
import type { TbankDividend } from '../../../integrations/tbank/tbank.api';
|
import type { TbankDividend } from '#src/integrations/tbank/tbank.api';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
decimalFromString,
|
decimalFromString,
|
||||||
formatDecimal,
|
formatDecimal,
|
||||||
multiply,
|
multiply,
|
||||||
} from '../../../common/decimal';
|
} from '#src/common/decimal';
|
||||||
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_SECOND } from '../../../common/time';
|
import { ISO_DATE_LENGTH, ISO_DATE_START, MILLISECONDS_PER_SECOND } from '#src/common/time';
|
||||||
import { decimal } from '../../../integrations/tbank/decimal';
|
import { decimal } from '#src/integrations/tbank/decimal';
|
||||||
|
|
||||||
import { UpcomingEventDto } from './upcoming-events.dto';
|
import { UpcomingEventDto } from './upcoming-events.dto';
|
||||||
|
|
||||||
export function dividendEvent(
|
export function dividendEvent(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class PrismaService {},
|
PrismaService: class PrismaService {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import type { Request } from 'express';
|
|||||||
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
import { Controller, Get, Param, Query, Req, UseGuards } from '@nestjs/common';
|
||||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
|
||||||
import { ApiProblemResponses } from '../../../common/decorators/api-safe-error-response.decorator';
|
import { ApiProblemResponses } from '#src/common/decorators/api-safe-error-response.decorator';
|
||||||
|
|
||||||
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
import { AccessPayload, JwtAuthGuard } from '../../auth/auth.api';
|
||||||
import {
|
import {
|
||||||
UpcomingEventsQueryDto,
|
UpcomingEventsQueryDto,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
import { IsDateString, IsOptional, Matches } from 'class-validator';
|
import { IsDateString, IsOptional, Matches } from 'class-validator';
|
||||||
|
|
||||||
import { MoneyDto } from '../../../common/money.dto';
|
import { MoneyDto } from '#src/common/money.dto';
|
||||||
|
|
||||||
import { AccountReferenceDto } from '../account-reference.dto';
|
import { AccountReferenceDto } from '../account-reference.dto';
|
||||||
import {
|
import {
|
||||||
InvestmentReadQueryDto,
|
InvestmentReadQueryDto,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { TbankModule } from '../../../integrations/tbank/tbank.module';
|
import { TbankModule } from '#src/integrations/tbank/tbank.module';
|
||||||
|
|
||||||
import { AuthModule } from '../../auth/auth.module';
|
import { AuthModule } from '../../auth/auth.module';
|
||||||
import { InstrumentSourcesModule } from '../instruments/instrument-sources.module';
|
import { InstrumentSourcesModule } from '../instruments/instrument-sources.module';
|
||||||
import { PortfolioModule } from '../portfolio/portfolio.module';
|
import { PortfolioModule } from '../portfolio/portfolio.module';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { decimalFromString } from '../../../common/decimal';
|
import { decimalFromString } from '#src/common/decimal';
|
||||||
|
|
||||||
import { bondEvent, dividendEvent } from './upcoming-event.mapper';
|
import { bondEvent, dividendEvent } from './upcoming-event.mapper';
|
||||||
jest.mock('../../../prisma/prisma.service', () => ({
|
jest.mock('#src/prisma/prisma.service', () => ({
|
||||||
PrismaService: class {},
|
PrismaService: class {},
|
||||||
}));
|
}));
|
||||||
const metadata = {
|
const metadata = {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user