Sergey Krylov cfadb2adbe feat: migrate from react-router-dom to @tanstack/react-router (code-first)
- Create code-first route tree in src/app/routing/routeTree.tsx
- Replace ProtectedRoute with beforeLoad auth guards
- Add useSearchParamsCompat for URLSearchParams access
- Update App.tsx, layouts, and all page/widget imports
- Add frontend tooling: biome, prettier, env config
- Update all tests for TanStack Router compatibility
- Remove react-router-dom dependency, @tanstack/router-plugin
- Consolidate biome config at root level
2026-06-23 06:51:48 +03:00

392 lines
8.1 KiB
TypeScript

export interface ApiResponseMeta {
cachedAt: string | null
fromCache: boolean
}
export interface ApiEnvelope<T> {
data: T
meta: ApiResponseMeta
}
export interface StockMarketData {
price: number | null
change: number | null
changePercent: number | null
open: number | null
high: number | null
low: number | null
volume: number
value: number
issueCapitalization: number | null
updatedAt: string
}
export interface ShareResponse {
secid: string
isin: string
name: string
shortName: string
latName: string | null
listLevel: number
issueSize: number
faceValue: number
faceUnit: string
type: string
marketData: StockMarketData
}
export interface DividendItem {
registryCloseDate: string
value: number
currency: string
}
export interface ShareHistoryItem {
date: string
open: number
high: number
low: number
close: number
volume: number
value: number
}
export interface BondMarketData {
price: number | null
yieldToMaturity: number | null
duration: number | null
accruedInt: number | null
couponValue: number | null
couponPercent: number | null
nextCouponDate: string | null
open: number
high: number | null
low: number | null
volume: number
updatedAt: string
}
export interface BondResponse {
secid: string
isin: string
name: string
shortName: string
latName: string | null
listLevel: number
issueSize: number
faceValue: number
faceUnit: string
matDate: string
couponValue: number
couponPercent: number | null
couponPeriod: number
nextCoupon: string | null
accruedInt: number
bondType: string
bondSubType: string
offerDate: string | null
buybackDate: string | null
marketData: BondMarketData
}
export interface BondHistoryItem {
date: string
closePrice: number
yieldClose: number | null
duration: number | null
}
export interface CandleItem {
open: number
high: number
low: number
close: number
volume: number
value: number
begin: string
end: string
}
export interface SearchResultItem {
secid: string
isin: string
shortName: string
type: 'share' | 'bond'
listLevel: number
currency: string | null
price: number | null
}
export interface HealthResponse {
status: string
timestamp: string
uptime: number
}
export interface UserResponse {
id: number
email: string
name: string | null
role: string
}
export interface AuthResponse {
user: UserResponse
accessToken: string
}
export interface Portfolio {
id: number
name: string
description: string | null
currency: string
createdAt: string
updatedAt: string
totalValue: number
positionCount: number
shareCount: number
bondCount: number
}
export interface PositionWithPrice {
id: number
portfolioId: number
secid: string
shortName: string | null
type: 'share' | 'bond'
quantity: number
notes: string | null
tags: string[] | null
currentPrice: number | null
buyPrice: number | null
buyDate: string | null
totalCost: number | null
currentValue: number | null
pnl: number | null
pnlPercent: number | null
dividendIncome: number | null
totalReturn: number | null
totalReturnPercent: number | null
weightPercent: number
change?: number | null
changePercent?: number | null
yieldToMaturity?: number | null
duration?: number | null
couponValue?: number | null
couponPercent?: number | null
nextCouponDate?: string | null
matDate?: string | null
accruedInt?: number | null
bid?: number | null
offer?: number | null
couponPeriod?: number | null
bondType?: string | null
offerDate?: string | null
}
export interface PortfolioDetail extends Portfolio {
positions: PositionWithPrice[]
totalValue: number
analytics: PortfolioSummary
}
export interface Position {
id: number
secid: string
quantity: number
notes: string | null
tags: string[] | null
portfolioId: number
createdAt: string
updatedAt: string
}
export interface PortfolioSummary {
totalInvested: number
totalValue: number
totalPnl: number
totalPnlPercent: number | null
totalDividends: number
totalReturn: number
totalReturnPercent: number | null
positionCount: number
weightedYield: number | null
}
export interface AnalyticsResponse {
positions: PositionWithPrice[]
summary: PortfolioSummary
}
export interface ScreenerItem {
secid: string
shortName: string
isin: string
type: 'share' | 'bond'
price: number | null
change: number | null
changePercent: number | null
volume: number
listLevel: number
capitalization: number | null
yieldToMaturity: number | null
duration: number | null
couponValue: number | null
couponPercent: number | null
accruedInt: number | null
matDate: string | null
bondType: string | null
}
export interface ScreenerResult {
items: ScreenerItem[]
total: number
page: number
pageSize: number
totalPages: number
}
export interface BrokerMoney {
currency: string
units: string
nano: number
value: number
}
export interface BrokerAccount {
id: string
type: 'brokerage' | 'iis'
name: string
status: string
openedAt: string | null
accessLevel: string | null
}
export interface BrokerPosition {
figi: string | null
instrumentUid: string | null
positionUid: string | null
ticker: string | null
classCode: string | null
instrumentType: string | null
name: string | null
quantity: number | null
blockedLots: number | null
currentPrice: BrokerMoney | null
currentValue: BrokerMoney | null
averagePositionPrice: BrokerMoney | null
expectedYieldPercent: number | null
dailyYield: BrokerMoney | null
}
export interface BrokerPortfolio {
account: BrokerAccount
positionCounts: {
shares: number
bonds: number
etf: number
other: number
}
totals: {
shares: BrokerMoney | null
bonds: BrokerMoney | null
etf: BrokerMoney | null
currencies: BrokerMoney | null
futures: BrokerMoney | null
options: BrokerMoney | null
structuredProducts: BrokerMoney | null
dfa: BrokerMoney | null
portfolio: BrokerMoney | null
}
yields: {
expectedPercent: number | null
daily: BrokerMoney | null
dailyPercent: number | null
}
cash: BrokerMoney[]
blockedCash: BrokerMoney[]
asOf: string
}
export type BrokerOperationCategory = 'trade' | 'income' | 'tax' | 'fee' | 'transfer' | 'other'
export interface BrokerOperation {
cursor: string | null
accountId: string
id: string | null
parentOperationId: string | null
date: string | null
type: string
category: BrokerOperationCategory
description: string | null
name: string | null
state: string | null
instrumentUid: string | null
figi: string | null
ticker: string | null
classCode: string | null
instrumentType: string | null
payment: BrokerMoney | null
price: BrokerMoney | null
commission: BrokerMoney | null
yield: BrokerMoney | null
accruedInt: BrokerMoney | null
quantity: number | null
quantityDone: number | null
}
export interface BrokerOperationsPage {
accountId: string
items: BrokerOperation[]
nextCursor: string | null
hasNext: boolean
asOf: string
}
export interface BrokerPositionsPage {
accountId: string
items: BrokerPosition[]
nextCursor: string | null
hasNext: boolean
asOf: string
}
export interface BrokerPortfolioEvent {
id: string
type: 'dividend' | 'coupon' | 'maturity' | 'offer'
source: 'forecast' | 'actual'
category: 'cashflow' | 'corporate'
eventDate: string
paymentDate: string | null
ticker: string | null
name: string | null
instrumentUid: string | null
instrumentType: 'share' | 'bond' | 'other'
quantitySnapshot: number | null
payoutPerUnit: number | null
estimatedAmount: number | null
actualAmount: number | null
currency: string | null
estimateMode: 'current_position' | null
}
export interface BrokerEventsSummary {
eventCount: number
nearestEventDate: string | null
totalEstimatedCashflow: number
actualCashflow: number
forecastEstimatedCashflow: number
dividendsTotal: number
couponsTotal: number
principalRepaymentTotal: number
actualDividendsTotal: number
actualCouponsTotal: number
actualPrincipalRepaymentTotal: number
}
export interface BrokerEventsData {
items: BrokerPortfolioEvent[]
summary: BrokerEventsSummary
asOf: string
}