feat: add stock details and ticker resolution
Expose stock search, market data, company information, dividends and portfolio history with exact instrument identity and verified ticker aliases. Include stock and bond position counts in account summaries.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
ParseUUIDPipe,
|
||||
Query,
|
||||
Req,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||
import type { Request } from 'express';
|
||||
import { AccessPayload } from '../auth/auth.types';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
import { ApiProblemResponses } from '../common/decorators/api-safe-error-response.decorator';
|
||||
import { StockService } from './stock.service';
|
||||
import {
|
||||
StockCandlesDto,
|
||||
StockCandlesQueryDto,
|
||||
StockCompanyDto,
|
||||
StockDividendsDto,
|
||||
StockDto,
|
||||
StockTickerParamsDto,
|
||||
StockPositionDto,
|
||||
StockQuoteDto,
|
||||
StockSearchQueryDto,
|
||||
StockSearchResultDto,
|
||||
} from './stock.dto';
|
||||
|
||||
@ApiTags('stocks')
|
||||
@ApiProblemResponses()
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('stocks')
|
||||
export class StockController {
|
||||
constructor(private readonly stocks: StockService) {}
|
||||
@Get()
|
||||
@ApiOkResponse({ type: [StockSearchResultDto] })
|
||||
search(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Query() query: StockSearchQueryDto,
|
||||
) {
|
||||
return this.stocks.search(request.user.sub, query.query);
|
||||
}
|
||||
@Get('by-ticker/:ticker')
|
||||
@ApiOkResponse({ type: StockDto })
|
||||
getByTicker(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param() params: StockTickerParamsDto,
|
||||
) {
|
||||
return this.stocks.getByTicker(request.user.sub, params.ticker);
|
||||
}
|
||||
@Get(':uid')
|
||||
@ApiOkResponse({ type: StockDto })
|
||||
get(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
) {
|
||||
return this.stocks.get(request.user.sub, uid);
|
||||
}
|
||||
@Get(':uid/quote')
|
||||
@ApiOkResponse({ type: StockQuoteDto })
|
||||
quote(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
) {
|
||||
return this.stocks.quote(request.user.sub, uid);
|
||||
}
|
||||
@Get(':uid/candles')
|
||||
@ApiOkResponse({ type: StockCandlesDto })
|
||||
candles(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
@Query() query: StockCandlesQueryDto,
|
||||
) {
|
||||
return this.stocks.candles(request.user.sub, uid, query.period);
|
||||
}
|
||||
@Get(':uid/position')
|
||||
@ApiOkResponse({ type: StockPositionDto })
|
||||
position(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
) {
|
||||
return this.stocks.position(request.user.sub, uid);
|
||||
}
|
||||
@Get(':uid/company')
|
||||
@ApiOkResponse({ type: StockCompanyDto })
|
||||
company(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
) {
|
||||
return this.stocks.company(request.user.sub, uid);
|
||||
}
|
||||
@Get(':uid/dividends')
|
||||
@ApiOkResponse({ type: StockDividendsDto })
|
||||
dividends(
|
||||
@Req() request: Request & { user: AccessPayload },
|
||||
@Param('uid', new ParseUUIDPipe()) uid: string,
|
||||
) {
|
||||
return this.stocks.dividends(request.user.sub, uid);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user