Helm Portfolio for Dummies
Syllabus Next →
Module 08 of 10

Configuration, Reports & UI

How tenant settings shape the experience, how PDFs get generated, and what users actually see when they log in.

20 minutes Completed Module 7

The Settings System

Portfolio is highly configurable per tenant. Settings are stored in the database using Spatie Laravel Settings — a package that persists typed setting classes to a settings table. There are four setting groups, each controlling a different aspect of the platform.

ConfigSettings
Controls what metrics and UI elements are visible
reportingQuarter string
The current reporting quarter (e.g., "Q4 2025"). When hideDatePicker is true, all views are locked to this quarter.
showIRR bool
Show or hide XIRR on dashboards and reports. Some clients hide IRR for young funds where early numbers are misleadingly extreme.
showFee bool
Show or hide fee information in investor views and reports.
hideValuationBridge bool
Hide the valuation bridge waterfall chart from dashboards. Can be hidden when not applicable.
hideDatePicker bool
Lock all views to the reportingQuarter — removes the date picker from the UI entirely. Prevents users from viewing non-finalized data.
showInvestorUnitsVPU bool
Show "Units" and "Value Per Unit" columns in investor tables. Only meaningful for unit-based funds.
overwriteCGWithReturns bool
Replace "Capital Gains" with "Total Returns" on dashboards. Same label, different calculation. A common source of confusion.
showCombinedView bool
Show the combined Fund + Direct view option in the StructureSwitcher. Clients with only funds or only directs don't need this.
ReportSettings
Controls branding and content for generated PDF reports
logo string
S3 URL to the client's logo. Displayed on the cover page and headers of QPR reports.
contacts array
Array of contact objects (name, email, phone) shown on the report cover page and footer.
organisationName string
The client's organization name as it appears on reports.
footer string
Custom footer text for all generated PDFs.
colours array
Whitelabel colour palette for reports — primary, secondary, accent. Applied to charts, headers, and highlights in the PDF output.
glossary string
Optional glossary of terms appended to QPR reports. Helps investors understand fund-specific terminology.
disclaimer string
Legal disclaimer text appended to report footers.
TaxSettings
Tax-related configuration
enableDistributionTax bool
Toggle tax withholding on distributions. When enabled, distribution calculations include a tax withholding component that reduces the net distribution amount to investors.
TransactionSettings
Controls transaction creation behavior
enableHistoricalAssetTransfer bool
Allow backdated asset transfers. When enabled, users can create asset transfers with historical dates (e.g., migrating legacy data). When disabled, transfers must use the current date.
Settings are per-tenant

Each tenant has its own copy of all settings. Client A might show IRR while Client B hides it. Client C might have the combined view enabled while Client D only has funds. This is what makes Portfolio work for diverse client types — the same codebase adapts via configuration.

Report Generation

Portfolio generates three types of PDF reports. All use the same pipeline: calculate metrics via the Go gRPC service, render HTML templates with the data, then convert to PDF using Chromium (headless browser).

Quarterly Performance Report (QPR)

The flagship report. Per-asset, includes all dashboard metrics (committed, called, paid-in, distributions, NAV, DPI, TVPI, XIRR), allocation charts, valuation bridge, and timeline data. Branded with client logo and colours from ReportSettings. Can include glossary and disclaimer.

Capital Call Notice

Per-investor breakdown of a capital call. Shows the investor's commitment, call percentage, amount due, and payment instructions. Generated when a capital call transaction is created.

Distribution Notice

Per-investor breakdown of a distribution. Shows the investor's share, distribution type (return of capital, income, etc.), and net amount after any tax withholding. Generated when a distribution transaction is created.

Generated PDFs are stored on S3 and linked to assets or investors via ReportFiles, UserAttachments, and AssetAttachments records in the database. Users can download them from the Documents tab in the frontend.

The Frontend

See it visually

For annotated mockups of the Dashboard, Investors Table, Data Import page, and Investor "My View," see the UI Visual Reference page. It shows exactly what each screen looks like with the data from our sample exercises.

The Portfolio UI is part of the Delio Frontend — a React + TypeScript application using Ant Design components. Here's the page map:

Dashboard

Overview with StructureSwitcher (Fund / Direct / Combined) and ViewModeToggle (Group vs My View). Widget cards, charts, and summary tables.

Investors Overview

List of all investors with key metrics. Click through to investor detail.

Investor Detail

Per-investor dashboard, investments breakdown, documents, and transaction history.

Investments Overview

All assets (funds and directs) with valuations, structure type, and status.

Transactions

Investor transactions and fee tabs. Create, view, and reverse transactions.

Ledger

Full journal-style ledger of all cash flows across the portfolio.

Data Import

9 import categories (investors, subscriptions, capital calls, etc.) plus import history with reversal support.

Investor Portfolio

Self-service "My View" for investors (LPs). Read-only view of their own positions, documents, and returns.

Dashboard Widgets

The dashboard cards are powered by three dedicated widget endpoints. Each endpoint returns pre-computed data from the Go calculation service (via cache):

EndpointWhat It Powers
/widgets/capital-overviewFund metrics cards: Committed, Called, Uncalled, Paid-In, Distributions, NAV, DPI, TVPI, RVPI, Capital Gains, XIRR
/widgets/direct-overviewDirect metrics cards: Investment, Valuation, Income, Yield, Return on Capital, Multiple, Profit
/widgets/aggregates-overviewCombined view: merged fund + direct totals for the unified dashboard

StructureSwitcher and ViewModeToggle

Two key UI controls sit at the top of the dashboard:

StructureSwitcher

Toggles between three portfolio views:

  • Fund — shows only fund-type assets (capital calls, distributions, NAV)
  • Direct — shows only direct investments (investment, valuation, income)
  • Combined — merged view (only visible if showCombinedView is enabled)

ViewModeToggle

Switches the data scope:

  • Group — all investors aggregated (the GP/admin view)
  • My View — filtered to the logged-in investor's own positions (the LP self-service view)

Feature Flags

Two organisation-level feature flags gate access to Portfolio features:

FlagPurpose
organisation.portfolio_enabled Legacy flag. When true, the organisation has access to the Portfolio module. Used during initial rollout.
organisation.enable_new_portfolio_reporting Enables the newer reporting pipeline (QPR generation). Organisations without this flag use an older report format or have reporting disabled entirely.
Feature flags vs ConfigSettings

Feature flags are organisation-level toggles that gate entire capabilities (can they use Portfolio at all?). ConfigSettings are tenant-level preferences that shape the experience (what do they see once they're in?). They live in different systems — flags in Delio Core, settings in Portfolio's own database.

Whitelabel

Portfolio supports semantic branding — clients can rename key entities to match their own terminology. For example, "Investor" can display as "Client" or "Partner" throughout the UI. This is configured through a branding context that maps semantic labels to display labels.

Combined with ReportSettings (logo, colours, footer, disclaimer), this means two tenants on the same Portfolio instance can have completely different-looking reports and UI labels while running the same underlying code.

The frontend checks the branding context for label overrides. If "Investor" is mapped to "Client", then:

  • The "Investors Overview" page title becomes "Clients Overview"
  • Table column headers change from "Investor" to "Client"
  • Report headers and notices use "Client" throughout

The underlying data model, API endpoints, and code all still use "investor" internally. The label swap is purely cosmetic at the UI and report layer.

Knowledge Check

Question 1

A client wants to hide IRR from their quarterly reports and lock all views to Q4 2025. Which settings need to be configured?

showIRR = false and reportingQuarter = "Q4 2025"
showIRR = false, hideDatePicker = true, and reportingQuarter = "Q4 2025"
organisation.enable_new_portfolio_reporting = false to disable reports entirely
Correct! You need all three: showIRR = false hides IRR everywhere, hideDatePicker = true prevents users from changing the date range, and reportingQuarter = "Q4 2025" sets the locked quarter. Just setting the reporting quarter without hiding the date picker would still let users browse other periods.
Not quite. Setting reportingQuarter alone doesn't lock the view — users can still pick other dates. You also need hideDatePicker = true to actually remove the date selector from the UI. And hiding IRR requires showIRR = false in ConfigSettings, not disabling reporting entirely. The correct answer is B.
Question 2

Where does the Quarterly Performance Report (QPR) get its financial data from?

Directly from the PostgreSQL database via SQL queries in the Laravel report builder
From the Go gRPC calculation service (same as the dashboard), then rendered as HTML and converted to PDF via Chromium
From a pre-computed data warehouse that runs overnight batch jobs
Correct! QPRs use the same Go calculation service that powers the dashboard. The Laravel app requests metrics via gRPC, populates an HTML template with the data, then uses headless Chromium to render the HTML to a PDF. The PDF is stored on S3 and linked to the asset via an attachment record.
Not quite. Reports don't query the database directly or use a data warehouse. They go through the same pipeline as the dashboard: Laravel calls the Go gRPC service for metrics, renders them into an HTML template, and converts to PDF using headless Chromium. This ensures report numbers match dashboard numbers exactly. The correct answer is B.

What's Next

You now understand how Portfolio is configured, how reports are generated, and what the frontend looks like. Next, we'll take an honest look at strengths, weaknesses, and gotchas — what Portfolio does well, where it falls short, and the landmines to watch out for.