You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

10 KiB

Data Model: Portfolio Performance Views

Feature: 003-portfolio-performance-views Date: 2026-03-16

Entity Relationship Overview

User ─1:N─► Entity ─1:N─► PartnershipMembership ◄─N:1─ Partnership
                │                                          │
                │                                          ├─1:N─► PartnershipAsset (has assetType)
                │                                          ├─1:N─► PartnershipValuation (has nav, date)
                │                                          └─1:N─► KDocument (has K1Data JSON, taxYear)
                │
                └─1:N─► Distribution (has amount, date, type)

Entities

Entity (existing — no changes)

Field Type Description
id String (UUID) Primary key
name String Display name (e.g., "Entity #1")
type EntityType enum INDIVIDUAL, TRUST, LLC, LP, CORPORATION, FOUNDATION, ESTATE
taxId String? Tax identification number
userId String Owner user FK

Role in feature: Primary grouping dimension for Portfolio Summary view. Each row = one entity.

Partnership (existing — no changes)

Field Type Description
id String (UUID) Primary key
name String Display name (e.g., "Partnership #1")
type PartnershipType enum LP, GP, LLC, JOINT_VENTURE, FUND
inceptionDate DateTime Used as date for initial contribution cash flow
fiscalYearEnd String? Month (e.g., "12" for December)
currency String Default "USD"
userId String Owner user FK

Role in feature: Contributes to all three views. Asset class determined by its PartnershipAsset records.

PartnershipMembership (existing — no changes)

Field Type Description
id String (UUID) Primary key
entityId String FK → Entity
partnershipId String FK → Partnership
ownershipPercent Decimal Ownership percentage (0–100)
capitalCommitment Decimal Original committed amount
capitalContributed Decimal Cumulative contributed to date
classType String? Interest class (e.g., "Class A")
effectiveDate DateTime Membership start
endDate DateTime? Null = active

Role in feature: Links entities to partnerships. Provides Original Commitment and capitalized amounts for Portfolio Summary. Unique constraint: [entityId, partnershipId, effectiveDate].

Distribution (existing — no changes)

Field Type Description
id String (UUID) Primary key
partnershipId String? FK → Partnership
entityId String FK → Entity
type DistributionType enum INCOME, RETURN_OF_CAPITAL, CAPITAL_GAIN, GUARANTEED_PAYMENT, DIVIDEND, INTEREST
amount Decimal Distribution amount
date DateTime Distribution date
currency String Default "USD"
taxWithheld Decimal? Withheld tax amount
notes String? Free-text notes

Role in feature: Feeds Distributions column in summaries, cash flow series for XIRR, and per-year distribution totals in Activity view.

PartnershipAsset (existing — no changes)

Field Type Description
id String (UUID) Primary key
partnershipId String FK → Partnership
assetType FamilyOfficeAssetType enum PUBLIC_EQUITY, PRIVATE_EQUITY, REAL_ESTATE, HEDGE_FUND, VENTURE_CAPITAL, FIXED_INCOME, COMMODITY, ART_COLLECTIBLE, CRYPTOCURRENCY, CASH, OTHER
name String Asset name
currentValue Decimal Latest value

Role in feature: Determines which asset class a partnership belongs to (majority assetType). Feeds Asset Class Summary grouping.

PartnershipValuation (existing — no changes)

Field Type Description
id String (UUID) Primary key
partnershipId String FK → Partnership
date DateTime Valuation date
nav Decimal Net asset value
source ValuationSource enum APPRAISAL, MARKET, MANUAL, NAV_STATEMENT, FUND_ADMIN

Role in feature: Provides "Residual Used" (latest NAV × ownership%) for RVPI and TVPI. Terminal value for XIRR cash flows.

KDocument (existing — data JSON schema extended)

Field Type Description
id String (UUID) Primary key
partnershipId String FK → Partnership
type KDocumentType enum K1, K3
taxYear Int Tax year (e.g., 2024)
filingStatus KDocumentStatus enum DRAFT, ESTIMATED, FINAL
data Json K1Data or K3Data structured JSON
documentFileId String? FK → Document

Unique constraint: [partnershipId, type, taxYear]

Role in feature: Primary data source for Activity view income components and tax basis fields.

K1Data JSON Schema (extended)

Existing fields (no changes)

Field K-1 Box Type Activity Column Mapping
ordinaryIncome Box 1 number Part of "Remaining K-1 Income/Ded."
netRentalIncome Box 2 number Part of "Remaining K-1 Income/Ded."
otherRentalIncome Box 3 number Part of "Remaining K-1 Income/Ded."
guaranteedPayments Box 4 number Part of "Remaining K-1 Income/Ded."
interestIncome Box 5 number "Interest" column
dividends Box 6a number "Dividends" column
qualifiedDividends Box 6b number (sub-detail of dividends)
royalties Box 7 number Part of "Remaining K-1 Income/Ded."
capitalGainLossShortTerm Box 8 number Part of "Cap Gains"
capitalGainLossLongTerm Box 9a number Part of "Cap Gains"
unrecaptured1250Gain Box 9b number Part of "Cap Gains"
section1231GainLoss Box 9c number Part of "Cap Gains"
otherIncome Box 11 number Part of "Remaining K-1 Income/Ded."
section179Deduction Box 12 number Part of "Remaining K-1 Income/Ded." (negative)
otherDeductions Box 13 number Part of "Remaining K-1 Income/Ded." (negative)
selfEmploymentEarnings Box 14 number Part of "Remaining K-1 Income/Ded."
foreignTaxesPaid Box 16 number Part of "Remaining K-1 Income/Ded." (negative)
alternativeMinimumTaxItems Box 17 number (informational)
distributionsCash Box 19a number Part of "Distributions"
distributionsProperty Box 19b number Part of "Distributions"

New fields (added for tax basis tracking)

Field Source Type Description
beginningTaxBasis Prior year ending or manual number? Beginning of year tax basis
endingTaxBasis Computed or manual number? End of year tax basis
endingGLBalance General ledger number? Ending GL balance per books
k1CapitalAccount K-1 Schedule L number? Ending K-1 capital account
otherAdjustments K-1 Box 18c etc. number? Other basis adjustments
activityNotes Manual entry string? Per-year notes (e.g., "AJE Completed")

All new fields are optional (?) to maintain backward compatibility with existing K-1 documents.

Derived/Computed Fields

These are computed at query time and not stored:

Summary View Computations (per entity or per asset class)

Metric Formula Notes
Original Commitment Σ membership.capitalCommitment Across active memberships in scope
Paid-In (ABS) Σ membership.capitalContributed Absolute value of contributions
% Called Paid-In ÷ Original Commitment × 100 Percentage; "N/A" if commitment = 0
Unfunded Commitment Original Commitment − Paid-In Can be 0
Distributions Σ distribution.amount All distributions in scope
Residual Used Σ (latestValuation.nav × membership.ownershipPercent / 100) Per-partnership NAV allocated by ownership
DPI Distributions ÷ Paid-In Decimal multiple; 0 if Paid-In = 0
RVPI Residual Used ÷ Paid-In Decimal multiple; 0 if Paid-In = 0
TVPI (Distributions + Residual Used) ÷ Paid-In Decimal multiple; 0 if Paid-In = 0
IRR (XIRR) Newton-Raphson on merged cash flows null → "N/A" if < 2 cash flows

Activity View Computations (per row)

Field Formula
Capital Gains shortTerm + longTerm + unrecaptured1250Gain + section1231GainLoss
Remaining K-1 Income/Ded. ordinaryIncome + netRentalIncome + otherRentalIncome + guaranteedPayments + royalties + otherIncome + selfEmploymentEarnings − section179Deduction − otherDeductions − foreignTaxesPaid
Total Income Interest + Dividends + Capital Gains + Remaining K-1 Income/Ded.
Book-to-Tax Adj endingGLBalance − endingTaxBasis
K-1 Capital vs Tax Basis Diff k1CapitalAccount − endingTaxBasis
Excess Distribution max(0, Distributions − (beginningTaxBasis + Contributions + Total Income + otherAdjustments))
Negative Basis? endingTaxBasis < 0 → "YES"
Δ Ending Basis vs Prior Year endingTaxBasis − beginningTaxBasis

State Transitions

KDocument Filing Status

DRAFT → ESTIMATED → FINAL

Each transition may update the K1Data values (including the new tax basis fields). The Activity view always shows the latest data regardless of filing status.

Validation Rules

Rule Scope Description
capitalCommitment ≥ 0 PartnershipMembership Commitment cannot be negative
capitalContributed ≥ 0 PartnershipMembership Contributed cannot be negative
capitalContributed ≤ capitalCommitment PartnershipMembership Cannot contribute more than committed
ownershipPercent ∈ (0, 100] PartnershipMembership Must be positive percentage
distribution.amount > 0 Distribution Distributions are positive flows
taxYear ∈ [1900, current+1] KDocument Reasonable year range
nav ≥ 0 PartnershipValuation NAV cannot be negative
Σ ownershipPercent per partnership ≤ 100 PartnershipMembership Total ownership cannot exceed 100%

FamilyOfficeAssetType → Display Label Mapping

Enum Value Display Label
REAL_ESTATE Real Estate
VENTURE_CAPITAL Venture Capital
PRIVATE_EQUITY Private Equity
HEDGE_FUND Hedge Fund
FIXED_INCOME Credit
COMMODITY Natural Resources
OTHER Other
PUBLIC_EQUITY Public Equity
ART_COLLECTIBLE Art & Collectibles
CRYPTOCURRENCY Cryptocurrency
CASH Cash

Note: "Co-Investment" and "Infrastructure" from the spec map to PRIVATE_EQUITY and OTHER respectively until dedicated enum values are added.