Browse Source

Fix filtering by holding

pull/7999/head
Thomas Kaul 2 weeks ago
parent
commit
37140d303d
  1. 24
      apps/api/src/app/endpoints/mcp/mcp.schemas.spec.ts
  2. 2
      apps/api/src/app/endpoints/mcp/mcp.schemas.ts
  3. 27
      apps/api/src/app/endpoints/mcp/mcp.service.spec.ts
  4. 28
      apps/api/src/app/endpoints/mcp/mcp.service.ts

24
apps/api/src/app/endpoints/mcp/mcp.schemas.spec.ts

@ -4,12 +4,36 @@ import {
SEARCH_QUERY_MINIMUM_LENGTH
} from '@ghostfolio/common/config';
import { DataSource } from '@prisma/client';
import {
GET_ACCOUNTS_PARAMETERS,
GET_ACTIVITIES_PARAMETERS,
IMPORT_ACTIVITIES_PARAMETERS,
SEARCH_ASSET_PROFILES_PARAMETERS
} from './mcp.schemas';
import { createActivity } from './mcp.test-utils';
describe('GET_ACCOUNTS_PARAMETERS', () => {
it('Refuses an empty symbol of the holding', () => {
expect(
GET_ACCOUNTS_PARAMETERS.safeParse({
holding: { dataSource: DataSource.YAHOO, symbol: '' }
}).success
).toBe(false);
});
});
describe('GET_ACTIVITIES_PARAMETERS', () => {
it('Refuses an empty symbol of the holding', () => {
expect(
GET_ACTIVITIES_PARAMETERS.safeParse({
holding: { dataSource: DataSource.YAHOO, symbol: '' }
}).success
).toBe(false);
});
});
describe('IMPORT_ACTIVITIES_PARAMETERS', () => {
function parse(activities: unknown[]) {
return IMPORT_ACTIVITIES_PARAMETERS.safeParse({ activities }).success;

2
apps/api/src/app/endpoints/mcp/mcp.schemas.ts

@ -18,7 +18,7 @@ const HOLDING_PARAMETER = z.object({
dataSource: z
.enum(DataSource)
.describe('The data source of the asset profile'),
symbol: z.string().describe('The symbol of the asset profile')
symbol: z.string().min(1).describe('The symbol of the asset profile')
});
export const GET_ACCOUNTS_PARAMETERS = z.object({

27
apps/api/src/app/endpoints/mcp/mcp.service.spec.ts

@ -113,6 +113,20 @@ describe('McpService', () => {
});
});
it('Resolves the mask of the data source of the Ghostfolio data provider', async () => {
configuration.DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER = [DataSource.YAHOO];
configuration.ENABLE_FEATURE_SUBSCRIPTION = true;
await mcpService.getAccounts({
userId,
holding: { dataSource: DataSource.GHOSTFOLIO, symbol: 'AAPL' }
});
expect(apiService.buildFiltersFromQueryParams).toHaveBeenCalledWith(
expect.objectContaining({ filterByDataSource: DataSource.YAHOO })
);
});
it('Gives the table of the accounts of the filters', async () => {
expect(await mcpService.getAccounts({ userId })).toEqual({
content: [{ text: '## Accounts', type: 'text' }]
@ -150,6 +164,19 @@ describe('McpService', () => {
});
});
it('Resolves the mask of the data source of the Ghostfolio data provider', async () => {
configuration.DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER = [DataSource.YAHOO];
configuration.ENABLE_FEATURE_SUBSCRIPTION = true;
await getActivities({
holding: { dataSource: DataSource.GHOSTFOLIO, symbol: 'AAPL' }
});
expect(apiService.buildFiltersFromQueryParams).toHaveBeenCalledWith(
expect.objectContaining({ filterByDataSource: DataSource.YAHOO })
);
});
it('Changes the range into the start date and the end date', async () => {
await getActivities({ range: '2024' });

28
apps/api/src/app/endpoints/mcp/mcp.service.ts

@ -43,7 +43,10 @@ export class McpService {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts: accountIds,
filterByAssetClasses: assetClasses,
filterByDataSource: holding?.dataSource,
filterByDataSource: getUnmaskedGhostfolioDataSource({
dataSource: holding?.dataSource,
ghostfolioDataSources: this.getGhostfolioDataSources()
}),
filterBySymbol: holding?.symbol
});
@ -79,7 +82,10 @@ export class McpService {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAssetClasses: assetClasses,
filterByDataSource: holding?.dataSource,
filterByDataSource: getUnmaskedGhostfolioDataSource({
dataSource: holding?.dataSource,
ghostfolioDataSources: this.getGhostfolioDataSources()
}),
filterBySymbol: holding?.symbol
});
@ -123,11 +129,7 @@ export class McpService {
permission: permissions.createActivity
});
const ghostfolioDataSources = this.configurationService.get(
'ENABLE_FEATURE_SUBSCRIPTION'
)
? this.configurationService.get('DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER')
: [];
const ghostfolioDataSources = this.getGhostfolioDataSources();
const activitiesDto = activities.map((activity) => {
return {
@ -171,11 +173,7 @@ export class McpService {
const { items } = await this.symbolService.lookup({ query, user });
const ghostfolioDataSources = this.configurationService.get(
'ENABLE_FEATURE_SUBSCRIPTION'
)
? this.configurationService.get('DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER')
: [];
const ghostfolioDataSources = this.getGhostfolioDataSources();
const assetProfiles = items.flatMap(
({
@ -210,6 +208,12 @@ export class McpService {
return this.getTextResult(JSON.stringify({ assetProfiles }, null, 2));
}
private getGhostfolioDataSources() {
return this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')
? this.configurationService.get('DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER')
: [];
}
private getTextResult(text: string) {
return { content: [{ text, type: 'text' as const }] };
}

Loading…
Cancel
Save