Browse Source

Refactoring

pull/5834/head
Thomas Kaul 4 days ago
parent
commit
f97b8259f4
  1. 128
      apps/api/src/app/endpoints/ai/ai.service.ts

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

@ -10,26 +10,25 @@ import type { AiPromptMode } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { generateText } from 'ai';
import { ColumnDescriptor } from 'tablemark';
const tablemark = require('tablemark').default;
// Column definitions for holdings table
const HOLDINGS_TABLE_COLUMNS: ({ key: string } & ColumnDescriptor)[] = [
{ key: 'CURRENCY', name: 'Currency' },
{ key: 'NAME', name: 'Name' },
{ key: 'SYMBOL', name: 'Symbol' },
{ key: 'ASSET_CLASS', name: 'Asset Class' },
{
align: 'right',
key: 'ALLOCATION_PERCENTAGE',
name: 'Allocation in Percentage'
},
{ key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' }
];
import type { ColumnDescriptor } from 'tablemark';
@Injectable()
export class AiService {
private readonly HOLDINGS_TABLE_COLUMNS: ({
key: string;
} & ColumnDescriptor)[] = [
{ key: 'NAME', name: 'Name' },
{ key: 'SYMBOL', name: 'Symbol' },
{ key: 'CURRENCY', name: 'Currency' },
{ key: 'ASSET_CLASS', name: 'Asset Class' },
{ key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' },
{
align: 'right',
key: 'ALLOCATION_PERCENTAGE',
name: 'Allocation in Percentage'
}
];
public constructor(
private readonly portfolioService: PortfolioService,
private readonly propertyService: PropertyService
@ -75,50 +74,71 @@ export class AiService {
userId
});
const holdingsTableColumns: ColumnDescriptor[] = HOLDINGS_TABLE_COLUMNS.map(
({ align, name }) => {
const holdingsTableColumns: ColumnDescriptor[] =
this.HOLDINGS_TABLE_COLUMNS.map(({ align, name }) => {
return { name, align: align ?? 'left' };
}
);
});
const holdingsTableRows = Object.values(holdings)
.sort((a, b) => {
return b.allocationInPercentage - a.allocationInPercentage;
})
.map((holding) => {
return HOLDINGS_TABLE_COLUMNS.reduce(
(row, { key, name }) => {
switch (key) {
case 'CURRENCY':
row[name] = holding.currency;
break;
case 'NAME':
row[name] = holding.name;
break;
case 'SYMBOL':
row[name] = holding.symbol;
break;
case 'ASSET_CLASS':
row[name] = holding.assetClass ?? '';
break;
case 'ALLOCATION_PERCENTAGE':
row[name] =
`${(holding.allocationInPercentage * 100).toFixed(3)}%`;
break;
case 'ASSET_SUB_CLASS':
row[name] = holding.assetSubClass ?? '';
break;
default:
row[name] = '';
break;
}
return row;
},
{} as Record<string, string>
);
});
.map(
({
allocationInPercentage,
assetClass,
assetSubClass,
currency,
name: label,
symbol
}) => {
return this.HOLDINGS_TABLE_COLUMNS.reduce(
(row, { key, name }) => {
switch (key) {
case 'ALLOCATION_PERCENTAGE':
row[name] = `${(allocationInPercentage * 100).toFixed(3)}%`;
break;
case 'ASSET_CLASS':
row[name] = assetClass ?? '';
break;
case 'ASSET_SUB_CLASS':
row[name] = assetSubClass ?? '';
break;
case 'CURRENCY':
row[name] = currency;
break;
case 'NAME':
row[name] = label;
break;
case 'SYMBOL':
row[name] = symbol;
break;
default:
row[name] = '';
break;
}
return row;
},
{} as Record<string, string>
);
}
);
// Dynamic import to load ESM module from CommonJS context
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const dynamicImport = new Function('s', 'return import(s)') as (
s: string
) => Promise<typeof import('tablemark')>;
const { tablemark } = await dynamicImport('tablemark');
const holdingsTableString = tablemark.default(holdingsTableRows, {
const holdingsTableString = tablemark(holdingsTableRows, {
columns: holdingsTableColumns
});

Loading…
Cancel
Save