From 9b86a9a73f2fe00509de2d74a51f3081a36cfd6a Mon Sep 17 00:00:00 2001 From: Akash Negi <95514575+AkashNegi1@users.noreply.github.com> Date: Wed, 24 Jun 2026 23:44:14 +0530 Subject: [PATCH] Task/remove deprecated SymbolProfile from PortfolioHoldingResponse (#7094) * Remove deprecated SymbolProfile * Update changelog --- CHANGELOG.md | 4 +- .../src/app/portfolio/portfolio.service.ts | 1 - .../holding-detail-dialog.component.ts | 52 +++++++++++------- .../holding-detail-dialog.html | 54 +++++++++---------- .../portfolio-holding-response.interface.ts | 4 -- 5 files changed, 60 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8a0ca796..76dbe113a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the throughput of the market data gathering queue by applying the rate limit per data source - Decreased the rate limiter duration of the market data gathering queue jobs from 4 to 3 seconds - -### Changed - +- Removed the deprecated `SymbolProfile` field from the endpoint `GET api/v1/portfolio/holding/:dataSource/:symbol` - Upgraded `@simplewebauthn/browser` and `@simplewebauthn/server` from version `13.2.2` to `13.3` ### Fixed diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 77cbb5b49..41697b346 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -957,7 +957,6 @@ export class PortfolioService { marketPrice, marketPriceMax, marketPriceMin, - SymbolProfile, tags, assetProfile: { assetClass: SymbolProfile.assetClass, diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index e14c638be..6fa3a4853 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -116,6 +116,19 @@ export class GfHoldingDetailDialogComponent implements OnInit { protected accounts: Account[]; protected activitiesCount: number; protected assetClass: string; + protected assetProfile: Pick< + EnhancedSymbolProfile, + | 'assetClass' + | 'assetSubClass' + | 'countries' + | 'currency' + | 'dataSource' + | 'isin' + | 'name' + | 'sectors' + | 'symbol' + | 'userId' + >; protected assetSubClass: string; protected averagePrice: number; protected averagePricePrecision = 2; @@ -164,7 +177,6 @@ export class GfHoldingDetailDialogComponent implements OnInit { }; protected sortColumn = 'date'; protected sortDirection: SortDirection = 'desc'; - protected SymbolProfile: EnhancedSymbolProfile; protected tagsAvailable: Tag[]; protected readonly translate = translate; protected user: User; @@ -266,6 +278,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { .subscribe( ({ activitiesCount, + assetProfile, averagePrice, dataProviderInfo, dateOfFirstActivity, @@ -280,11 +293,11 @@ export class GfHoldingDetailDialogComponent implements OnInit { netPerformancePercentWithCurrencyEffect, netPerformanceWithCurrencyEffect, quantity, - SymbolProfile, tags, value }) => { this.activitiesCount = activitiesCount; + this.assetProfile = assetProfile; this.averagePrice = averagePrice; if ( @@ -322,8 +335,8 @@ export class GfHoldingDetailDialogComponent implements OnInit { this.user?.permissions, permissions.readMarketDataOfOwnAssetProfile ) && - SymbolProfile?.dataSource === 'MANUAL' && - SymbolProfile?.userId === this.user?.id; + assetProfile?.dataSource === 'MANUAL' && + assetProfile?.userId === this.user?.id; this.historicalDataItems = historicalData.map( ({ averagePrice, date, marketPrice }) => { @@ -402,7 +415,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { if (Number.isInteger(this.quantity)) { this.quantityPrecision = 0; - } else if (SymbolProfile?.assetSubClass === 'CRYPTOCURRENCY') { + } else if (assetProfile?.assetSubClass === 'CRYPTOCURRENCY') { if (this.quantity < 10) { this.quantityPrecision = 8; } else if (this.quantity < 1000) { @@ -413,7 +426,6 @@ export class GfHoldingDetailDialogComponent implements OnInit { } this.sectors = {}; - this.SymbolProfile = SymbolProfile; this.tags = tags.map((tag) => { return { @@ -427,21 +439,21 @@ export class GfHoldingDetailDialogComponent implements OnInit { this.value = value; const reportDataGlitchSubject = `Ghostfolio Data Glitch Report${ - this.SymbolProfile?.symbol ? ` (${this.SymbolProfile.symbol})` : '' + this.assetProfile?.symbol ? ` (${this.assetProfile.symbol})` : '' }`; - this.reportDataGlitchMail = `mailto:hi@ghostfol.io?Subject=${reportDataGlitchSubject}&body=Hello%0D%0DI would like to report a data glitch for%0D%0DSymbol: ${this.SymbolProfile?.symbol}%0DData Source: ${this.SymbolProfile?.dataSource}%0D%0DAdditional notes:%0D%0DCan you please take a look?%0D%0DKind regards`; + this.reportDataGlitchMail = `mailto:hi@ghostfol.io?Subject=${reportDataGlitchSubject}&body=Hello%0D%0DI would like to report a data glitch for%0D%0DSymbol: ${this.assetProfile?.symbol}%0DData Source: ${this.assetProfile?.dataSource}%0D%0DAdditional notes:%0D%0DCan you please take a look?%0D%0DKind regards`; - if (this.SymbolProfile?.assetClass) { - this.assetClass = translate(this.SymbolProfile?.assetClass); + if (this.assetProfile?.assetClass) { + this.assetClass = translate(this.assetProfile?.assetClass); } - if (this.SymbolProfile?.assetSubClass) { - this.assetSubClass = translate(this.SymbolProfile?.assetSubClass); + if (this.assetProfile?.assetSubClass) { + this.assetSubClass = translate(this.assetProfile?.assetSubClass); } - if (this.SymbolProfile?.countries?.length > 0) { - for (const country of this.SymbolProfile.countries) { + if (this.assetProfile?.countries?.length > 0) { + for (const country of this.assetProfile.countries) { this.countries[country.code] = { name: getCountryName({ code: country.code }), value: country.weight @@ -449,8 +461,8 @@ export class GfHoldingDetailDialogComponent implements OnInit { } } - if (this.SymbolProfile?.sectors?.length > 0) { - for (const sector of this.SymbolProfile.sectors) { + if (this.assetProfile?.sectors?.length > 0) { + for (const sector of this.assetProfile.sectors) { this.sectors[sector.name] = { name: translate(sector.name), value: sector.weight @@ -570,12 +582,12 @@ export class GfHoldingDetailDialogComponent implements OnInit { const activity: CreateOrderDto = { accountId: this.accounts.length === 1 ? this.accounts[0].id : undefined, comment: undefined, - currency: this.SymbolProfile?.currency ?? '', - dataSource: this.SymbolProfile?.dataSource, + currency: this.assetProfile?.currency ?? '', + dataSource: this.assetProfile?.dataSource, date: today.toISOString(), fee: 0, quantity: this.quantity, - symbol: this.SymbolProfile?.symbol ?? '', + symbol: this.assetProfile?.symbol ?? '', tags: this.tags.map(({ id }) => { return id; }), @@ -606,7 +618,7 @@ export class GfHoldingDetailDialogComponent implements OnInit { .subscribe((data) => { downloadAsFile({ content: data, - fileName: `ghostfolio-export-${this.SymbolProfile?.symbol}-${format( + fileName: `ghostfolio-export-${this.assetProfile?.symbol}-${format( parseISO(data.meta.date), 'yyyyMMddHHmm' )}.json`, diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index 0d5691874..ff1d19cc3 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1,7 +1,7 @@ @@ -24,11 +24,11 @@ [benchmarkDataItems]="benchmarkDataItems" [benchmarkLabel]="benchmarkLabel" [colorScheme]="data.colorScheme" - [currency]="SymbolProfile?.currency" + [currency]="assetProfile?.currency" [historicalDataItems]="historicalDataItems" [isAnimated]="true" [label]=" - isUUID(data.symbol) ? (SymbolProfile?.name ?? data.symbol) : data.symbol + isUUID(data.symbol) ? (assetProfile?.name ?? data.symbol) : data.symbol " [locale]="data.locale" [showGradient]="true" @@ -60,8 +60,8 @@ [value]="netPerformanceWithCurrencyEffect" > @if ( - SymbolProfile?.currency && - data.baseCurrency !== SymbolProfile?.currency + assetProfile?.currency && + data.baseCurrency !== assetProfile?.currency ) { Change with currency effect } @else { @@ -80,8 +80,8 @@ [value]="netPerformancePercentWithCurrencyEffect" > @if ( - SymbolProfile?.currency && - data.baseCurrency !== SymbolProfile?.currency + assetProfile?.currency && + data.baseCurrency !== assetProfile?.currency ) { Performance with currency effect } @else { @@ -96,7 +96,7 @@ [isCurrency]="true" [locale]="data.locale" [precision]="averagePricePrecision" - [unit]="SymbolProfile?.currency" + [unit]="assetProfile?.currency" [value]="averagePrice" >Average Unit Price @@ -108,7 +108,7 @@ [isCurrency]="true" [locale]="data.locale" [precision]="marketPricePrecision" - [unit]="SymbolProfile?.currency" + [unit]="assetProfile?.currency" [value]="marketPrice" >Market Price @@ -124,7 +124,7 @@ [isCurrency]="true" [locale]="data.locale" [precision]="marketPriceMinPrecision" - [unit]="SymbolProfile?.currency" + [unit]="assetProfile?.currency" [value]="marketPriceMin" >Minimum Price @@ -140,7 +140,7 @@ [isCurrency]="true" [locale]="data.locale" [precision]="marketPriceMaxPrecision" - [unit]="SymbolProfile?.currency" + [unit]="assetProfile?.currency" [value]="marketPriceMax" >Maximum Price @@ -250,23 +250,23 @@ > @if ( - SymbolProfile?.countries?.length > 0 || - SymbolProfile?.sectors?.length > 0 + assetProfile?.countries?.length > 0 || + assetProfile?.sectors?.length > 0 ) { @if ( - SymbolProfile?.countries?.length === 1 && - SymbolProfile?.sectors?.length === 1 + assetProfile?.countries?.length === 1 && + assetProfile?.sectors?.length === 1 ) {
Sector
- @if (SymbolProfile?.countries?.length === 1) { + @if (assetProfile?.countries?.length === 1) {
CountrySymbol
@@ -322,8 +322,8 @@ ISIN @@ -404,12 +404,12 @@
Market Data
@@ -462,8 +462,8 @@ mat-stroked-button [queryParams]="{ assetProfileDialog: true, - dataSource: SymbolProfile?.dataSource, - symbol: SymbolProfile?.symbol + dataSource: assetProfile?.dataSource, + symbol: assetProfile?.symbol }" [routerLink]="routerLinkAdminControlMarketData" (click)="onClose()" diff --git a/libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts b/libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts index 3b07666c9..075234e6a 100644 --- a/libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts +++ b/libs/common/src/lib/interfaces/responses/portfolio-holding-response.interface.ts @@ -44,10 +44,6 @@ export interface PortfolioHoldingResponse { netPerformanceWithCurrencyEffect: number; performances: Benchmark['performances']; quantity: number; - - /* @deprecated */ - SymbolProfile: EnhancedSymbolProfile; - tags: Tag[]; value: number; }