Skip to content

Portfolio builder

@investec/plugins-portfolio-builder retrieves the portfolios allowed by the authenticated client context, stores them in a shared state object, and keeps net-worth totals up to date.

Package

sh
npm install --save @investec/plugins-portfolio-builder

What it owns

  • environment-aware portfolio endpoint selection
  • direct fetch helpers for individual portfolio types
  • aggregate state in portfolioBuilder
  • totals calculation across included portfolios
  • optional exclusions from totals
  • streamed multi-portfolio loading through getAllPortfoliosStream(...)

Public contract

The package exports:

  • portfolioBuilder
  • portfolio
  • portfolio types such as IPortfolioEntity

portfolioBuilder contains:

  • activeEnvironment
  • profileSwitch
  • updateAppState
  • currentPortfolioState
  • authResponse
  • clearState

Integration pattern

Set the environment and auth context first:

ts
import {
  portfolio,
  portfolioBuilder,
} from '@investec/plugins-portfolio-builder';

portfolioBuilder.activeEnvironment = 'staging';
portfolioBuilder.authResponse.next(authResponse);

portfolioBuilder.updateAppState.subscribe((state) => {
  // Persist or forward portfolio state.
});

Use direct fetch methods when you need one portfolio:

ts
await portfolio.getPrivateBankZAPortfolio('ZAR', profileId);

Use the streaming method when a shell or SDK host needs the full aggregate flow:

ts
portfolio.getAllPortfoliosStream(target);

target must match the exported HookTarget shape and provide source.postMessage(...).

Runtime behaviour

Direct methods such as getPrivateBankZAPortfolio(...), getPrivateBankUKPortfolio(...), getWealthAndInvestmentZAPortfolio(...), getAllNonInvestecAccounts(...), and the other portfolio-specific methods:

  • fetch the relevant endpoint
  • merge the response into currentPortfolioState
  • update totals
  • push the new state through updateAppState

getAllPortfoliosStream(...) orchestrates those methods from auth context and posts intermediate and final results through target.source.postMessage(...) using __id: 'portfolio.stream'.

State shape

The aggregate state includes:

  • portfolios
  • totals
  • callResultMap
  • currency
  • contactData
  • excludes

Totals are recalculated whenever portfolios or exclusions change.

How consumers extend it

Consumers extend this package through orchestration and post-processing:

  • push authResponse and selected-profile context before calling portfolio methods;
  • call direct portfolio methods when only one portfolio family is needed;
  • use getAllPortfoliosStream(...) when a host needs incremental updates;
  • use UpdatePortfolioExcludes(...) to change which loaded portfolios contribute to totals;
  • persist or transform the emitted state for product-specific rendering.

Change the package when a new portfolio family, endpoint, contact-data rule, or shared aggregation rule is needed.

Extension example: load one portfolio family and exclude it from totals

ts
import {
  portfolio,
  portfolioBuilder,
  type IPortfolioEntity,
} from '@investec/plugins-portfolio-builder';

let latestPortfolioState: IPortfolioEntity | undefined;

portfolioBuilder.activeEnvironment = 'staging';
portfolioBuilder.authResponse.next(authResponse);

portfolioBuilder.updateAppState.subscribe((state) => {
  latestPortfolioState = state;
});

await portfolio.getPrivateBankZAPortfolio('ZAR', selectedProfileId);

await portfolio.UpdatePortfolioExcludes([
  { flag: 'PrivateBankZA', result: true },
]);

console.log(latestPortfolioState?.totals);

Consumer notes

  • profileSwitch affects how the selected profile data is interpreted by the aggregate streaming flow.
  • Some portfolio methods also populate contactData.
  • UpdatePortfolioExcludes(...) changes which portfolios contribute to totals; it does not delete the portfolio payload itself.
  • clearState.next() resets both the current portfolio state and the cached auth response.