Browse Source

Feature/extend holdings table of AI prompt with date of first activity (#7698)

* Extend holdings table with date of first activity

* Update changelog
pull/7700/head^2
Thomas Kaul 6 days ago
committed by GitHub
parent
commit
745a0eed35
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      CHANGELOG.md
  2. 13
      apps/api/src/app/endpoints/ai/ai.service.ts

7
CHANGELOG.md

@ -5,6 +5,13 @@ 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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Extended the holdings table by the date of first activity in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental)
- Extended the holdings table by the date of first activity in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental)
## 3.58.0 - 2026-08-22 ## 3.58.0 - 2026-08-22
### Changed ### Changed

13
apps/api/src/app/endpoints/ai/ai.service.ts

@ -5,12 +5,14 @@ import {
PROPERTY_API_KEY_OPENROUTER, PROPERTY_API_KEY_OPENROUTER,
PROPERTY_OPENROUTER_MODEL PROPERTY_OPENROUTER_MODEL
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { Filter } from '@ghostfolio/common/interfaces'; import { Filter } from '@ghostfolio/common/interfaces';
import type { AiPromptMode } from '@ghostfolio/common/types'; import type { AiPromptMode } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { createOpenRouter } from '@openrouter/ai-sdk-provider'; import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { generateText } from 'ai'; import { generateText } from 'ai';
import { format } from 'date-fns';
import type { ColumnDescriptor } from 'tablemark'; import type { ColumnDescriptor } from 'tablemark';
@Injectable() @Injectable()
@ -21,6 +23,7 @@ export class AiService {
| 'ASSET_CLASS' | 'ASSET_CLASS'
| 'ASSET_SUB_CLASS' | 'ASSET_SUB_CLASS'
| 'CURRENCY' | 'CURRENCY'
| 'DATE_OF_FIRST_ACTIVITY'
| 'NAME' | 'NAME'
| 'SYMBOL'; | 'SYMBOL';
} & ColumnDescriptor)[] = [ } & ColumnDescriptor)[] = [
@ -29,6 +32,7 @@ export class AiService {
{ key: 'CURRENCY', name: 'Currency' }, { key: 'CURRENCY', name: 'Currency' },
{ key: 'ASSET_CLASS', name: 'Asset Class' }, { key: 'ASSET_CLASS', name: 'Asset Class' },
{ key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' }, { key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' },
{ key: 'DATE_OF_FIRST_ACTIVITY', name: 'Date of First Activity' },
{ {
align: 'right', align: 'right',
key: 'ALLOCATION_PERCENTAGE', key: 'ALLOCATION_PERCENTAGE',
@ -104,7 +108,8 @@ export class AiService {
currency, currency,
name: label, name: label,
symbol symbol
} },
dateOfFirstActivity
}) => { }) => {
return AiService.HOLDINGS_TABLE_COLUMN_DEFINITIONS.reduce( return AiService.HOLDINGS_TABLE_COLUMN_DEFINITIONS.reduce(
(row, { key, name }) => { (row, { key, name }) => {
@ -125,6 +130,12 @@ export class AiService {
row[name] = currency; row[name] = currency;
break; break;
case 'DATE_OF_FIRST_ACTIVITY':
row[name] = dateOfFirstActivity
? format(dateOfFirstActivity, DATE_FORMAT)
: '';
break;
case 'NAME': case 'NAME':
row[name] = label; row[name] = label;
break; break;

Loading…
Cancel
Save