Files
backend/src/modules/investments/income/income-analytics.dto.ts
T
codex-bot 31b0e15579
Backend verify / commits (push) Skipped
Backend verify / security (push) Successful in 13s
Backend verify / verify (push) Failing after 7m1s
feat: unify income payment cards and drop period comparisons (WealthLedger/main#33) (#83)
feat: unify income payment cards and drop period comparisons (WealthLedger/main#33)
2026-10-13 18:16:46 +03:00

163 lines
4.4 KiB
TypeScript

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsOptional, Matches } from 'class-validator';
import { MoneyDto } from '../../../common/money.dto';
import {
InvestmentDependencyDto,
InvestmentReadQueryDto,
InvestmentResourceMetaDto,
} from '../investment-resource.dto';
import { BrokerageOperationDto } from '../operations/operations.api';
const dateOnly = /^\d{4}-\d{2}-\d{2}$/;
export class IncomeAnalyticsQueryDto extends InvestmentReadQueryDto {
@ApiPropertyOptional({
format: 'date',
description:
'Inclusive calendar date in Europe/Moscow. Supply both from/to or neither.',
})
@IsOptional()
@Matches(dateOnly)
from?: string;
@ApiPropertyOptional({
format: 'date',
description:
'Inclusive calendar date in Europe/Moscow, no later than today. Supply both from/to or neither.',
})
@IsOptional()
@Matches(dateOnly)
to?: string;
}
export class IncomePeriodDto {
@ApiProperty({ format: 'date' })
declare from: string;
@ApiProperty({ format: 'date' })
declare to: string;
}
export class IncomeCurrencySummaryDto {
@ApiProperty()
declare currency: string;
@ApiProperty({ type: MoneyDto })
declare coupon: MoneyDto;
@ApiProperty({ type: MoneyDto })
declare dividend: MoneyDto;
@ApiProperty({ type: MoneyDto })
declare total: MoneyDto;
}
export class IncomeSummaryDto {
@ApiProperty()
declare accountId: string;
@ApiProperty({ type: IncomePeriodDto })
declare period: IncomePeriodDto;
@ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true })
declare totalsByCurrency: IncomeCurrencySummaryDto[];
@ApiProperty({ format: 'date-time' })
declare calculatedAt: string;
}
export class IncomeBucketDto {
@ApiProperty({ type: IncomePeriodDto })
declare period: IncomePeriodDto;
@ApiProperty({ type: IncomeCurrencySummaryDto, isArray: true })
declare totalsByCurrency: IncomeCurrencySummaryDto[];
}
export class IncomeInstrumentDto {
@ApiProperty()
declare key: string;
@ApiProperty({ type: String, nullable: true })
declare figi: null | string;
@ApiProperty({ type: String, nullable: true })
declare instrumentUid: null | string;
@ApiProperty({ type: String, nullable: true })
declare ticker: null | string;
@ApiProperty({ type: String, nullable: true })
declare instrumentType: null | string;
@ApiProperty()
declare displayName: string;
@ApiProperty({ type: MoneyDto })
declare coupon: MoneyDto;
@ApiProperty({ type: MoneyDto })
declare dividend: MoneyDto;
@ApiProperty({ type: MoneyDto })
declare total: MoneyDto;
@ApiProperty()
declare receiptCount: number;
}
export class IncomeAnalyticsEntryDto extends BrokerageOperationDto {
@ApiProperty()
declare instrumentKey: string;
}
export class IncomeAnalyticsDto extends IncomeSummaryDto {
@ApiProperty({ enum: ['day', 'week', 'month'] })
declare bucketGranularity: 'day' | 'month' | 'week';
@ApiProperty({ type: IncomeBucketDto, isArray: true })
declare buckets: IncomeBucketDto[];
@ApiProperty({ type: IncomeInstrumentDto, isArray: true })
declare instruments: IncomeInstrumentDto[];
@ApiProperty({ type: IncomeAnalyticsEntryDto, isArray: true })
declare entries: IncomeAnalyticsEntryDto[];
}
export class IncomeSummaryResourceDto {
@ApiProperty({ type: IncomeSummaryDto, nullable: true })
declare data: IncomeSummaryDto | null;
@ApiProperty({ type: InvestmentResourceMetaDto })
declare meta: InvestmentResourceMetaDto;
}
const incomeDependencyRoles = ['selected'] as const;
export class IncomeDependencyDto extends InvestmentDependencyDto {
@ApiProperty({ enum: incomeDependencyRoles })
declare role: (typeof incomeDependencyRoles)[number];
}
export class IncomeAnalyticsMetaDto extends InvestmentResourceMetaDto {
// eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality -- Overrides optional dependencies inherited from InvestmentResourceMetaDto.
@ApiProperty({
type: IncomeDependencyDto,
isArray: true,
required: true,
description:
'Dependencies identified by role, not array order or resourceKey. A missing role is unavailable.',
})
declare dependencies: IncomeDependencyDto[];
}
export class IncomeAnalyticsResourceDto {
@ApiProperty({ type: IncomeAnalyticsDto, nullable: true })
declare data: IncomeAnalyticsDto | null;
@ApiProperty({ type: IncomeAnalyticsMetaDto })
declare meta: IncomeAnalyticsMetaDto;
}