From 05c49999dfcadf72b4d43e747dc9ad88d2e84a67 Mon Sep 17 00:00:00 2001 From: Vansh Date: Sat, 25 Oct 2025 22:04:11 +0530 Subject: [PATCH] refactor: added holding table columns array --- apps/api/src/app/endpoints/ai/ai.service.ts | 88 ++++++++++++--------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/apps/api/src/app/endpoints/ai/ai.service.ts b/apps/api/src/app/endpoints/ai/ai.service.ts index cedc1ea3f..b94f9ebe8 100644 --- a/apps/api/src/app/endpoints/ai/ai.service.ts +++ b/apps/api/src/app/endpoints/ai/ai.service.ts @@ -12,15 +12,19 @@ import { createOpenRouter } from '@openrouter/ai-sdk-provider'; import { generateText } from 'ai'; import tablemark, { ColumnDescriptor } from 'tablemark'; -// Column name constants for holdings table -const HOLDINGS_TABLE_COLUMNS = { - CURRENCY: 'Currency', - NAME: 'Name', - SYMBOL: 'Symbol', - ASSET_CLASS: 'Asset Class', - ALLOCATION_PERCENTAGE: 'Allocation in Percentage', - ASSET_SUB_CLASS: 'Asset Sub Class' -} as const; +// 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' }, + { + key: 'ALLOCATION_PERCENTAGE', + name: 'Allocation in Percentage', + align: 'right' + }, + { key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' } +]; @Injectable() export class AiService { @@ -69,38 +73,50 @@ export class AiService { userId }); - const holdingsTableColumns: ColumnDescriptor[] = [ - { name: HOLDINGS_TABLE_COLUMNS.CURRENCY }, - { name: HOLDINGS_TABLE_COLUMNS.NAME }, - { name: HOLDINGS_TABLE_COLUMNS.SYMBOL }, - { name: HOLDINGS_TABLE_COLUMNS.ASSET_CLASS }, - { align: 'right', name: HOLDINGS_TABLE_COLUMNS.ALLOCATION_PERCENTAGE }, - { name: HOLDINGS_TABLE_COLUMNS.ASSET_SUB_CLASS } - ]; + const holdingsTableColumns: ColumnDescriptor[] = HOLDINGS_TABLE_COLUMNS.map( + ({ name, align }) => ({ name, align: align ?? 'left' }) + ); + + const getColumnValue = ( + key: string, + 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) .sort((a, b) => { return b.allocationInPercentage - a.allocationInPercentage; }) - .map( - ({ - allocationInPercentage, - assetClass, - assetSubClass, - currency, - 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 ?? '' - }; - } - ); + .map((holding) => { + const row: Record = {}; + HOLDINGS_TABLE_COLUMNS.forEach(({ key, name }) => { + row[name] = getColumnValue(key, holding); + }); + return row; + }); const holdingsTableString = tablemark(holdingsTableRows, { columns: holdingsTableColumns