|
|
@ -12,15 +12,19 @@ import { createOpenRouter } from '@openrouter/ai-sdk-provider'; |
|
|
import { generateText } from 'ai'; |
|
|
import { generateText } from 'ai'; |
|
|
import tablemark, { ColumnDescriptor } from 'tablemark'; |
|
|
import tablemark, { ColumnDescriptor } from 'tablemark'; |
|
|
|
|
|
|
|
|
// Column name constants for holdings table
|
|
|
// Column definitions for holdings table
|
|
|
const HOLDINGS_TABLE_COLUMNS = { |
|
|
const HOLDINGS_TABLE_COLUMNS: ({ key: string } & ColumnDescriptor)[] = [ |
|
|
CURRENCY: 'Currency', |
|
|
{ key: 'CURRENCY', name: 'Currency' }, |
|
|
NAME: 'Name', |
|
|
{ key: 'NAME', name: 'Name' }, |
|
|
SYMBOL: 'Symbol', |
|
|
{ key: 'SYMBOL', name: 'Symbol' }, |
|
|
ASSET_CLASS: 'Asset Class', |
|
|
{ key: 'ASSET_CLASS', name: 'Asset Class' }, |
|
|
ALLOCATION_PERCENTAGE: 'Allocation in Percentage', |
|
|
{ |
|
|
ASSET_SUB_CLASS: 'Asset Sub Class' |
|
|
key: 'ALLOCATION_PERCENTAGE', |
|
|
} as const; |
|
|
name: 'Allocation in Percentage', |
|
|
|
|
|
align: 'right' |
|
|
|
|
|
}, |
|
|
|
|
|
{ key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' } |
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
@Injectable() |
|
|
@Injectable() |
|
|
export class AiService { |
|
|
export class AiService { |
|
|
@ -69,38 +73,50 @@ export class AiService { |
|
|
userId |
|
|
userId |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const holdingsTableColumns: ColumnDescriptor[] = [ |
|
|
const holdingsTableColumns: ColumnDescriptor[] = HOLDINGS_TABLE_COLUMNS.map( |
|
|
{ name: HOLDINGS_TABLE_COLUMNS.CURRENCY }, |
|
|
({ name, align }) => ({ name, align: align ?? 'left' }) |
|
|
{ name: HOLDINGS_TABLE_COLUMNS.NAME }, |
|
|
); |
|
|
{ name: HOLDINGS_TABLE_COLUMNS.SYMBOL }, |
|
|
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.ASSET_CLASS }, |
|
|
const getColumnValue = ( |
|
|
{ align: 'right', name: HOLDINGS_TABLE_COLUMNS.ALLOCATION_PERCENTAGE }, |
|
|
key: string, |
|
|
{ name: HOLDINGS_TABLE_COLUMNS.ASSET_SUB_CLASS } |
|
|
holding: { |
|
|
]; |
|
|
currency: string; |
|
|
|
|
|
name: string; |
|
|
|
|
|
symbol: string; |
|
|
|
|
|
assetClass?: string; |
|
|
|
|
|
allocationInPercentage: number; |
|
|
|
|
|
assetSubClass?: string; |
|
|
|
|
|
} |
|
|
|
|
|
) => { |
|
|
|
|
|
switch (key) { |
|
|
|
|
|
case 'CURRENCY': |
|
|
|
|
|
return holding.currency; |
|
|
|
|
|
case 'NAME': |
|
|
|
|
|
return holding.name; |
|
|
|
|
|
case 'SYMBOL': |
|
|
|
|
|
return holding.symbol; |
|
|
|
|
|
case 'ASSET_CLASS': |
|
|
|
|
|
return holding.assetClass ?? ''; |
|
|
|
|
|
case 'ALLOCATION_PERCENTAGE': |
|
|
|
|
|
return `${(holding.allocationInPercentage * 100).toFixed(3)}%`; |
|
|
|
|
|
case 'ASSET_SUB_CLASS': |
|
|
|
|
|
return holding.assetSubClass ?? ''; |
|
|
|
|
|
default: |
|
|
|
|
|
return ''; |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
const holdingsTableRows = Object.values(holdings) |
|
|
const holdingsTableRows = Object.values(holdings) |
|
|
.sort((a, b) => { |
|
|
.sort((a, b) => { |
|
|
return b.allocationInPercentage - a.allocationInPercentage; |
|
|
return b.allocationInPercentage - a.allocationInPercentage; |
|
|
}) |
|
|
}) |
|
|
.map( |
|
|
.map((holding) => { |
|
|
({ |
|
|
const row: Record<string, string> = {}; |
|
|
allocationInPercentage, |
|
|
HOLDINGS_TABLE_COLUMNS.forEach(({ key, name }) => { |
|
|
assetClass, |
|
|
row[name] = getColumnValue(key, holding); |
|
|
assetSubClass, |
|
|
}); |
|
|
currency, |
|
|
return row; |
|
|
name, |
|
|
}); |
|
|
symbol |
|
|
|
|
|
}) => { |
|
|
|
|
|
return { |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.CURRENCY]: currency, |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.NAME]: name, |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.SYMBOL]: symbol, |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.ASSET_CLASS]: assetClass ?? '', |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.ALLOCATION_PERCENTAGE]: `${(allocationInPercentage * 100).toFixed(3)}%`, |
|
|
|
|
|
[HOLDINGS_TABLE_COLUMNS.ASSET_SUB_CLASS]: assetSubClass ?? '' |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
const holdingsTableString = tablemark(holdingsTableRows, { |
|
|
const holdingsTableString = tablemark(holdingsTableRows, { |
|
|
columns: holdingsTableColumns |
|
|
columns: holdingsTableColumns |
|
|
|