From d29ba0153d03039cdb4353f876cb481ec15938bb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 21 Apr 2025 19:46:40 +0200 Subject: [PATCH] Various improvements --- .../watchlist/watchlist.controller.ts | 19 +++++++++++++------ .../endpoints/watchlist/watchlist.module.ts | 8 +++++++- .../endpoints/watchlist/watchlist.service.ts | 2 +- libs/common/src/lib/permissions.ts | 3 ++- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts b/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts index 52da97777..0d25172c8 100644 --- a/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts +++ b/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts @@ -1,5 +1,7 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; +import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor'; import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; import { RequestWithUser } from '@ghostfolio/common/types'; @@ -13,10 +15,12 @@ import { Inject, Param, Post, - UseGuards + UseGuards, + UseInterceptors } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { DataSource } from '@prisma/client'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { CreateWatchlistItemDto } from './create-watchlist-item.dto'; @@ -32,6 +36,7 @@ export class WatchlistController { @Post() @HasPermission(permissions.createWatchlistItem) @UseGuards(AuthGuard('jwt')) + @UseInterceptors(TransformDataSourceInRequestInterceptor) public async createWatchlistItem(@Body() data: CreateWatchlistItemDto) { return this.watchlistService.createWatchlistItem({ dataSource: data.dataSource, @@ -43,16 +48,17 @@ export class WatchlistController { @Delete(':dataSource/:symbol') @HasPermission(permissions.deleteWatchlistItem) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @UseInterceptors(TransformDataSourceInRequestInterceptor) public async deleteWatchlistItem( - @Param('dataSource') dataSource: string, + @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ) { const watchlistItem = await this.watchlistService .getWatchlistItems(this.request.user.id) .then((items) => { - return items.find( - (item) => item.dataSource === dataSource && item.symbol === symbol - ); + return items.find((item) => { + return item.dataSource === dataSource && item.symbol === symbol; + }); }); if (!watchlistItem) { @@ -63,8 +69,8 @@ export class WatchlistController { } return this.watchlistService.deleteWatchlistItem({ + dataSource, symbol, - dataSource: watchlistItem.dataSource, userId: this.request.user.id }); } @@ -72,6 +78,7 @@ export class WatchlistController { @Get() @HasPermission(permissions.readWatchlist) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @UseInterceptors(TransformDataSourceInResponseInterceptor) public async getWatchlistItems(): Promise { return this.watchlistService.getWatchlistItems(this.request.user.id); } diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.module.ts b/apps/api/src/app/endpoints/watchlist/watchlist.module.ts index 953d15956..072c0b43e 100644 --- a/apps/api/src/app/endpoints/watchlist/watchlist.module.ts +++ b/apps/api/src/app/endpoints/watchlist/watchlist.module.ts @@ -1,3 +1,5 @@ +import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; +import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { Module } from '@nestjs/common'; @@ -7,7 +9,11 @@ import { WatchlistService } from './watchlist.service'; @Module({ controllers: [WatchlistController], - imports: [PrismaModule], + imports: [ + TransformDataSourceInRequestModule, + TransformDataSourceInResponseModule, + PrismaModule + ], providers: [WatchlistService] }) export class WatchlistModule {} diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.service.ts b/apps/api/src/app/endpoints/watchlist/watchlist.service.ts index 2c7a743cb..fdb9dd97a 100644 --- a/apps/api/src/app/endpoints/watchlist/watchlist.service.ts +++ b/apps/api/src/app/endpoints/watchlist/watchlist.service.ts @@ -25,7 +25,7 @@ export class WatchlistService { if (!symbolProfile) { throw new NotFoundException( - `Asset profile not found for ${symbol} (${dataSource}).` + `Asset profile not found for ${symbol} (${dataSource})` ); } diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index b154f92c2..592167562 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -106,7 +106,8 @@ export function getPermissions(aRole: Role): string[] { permissions.accessAssistant, permissions.accessHoldingsChart, permissions.createUserAccount, - permissions.readAiPrompt + permissions.readAiPrompt, + permissions.readWatchlist ]; case 'USER':