From 0879fede391562aa1deae36c2f424e8d5d37b42b Mon Sep 17 00:00:00 2001 From: 0pilatos0 Date: Sat, 27 Dec 2025 23:05:43 +0100 Subject: [PATCH] Feature/create endpoint to get all platforms (#6096) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new endpoint GET api/v1/platforms to retrieve all platforms with readPlatforms permission. This provides a simpler alternative to the existing platform endpoint that includes account counts. - Create PlatformsController with GET endpoint using readPlatforms permission - Create PlatformsModule importing PlatformModule for service reuse - Register PlatformsModule in app.module.ts - Add readPlatforms permission to USER role 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- apps/api/src/app/app.module.ts | 2 ++ .../platforms/platforms.controller.ts | 20 +++++++++++++++++++ .../endpoints/platforms/platforms.module.ts | 11 ++++++++++ libs/common/src/lib/permissions.ts | 1 + 4 files changed, 34 insertions(+) create mode 100644 apps/api/src/app/endpoints/platforms/platforms.controller.ts create mode 100644 apps/api/src/app/endpoints/platforms/platforms.module.ts diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 5ec148558..89f52e1ea 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -37,6 +37,7 @@ import { AssetsModule } from './endpoints/assets/assets.module'; import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module'; import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module'; import { MarketDataModule } from './endpoints/market-data/market-data.module'; +import { PlatformsModule } from './endpoints/platforms/platforms.module'; import { PublicModule } from './endpoints/public/public.module'; import { SitemapModule } from './endpoints/sitemap/sitemap.module'; import { TagsModule } from './endpoints/tags/tags.module'; @@ -95,6 +96,7 @@ import { UserModule } from './user/user.module'; MarketDataModule, OrderModule, PlatformModule, + PlatformsModule, PortfolioModule, PortfolioSnapshotQueueModule, PrismaModule, diff --git a/apps/api/src/app/endpoints/platforms/platforms.controller.ts b/apps/api/src/app/endpoints/platforms/platforms.controller.ts new file mode 100644 index 000000000..7ad63cb29 --- /dev/null +++ b/apps/api/src/app/endpoints/platforms/platforms.controller.ts @@ -0,0 +1,20 @@ +import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; +import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; +import { permissions } from '@ghostfolio/common/permissions'; + +import { Controller, Get, UseGuards } from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { Platform } from '@prisma/client'; + +@Controller('platforms') +export class PlatformsController { + public constructor(private readonly platformService: PlatformService) {} + + @Get() + @HasPermission(permissions.readPlatforms) + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + public async getPlatforms(): Promise { + return this.platformService.getPlatforms(); + } +} diff --git a/apps/api/src/app/endpoints/platforms/platforms.module.ts b/apps/api/src/app/endpoints/platforms/platforms.module.ts new file mode 100644 index 000000000..21d0edf69 --- /dev/null +++ b/apps/api/src/app/endpoints/platforms/platforms.module.ts @@ -0,0 +1,11 @@ +import { PlatformModule } from '@ghostfolio/api/app/platform/platform.module'; + +import { Module } from '@nestjs/common'; + +import { PlatformsController } from './platforms.controller'; + +@Module({ + controllers: [PlatformsController], + imports: [PlatformModule] +}) +export class PlatformsModule {} diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 3fd2bef8c..9730c63a4 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -136,6 +136,7 @@ export function getPermissions(aRole: Role): string[] { permissions.deleteWatchlistItem, permissions.readAiPrompt, permissions.readMarketDataOfOwnAssetProfile, + permissions.readPlatforms, permissions.readWatchlist, permissions.updateAccount, permissions.updateAccess,