Files
backend/src/tbank/brokerage-operation.dto.ts
T
ksv741 e6f58ef0ee feat: add manual bank card ledger
Store exact RUB balances, atomic transfers, linked refunds and versioned edits independently of T-Bank. Add migration, HTTP and durability verification.
2026-09-12 18:34:18 +03:00

139 lines
3.0 KiB
TypeScript

import { Transform, Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsArray,
IsDateString,
IsEnum,
IsInt,
IsOptional,
IsString,
IsUUID,
Max,
MaxLength,
Min,
} from 'class-validator';
import { MoneyDto } from '../common/money.dto';
import { AccountReferenceDto } from './account-reference.dto';
export const operationCategories = [
'trade',
'income',
'tax',
'fee',
'transfer',
'other',
] as const;
export type OperationCategory = (typeof operationCategories)[number];
export class BrokerageOperationsQueryDto {
@ApiPropertyOptional({
format: 'uuid',
description:
'Instrument UID. Without from, includes history since the earliest available account opening.',
})
@IsOptional()
@IsUUID()
instrumentUid?: string;
@ApiPropertyOptional({ format: 'date-time' })
@IsOptional()
@IsDateString()
from?: string;
@ApiPropertyOptional({ format: 'date-time' })
@IsOptional()
@IsDateString()
to?: string;
@ApiPropertyOptional({ enum: operationCategories, isArray: true })
@IsOptional()
@Transform(({ value }: { value: unknown }) =>
typeof value === 'string' ? value.split(',').filter(Boolean) : value,
)
@IsArray()
@IsEnum(operationCategories, { each: true })
categories?: OperationCategory[];
@ApiPropertyOptional()
@IsOptional()
@IsString()
@MaxLength(4096)
cursor?: string;
@ApiPropertyOptional({ minimum: 1, maximum: 1000, default: 100 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
@Max(1000)
limit?: number;
}
export class BrokerageOperationDto {
@ApiPropertyOptional({ type: AccountReferenceDto })
account?: AccountReferenceDto;
@ApiProperty()
id: string;
@ApiProperty({ format: 'date-time' })
occurredAt: string;
@ApiProperty()
type: string;
@ApiProperty({ enum: operationCategories })
category: OperationCategory;
@ApiProperty()
description: string;
@ApiProperty({ type: String, nullable: true })
figi: string | null;
@ApiProperty({ type: String, nullable: true })
instrumentUid: string | null;
@ApiProperty({ type: String, nullable: true })
ticker: string | null;
@ApiProperty({ type: String, nullable: true })
instrumentType: string | null;
@ApiProperty({ type: String, nullable: true })
logoName: string | null;
@ApiProperty({ type: MoneyDto, nullable: true })
payment: MoneyDto | null;
@ApiProperty({ type: String, nullable: true })
quantity: string | null;
@ApiProperty({ type: MoneyDto, nullable: true })
price: MoneyDto | null;
@ApiProperty({ type: MoneyDto, nullable: true })
accruedInterest: MoneyDto | null;
@ApiProperty({ type: MoneyDto, nullable: true })
commission: MoneyDto | null;
}
export class BrokerageOperationsPageDto {
@ApiProperty()
accountId: string;
@ApiProperty({ type: BrokerageOperationDto, isArray: true })
items: BrokerageOperationDto[];
@ApiProperty({ type: String, nullable: true })
nextCursor: string | null;
@ApiProperty()
hasNext: boolean;
@ApiProperty({ format: 'date-time' })
observedAt: string;
}