Browse Source

Task/remove deprecated attributes from holdings of public portfolio endpoint response (#6923)

* Remove deprecated attributes

* Update changelog
pull/6915/head
Thomas Kaul 3 days ago
committed by GitHub
parent
commit
5b9df03a1e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 24
      apps/api/src/app/endpoints/public/public.controller.ts
  3. 15
      apps/api/src/app/portfolio/portfolio.controller.ts
  4. 16
      apps/client/src/app/pages/public/public-page.component.ts
  5. 22
      libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts
  6. 23
      libs/ui/src/lib/holdings-table/holdings-table.component.html

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Removed the deprecated attributes (`assetClass`, `countries`, `currency`, `dataSource`, `name`, `sectors`, `symbol` and `url`) from the holdings of the public portfolio endpoint response
- Upgraded `@keyv/redis` from version `4.4.0` to `5.1.6` - Upgraded `@keyv/redis` from version `4.4.0` to `5.1.6`
## 3.4.0 - 2026-05-21 ## 3.4.0 - 2026-05-21

24
apps/api/src/app/endpoints/public/public.controller.ts

@ -167,19 +167,25 @@ export class PublicController {
publicPortfolioResponse.holdings[symbol] = { publicPortfolioResponse.holdings[symbol] = {
allocationInPercentage: allocationInPercentage:
portfolioPosition.valueInBaseCurrency / totalValue, portfolioPosition.valueInBaseCurrency / totalValue,
assetClass: hasDetails ? portfolioPosition.assetClass : undefined, assetProfile: {
assetProfile: hasDetails ? portfolioPosition.assetProfile : undefined, ...portfolioPosition.assetProfile,
countries: hasDetails ? portfolioPosition.countries : [], ...(hasDetails
currency: hasDetails ? portfolioPosition.currency : undefined, ? {}
dataSource: portfolioPosition.dataSource, : {
assetClass: undefined,
assetClassLabel: undefined,
assetSubClass: undefined,
assetSubClassLabel: undefined,
countries: [],
currency: undefined,
holdings: [],
sectors: []
})
},
dateOfFirstActivity: portfolioPosition.dateOfFirstActivity, dateOfFirstActivity: portfolioPosition.dateOfFirstActivity,
markets: hasDetails ? portfolioPosition.markets : undefined, markets: hasDetails ? portfolioPosition.markets : undefined,
name: portfolioPosition.name,
netPerformancePercentWithCurrencyEffect: netPerformancePercentWithCurrencyEffect:
portfolioPosition.netPerformancePercentWithCurrencyEffect, portfolioPosition.netPerformancePercentWithCurrencyEffect,
sectors: hasDetails ? portfolioPosition.sectors : [],
symbol: portfolioPosition.symbol,
url: portfolioPosition.url,
valueInPercentage: portfolioPosition.valueInBaseCurrency / totalValue valueInPercentage: portfolioPosition.valueInBaseCurrency / totalValue
}; };
} }

15
apps/api/src/app/portfolio/portfolio.controller.ts

@ -220,6 +220,21 @@ export class PortfolioController {
hasDetails || portfolioPosition.assetClass === AssetClass.LIQUIDITY hasDetails || portfolioPosition.assetClass === AssetClass.LIQUIDITY
? portfolioPosition.assetClass ? portfolioPosition.assetClass
: undefined, : undefined,
assetProfile: {
...portfolioPosition.assetProfile,
...(hasDetails
? {}
: {
assetClass: undefined,
assetClassLabel: undefined,
assetSubClass: undefined,
assetSubClassLabel: undefined,
countries: [],
currency: undefined,
holdings: [],
sectors: []
})
},
assetSubClass: assetSubClass:
hasDetails || portfolioPosition.assetSubClass === AssetSubClass.CASH hasDetails || portfolioPosition.assetSubClass === AssetSubClass.CASH
? portfolioPosition.assetSubClass ? portfolioPosition.assetSubClass

16
apps/client/src/app/pages/public/public-page.component.ts

@ -172,16 +172,16 @@ export class GfPublicPageComponent implements OnInit {
this.holdings.push(position); this.holdings.push(position);
this.positions[symbol] = { this.positions[symbol] = {
currency: position.currency, currency: position.assetProfile.currency,
name: position.name, name: position.assetProfile.name,
value: position.allocationInPercentage value: position.allocationInPercentage
}; };
if (position.assetClass !== AssetClass.LIQUIDITY) { if (position.assetProfile.assetClass !== AssetClass.LIQUIDITY) {
// Prepare analysis data by continents, countries, holdings and sectors except for liquidity // Prepare analysis data by continents, countries, holdings and sectors except for liquidity
if (position.countries.length > 0) { if (position.assetProfile.countries.length > 0) {
for (const country of position.countries) { for (const country of position.assetProfile.countries) {
const { code, continent, name, weight } = country; const { code, continent, name, weight } = country;
if (this.continents[continent]?.value) { if (this.continents[continent]?.value) {
@ -220,8 +220,8 @@ export class GfPublicPageComponent implements OnInit {
0; 0;
} }
if (position.sectors.length > 0) { if (position.assetProfile.sectors.length > 0) {
for (const sector of position.sectors) { for (const sector of position.assetProfile.sectors) {
const { name, weight } = sector; const { name, weight } = sector;
if (this.sectors[name]?.value) { if (this.sectors[name]?.value) {
@ -245,7 +245,7 @@ export class GfPublicPageComponent implements OnInit {
} }
this.symbols[prettifySymbol(symbol)] = { this.symbols[prettifySymbol(symbol)] = {
name: position.name, name: position.assetProfile.name,
symbol: prettifySymbol(symbol), symbol: prettifySymbol(symbol),
value: isNumber(position.valueInBaseCurrency) value: isNumber(position.valueInBaseCurrency)
? position.valueInBaseCurrency ? position.valueInBaseCurrency

22
libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts

@ -14,32 +14,10 @@ export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
[symbol: string]: Pick< [symbol: string]: Pick<
PortfolioPosition, PortfolioPosition,
| 'allocationInPercentage' | 'allocationInPercentage'
/** @deprecated */
| 'assetClass'
| 'assetProfile' | 'assetProfile'
/** @deprecated */
| 'countries'
| 'currency'
/** @deprecated */
| 'dataSource'
| 'dateOfFirstActivity' | 'dateOfFirstActivity'
| 'markets' | 'markets'
/** @deprecated */
| 'name'
| 'netPerformancePercentWithCurrencyEffect' | 'netPerformancePercentWithCurrencyEffect'
/** @deprecated */
| 'sectors'
/** @deprecated */
| 'symbol'
/** @deprecated */
| 'url'
| 'valueInBaseCurrency' | 'valueInBaseCurrency'
| 'valueInPercentage' | 'valueInPercentage'
>; >;

23
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -11,26 +11,31 @@
<th *matHeaderCellDef class="px-1" mat-header-cell></th> <th *matHeaderCellDef class="px-1" mat-header-cell></th>
<td *matCellDef="let element" class="px-1 text-center" mat-cell> <td *matCellDef="let element" class="px-1 text-center" mat-cell>
<gf-entity-logo <gf-entity-logo
[dataSource]="element.dataSource" [dataSource]="element.assetProfile.dataSource"
[symbol]="element.symbol" [symbol]="element.assetProfile.symbol"
[tooltip]="element.name" [tooltip]="element.assetProfile.name"
/> />
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="nameWithSymbol"> <ng-container matColumnDef="nameWithSymbol">
<th *matHeaderCellDef class="px-1" mat-header-cell mat-sort-header="name"> <th
*matHeaderCellDef
class="px-1"
mat-header-cell
mat-sort-header="assetProfile.name"
>
<ng-container i18n>Name</ng-container> <ng-container i18n>Name</ng-container>
</th> </th>
<td *matCellDef="let element" class="line-height-1 px-1" mat-cell> <td *matCellDef="let element" class="line-height-1 px-1" mat-cell>
<div class="text-truncate"> <div class="text-truncate">
{{ element.name }} {{ element.assetProfile.name }}
@if (element.name === element.symbol) { @if (element.assetProfile.name === element.assetProfile.symbol) {
<span>({{ element.assetProfile.assetSubClassLabel }})</span> <span>({{ element.assetProfile.assetSubClassLabel }})</span>
} }
</div> </div>
<div> <div>
<small class="text-muted">{{ element.symbol }}</small> <small class="text-muted">{{ element.assetProfile.symbol }}</small>
</div> </div>
</td> </td>
</ng-container> </ng-container>
@ -185,8 +190,8 @@
(click)=" (click)="
canShowDetails(row) && canShowDetails(row) &&
onOpenHoldingDialog({ onOpenHoldingDialog({
dataSource: row.dataSource, dataSource: row.assetProfile.dataSource,
symbol: row.symbol symbol: row.assetProfile.symbol
}) })
" "
></tr> ></tr>

Loading…
Cancel
Save