Browse Source

Merge f447591f68 into bd50767cdc

pull/8066/merge
Szymon Łągiewka 11 hours ago
committed by GitHub
parent
commit
c7cf248389
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      apps/api/src/app/account/interfaces/cash-details.interface.ts
  2. 21
      apps/api/src/app/activities/activities.service.spec.ts
  3. 8
      apps/api/src/app/app.module.spec.ts
  4. 4
      apps/api/src/app/auth/interfaces/interfaces.ts
  5. 3
      apps/api/src/app/auth/oidc.strategy.ts
  6. 4
      apps/api/src/app/endpoints/ai/ai.controller.spec.ts
  7. 2
      apps/api/src/app/endpoints/ai/ai.schemas.spec.ts
  8. 18
      apps/api/src/app/endpoints/ai/ai.service.spec.ts
  9. 2
      apps/api/src/app/endpoints/ai/ai.test-utils.ts
  10. 2
      apps/api/src/app/endpoints/ai/types/account-hint.type.ts
  11. 2
      apps/api/src/app/endpoints/ai/types/account-to-match.type.ts
  12. 4
      apps/api/src/app/endpoints/ai/types/activity-row.type.ts
  13. 2
      apps/api/src/app/endpoints/ai/types/asset-to-match.type.ts
  14. 11
      apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.spec.ts
  15. 8
      apps/api/src/app/endpoints/benchmarks/benchmarks.service.spec.ts
  16. 8
      apps/api/src/app/endpoints/benchmarks/benchmarks.service.time-zone.spec.ts
  17. 9
      apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts
  18. 14
      apps/api/src/app/endpoints/mcp/mcp.service.spec.ts
  19. 2
      apps/api/src/app/endpoints/mcp/mcp.test-utils.ts
  20. 4
      apps/api/src/app/endpoints/mcp/types/activity-to-import.type.ts
  21. 31
      apps/api/src/app/import/import.service.spec.ts
  22. 2
      apps/api/src/app/import/interfaces/asset-profile-to-create.interface.ts
  23. 8
      apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts
  24. 6
      apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts
  25. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts
  26. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur-in-base-currency-eur.spec.ts
  27. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts
  28. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-before-first-market-price.spec.ts
  29. 4
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts
  30. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts
  31. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy-with-dividend.spec.ts
  32. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts
  33. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-fee-and-dividend.spec.ts
  34. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts
  35. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-manual-buy-before-first-market-price.spec.ts
  36. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-manual-buy-with-market-price-between-chart-dates.spec.ts
  37. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-and-sell.spec.ts
  38. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-from-two-data-sources.spec.ts
  39. 5
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-stock-split.spec.ts
  40. 2
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-valuable.spec.ts
  41. 4
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.spec.ts
  42. 20
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  43. 8
      apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts
  44. 8
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts
  45. 6
      apps/api/src/app/portfolio/current-rate.service.mock.ts
  46. 16
      apps/api/src/app/portfolio/current-rate.service.spec.ts
  47. 2
      apps/api/src/app/portfolio/interfaces/accumulated-values.interface.ts
  48. 2
      apps/api/src/app/portfolio/interfaces/average-investment-item.interface.ts
  49. 2
      apps/api/src/app/portfolio/interfaces/get-value-object.interface.ts
  50. 7
      apps/api/src/app/portfolio/interfaces/get-values-object.interface.ts
  51. 8
      apps/api/src/app/portfolio/interfaces/get-values-params.interface.ts
  52. 4
      apps/api/src/app/portfolio/interfaces/holding-balance.interface.ts
  53. 2
      apps/api/src/app/portfolio/interfaces/holding-balances-at-date.interface.ts
  54. 4
      apps/api/src/app/portfolio/interfaces/holding-performance.interface.ts
  55. 4
      apps/api/src/app/portfolio/interfaces/holding-valuation-item.interface.ts
  56. 4
      apps/api/src/app/portfolio/interfaces/holding-valuation.interface.ts
  57. 4
      apps/api/src/app/portfolio/interfaces/portfolio-calculator-activity-item.interface.ts
  58. 2
      apps/api/src/app/portfolio/interfaces/portfolio-calculator-activity.interface.ts
  59. 2
      apps/api/src/app/portfolio/interfaces/portfolio-calculator-holding.interface.ts
  60. 2
      apps/api/src/app/portfolio/interfaces/weighted-investment.interface.ts
  61. 11
      apps/api/src/app/portfolio/portfolio.service.spec.ts
  62. 2
      apps/api/src/app/portfolio/types/performance-percentages.type.ts
  63. 4
      apps/api/src/app/redis-cache/redis-cache.service.mock.ts
  64. 2
      apps/api/src/decorators/impersonation.decorator.ts
  65. 2
      apps/api/src/decorators/requires-scope-of-access.decorator.ts
  66. 2
      apps/api/src/decorators/requires-scope.decorator.ts
  67. 2
      apps/api/src/events/asset-profile-changed.event.ts
  68. 5
      apps/api/src/guards/impersonation-write.guard.spec.ts
  69. 2
      apps/api/src/guards/impersonation.guard.spec.ts
  70. 6
      apps/api/src/guards/oauth-callback.guard.ts
  71. 5
      apps/api/src/guards/scope.guard.spec.ts
  72. 2
      apps/api/src/helper/account.helper.ts
  73. 2
      apps/api/src/helper/activity.helper.ts
  74. 2
      apps/api/src/helper/data-source.helper.spec.ts
  75. 5
      apps/api/src/helper/data-source.helper.ts
  76. 2
      apps/api/src/helper/execution-context.helper.ts
  77. 2
      apps/api/src/helper/interfaces/table-parameters.interface.ts
  78. 2
      apps/api/src/helper/markdown-table.helper.spec.ts
  79. 2
      apps/api/src/helper/markdown-table.helper.ts
  80. 2
      apps/api/src/helper/object.helper.spec.ts
  81. 4
      apps/api/src/helper/portfolio.helper.ts
  82. 2
      apps/api/src/helper/redis.helper.ts
  83. 2
      apps/api/src/helper/sector.helper.ts
  84. 2
      apps/api/src/helper/security-headers.helper.spec.ts
  85. 2
      apps/api/src/helper/security-headers.helper.ts
  86. 7
      apps/api/src/main.ts
  87. 2
      apps/api/src/middlewares/language-redirect.middleware.ts
  88. 8
      apps/api/src/middlewares/mcp-authorization.middleware.ts
  89. 4
      apps/api/src/models/interfaces/rule.interface.ts
  90. 10
      apps/api/src/models/rule.ts
  91. 13
      apps/api/src/models/rules/account-cluster-risk/current-investment.ts
  92. 9
      apps/api/src/models/rules/account-cluster-risk/single-account.ts
  93. 9
      apps/api/src/models/rules/asset-class-cluster-risk/equity.ts
  94. 9
      apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts
  95. 9
      apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts
  96. 9
      apps/api/src/models/rules/currency-cluster-risk/current-investment.ts
  97. 6
      apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts
  98. 6
      apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts
  99. 6
      apps/api/src/models/rules/emergency-fund/emergency-fund-coverage.ts
  100. 6
      apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts

2
apps/api/src/app/account/interfaces/cash-details.interface.ts

@ -1,4 +1,4 @@
import { AccountWithBalance } from '@ghostfolio/common/types'; import type { AccountWithBalance } from '@ghostfolio/common/types';
export interface CashDetails { export interface CashDetails {
accounts: AccountWithBalance[]; accounts: AccountWithBalance[];

21
apps/api/src/app/activities/activities.service.spec.ts

@ -1,30 +1,29 @@
import { AccountService } from '@ghostfolio/api/app/account/account.service'; import type { AccountService } from '@ghostfolio/api/app/account/account.service';
import { import {
activityDummyData, activityDummyData,
assetProfileDummyData assetProfileDummyData
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
import { WHERE_ACTIVITY_NOT_DRAFT } from '@ghostfolio/api/helper/activity.helper'; import { WHERE_ACTIVITY_NOT_DRAFT } from '@ghostfolio/api/helper/activity.helper';
import { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service'; import type { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import type { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import type { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; import type { TagService } from '@ghostfolio/api/services/tag/tag.service';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import { import {
INVESTMENT_ACTIVITY_TYPES, INVESTMENT_ACTIVITY_TYPES,
NON_INVESTMENT_ACTIVITY_TYPES NON_INVESTMENT_ACTIVITY_TYPES
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity, Filter } from '@ghostfolio/common/interfaces'; import type { Activity, Filter } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types'; import type { DateRange } from '@ghostfolio/common/types';
import { EventEmitter2 } from '@nestjs/event-emitter'; import type { EventEmitter2 } from '@nestjs/event-emitter';
import type { AssetProfileSplit, Prisma } from '@prisma/client';
import { import {
AssetClass, AssetClass,
AssetProfileSplit,
AssetSubClass, AssetSubClass,
DataSource, DataSource,
Prisma,
Type as ActivityType Type as ActivityType
} from '@prisma/client'; } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';

8
apps/api/src/app/app.module.spec.ts

@ -1,9 +1,5 @@
import { import type { DynamicModule, ForwardReference, Type } from '@nestjs/common';
DynamicModule, import { RequestMethod } from '@nestjs/common';
ForwardReference,
RequestMethod,
Type
} from '@nestjs/common';
import { import {
GUARDS_METADATA, GUARDS_METADATA,
METHOD_METADATA, METHOD_METADATA,

4
apps/api/src/app/auth/interfaces/interfaces.ts

@ -1,6 +1,6 @@
import { AuthDeviceDto } from '@ghostfolio/common/dtos'; import type { AuthDeviceDto } from '@ghostfolio/common/dtos';
import { Provider } from '@prisma/client'; import type { Provider } from '@prisma/client';
export interface AuthDeviceDialogParams { export interface AuthDeviceDialogParams {
authDevice: AuthDeviceDto; authDevice: AuthDeviceDto;

3
apps/api/src/app/auth/oidc.strategy.ts

@ -2,7 +2,8 @@ import { Injectable, Logger } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport'; import { PassportStrategy } from '@nestjs/passport';
import { Provider } from '@prisma/client'; import { Provider } from '@prisma/client';
import { Request } from 'express'; import { Request } from 'express';
import { Strategy, type StrategyOptions } from 'passport-openidconnect'; import { Strategy } from 'passport-openidconnect';
import type { StrategyOptions } from 'passport-openidconnect';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { import {

4
apps/api/src/app/endpoints/ai/ai.controller.spec.ts

@ -2,7 +2,7 @@ import { HAS_PERMISSION_KEY } from '@ghostfolio/api/decorators/has-permission.de
import { CallerFacingError } from '@ghostfolio/api/errors/caller-facing.error'; import { CallerFacingError } from '@ghostfolio/api/errors/caller-facing.error';
import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard'; import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { ApiService } from '@ghostfolio/api/services/api/api.service'; import type { ApiService } from '@ghostfolio/api/services/api/api.service';
import { import {
AI_ACTIVITIES_TIMEOUT, AI_ACTIVITIES_TIMEOUT,
AI_MAX_ACTIVITIES, AI_MAX_ACTIVITIES,
@ -24,7 +24,7 @@ import { StatusCodes } from 'http-status-codes';
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import { AiController } from './ai.controller'; import { AiController } from './ai.controller';
import { AiService } from './ai.service'; import type { AiService } from './ai.service';
// The packages are ECMAScript modules, which Jest cannot load // The packages are ECMAScript modules, which Jest cannot load
jest.mock('@openrouter/ai-sdk-provider', () => { jest.mock('@openrouter/ai-sdk-provider', () => {

2
apps/api/src/app/endpoints/ai/ai.schemas.spec.ts

@ -8,7 +8,7 @@ import { z } from 'zod';
import { ACTIVITY_ROWS_OUTPUT, ROW_MATCHES_OUTPUT } from './ai.schemas'; import { ACTIVITY_ROWS_OUTPUT, ROW_MATCHES_OUTPUT } from './ai.schemas';
import { createActivityRow } from './ai.test-utils'; import { createActivityRow } from './ai.test-utils';
import { ActivityRow } from './types/activity-row.type'; import type { ActivityRow } from './types/activity-row.type';
describe('ACTIVITY_ROWS_OUTPUT', () => { describe('ACTIVITY_ROWS_OUTPUT', () => {
it('Accepts a row with null for the values which the file does not show', () => { it('Accepts a row with null for the values which the file does not show', () => {

18
apps/api/src/app/endpoints/ai/ai.service.spec.ts

@ -1,10 +1,10 @@
import { McpService } from '@ghostfolio/api/app/endpoints/mcp/mcp.service'; import type { McpService } from '@ghostfolio/api/app/endpoints/mcp/mcp.service';
import { CallerFacingError } from '@ghostfolio/api/errors/caller-facing.error'; import { CallerFacingError } from '@ghostfolio/api/errors/caller-facing.error';
import { encodeDataSource } from '@ghostfolio/api/helper/data-source.helper'; import { encodeDataSource } from '@ghostfolio/api/helper/data-source.helper';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import type { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { PortfolioTableService } from '@ghostfolio/api/services/portfolio-table/portfolio-table.service'; import type { PortfolioTableService } from '@ghostfolio/api/services/portfolio-table/portfolio-table.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import type { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { import {
DEFAULT_LOCALE, DEFAULT_LOCALE,
PROPERTY_API_KEY_OPENROUTER, PROPERTY_API_KEY_OPENROUTER,
@ -20,14 +20,14 @@ import { Logger } from '@nestjs/common';
import { createOpenRouter } from '@openrouter/ai-sdk-provider'; import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { DataSource, Type as ActivityType } from '@prisma/client'; import { DataSource, Type as ActivityType } from '@prisma/client';
import { generateText, NoObjectGeneratedError } from 'ai'; import { generateText, NoObjectGeneratedError } from 'ai';
import { z } from 'zod'; import type { z } from 'zod';
import { ACTIVITY_ROWS_OUTPUT, ROW_MATCHES_OUTPUT } from './ai.schemas'; import { ACTIVITY_ROWS_OUTPUT, ROW_MATCHES_OUTPUT } from './ai.schemas';
import { AiService } from './ai.service'; import { AiService } from './ai.service';
import { createActivityRow } from './ai.test-utils'; import { createActivityRow } from './ai.test-utils';
import { AccountHint } from './types/account-hint.type'; import type { AccountHint } from './types/account-hint.type';
import { AccountToMatch } from './types/account-to-match.type'; import type { AccountToMatch } from './types/account-to-match.type';
import { ActivityRow } from './types/activity-row.type'; import type { ActivityRow } from './types/activity-row.type';
// The packages are ECMAScript modules, which Jest cannot load // The packages are ECMAScript modules, which Jest cannot load
jest.mock('@openrouter/ai-sdk-provider', () => { jest.mock('@openrouter/ai-sdk-provider', () => {

2
apps/api/src/app/endpoints/ai/ai.test-utils.ts

@ -1,6 +1,6 @@
import { Type as ActivityType } from '@prisma/client'; import { Type as ActivityType } from '@prisma/client';
import { ActivityRow } from './types/activity-row.type'; import type { ActivityRow } from './types/activity-row.type';
export function createActivityRow( export function createActivityRow(
overrides: Partial<ActivityRow> = {} overrides: Partial<ActivityRow> = {}

2
apps/api/src/app/endpoints/ai/types/account-hint.type.ts

@ -1,4 +1,4 @@
import { ActivityRow } from './activity-row.type'; import type { ActivityRow } from './activity-row.type';
export type AccountHint = Pick<ActivityRow, 'accountName'> & { export type AccountHint = Pick<ActivityRow, 'accountName'> & {
broker: string | null; broker: string | null;

2
apps/api/src/app/endpoints/ai/types/account-to-match.type.ts

@ -1,3 +1,3 @@
import { Account } from '@prisma/client'; import type { Account } from '@prisma/client';
export type AccountToMatch = Pick<Account, 'currency' | 'id' | 'name'>; export type AccountToMatch = Pick<Account, 'currency' | 'id' | 'name'>;

4
apps/api/src/app/endpoints/ai/types/activity-row.type.ts

@ -1,5 +1,5 @@
import { z } from 'zod'; import type { z } from 'zod';
import { ACTIVITY_ROWS_OUTPUT } from '../ai.schemas'; import type { ACTIVITY_ROWS_OUTPUT } from '../ai.schemas';
export type ActivityRow = z.infer<typeof ACTIVITY_ROWS_OUTPUT>['rows'][number]; export type ActivityRow = z.infer<typeof ACTIVITY_ROWS_OUTPUT>['rows'][number];

2
apps/api/src/app/endpoints/ai/types/asset-to-match.type.ts

@ -1,4 +1,4 @@
import { ActivityRow } from './activity-row.type'; import type { ActivityRow } from './activity-row.type';
export type AssetToMatch = Pick< export type AssetToMatch = Pick<
ActivityRow, ActivityRow,

11
apps/api/src/app/endpoints/asset-profiles/asset-profiles.service.spec.ts

@ -1,11 +1,12 @@
import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import type { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service';
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
import { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service'; import type { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service';
import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import type { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service';
import { NotFoundException } from '@nestjs/common'; import { NotFoundException } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter'; import type { EventEmitter2 } from '@nestjs/event-emitter';
import { AssetProfileSplit, DataSource } from '@prisma/client'; import type { AssetProfileSplit } from '@prisma/client';
import { DataSource } from '@prisma/client';
import { AssetProfilesService } from './asset-profiles.service'; import { AssetProfilesService } from './asset-profiles.service';

8
apps/api/src/app/endpoints/benchmarks/benchmarks.service.spec.ts

@ -1,8 +1,8 @@
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import type { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; import type { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import type { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { DataSource } from '@prisma/client'; import { DataSource } from '@prisma/client';

8
apps/api/src/app/endpoints/benchmarks/benchmarks.service.time-zone.spec.ts

@ -2,11 +2,11 @@
* @jest-environment <rootDir>/jest-environment-tz.js * @jest-environment <rootDir>/jest-environment-tz.js
* @jest-environment-options {"timeZone": "America/New_York"} * @jest-environment-options {"timeZone": "America/New_York"}
*/ */
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import type { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; import type { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import type { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { DataSource } from '@prisma/client'; import { DataSource } from '@prisma/client';

9
apps/api/src/app/endpoints/mcp/mcp.controller.spec.ts

@ -3,10 +3,10 @@ import { McpToolExceptionFilter } from '@ghostfolio/api/filters/mcp-tool-excepti
import { AccessGuard } from '@ghostfolio/api/guards/access.guard'; import { AccessGuard } from '@ghostfolio/api/guards/access.guard';
import { getMcpUserOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper'; import { getMcpUserOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper';
import { SubscriptionType } from '@ghostfolio/common/enums'; import { SubscriptionType } from '@ghostfolio/common/enums';
import type { Scope } from '@ghostfolio/common/scopes';
import { import {
getScopesOfAccess, getScopesOfAccess,
getScopesOfAccessLevel, getScopesOfAccessLevel,
Scope,
scopes scopes
} from '@ghostfolio/common/scopes'; } from '@ghostfolio/common/scopes';
import type { import type {
@ -18,17 +18,16 @@ import {
EXCEPTION_FILTERS_METADATA, EXCEPTION_FILTERS_METADATA,
GUARDS_METADATA GUARDS_METADATA
} from '@nestjs/common/constants'; } from '@nestjs/common/constants';
import type { AccessMatchMode, ToolMetadata } from '@rekog/mcp-nest';
import { import {
AccessMatchMode,
MCP_SCOPES_MATCH_METADATA_KEY, MCP_SCOPES_MATCH_METADATA_KEY,
MCP_SCOPES_METADATA_KEY, MCP_SCOPES_METADATA_KEY,
MCP_TOOL_METADATA_KEY, MCP_TOOL_METADATA_KEY,
ToolAuthorizationService, ToolAuthorizationService
ToolMetadata
} from '@rekog/mcp-nest'; } from '@rekog/mcp-nest';
import { GhostfolioMcpController } from './mcp.controller'; import { GhostfolioMcpController } from './mcp.controller';
import { McpService } from './mcp.service'; import type { McpService } from './mcp.service';
/** /**
* Gives the metadata which a decorator sets on the method of a tool. The * Gives the metadata which a decorator sets on the method of a tool. The

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

@ -1,16 +1,16 @@
import { ImportValidationError } from '@ghostfolio/api/app/import/errors/import-validation.error'; import { ImportValidationError } from '@ghostfolio/api/app/import/errors/import-validation.error';
import { ImportService } from '@ghostfolio/api/app/import/import.service'; import type { ImportService } from '@ghostfolio/api/app/import/import.service';
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; import type { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { UserService } from '@ghostfolio/api/app/user/user.service'; import type { UserService } from '@ghostfolio/api/app/user/user.service';
import { encodeDataSource } from '@ghostfolio/api/helper/data-source.helper'; import { encodeDataSource } from '@ghostfolio/api/helper/data-source.helper';
import { ApiService } from '@ghostfolio/api/services/api/api.service'; import type { ApiService } from '@ghostfolio/api/services/api/api.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { PortfolioTableService } from '@ghostfolio/api/services/portfolio-table/portfolio-table.service'; import type { PortfolioTableService } from '@ghostfolio/api/services/portfolio-table/portfolio-table.service';
import { import {
DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGE_CODE,
MCP_MAX_ACTIVITIES MCP_MAX_ACTIVITIES
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { Activity, Filter } from '@ghostfolio/common/interfaces'; import type { Activity, Filter } from '@ghostfolio/common/interfaces';
import { permissions } from '@ghostfolio/common/permissions'; import { permissions } from '@ghostfolio/common/permissions';
import type { UserWithSettings } from '@ghostfolio/common/types'; import type { UserWithSettings } from '@ghostfolio/common/types';

2
apps/api/src/app/endpoints/mcp/mcp.test-utils.ts

@ -1,6 +1,6 @@
import { Type as ActivityType } from '@prisma/client'; import { Type as ActivityType } from '@prisma/client';
import { ActivityToImport } from './types/activity-to-import.type'; import type { ActivityToImport } from './types/activity-to-import.type';
export function createActivity( export function createActivity(
overrides: Partial<ActivityToImport> = {} overrides: Partial<ActivityToImport> = {}

4
apps/api/src/app/endpoints/mcp/types/activity-to-import.type.ts

@ -1,6 +1,6 @@
import { z } from 'zod'; import type { z } from 'zod';
import { IMPORT_ACTIVITIES_PARAMETERS } from '../mcp.schemas'; import type { IMPORT_ACTIVITIES_PARAMETERS } from '../mcp.schemas';
export type ActivityToImport = z.infer< export type ActivityToImport = z.infer<
typeof IMPORT_ACTIVITIES_PARAMETERS typeof IMPORT_ACTIVITIES_PARAMETERS

31
apps/api/src/app/import/import.service.spec.ts

@ -1,27 +1,28 @@
import { AccountService } from '@ghostfolio/api/app/account/account.service'; import type { AccountService } from '@ghostfolio/api/app/account/account.service';
import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import type { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service';
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; import type { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
import { ApiService } from '@ghostfolio/api/services/api/api.service'; import type { ApiService } from '@ghostfolio/api/services/api/api.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import type { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import type { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import type { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import type { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; import type { TagService } from '@ghostfolio/api/services/tag/tag.service';
import { NON_INVESTMENT_ACTIVITY_TYPES } from '@ghostfolio/common/config'; import { NON_INVESTMENT_ACTIVITY_TYPES } from '@ghostfolio/common/config';
import { import type {
CreateAssetProfileWithMarketDataDto, CreateAssetProfileWithMarketDataDto,
CreateOrderDto CreateOrderDto
} from '@ghostfolio/common/dtos'; } from '@ghostfolio/common/dtos';
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
import { import type {
Activity, Activity,
AssetProfileIdentifier AssetProfileIdentifier
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { UserWithSettings } from '@ghostfolio/common/types'; import type { UserWithSettings } from '@ghostfolio/common/types';
import { DataSource, SymbolProfile } from '@prisma/client'; import type { SymbolProfile } from '@prisma/client';
import { DataSource } from '@prisma/client';
import { isUUID } from 'class-validator'; import { isUUID } from 'class-validator';
import { parseISO } from 'date-fns'; import { parseISO } from 'date-fns';

2
apps/api/src/app/import/interfaces/asset-profile-to-create.interface.ts

@ -1,4 +1,4 @@
import { Prisma } from '@prisma/client'; import type { Prisma } from '@prisma/client';
export interface AssetProfileToCreate { export interface AssetProfileToCreate {
assetProfile: Prisma.SymbolProfileCreateInput; assetProfile: Prisma.SymbolProfileCreateInput;

8
apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts

@ -1,8 +1,8 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import type { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type'; import type { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import type { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class MwrPortfolioCalculator extends PortfolioCalculator { export class MwrPortfolioCalculator extends PortfolioCalculator {

6
apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts

@ -1,12 +1,12 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import type { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { import type {
Activity, Activity,
ExportResponse, ExportResponse,
HistoricalDataItem HistoricalDataItem
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types'; import type { DateRange } from '@ghostfolio/common/types';
import { readFileSync } from 'node:fs'; import { readFileSync } from 'node:fs';
import { join } from 'node:path'; import { join } from 'node:path';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur-in-base-currency-eur.spec.ts

@ -15,7 +15,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity, ExportResponse } from '@ghostfolio/common/interfaces'; import type { Activity, ExportResponse } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btceur.spec.ts

@ -14,7 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity, ExportResponse } from '@ghostfolio/common/interfaces'; import type { Activity, ExportResponse } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-before-first-market-price.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {

4
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-cash.spec.ts

@ -11,7 +11,7 @@ import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.s
import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock';
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
import { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service'; import type { AssetProfileSplitService } from '@ghostfolio/api/services/asset-profile-split/asset-profile-split.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
@ -19,7 +19,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { PortfolioSnapshotHolding } from '@ghostfolio/common/models'; import type { PortfolioSnapshotHolding } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { DataSource } from '@prisma/client'; import { DataSource } from '@prisma/client';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy-with-dividend.spec.ts

@ -14,7 +14,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts

@ -14,7 +14,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-fee-and-dividend.spec.ts

@ -14,7 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-manual-buy-before-first-market-price.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-manual-buy-with-market-price-between-chart-dates.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-and-sell.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-from-two-data-sources.spec.ts

@ -14,7 +14,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

5
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-stock-split.spec.ts

@ -14,10 +14,11 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { AssetProfileSplit, DataSource } from '@prisma/client'; import type { AssetProfileSplit } from '@prisma/client';
import { DataSource } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {

2
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-valuable.spec.ts

@ -13,7 +13,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

4
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.spec.ts

@ -2,7 +2,7 @@
* @jest-environment <rootDir>/jest-environment-tz.js * @jest-environment <rootDir>/jest-environment-tz.js
* @jest-environment-options {"timeZone": "America/New_York"} * @jest-environment-options {"timeZone": "America/New_York"}
*/ */
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import type { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory';
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
@ -14,7 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; import type { HistoricalDataItem } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {

20
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -1,11 +1,11 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accumulated-values.interface'; import type { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accumulated-values.interface';
import { AverageInvestmentItem } from '@ghostfolio/api/app/portfolio/interfaces/average-investment-item.interface'; import type { AverageInvestmentItem } from '@ghostfolio/api/app/portfolio/interfaces/average-investment-item.interface';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import type { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface'; import type { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface';
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface'; import type { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface';
import { WeightedInvestment } from '@ghostfolio/api/app/portfolio/interfaces/weighted-investment.interface'; import type { WeightedInvestment } from '@ghostfolio/api/app/portfolio/interfaces/weighted-investment.interface';
import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type'; import type { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { import {
getAnnualizedPerformancePercent, getAnnualizedPerformancePercent,
getIntervalFromDateRange getIntervalFromDateRange
@ -15,12 +15,12 @@ import {
getAssetProfileIdentifier, getAssetProfileIdentifier,
parseDate parseDate
} from '@ghostfolio/common/helper'; } from '@ghostfolio/common/helper';
import { import type {
AssetProfileIdentifier, AssetProfileIdentifier,
HistoricalDataItem HistoricalDataItem
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import type { PortfolioSnapshot } from '@ghostfolio/common/models';
import { DateRange } from '@ghostfolio/common/types'; import type { DateRange } from '@ghostfolio/common/types';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
import { Big } from 'big.js'; import { Big } from 'big.js';

8
apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts

@ -1,8 +1,8 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import type { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type'; import type { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import type { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class RoiPortfolioCalculator extends PortfolioCalculator { export class RoiPortfolioCalculator extends PortfolioCalculator {

8
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts

@ -1,8 +1,8 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import type { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type'; import type { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import type { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class TwrPortfolioCalculator extends PortfolioCalculator { export class TwrPortfolioCalculator extends PortfolioCalculator {

6
apps/api/src/app/portfolio/current-rate.service.mock.ts

@ -9,9 +9,9 @@ import {
isSameDay isSameDay
} from 'date-fns'; } from 'date-fns';
import { GetValueObject } from './interfaces/get-value-object.interface'; import type { GetValueObject } from './interfaces/get-value-object.interface';
import { GetValuesObject } from './interfaces/get-values-object.interface'; import type { GetValuesObject } from './interfaces/get-values-object.interface';
import { GetValuesParams } from './interfaces/get-values-params.interface'; import type { GetValuesParams } from './interfaces/get-values-params.interface';
function mockGetValue({ function mockGetValue({
dataSource, dataSource,

16
apps/api/src/app/portfolio/current-rate.service.spec.ts

@ -1,21 +1,17 @@
import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import type { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { resetHours } from '@ghostfolio/common/helper'; import { resetHours } from '@ghostfolio/common/helper';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { import type { MarketData, Order } from '@prisma/client';
DataSource, import { DataSource, Type as ActivityType } from '@prisma/client';
MarketData,
Order,
Type as ActivityType
} from '@prisma/client';
import { addDays, subDays } from 'date-fns'; import { addDays, subDays } from 'date-fns';
import { CurrentRateService } from './current-rate.service'; import { CurrentRateService } from './current-rate.service';
import { DateQuery } from './interfaces/date-query.interface'; import type { DateQuery } from './interfaces/date-query.interface';
import { GetValuesObject } from './interfaces/get-values-object.interface'; import type { GetValuesObject } from './interfaces/get-values-object.interface';
jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => { jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => {
return { return {

2
apps/api/src/app/portfolio/interfaces/accumulated-values.interface.ts

@ -1,4 +1,4 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
export interface AccumulatedValues { export interface AccumulatedValues {
investmentValueWithCurrencyEffect: Big; investmentValueWithCurrencyEffect: Big;

2
apps/api/src/app/portfolio/interfaces/average-investment-item.interface.ts

@ -1,4 +1,4 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
export interface AverageInvestmentItem { export interface AverageInvestmentItem {
daysUntilNextItem: number; daysUntilNextItem: number;

2
apps/api/src/app/portfolio/interfaces/get-value-object.interface.ts

@ -1,4 +1,4 @@
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
export interface GetValueObject extends AssetProfileIdentifier { export interface GetValueObject extends AssetProfileIdentifier {
date: Date; date: Date;

7
apps/api/src/app/portfolio/interfaces/get-values-object.interface.ts

@ -1,6 +1,9 @@
import { DataProviderInfo, ResponseError } from '@ghostfolio/common/interfaces'; import type {
DataProviderInfo,
ResponseError
} from '@ghostfolio/common/interfaces';
import { GetValueObject } from './get-value-object.interface'; import type { GetValueObject } from './get-value-object.interface';
export interface GetValuesObject { export interface GetValuesObject {
dataProviderInfos: DataProviderInfo[]; dataProviderInfos: DataProviderInfo[];

8
apps/api/src/app/portfolio/interfaces/get-values-params.interface.ts

@ -1,8 +1,8 @@
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import type { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { SubscriptionType } from '@ghostfolio/common/enums'; import type { SubscriptionType } from '@ghostfolio/common/enums';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { DateQuery } from './date-query.interface'; import type { DateQuery } from './date-query.interface';
export interface GetValuesParams { export interface GetValuesParams {
assetProfileIdentifiersWithQuotes: AssetProfileIdentifier[]; assetProfileIdentifiersWithQuotes: AssetProfileIdentifier[];

4
apps/api/src/app/portfolio/interfaces/holding-balance.interface.ts

@ -1,5 +1,5 @@
import { AssetSubClass, DataSource, Tag } from '@prisma/client'; import type { AssetSubClass, DataSource, Tag } from '@prisma/client';
import { Big } from 'big.js'; import type { Big } from 'big.js';
export interface HoldingBalance { export interface HoldingBalance {
activitiesCount: number; activitiesCount: number;

2
apps/api/src/app/portfolio/interfaces/holding-balances-at-date.interface.ts

@ -1,4 +1,4 @@
import { HoldingBalance } from './holding-balance.interface'; import type { HoldingBalance } from './holding-balance.interface';
export interface HoldingBalancesAtDate { export interface HoldingBalancesAtDate {
date: string; date: string;

4
apps/api/src/app/portfolio/interfaces/holding-performance.interface.ts

@ -1,6 +1,6 @@
import { DateRange } from '@ghostfolio/common/types'; import type { DateRange } from '@ghostfolio/common/types';
import { Big } from 'big.js'; import type { Big } from 'big.js';
export interface HoldingPerformance { export interface HoldingPerformance {
averageInvestment: Big; averageInvestment: Big;

4
apps/api/src/app/portfolio/interfaces/holding-valuation-item.interface.ts

@ -1,6 +1,6 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
import { PortfolioCalculatorActivityItem } from './portfolio-calculator-activity-item.interface'; import type { PortfolioCalculatorActivityItem } from './portfolio-calculator-activity-item.interface';
export interface HoldingValuationItem extends Pick< export interface HoldingValuationItem extends Pick<
PortfolioCalculatorActivityItem, PortfolioCalculatorActivityItem,

4
apps/api/src/app/portfolio/interfaces/holding-valuation.interface.ts

@ -1,6 +1,6 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
import { HoldingValuationItem } from './holding-valuation-item.interface'; import type { HoldingValuationItem } from './holding-valuation-item.interface';
export interface HoldingValuation { export interface HoldingValuation {
currentValues: { [date: string]: Big }; currentValues: { [date: string]: Big };

4
apps/api/src/app/portfolio/interfaces/portfolio-calculator-activity-item.interface.ts

@ -1,6 +1,6 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
import { PortfolioCalculatorActivity } from './portfolio-calculator-activity.interface'; import type { PortfolioCalculatorActivity } from './portfolio-calculator-activity.interface';
export interface PortfolioCalculatorActivityItem extends PortfolioCalculatorActivity { export interface PortfolioCalculatorActivityItem extends PortfolioCalculatorActivity {
feeInBaseCurrencyWithCurrencyEffect?: Big; feeInBaseCurrencyWithCurrencyEffect?: Big;

2
apps/api/src/app/portfolio/interfaces/portfolio-calculator-activity.interface.ts

@ -1,4 +1,4 @@
import { Activity } from '@ghostfolio/common/interfaces'; import type { Activity } from '@ghostfolio/common/interfaces';
export interface PortfolioCalculatorActivity extends Pick< export interface PortfolioCalculatorActivity extends Pick<
Activity, Activity,

2
apps/api/src/app/portfolio/interfaces/portfolio-calculator-holding.interface.ts

@ -1,4 +1,4 @@
import { PortfolioSnapshotHolding } from '@ghostfolio/common/models'; import type { PortfolioSnapshotHolding } from '@ghostfolio/common/models';
export interface PortfolioCalculatorHolding extends PortfolioSnapshotHolding { export interface PortfolioCalculatorHolding extends PortfolioSnapshotHolding {
includeInHoldings: boolean; includeInHoldings: boolean;

2
apps/api/src/app/portfolio/interfaces/weighted-investment.interface.ts

@ -1,4 +1,4 @@
import { Big } from 'big.js'; import type { Big } from 'big.js';
export interface WeightedInvestment { export interface WeightedInvestment {
grossPerformanceAtStartDate: Big; grossPerformanceAtStartDate: Big;

11
apps/api/src/app/portfolio/portfolio.service.spec.ts

@ -1,8 +1,8 @@
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service';
import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service';
import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; import type { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface';
import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service';
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import type { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory';
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
@ -17,15 +17,16 @@ import {
UNKNOWN_KEY UNKNOWN_KEY
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { import type {
Activity, Activity,
AssetProfileIdentifier, AssetProfileIdentifier,
Filter, Filter,
PortfolioSummary PortfolioSummary
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { AccountWithBalance, DateRange } from '@ghostfolio/common/types'; import type { AccountWithBalance, DateRange } from '@ghostfolio/common/types';
import { AssetClass, DataSource, Prisma } from '@prisma/client'; import type { Prisma } from '@prisma/client';
import { AssetClass, DataSource } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { endOfDay } from 'date-fns'; import { endOfDay } from 'date-fns';
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';

2
apps/api/src/app/portfolio/types/performance-percentages.type.ts

@ -1,4 +1,4 @@
import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; import type { HistoricalDataItem } from '@ghostfolio/common/interfaces';
export type PerformancePercentages = Required< export type PerformancePercentages = Required<
Pick< Pick<

4
apps/api/src/app/redis-cache/redis-cache.service.mock.ts

@ -1,5 +1,5 @@
import { Filter } from '@ghostfolio/common/interfaces'; import type { Filter } from '@ghostfolio/common/interfaces';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import type { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export const RedisCacheServiceMock = { export const RedisCacheServiceMock = {
cache: new Map<string, string>(), cache: new Map<string, string>(),

2
apps/api/src/decorators/impersonation.decorator.ts

@ -4,9 +4,9 @@ import type {
RequestWithUser RequestWithUser
} from '@ghostfolio/common/types'; } from '@ghostfolio/common/types';
import type { ExecutionContext } from '@nestjs/common';
import { import {
createParamDecorator, createParamDecorator,
ExecutionContext,
InternalServerErrorException InternalServerErrorException
} from '@nestjs/common'; } from '@nestjs/common';

2
apps/api/src/decorators/requires-scope-of-access.decorator.ts

@ -1,7 +1,7 @@
import { REQUIRES_SCOPE_KEY } from '@ghostfolio/api/decorators/requires-scope.decorator'; import { REQUIRES_SCOPE_KEY } from '@ghostfolio/api/decorators/requires-scope.decorator';
import { AccessGuard } from '@ghostfolio/api/guards/access.guard'; import { AccessGuard } from '@ghostfolio/api/guards/access.guard';
import { ScopeGuard } from '@ghostfolio/api/guards/scope.guard'; import { ScopeGuard } from '@ghostfolio/api/guards/scope.guard';
import { Scope } from '@ghostfolio/common/scopes'; import type { Scope } from '@ghostfolio/common/scopes';
import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common'; import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
import { ToolScopes } from '@rekog/mcp-nest'; import { ToolScopes } from '@rekog/mcp-nest';

2
apps/api/src/decorators/requires-scope.decorator.ts

@ -1,7 +1,7 @@
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { ImpersonationGuard } from '@ghostfolio/api/guards/impersonation.guard'; import { ImpersonationGuard } from '@ghostfolio/api/guards/impersonation.guard';
import { ScopeGuard } from '@ghostfolio/api/guards/scope.guard'; import { ScopeGuard } from '@ghostfolio/api/guards/scope.guard';
import { Scope } from '@ghostfolio/common/scopes'; import type { Scope } from '@ghostfolio/common/scopes';
import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common'; import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport'; import { AuthGuard } from '@nestjs/passport';

2
apps/api/src/events/asset-profile-changed.event.ts

@ -1,4 +1,4 @@
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import type { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
export class AssetProfileChangedEvent { export class AssetProfileChangedEvent {
public constructor( public constructor(

5
apps/api/src/guards/impersonation-write.guard.spec.ts

@ -1,10 +1,11 @@
import { ALLOW_DURING_IMPERSONATION_KEY } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator'; import { ALLOW_DURING_IMPERSONATION_KEY } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator';
import { REQUIRES_SCOPE_KEY } from '@ghostfolio/api/decorators/requires-scope.decorator'; import { REQUIRES_SCOPE_KEY } from '@ghostfolio/api/decorators/requires-scope.decorator';
import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config'; import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config';
import { Scope, scopes } from '@ghostfolio/common/scopes'; import type { Scope } from '@ghostfolio/common/scopes';
import { scopes } from '@ghostfolio/common/scopes';
import { HttpException } from '@nestjs/common'; import { HttpException } from '@nestjs/common';
import { Reflector } from '@nestjs/core'; import type { Reflector } from '@nestjs/core';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host'; import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { ImpersonationWriteGuard } from './impersonation-write.guard'; import { ImpersonationWriteGuard } from './impersonation-write.guard';

2
apps/api/src/guards/impersonation.guard.spec.ts

@ -1,4 +1,4 @@
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import type { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { import {
HEADER_KEY_IMPERSONATION, HEADER_KEY_IMPERSONATION,
HTTP_RESPONSE_MESSAGE_IMPERSONATION_UNRESOLVED HTTP_RESPONSE_MESSAGE_IMPERSONATION_UNRESOLVED

6
apps/api/src/guards/oauth-callback.guard.ts

@ -1,5 +1,7 @@
import { Logger, mixin, Type } from '@nestjs/common'; import type { Type } from '@nestjs/common';
import { AuthGuard, IAuthGuard } from '@nestjs/passport'; import { Logger, mixin } from '@nestjs/common';
import type { IAuthGuard } from '@nestjs/passport';
import { AuthGuard } from '@nestjs/passport';
export function OAuthCallbackGuard(strategy: string): Type<IAuthGuard> { export function OAuthCallbackGuard(strategy: string): Type<IAuthGuard> {
class OAuthCallbackGuardMixin extends AuthGuard(strategy) { class OAuthCallbackGuardMixin extends AuthGuard(strategy) {

5
apps/api/src/guards/scope.guard.spec.ts

@ -1,7 +1,8 @@
import { Scope, scopes } from '@ghostfolio/common/scopes'; import type { Scope } from '@ghostfolio/common/scopes';
import { scopes } from '@ghostfolio/common/scopes';
import { HttpException } from '@nestjs/common'; import { HttpException } from '@nestjs/common';
import { Reflector } from '@nestjs/core'; import type { Reflector } from '@nestjs/core';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host'; import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { ScopeGuard } from './scope.guard'; import { ScopeGuard } from './scope.guard';

2
apps/api/src/helper/account.helper.ts

@ -1,7 +1,7 @@
import { TAG_ID_EXCLUDE_FROM_ANALYSIS } from '@ghostfolio/common/config'; import { TAG_ID_EXCLUDE_FROM_ANALYSIS } from '@ghostfolio/common/config';
import { getStartOfUtcDateOfTomorrow } from '@ghostfolio/common/helper'; import { getStartOfUtcDateOfTomorrow } from '@ghostfolio/common/helper';
import { Prisma } from '@prisma/client'; import type { Prisma } from '@prisma/client';
export const WHERE_ACCOUNT_NOT_EXCLUDED: Prisma.AccountWhereInput = { export const WHERE_ACCOUNT_NOT_EXCLUDED: Prisma.AccountWhereInput = {
tags: { tags: {

2
apps/api/src/helper/activity.helper.ts

@ -3,7 +3,7 @@ import {
TAG_ID_DRAFT TAG_ID_DRAFT
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { Prisma, Type as ActivityType } from '@prisma/client'; import type { Prisma, Type as ActivityType } from '@prisma/client';
import { endOfToday, isAfter } from 'date-fns'; import { endOfToday, isAfter } from 'date-fns';
import { uniqBy } from 'lodash-es'; import { uniqBy } from 'lodash-es';

2
apps/api/src/helper/data-source.helper.spec.ts

@ -1,4 +1,4 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataSource } from '@prisma/client'; import { DataSource } from '@prisma/client';

5
apps/api/src/helper/data-source.helper.ts

@ -1,6 +1,7 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataSource, Prisma } from '@prisma/client'; import type { Prisma } from '@prisma/client';
import { DataSource } from '@prisma/client';
import { isEmpty } from 'lodash-es'; import { isEmpty } from 'lodash-es';
import { createHash } from 'node:crypto'; import { createHash } from 'node:crypto';

2
apps/api/src/helper/execution-context.helper.ts

@ -1,4 +1,4 @@
import { ExecutionContext } from '@nestjs/common'; import type { ExecutionContext } from '@nestjs/common';
/** /**
* Gives the underlying HTTP request of a request of any kind. A tool of the * Gives the underlying HTTP request of a request of any kind. A tool of the

2
apps/api/src/helper/interfaces/table-parameters.interface.ts

@ -1,4 +1,4 @@
import { TableColumnDefinition } from './table-column-definition.interface'; import type { TableColumnDefinition } from './table-column-definition.interface';
export interface TableParameters<T, C> { export interface TableParameters<T, C> {
columnDefinitions: readonly TableColumnDefinition<T, C>[]; columnDefinitions: readonly TableColumnDefinition<T, C>[];

2
apps/api/src/helper/markdown-table.helper.spec.ts

@ -1,4 +1,4 @@
import { TableColumnDefinition } from './interfaces/table-column-definition.interface'; import type { TableColumnDefinition } from './interfaces/table-column-definition.interface';
import { getTableInput } from './markdown-table.helper'; import { getTableInput } from './markdown-table.helper';
interface Holding { interface Holding {

2
apps/api/src/helper/markdown-table.helper.ts

@ -1,4 +1,4 @@
import { TableParameters } from './interfaces/table-parameters.interface'; import type { TableParameters } from './interfaces/table-parameters.interface';
/** /**
* Gives the columns and the rows in the form which the renderer takes, with * Gives the columns and the rows in the form which the renderer takes, with

2
apps/api/src/helper/object.helper.spec.ts

@ -1,5 +1,5 @@
import { DEFAULT_REDACTED_PATHS } from '@ghostfolio/common/config'; import { DEFAULT_REDACTED_PATHS } from '@ghostfolio/common/config';
import { PortfolioDetails } from '@ghostfolio/common/interfaces'; import type { PortfolioDetails } from '@ghostfolio/common/interfaces';
import { query, redactPaths } from './object.helper'; import { query, redactPaths } from './object.helper';

4
apps/api/src/helper/portfolio.helper.ts

@ -1,6 +1,6 @@
import { PortfolioDetails } from '@ghostfolio/common/interfaces'; import type { PortfolioDetails } from '@ghostfolio/common/interfaces';
import { Type as ActivityType } from '@prisma/client'; import type { Type as ActivityType } from '@prisma/client';
export function convertValuesToPercentages({ export function convertValuesToPercentages({
accounts, accounts,

2
apps/api/src/helper/redis.helper.ts

@ -1,4 +1,4 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
export function getRedisConnectionOptions( export function getRedisConnectionOptions(
configurationService: ConfigurationService configurationService: ConfigurationService

2
apps/api/src/helper/sector.helper.ts

@ -1,5 +1,5 @@
import { SECTORS } from '@ghostfolio/common/config'; import { SECTORS } from '@ghostfolio/common/config';
import { SectorName } from '@ghostfolio/common/types'; import type { SectorName } from '@ghostfolio/common/types';
import { Logger } from '@nestjs/common'; import { Logger } from '@nestjs/common';

2
apps/api/src/helper/security-headers.helper.spec.ts

@ -1,5 +1,5 @@
import helmet from 'helmet'; import helmet from 'helmet';
import { IncomingMessage, ServerResponse } from 'node:http'; import type { IncomingMessage, ServerResponse } from 'node:http';
import { getHelmetOptions } from './security-headers.helper'; import { getHelmetOptions } from './security-headers.helper';

2
apps/api/src/helper/security-headers.helper.ts

@ -1,4 +1,4 @@
import { HelmetOptions } from 'helmet'; import type { HelmetOptions } from 'helmet';
export function getHelmetOptions({ export function getHelmetOptions({
isSubscriptionEnabled isSubscriptionEnabled

7
apps/api/src/main.ts

@ -13,9 +13,9 @@ import {
SUPPORTED_LANGUAGE_CODES SUPPORTED_LANGUAGE_CODES
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import type { LogLevel } from '@nestjs/common';
import { import {
Logger, Logger,
LogLevel,
ShutdownSignal, ShutdownSignal,
ValidationPipe, ValidationPipe,
VersioningType VersioningType
@ -23,9 +23,10 @@ import {
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express'; import type { NestExpressApplication } from '@nestjs/platform-express';
import { MCP_STRATEGY, McpStrategy } from '@rekog/mcp-nest'; import type { McpStrategy } from '@rekog/mcp-nest';
import { MCP_STRATEGY } from '@rekog/mcp-nest';
import cookieParser from 'cookie-parser'; import cookieParser from 'cookie-parser';
import { NextFunction, Request, Response } from 'express'; import type { NextFunction, Request, Response } from 'express';
import helmet from 'helmet'; import helmet from 'helmet';
import { EnvHttpProxyAgent, setGlobalDispatcher } from 'undici'; import { EnvHttpProxyAgent, setGlobalDispatcher } from 'undici';

2
apps/api/src/middlewares/language-redirect.middleware.ts

@ -1,7 +1,7 @@
import { environment } from '@ghostfolio/api/environments/environment'; import { environment } from '@ghostfolio/api/environments/environment';
import { getLanguageCodeFromHeader } from '@ghostfolio/api/helper/language.helper'; import { getLanguageCodeFromHeader } from '@ghostfolio/api/helper/language.helper';
import { NextFunction, Request, Response } from 'express'; import type { NextFunction, Request, Response } from 'express';
import { StatusCodes } from 'http-status-codes'; import { StatusCodes } from 'http-status-codes';
export function languageRedirectMiddleware( export function languageRedirectMiddleware(

8
apps/api/src/middlewares/mcp-authorization.middleware.ts

@ -1,13 +1,13 @@
import { UserService } from '@ghostfolio/api/app/user/user.service'; import type { UserService } from '@ghostfolio/api/app/user/user.service';
import { getAccessIdOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper'; import { getAccessIdOfBearerToken } from '@ghostfolio/api/helper/bearer-token.helper';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import type { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import type { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { HEADER_KEY_TOKEN, MCP_REALM } from '@ghostfolio/common/config'; import { HEADER_KEY_TOKEN, MCP_REALM } from '@ghostfolio/common/config';
import { hasRole } from '@ghostfolio/common/permissions'; import { hasRole } from '@ghostfolio/common/permissions';
import type { ImpersonationContext } from '@ghostfolio/common/types'; import type { ImpersonationContext } from '@ghostfolio/common/types';
import { RequestClient } from '@prisma/client'; import { RequestClient } from '@prisma/client';
import { NextFunction, Request, Response } from 'express'; import type { NextFunction, Request, Response } from 'express';
import { getReasonPhrase, StatusCodes } from 'http-status-codes'; import { getReasonPhrase, StatusCodes } from 'http-status-codes';
/** /**

4
apps/api/src/models/interfaces/rule.interface.ts

@ -1,6 +1,6 @@
import { RuleSettings } from '@ghostfolio/common/interfaces'; import type { RuleSettings } from '@ghostfolio/common/interfaces';
import { EvaluationResult } from './evaluation-result.interface'; import type { EvaluationResult } from './evaluation-result.interface';
export interface RuleInterface<T extends RuleSettings> { export interface RuleInterface<T extends RuleSettings> {
evaluate(aRuleSettings: T): EvaluationResult; evaluate(aRuleSettings: T): EvaluationResult;

10
apps/api/src/models/rule.ts

@ -1,6 +1,6 @@
import { XRayRuleKey } from '@ghostfolio/api/models/types/x-ray-rule-key.type'; import type { XRayRuleKey } from '@ghostfolio/api/models/types/x-ray-rule-key.type';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { import type {
PortfolioPosition, PortfolioPosition,
PortfolioReportRule, PortfolioReportRule,
RuleSettings RuleSettings
@ -9,8 +9,8 @@ import {
import { Big } from 'big.js'; import { Big } from 'big.js';
import { groupBy } from 'lodash-es'; import { groupBy } from 'lodash-es';
import { EvaluationResult } from './interfaces/evaluation-result.interface'; import type { EvaluationResult } from './interfaces/evaluation-result.interface';
import { RuleInterface } from './interfaces/rule.interface'; import type { RuleInterface } from './interfaces/rule.interface';
export abstract class Rule<T extends RuleSettings> implements RuleInterface<T> { export abstract class Rule<T extends RuleSettings> implements RuleInterface<T> {
protected exchangeRateDataService: ExchangeRateDataService; protected exchangeRateDataService: ExchangeRateDataService;

13
apps/api/src/models/rules/account-cluster-risk/current-investment.ts

@ -1,9 +1,12 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioDetails, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioDetails,
import { Account } from '@prisma/client'; RuleSettings
} from '@ghostfolio/common/interfaces';
import type { Account } from '@prisma/client';
export class AccountClusterRiskCurrentInvestment extends Rule<Settings> { export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
private accounts: PortfolioDetails['accounts']; private accounts: PortfolioDetails['accounts'];

9
apps/api/src/models/rules/account-cluster-risk/single-account.ts

@ -1,7 +1,10 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioDetails, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioDetails,
RuleSettings
} from '@ghostfolio/common/interfaces';
export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> { export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> {
private accounts: PortfolioDetails['accounts']; private accounts: PortfolioDetails['accounts'];

9
apps/api/src/models/rules/asset-class-cluster-risk/equity.ts

@ -1,7 +1,10 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioPosition, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioPosition,
RuleSettings
} from '@ghostfolio/common/interfaces';
export class AssetClassClusterRiskEquity extends Rule<Settings> { export class AssetClassClusterRiskEquity extends Rule<Settings> {
private holdings: PortfolioPosition[]; private holdings: PortfolioPosition[];

9
apps/api/src/models/rules/asset-class-cluster-risk/fixed-income.ts

@ -1,7 +1,10 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioPosition, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioPosition,
RuleSettings
} from '@ghostfolio/common/interfaces';
export class AssetClassClusterRiskFixedIncome extends Rule<Settings> { export class AssetClassClusterRiskFixedIncome extends Rule<Settings> {
private holdings: PortfolioPosition[]; private holdings: PortfolioPosition[];

9
apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts

@ -1,7 +1,10 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioPosition, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioPosition,
RuleSettings
} from '@ghostfolio/common/interfaces';
export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> { export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> {
private holdings: PortfolioPosition[]; private holdings: PortfolioPosition[];

9
apps/api/src/models/rules/currency-cluster-risk/current-investment.ts

@ -1,7 +1,10 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PortfolioPosition, RuleSettings } from '@ghostfolio/common/interfaces'; import type {
PortfolioPosition,
RuleSettings
} from '@ghostfolio/common/interfaces';
export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> { export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
private holdings: PortfolioPosition[]; private holdings: PortfolioPosition[];

6
apps/api/src/models/rules/economic-market-cluster-risk/developed-markets.ts

@ -1,7 +1,7 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { RuleSettings } from '@ghostfolio/common/interfaces'; import type { RuleSettings } from '@ghostfolio/common/interfaces';
export class EconomicMarketClusterRiskDevelopedMarkets extends Rule<Settings> { export class EconomicMarketClusterRiskDevelopedMarkets extends Rule<Settings> {
private currentValueInBaseCurrency: number; private currentValueInBaseCurrency: number;

6
apps/api/src/models/rules/economic-market-cluster-risk/emerging-markets.ts

@ -1,7 +1,7 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { RuleSettings } from '@ghostfolio/common/interfaces'; import type { RuleSettings } from '@ghostfolio/common/interfaces';
export class EconomicMarketClusterRiskEmergingMarkets extends Rule<Settings> { export class EconomicMarketClusterRiskEmergingMarkets extends Rule<Settings> {
private currentValueInBaseCurrency: number; private currentValueInBaseCurrency: number;

6
apps/api/src/models/rules/emergency-fund/emergency-fund-coverage.ts

@ -1,7 +1,7 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { RuleSettings } from '@ghostfolio/common/interfaces'; import type { RuleSettings } from '@ghostfolio/common/interfaces';
import { Big } from 'big.js'; import { Big } from 'big.js';

6
apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts

@ -1,7 +1,7 @@
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { RuleSettings } from '@ghostfolio/common/interfaces'; import type { RuleSettings } from '@ghostfolio/common/interfaces';
export class EmergencyFundSetup extends Rule<Settings> { export class EmergencyFundSetup extends Rule<Settings> {
private emergencyFundInBaseCurrency: number; private emergencyFundInBaseCurrency: number;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save