From c5c11929008ac5bf6c4e56bcf9fe337f3a99d4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20G=C3=BCnther?= Date: Sat, 11 Oct 2025 17:07:42 +0200 Subject: [PATCH 1/8] Bugfix/import of custom asset profiles (#5670) * Import of custom asset profiles * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/import/import.service.ts | 38 ++++++++++++++++ test/import/ok/penthouse-apartment.json | 53 +++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 test/import/ok/penthouse-apartment.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a7b3b48..c7472e421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the server startup message to properly display IPv6 addresses +- Fixed an issue where importing custom asset profiles failed due to validation errors ## 2.207.0 - 2025-10-08 diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 82231d237..69ec781c3 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -373,6 +373,7 @@ export class ImportService { const assetProfiles = await this.validateActivities({ activitiesDto, + assetProfilesWithMarketDataDto, maxActivitiesToImport, user }); @@ -698,10 +699,12 @@ export class ImportService { private async validateActivities({ activitiesDto, + assetProfilesWithMarketDataDto, maxActivitiesToImport, user }: { activitiesDto: Partial[]; + assetProfilesWithMarketDataDto: ImportDataDto['assetProfiles']; maxActivitiesToImport: number; user: UserWithSettings; }) { @@ -749,6 +752,41 @@ export class ImportService { )?.[symbol] }; + if (!assetProfile?.name) { + const assetProfileInImport = assetProfilesWithMarketDataDto?.find( + (profile) => { + return ( + profile.dataSource === dataSource && profile.symbol === symbol + ); + } + ); + + if (assetProfileInImport) { + // Merge all fields of custom asset profiles into the validation object + Object.assign(assetProfile, { + assetClass: assetProfileInImport.assetClass, + assetSubClass: assetProfileInImport.assetSubClass, + comment: assetProfileInImport.comment, + countries: assetProfileInImport.countries, + currency: assetProfileInImport.currency, + cusip: assetProfileInImport.cusip, + dataSource: assetProfileInImport.dataSource, + figi: assetProfileInImport.figi, + figiComposite: assetProfileInImport.figiComposite, + figiShareClass: assetProfileInImport.figiShareClass, + holdings: assetProfileInImport.holdings, + isActive: assetProfileInImport.isActive, + isin: assetProfileInImport.isin, + name: assetProfileInImport.name, + scraperConfiguration: assetProfileInImport.scraperConfiguration, + sectors: assetProfileInImport.sectors, + symbol: assetProfileInImport.symbol, + symbolMapping: assetProfileInImport.symbolMapping, + url: assetProfileInImport.url + }); + } + } + if ( (dataSource !== 'MANUAL' && type === 'BUY') || type === 'DIVIDEND' || diff --git a/test/import/ok/penthouse-apartment.json b/test/import/ok/penthouse-apartment.json new file mode 100644 index 000000000..3b230cf76 --- /dev/null +++ b/test/import/ok/penthouse-apartment.json @@ -0,0 +1,53 @@ +{ + "meta": { + "date": "2023-02-05T00:00:00.000Z", + "version": "dev" + }, + "accounts": [], + "assetProfiles": [ + { + "assetClass": null, + "assetSubClass": null, + "comment": null, + "countries": [], + "currency": "USD", + "cusip": null, + "dataSource": "MANUAL", + "figi": null, + "figiComposite": null, + "figiShareClass": null, + "holdings": [], + "isActive": true, + "isin": null, + "marketData": [], + "name": "Penthouse Apartment", + "scraperConfiguration": null, + "sectors": [], + "symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1", + "symbolMapping": {}, + "url": null + } + ], + "platforms": [], + "tags": [], + "activities": [ + { + "accountId": null, + "comment": null, + "currency": "USD", + "dataSource": "MANUAL", + "date": "2022-01-01T00:00:00.000Z", + "fee": 0, + "quantity": 1, + "symbol": "7e91b7d4-1430-4212-8380-289a06c9bbc1", + "tags": [], + "type": "BUY", + "unitPrice": 500000, + } + ], + "user": { + "settings": { + "currency": "USD" + } + } +} From 13838bed6d20307eccf3ea02cb632ea0e5642b5c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 11 Oct 2025 20:12:37 +0200 Subject: [PATCH 2/8] Feature/improve language localization for de 20250811 (#5730) * Update translation * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.de.xlf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7472e421..1128a6205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed the _As seen in_ section on the landing page to an animated carousel - Refactored various components to use self-closing tags +- Improved the language localization for German (`de`) ### Fixed diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 3e12ef852..9211617f0 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -5409,7 +5409,7 @@ , - entnehmen, +  entnehmen, apps/client/src/app/pages/portfolio/fire/fire-page.html 93 From d2fe16c794edc91334b8c58ecb492705b59ef694 Mon Sep 17 00:00:00 2001 From: Tanbir Ali <124070023+tanbirali@users.noreply.github.com> Date: Sat, 11 Oct 2025 23:44:25 +0530 Subject: [PATCH 3/8] Task/refactor transactionCount to activitiesCount in portfolio holding response (#5709) * Refactor transactionCount to activitiesCount in portfolio holding response * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/portfolio.service.ts | 6 +++--- .../holding-detail-dialog.component.ts | 8 +++----- .../holding-detail-dialog/holding-detail-dialog.html | 6 +++--- .../responses/portfolio-holding-response.interface.ts | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1128a6205..d178ae97a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Changed the _As seen in_ section on the landing page to an animated carousel +- Refactored `transactionCount` to `activitiesCount` in the endpoint `GET api/v1/portfolio/holding/:dataSource/:symbol` - Refactored various components to use self-closing tags - Improved the language localization for German (`de`) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index e73f79784..f774378ef 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -778,6 +778,7 @@ export class PortfolioService { if (activities.length === 0) { return { activities: [], + activitiesCount: 0, averagePrice: undefined, dataProviderInfo: undefined, dividendInBaseCurrency: undefined, @@ -802,7 +803,6 @@ export class PortfolioService { quantity: undefined, SymbolProfile: undefined, tags: [], - transactionCount: undefined, value: undefined }; } @@ -966,8 +966,8 @@ export class PortfolioService { marketPriceMin, SymbolProfile, tags, - transactionCount, activities: activitiesOfHolding, + activitiesCount: transactionCount, averagePrice: averagePrice.toNumber(), dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0], dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), @@ -1070,6 +1070,7 @@ export class PortfolioService { marketPriceMin, SymbolProfile, activities: [], + activitiesCount: 0, averagePrice: 0, dataProviderInfo: undefined, dividendInBaseCurrency: 0, @@ -1095,7 +1096,6 @@ export class PortfolioService { }, quantity: 0, tags: [], - transactionCount: undefined, value: 0 }; } 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 8f6616174..d4c1c59c1 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 @@ -100,6 +100,7 @@ import { HoldingDetailDialogParams } from './interfaces/interfaces'; templateUrl: 'holding-detail-dialog.html' }) export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { + public activitiesCount: number; public activityForm: FormGroup; public accounts: Account[]; public assetClass: string; @@ -151,8 +152,6 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { public SymbolProfile: EnhancedSymbolProfile; public tags: Tag[]; public tagsAvailable: Tag[]; - public totalItems: number; - public transactionCount: number; public user: User; public value: number; @@ -261,6 +260,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { .pipe(takeUntil(this.unsubscribeSubject)) .subscribe( ({ + activitiesCount, averagePrice, dataProviderInfo, dividendInBaseCurrency, @@ -279,9 +279,9 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { quantity, SymbolProfile, tags, - transactionCount, value }) => { + this.activitiesCount = activitiesCount; this.averagePrice = averagePrice; if ( @@ -429,8 +429,6 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { this.activityForm.setValue({ tags: this.tags }, { emitEvent: false }); - this.transactionCount = transactionCount; - this.totalItems = transactionCount; this.value = value; if (SymbolProfile?.assetClass) { 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 651f01a65..298692303 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 @@ -223,9 +223,9 @@ - @if (transactionCount === 1) { + @if (activitiesCount === 1) { Activity } @else { Activities @@ -363,7 +363,7 @@ [sortColumn]="sortColumn" [sortDirection]="sortDirection" [sortDisabled]="true" - [totalItems]="totalItems" + [totalItems]="activitiesCount" (activityToClone)="onCloneActivity($event)" (activityToUpdate)="onUpdateActivity($event)" (export)="onExport()" 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 000460228..b82a8f85d 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 @@ -10,6 +10,7 @@ import { Tag } from '@prisma/client'; export interface PortfolioHoldingResponse { activities: Activity[]; + activitiesCount: number; averagePrice: number; dataProviderInfo: DataProviderInfo; dividendInBaseCurrency: number; @@ -34,6 +35,5 @@ export interface PortfolioHoldingResponse { quantity: number; SymbolProfile: EnhancedSymbolProfile; tags: Tag[]; - transactionCount: number; value: number; } From df16aba5c69d3c53557e801b19616600f8cdb2b1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 11 Oct 2025 20:37:37 +0200 Subject: [PATCH 4/8] Feature/upgrade prisma to version 6.17.1 (#5732) * Upgrade prisma to version 6.17.1 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 72 +++++++++++++++++++++++------------------------ package.json | 4 +-- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d178ae97a..e26093a0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactored `transactionCount` to `activitiesCount` in the endpoint `GET api/v1/portfolio/holding/:dataSource/:symbol` - Refactored various components to use self-closing tags - Improved the language localization for German (`de`) +- Upgraded `prisma` from version `6.16.1` to `6.16.3` ### Fixed diff --git a/package-lock.json b/package-lock.json index 55e453cce..0f313a101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "@nestjs/schedule": "6.0.0", "@nestjs/serve-static": "5.0.3", "@openrouter/ai-sdk-provider": "0.7.2", - "@prisma/client": "6.16.3", + "@prisma/client": "6.17.1", "@simplewebauthn/browser": "13.1.0", "@simplewebauthn/server": "13.1.1", "@stripe/stripe-js": "7.9.0", @@ -149,7 +149,7 @@ "nx": "21.5.1", "prettier": "3.6.2", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.16.3", + "prisma": "6.17.1", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.3.0", @@ -11960,9 +11960,9 @@ "license": "MIT" }, "node_modules/@prisma/client": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.3.tgz", - "integrity": "sha512-JfNfAtXG+/lIopsvoZlZiH2k5yNx87mcTS4t9/S5oufM1nKdXYxOvpDC1XoTCFBa5cQh7uXnbMPsmZrwZY80xw==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.17.1.tgz", + "integrity": "sha512-zL58jbLzYamjnNnmNA51IOZdbk5ci03KviXCuB0Tydc9btH2kDWsi1pQm2VecviRTM7jGia0OPPkgpGnT3nKvw==", "hasInstallScript": true, "license": "Apache-2.0", "engines": { @@ -11982,9 +11982,9 @@ } }, "node_modules/@prisma/config": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.3.tgz", - "integrity": "sha512-VlsLnG4oOuKGGMToEeVaRhoTBZu5H3q51jTQXb/diRags3WV0+BQK5MolJTtP6G7COlzoXmWeS11rNBtvg+qFQ==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.17.1.tgz", + "integrity": "sha512-fs8wY6DsvOCzuiyWVckrVs1LOcbY4LZNz8ki4uUIQ28jCCzojTGqdLhN2Jl5lDnC1yI8/gNIKpsWDM8pLhOdwA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { @@ -11995,53 +11995,53 @@ } }, "node_modules/@prisma/debug": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.3.tgz", - "integrity": "sha512-89DdqWtdKd7qoc9/qJCKLTazj3W3zPEiz0hc7HfZdpjzm21c7orOUB5oHWJsG+4KbV4cWU5pefq3CuDVYF9vgA==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.17.1.tgz", + "integrity": "sha512-Vf7Tt5Wh9XcndpbmeotuqOMLWPTjEKCsgojxXP2oxE1/xYe7PtnP76hsouG9vis6fctX+TxgmwxTuYi/+xc7dQ==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.3.tgz", - "integrity": "sha512-b+Rl4nzQDcoqe6RIpSHv8f5lLnwdDGvXhHjGDiokObguAAv/O1KaX1Oc69mBW/GFWKQpCkOraobLjU6s1h8HGg==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.17.1.tgz", + "integrity": "sha512-D95Ik3GYZkqZ8lSR4EyFOJ/tR33FcYRP8kK61o+WMsyD10UfJwd7+YielflHfKwiGodcqKqoraWw8ElAgMDbPw==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.3", - "@prisma/engines-version": "6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", - "@prisma/fetch-engine": "6.16.3", - "@prisma/get-platform": "6.16.3" + "@prisma/debug": "6.17.1", + "@prisma/engines-version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", + "@prisma/fetch-engine": "6.17.1", + "@prisma/get-platform": "6.17.1" } }, "node_modules/@prisma/engines-version": { - "version": "6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a.tgz", - "integrity": "sha512-fftRmosBex48Ph1v2ll1FrPpirwtPZpNkE5CDCY1Lw2SD2ctyrLlVlHiuxDAAlALwWBOkPbAll4+EaqdGuMhJw==", + "version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac.tgz", + "integrity": "sha512-17140E3huOuD9lMdJ9+SF/juOf3WR3sTJMVyyenzqUPbuH+89nPhSWcrY+Mf7tmSs6HvaO+7S+HkELinn6bhdg==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.3.tgz", - "integrity": "sha512-bUoRIkVaI+CCaVGrSfcKev0/Mk4ateubqWqGZvQ9uCqFv2ENwWIR3OeNuGin96nZn5+SkebcD7RGgKr/+mJelw==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.17.1.tgz", + "integrity": "sha512-AYZiHOs184qkDMiTeshyJCtyL4yERkjfTkJiSJdYuSfc24m94lTNL5+GFinZ6vVz+ktX4NJzHKn1zIFzGTWrWg==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.3", - "@prisma/engines-version": "6.16.1-1.bb420e667c1820a8c05a38023385f6cc7ef8e83a", - "@prisma/get-platform": "6.16.3" + "@prisma/debug": "6.17.1", + "@prisma/engines-version": "6.17.1-1.272a37d34178c2894197e17273bf937f25acdeac", + "@prisma/get-platform": "6.17.1" } }, "node_modules/@prisma/get-platform": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.3.tgz", - "integrity": "sha512-X1LxiFXinJ4iQehrodGp0f66Dv6cDL0GbRlcCoLtSu6f4Wi+hgo7eND/afIs5029GQLgNWKZ46vn8hjyXTsHLA==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.17.1.tgz", + "integrity": "sha512-AKEn6fsfz0r482S5KRDFlIGEaq9wLNcgalD1adL+fPcFFblIKs1sD81kY/utrHdqKuVC6E1XSRpegDK3ZLL4Qg==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.16.3" + "@prisma/debug": "6.17.1" } }, "node_modules/@redis/client": { @@ -35747,15 +35747,15 @@ } }, "node_modules/prisma": { - "version": "6.16.3", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.3.tgz", - "integrity": "sha512-4tJq3KB9WRshH5+QmzOLV54YMkNlKOtLKaSdvraI5kC/axF47HuOw6zDM8xrxJ6s9o2WodY654On4XKkrobQdQ==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.17.1.tgz", + "integrity": "sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.16.3", - "@prisma/engines": "6.16.3" + "@prisma/config": "6.17.1", + "@prisma/engines": "6.17.1" }, "bin": { "prisma": "build/index.js" diff --git a/package.json b/package.json index 5f99a4d11..b0a801bf8 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "@nestjs/schedule": "6.0.0", "@nestjs/serve-static": "5.0.3", "@openrouter/ai-sdk-provider": "0.7.2", - "@prisma/client": "6.16.3", + "@prisma/client": "6.17.1", "@simplewebauthn/browser": "13.1.0", "@simplewebauthn/server": "13.1.1", "@stripe/stripe-js": "7.9.0", @@ -195,7 +195,7 @@ "nx": "21.5.1", "prettier": "3.6.2", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.16.3", + "prisma": "6.17.1", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.3.0", From a9f38aaf90451079b7db39e31db661932a6514ce Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 11 Oct 2025 20:38:09 +0200 Subject: [PATCH 5/8] Task/remove deprecated position endpoints from portfolio controller (#5733) * Remove deprecated endpoints * GET api/v1/portfolio/position/:dataSource/:symbol * PUT api/v1/portfolio/position/:dataSource/:symbol/tags * Update changelog --- CHANGELOG.md | 2 + .../src/app/portfolio/portfolio.controller.ts | 66 ------------------- 2 files changed, 2 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e26093a0c..01883f0f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed the _As seen in_ section on the landing page to an animated carousel - Refactored `transactionCount` to `activitiesCount` in the endpoint `GET api/v1/portfolio/holding/:dataSource/:symbol` - Refactored various components to use self-closing tags +- Removed the deprecated endpoint `GET api/v1/portfolio/position/:dataSource/:symbol` +- Removed the deprecated endpoint `PUT api/v1/portfolio/position/:dataSource/:symbol/tags` - Improved the language localization for German (`de`) - Upgraded `prisma` from version `6.16.1` to `6.16.3` diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 5659818a8..19b0636c7 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -610,36 +610,6 @@ export class PortfolioController { return performanceInformation; } - /** - * @deprecated - */ - @Get('position/:dataSource/:symbol') - @UseInterceptors(RedactValuesInResponseInterceptor) - @UseInterceptors(TransformDataSourceInRequestInterceptor) - @UseInterceptors(TransformDataSourceInResponseInterceptor) - @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - public async getPosition( - @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, - @Param('dataSource') dataSource: DataSource, - @Param('symbol') symbol: string - ): Promise { - const holding = await this.portfolioService.getHolding({ - dataSource, - impersonationId, - symbol, - userId: this.request.user.id - }); - - if (!holding) { - throw new HttpException( - getReasonPhrase(StatusCodes.NOT_FOUND), - StatusCodes.NOT_FOUND - ); - } - - return holding; - } - @Get('report') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async getReport( @@ -699,40 +669,4 @@ export class PortfolioController { userId: this.request.user.id }); } - - /** - * @deprecated - */ - @HasPermission(permissions.updateOrder) - @Put('position/:dataSource/:symbol/tags') - @UseInterceptors(TransformDataSourceInRequestInterceptor) - @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - public async updatePositionTags( - @Body() data: UpdateHoldingTagsDto, - @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, - @Param('dataSource') dataSource: DataSource, - @Param('symbol') symbol: string - ): Promise { - const holding = await this.portfolioService.getHolding({ - dataSource, - impersonationId, - symbol, - userId: this.request.user.id - }); - - if (!holding) { - throw new HttpException( - getReasonPhrase(StatusCodes.NOT_FOUND), - StatusCodes.NOT_FOUND - ); - } - - await this.portfolioService.updateTags({ - dataSource, - impersonationId, - symbol, - tags: data.tags, - userId: this.request.user.id - }); - } } From fc4d5774fa586f9eff75f2e1db3d6b67a4f05347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20=C5=81=C4=85giewka?= Date: Sat, 11 Oct 2025 20:42:40 +0200 Subject: [PATCH 6/8] =?UTF-8?q?Bugfix/enable=20IPv6=20connectivity=C2=A0fo?= =?UTF-8?q?r=20Redis=20in=20job=20queue=20module=20(#5726)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enable IPv6 connectivity for Redis in job queue module * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/app.module.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01883f0f3..6139cbbab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the server startup message to properly display IPv6 addresses +- Enabled IPv6 connectivity for _Redis_ in the job queue module by setting the address family - Fixed an issue where importing custom asset profiles failed due to validation errors ## 2.207.0 - 2025-10-08 diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 8596aa0eb..86ceede28 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -71,9 +71,10 @@ import { UserModule } from './user/user.module'; BullModule.forRoot({ redis: { db: parseInt(process.env.REDIS_DB ?? '0', 10), + family: 0, host: process.env.REDIS_HOST, - port: parseInt(process.env.REDIS_PORT ?? '6379', 10), - password: process.env.REDIS_PASSWORD + password: process.env.REDIS_PASSWORD, + port: parseInt(process.env.REDIS_PORT ?? '6379', 10) } }), CacheModule, From c1c7d82c836b4bc345055bba4090de7527d6c072 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 11 Oct 2025 20:44:59 +0200 Subject: [PATCH 7/8] Release 2.208.0 (#5734) --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6139cbbab..ce142e8e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.208.0 - 2025-10-11 ### Added diff --git a/package-lock.json b/package-lock.json index 0f313a101..75e1f50fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.207.0", + "version": "2.208.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.207.0", + "version": "2.208.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index b0a801bf8..28968c2c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.207.0", + "version": "2.208.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 20da95239ec211f3f834ee5014b5a3fd735f2dfb Mon Sep 17 00:00:00 2001 From: Lagmator22 <133108827+Lagmator22@users.noreply.github.com> Date: Sun, 12 Oct 2025 02:18:18 +0530 Subject: [PATCH 8/8] Task/refactor liabilities to liabilitiesInBaseCurrency in portfolio summary interface (#5725) * Refactor liabilities to liabilitiesInBaseCurrency --- apps/api/src/app/portfolio/portfolio.service.ts | 2 +- .../portfolio-summary/portfolio-summary.component.html | 7 +++++-- .../src/lib/interfaces/portfolio-summary.interface.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index f774378ef..a5bc10fbd 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -2106,7 +2106,7 @@ export class PortfolioService { .plus(fees) .toNumber(), interest: interest.toNumber(), - liabilities: liabilities.toNumber(), + liabilitiesInBaseCurrency: liabilities.toNumber(), totalInvestment: totalInvestment.toNumber(), totalValueInBaseCurrency: netWorth }; diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 19f125523..c8d710019 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -242,7 +242,10 @@
Liabilities
- @if (summary?.liabilities || summary?.liabilities === 0) { + @if ( + summary?.liabilitiesInBaseCurrency || + summary?.liabilitiesInBaseCurrency === 0 + ) { - }
diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index 05fac0ba0..092a4bb97 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -21,7 +21,7 @@ export interface PortfolioSummary extends PortfolioPerformance { grossPerformance: number; grossPerformanceWithCurrencyEffect: number; interest: number; - liabilities: number; + liabilitiesInBaseCurrency: number; totalBuy: number; totalSell: number; totalValueInBaseCurrency?: number;