mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.5 KiB
193 lines
5.5 KiB
import { DATE_RANGE_PATTERN } from '@ghostfolio/api/dtos/date-range-filter.dto';
|
|
import { isValidEncodedDataSource } from '@ghostfolio/api/helper/data-source.helper';
|
|
import {
|
|
COMMENT_MAXIMUM_LENGTH,
|
|
DATE_RANGES,
|
|
DEFAULT_DATE_RANGE,
|
|
MCP_MAX_ACCOUNTS,
|
|
MCP_MAX_ACTIVITIES,
|
|
SEARCH_QUERY_MAXIMUM_LENGTH,
|
|
SEARCH_QUERY_MINIMUM_LENGTH,
|
|
SYMBOL_MAXIMUM_LENGTH
|
|
} from '@ghostfolio/common/config';
|
|
import {
|
|
isValidCurrencyCode,
|
|
isValidDateAfter1970
|
|
} from '@ghostfolio/common/helper';
|
|
|
|
import { AssetClass, DataSource, Type as ActivityType } from '@prisma/client';
|
|
import { z } from 'zod';
|
|
|
|
const DATA_SOURCE_PARAMETER_ERROR = `Invalid option: expected one of ${Object.values(DataSource).join('|')} or a data source as given by a tool`;
|
|
|
|
const DATA_SOURCE_PARAMETER = z
|
|
.union(
|
|
[
|
|
z.enum(DataSource),
|
|
z.string().refine(isValidEncodedDataSource, {
|
|
error: DATA_SOURCE_PARAMETER_ERROR
|
|
})
|
|
],
|
|
{ error: DATA_SOURCE_PARAMETER_ERROR }
|
|
)
|
|
.describe('The data source of the asset profile');
|
|
|
|
const SYMBOL_PARAMETER = z
|
|
.string()
|
|
.trim()
|
|
.min(1)
|
|
.max(SYMBOL_MAXIMUM_LENGTH)
|
|
.describe('The symbol of the asset profile');
|
|
|
|
const HOLDING_PARAMETER = z.object({
|
|
dataSource: DATA_SOURCE_PARAMETER,
|
|
symbol: SYMBOL_PARAMETER
|
|
});
|
|
|
|
export const GET_ACCOUNTS_PARAMETERS = z.object({
|
|
accountIds: z
|
|
.array(z.string().min(1))
|
|
.min(1)
|
|
.max(MCP_MAX_ACCOUNTS)
|
|
.optional()
|
|
.describe(
|
|
`The identifiers of the accounts to get, at most ${MCP_MAX_ACCOUNTS}`
|
|
),
|
|
assetClasses: z
|
|
.array(z.enum(AssetClass))
|
|
.min(1)
|
|
.optional()
|
|
.describe('The asset classes of the accounts to get'),
|
|
holding: HOLDING_PARAMETER.optional().describe(
|
|
'The asset profile of the accounts to get'
|
|
)
|
|
});
|
|
|
|
export const GET_ACTIVITIES_PARAMETERS = z.object({
|
|
activityTypes: z
|
|
.array(z.enum(ActivityType))
|
|
.min(1)
|
|
.optional()
|
|
.describe('The types of the activities to get'),
|
|
assetClasses: z
|
|
.array(z.enum(AssetClass))
|
|
.min(1)
|
|
.optional()
|
|
.describe('The asset classes of the activities to get'),
|
|
holding: HOLDING_PARAMETER.optional().describe(
|
|
'The asset profile of the activities to get'
|
|
),
|
|
range: z
|
|
.string()
|
|
.regex(DATE_RANGE_PATTERN)
|
|
.optional()
|
|
.describe(
|
|
`The date range of the activities to get, either ${DATE_RANGES.join(
|
|
', '
|
|
)} or a calendar year like 2024`
|
|
),
|
|
skip: z
|
|
.number()
|
|
.int()
|
|
.min(0)
|
|
.optional()
|
|
.describe('The number of activities to skip'),
|
|
take: z
|
|
.number()
|
|
.int()
|
|
.min(1)
|
|
.max(MCP_MAX_ACTIVITIES)
|
|
.default(MCP_MAX_ACTIVITIES)
|
|
.describe(`The number of activities to get, at most ${MCP_MAX_ACTIVITIES}`)
|
|
});
|
|
|
|
export const GET_PERFORMANCE_PARAMETERS = z.object({
|
|
accountIds: z
|
|
.array(z.string().min(1))
|
|
.min(1)
|
|
.max(MCP_MAX_ACCOUNTS)
|
|
.optional()
|
|
.describe(
|
|
`The identifiers of the accounts of the performance, at most ${MCP_MAX_ACCOUNTS}`
|
|
),
|
|
assetClasses: z
|
|
.array(z.enum(AssetClass))
|
|
.min(1)
|
|
.optional()
|
|
.describe('The asset classes of the performance'),
|
|
holding: HOLDING_PARAMETER.optional().describe(
|
|
'The asset profile of the performance'
|
|
),
|
|
range: z
|
|
.string()
|
|
.regex(DATE_RANGE_PATTERN)
|
|
.default(DEFAULT_DATE_RANGE)
|
|
.describe(
|
|
`The date range of the performance, either ${DATE_RANGES.join(
|
|
', '
|
|
)} or a calendar year like 2024`
|
|
)
|
|
});
|
|
|
|
export const IMPORT_ACTIVITIES_PARAMETERS = z.object({
|
|
activities: z
|
|
.array(
|
|
z.object({
|
|
accountId: z
|
|
.string()
|
|
.min(1)
|
|
.optional()
|
|
.describe('The identifier of the account of the activity'),
|
|
comment: z
|
|
.string()
|
|
.trim()
|
|
.max(COMMENT_MAXIMUM_LENGTH)
|
|
.optional()
|
|
.describe('The comment of the activity'),
|
|
currency: z
|
|
.string()
|
|
.refine(isValidCurrencyCode)
|
|
.describe(
|
|
'The currency of the fee and of the unit price, as an ISO 4217 code in upper case'
|
|
),
|
|
dataSource: DATA_SOURCE_PARAMETER.optional(),
|
|
date: z
|
|
.string()
|
|
.refine(isValidDateAfter1970)
|
|
.describe(
|
|
'The date of the activity, as an ISO 8601 date or date and time'
|
|
),
|
|
fee: z.number().min(0).describe('The fee of the activity'),
|
|
quantity: z.number().min(0).describe('The quantity of the activity'),
|
|
symbol: SYMBOL_PARAMETER.describe(
|
|
'The symbol of the asset profile, or the description of a non-investment activity when no data source is given'
|
|
),
|
|
type: z
|
|
.enum(ActivityType)
|
|
.describe(
|
|
'The type of the activity; DEPOSIT is incoming cash and WITHDRAWAL is outgoing cash'
|
|
),
|
|
updateAccountBalance: z
|
|
.boolean()
|
|
.optional()
|
|
.describe(
|
|
'Whether to update the account cash balance; deposits and withdrawals with an account update it by default, while other activity types do not'
|
|
),
|
|
unitPrice: z.number().min(0).describe('The unit price of the activity')
|
|
})
|
|
)
|
|
.min(1)
|
|
.max(MCP_MAX_ACTIVITIES)
|
|
.describe(`The activities to import, at most ${MCP_MAX_ACTIVITIES}`)
|
|
});
|
|
|
|
export const SEARCH_ASSET_PROFILES_PARAMETERS = z.object({
|
|
query: z
|
|
.string()
|
|
.trim()
|
|
.min(SEARCH_QUERY_MINIMUM_LENGTH)
|
|
.max(SEARCH_QUERY_MAXIMUM_LENGTH)
|
|
.describe(
|
|
'The name, ticker symbol or ISIN of the financial asset, for example Apple, AAPL, Bitcoin or US0378331005'
|
|
)
|
|
});
|
|
|