Scenario Financial Service - Phase 1 MVP
Overview
The Scenario Financial Service calculates the financial impact (P&L and cash flow) of operational scenarios within the Judgment Engine. This service enables executives to model "what-if" scenarios by translating operational decisions into quantified financial projections.
Key Capability: Link operational scenarios to financial impact, enabling scenario comparison and financial decision-making.
Architecture:
- Service-based calculation engine
- Repository-based data persistence
- API-driven scenario analysis
- Multi-period financial projections
System Architecture
┌──────────────────────────────────────────────────────────┐
│ Decision Problem Scenario │
│ (operational parameters: growth rate, margin impact) │
└────────────────────────┬─────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ ScenarioFinancialService │
│ ├─ Get baseline financials (historical P&L) │
│ ├─ Project revenue (apply scenario growth rate) │
│ ├─ Project expenses (COGS, OpEx, D&A, Interest) │
│ ├─ Calculate working capital impact │
│ ├─ Generate cash flow statement │
│ ├─ Calculate financial ratios │
│ └─ Store results in scenario_financial_results │
└────────────────────────┬─────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ scenario_financial_results Table │
│ ├─ scenario_id, period_year, period_month │
│ ├─ P&L items (revenue, COGS, OpEx, EBITDA, NI) │
│ ├─ Cash flow (OCF, CapEx, FCF) │
│ ├─ Working capital (AR, inventory, AP) │
│ ├─ Financial ratios (profitability, solvency, etc.) │
│ └─ Scenario parameters (what drove the projection) │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ API Endpoints │
│ ├─ POST /scenarios/:id/calculate-financial-impact │
│ ├─ GET /scenarios/:id/financial-projection │
│ ├─ GET /scenarios/:id/pnl-summary │
│ ├─ GET /scenarios/:id/cash-flow-projection │
│ ├─ GET /scenarios/:id/financial-ratios │
│ ├─ GET /scenarios/:id/npv-analysis │
│ └─ POST /scenarios/:id1/compare/:id2 │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ Frontend Dashboard │
│ ├─ Scenario P&L by period │
│ ├─ Cash flow projections │
│ ├─ Financial ratio trends │
│ ├─ Scenario comparison (side-by-side) │
│ └─ NPV analysis │
└──────────────────────────────────────────────────────────┘
Financial Projection Model
1. Revenue Projection
Scenarios define a revenue_growth_rate parameter (e.g., 0.05 = 5% annual growth):
Projected Revenue = Baseline Revenue × (1 + growth_rate)^year
For Year 1: $1,000,000 × (1 + 0.05)^1 = $1,050,000
For Year 2: $1,000,000 × (1 + 0.05)^2 = $1,102,500
2. Gross Profit Calculation
COGS is maintained as a percentage of revenue:
COGS % = Baseline COGS / Baseline Revenue
Projected COGS = Projected Revenue × COGS %
Projected Gross Profit = Projected Revenue - Projected COGS
Customization: Scenarios can override cogs_pct_revenue to model margin compression or improvement.
3. Operating Expenses (OpEx)
OpEx grows at a different rate than revenue (modeling operating leverage):
Projected OpEx = Baseline OpEx × (1 + opex_growth_rate)^year + opex_fixed_adjustment
Default: opex_growth_rate = 0.03 (3% growth, slower than revenue for leverage)
OpEx Components:
- SG&A expenses
- R&D spend (configurable as % of revenue or fixed)
- Depreciation & Amortization (estimated as % of baseline)
4. EBITDA Calculation
EBITDA = Gross Profit - Operating Expenses
EBITDA Margin % = EBITDA / Revenue
5. Interest & Tax Impact
Interest Expense: Assumed constant (or linked to debt level in Phase 2)
Tax: Applied at baseline effective tax rate
Tax Rate = (Baseline EBITDA - Baseline Net Income - Interest) / Baseline EBITDA
Net Income = (EBITDA - D&A - Interest) × (1 - Tax Rate)
Working Capital Analysis
Cash Conversion Cycle Components
Days Sales Outstanding (DSO) - How long to collect receivables:
AR = (Revenue / 365) × DSO
Days Inventory Outstanding (DIO) - How long inventory sits:
Inventory = (COGS / 365) × DIO
Days Payable Outstanding (DPO) - How long to pay suppliers:
AP = (COGS / 365) × DPO
Working Capital Change
Working Capital = AR + Inventory - AP
WC Change = Current WC - Prior Year WC
Impact: Higher revenue growth → higher AR + inventory → cash outflow → negative impact on FCF
Cash Flow Statement
Operating Cash Flow (OCF)
OCF = Net Income + D&A - Change in Working Capital
This is the cash generated by core operations.
Free Cash Flow (FCF)
FCF = OCF - CapEx
This is the cash available for debt repayment and reinvestment.
Multi-Year FCF
The service calculates FCF for each projected year, enabling NPV calculations:
NPV = Σ (FCF_t / (1 + discount_rate)^t)
Default discount rate: 10% (adjustable via API)
Financial Ratios
Profitability Ratios
Gross Profit Margin % = (Gross Profit / Revenue) × 100
Operating Margin % = (EBITDA / Revenue) × 100
Net Profit Margin % = (Net Income / Revenue) × 100
ROA (Return on Assets) % = (Net Income / Total Assets) × 100
ROE (Return on Equity) % = (Net Income / Equity) × 100
Solvency Ratios
Debt-to-Equity = Total Debt / Equity
Debt-to-EBITDA = Total Debt / EBITDA
Interest Coverage = EBITDA / Interest Expense
Liquidity Ratios
Current Ratio = Current Assets / Current Liabilities
Quick Ratio = (Current Assets - Inventory) / Current Liabilities
Efficiency Ratios
Asset Turnover = Revenue / Total Assets
Inventory Turnover = COGS / Avg Inventory
Receivables Turnover = Revenue / Avg AR
Scenario Parameters
When creating or updating a scenario, pass these optional parameters:
{
"predicted_impact": {
// Revenue & Growth
"revenue_growth_rate": 0.05, // 5% annual growth (default)
// COGS & Margin
"cogs_pct_revenue": 0.60, // 60% COGS (default: use baseline)
// Operating Expenses
"opex_growth_rate": 0.03, // 3% annual OpEx growth (default)
"opex_fixed_adjustment": 50000, // Add fixed cost (default: 0)
// R&D Investment
"rd_spend_pct_revenue": 0.04, // 4% R&D spend (default: use baseline)
// Capital Expenditure
"capex_pct_revenue": 0.08, // 8% CapEx (default: 5%)
// Working Capital (optional)
"dso_days": 45, // Days to collect (default: baseline)
"inventory_days": 60, // Days inventory sits (default: baseline)
"dpo_days": 30 // Days to pay suppliers (default: baseline)
}
}
API Endpoints
1. Calculate Financial Impact
POST /api/scenarios/:scenarioId/calculate-financial-impact
Request:
{
"baselineYear": 2024,
"projectionYears": 5,
"periodType": "annual",
"discountRate": 0.1
}
Response:
{
"success": true,
"scenario_id": "scenario-123",
"baseline_year": 2024,
"projection_years": 5,
"results_stored": 5,
"summary": {
"first_year_revenue": 1050000,
"last_year_revenue": 1276282,
"revenue_cagr_pct": 5.0,
"cumulative_fcf": 750000,
"avg_fcf_margin_pct": 8.5
}
}
Use Case: Trigger financial impact calculation when scenario is created or parameters change
2. Get Financial Projection
GET /api/scenarios/:scenarioId/financial-projection
Response:
{
"success": true,
"scenario_id": "scenario-123",
"scenario_name": "Revenue Growth 10%",
"results_count": 5,
"projections": [
{
"period_year": 2025,
"revenue": 1100000,
"gross_profit": 440000,
"ebitda": 220000,
"net_income": 165000,
"free_cash_flow": 115000,
"financial_ratios": {
"roe": 13.75,
"debt_to_equity": 0.33,
"current_ratio": 2.2
}
}
// ... additional years
]
}
Use Case: Display full P&L and financial details for scenario
3. P&L Summary
GET /api/scenarios/:scenarioId/pnl-summary
Response:
{
"success": true,
"scenario_id": "scenario-123",
"periods": [
{
"period": "annual:2025",
"revenue": 1100000,
"ebitda": 220000,
"ebitda_margin_pct": 20.0,
"net_income": 165000,
"net_margin_pct": 15.0
}
// ... additional years
]
}
Use Case: Quick summary of key P&L metrics by year
4. Cash Flow Projection
GET /api/scenarios/:scenarioId/cash-flow-projection
Response:
{
"success": true,
"scenario_id": "scenario-123",
"periods": [
{
"period_year": 2025,
"operating_cf": 180000,
"capex": 50000,
"free_cash_flow": 130000,
"working_capital_change": -20000
}
// ... additional years
],
"cumulative_fcf": 650000,
"avg_fcf": 130000
}
Use Case: Analyze cash generation and capital deployment
5. Financial Ratios
GET /api/scenarios/:scenarioId/financial-ratios
Response:
{
"success": true,
"scenario_id": "scenario-123",
"periods": [
{
"period_year": 2025,
"ratios": {
"gross_profit_margin": 40.0,
"operating_margin": 20.0,
"net_profit_margin": 15.0,
"roe": 13.75,
"roa": 8.25,
"debt_to_equity": 0.33,
"debt_to_ebitda": 1.82,
"interest_coverage": 7.33,
"current_ratio": 2.2,
"quick_ratio": 1.8,
"asset_turnover": 0.55
}
}
// ... additional years
]
}
Use Case: Financial health assessment and ratio analysis
6. NPV Analysis
GET /api/scenarios/:scenarioId/npv-analysis?discountRate=0.1
Response:
{
"success": true,
"scenario_id": "scenario-123",
"discount_rate_pct": 10,
"cash_flows": [
{
"year": 2025,
"cash_flow": 130000,
"discount_factor": 1.0,
"present_value": 130000
},
{
"year": 2026,
"cash_flow": 145000,
"discount_factor": 1.1,
"present_value": 131818
}
// ... additional years
],
"npv": 650000
}
Use Case: Time-value-of-money analysis for investment decisions
7. Compare Scenarios
POST /api/scenarios/:scenarioId1/compare/:scenarioId2
Request:
{
"year": 2025
}
Response:
{
"success": true,
"scenario1_name": "Conservative Growth",
"scenario2_name": "Aggressive Growth",
"comparison_year": 2025,
"scenario1": {
"id": "scenario-123",
"revenue": 1050000,
"net_income": 157500,
"free_cash_flow": 110000,
"ebitda_margin_pct": 19.0
},
"scenario2": {
"id": "scenario-124",
"revenue": 1150000,
"net_income": 172500,
"free_cash_flow": 115000,
"ebitda_margin_pct": 19.1
},
"delta": {
"revenue_delta": 100000,
"revenue_delta_pct": 9.5,
"net_income_delta": 15000,
"net_income_delta_pct": 9.5,
"fcf_delta": 5000,
"fcf_delta_pct": 4.5
}
}
Use Case: Executive decision-making comparing strategic alternatives
Integration with Scenarios
Creating a Scenario with Financial Parameters
// Via API
POST /api/internal/v1/scenarios
{
"decision_problem_id": "problem-123",
"name": "Revenue Growth 10%",
"description": "Assume 10% revenue growth with operating leverage",
"predicted_impact": {
"revenue_growth_rate": 0.10,
"capex_pct_revenue": 0.07
},
"confidence": 65
}
Triggering Financial Calculation
After scenario is created, either:
Option 1: Automatically (via webhook in Phase 2)
// In ScenariosService.createScenario()
await ScenarioFinancialService.calculateScenarioFinancialImpact(user, scenario.id, {
projectionYears: 5
});
Option 2: Manually (via API)
POST /api/scenarios/scenario-123/calculate-financial-impact
{
"projectionYears": 5,
"discountRate": 0.1
}
Retrieving Results
Frontend can then query any of the 6 financial endpoints to retrieve and display projections.
Database Schema
scenario_financial_results Table
CREATE TABLE scenario_financial_results (
id UUID PRIMARY KEY,
scenario_id UUID NOT NULL,
tenant_id UUID NOT NULL,
period_year INTEGER NOT NULL,
period_month INTEGER,
period_type ENUM('annual', 'quarterly', 'monthly'),
-- P&L Items
revenue DECIMAL(15,2),
cogs DECIMAL(15,2),
gross_profit DECIMAL(15,2),
opex DECIMAL(15,2),
rd_spend DECIMAL(15,2),
ebitda DECIMAL(15,2),
depreciation_amortization DECIMAL(15,2),
interest_expense DECIMAL(15,2),
tax_expense DECIMAL(15,2),
net_income DECIMAL(15,2),
-- Cash Flow
operating_cf DECIMAL(15,2),
capex DECIMAL(15,2),
free_cash_flow DECIMAL(15,2),
-- Working Capital
accounts_receivable DECIMAL(15,2),
inventory DECIMAL(15,2),
accounts_payable DECIMAL(15,2),
working_capital_change DECIMAL(15,2),
-- Financial Ratios
financial_ratios JSONB,
-- Metadata
scenario_parameters JSONB,
calculation_method TEXT,
confidence_score DECIMAL(3,2),
created_at TIMESTAMP,
updated_at TIMESTAMP,
UNIQUE(scenario_id, period_year, period_month, period_type),
INDEX(scenario_id),
INDEX(tenant_id)
);
Configuration
Default Projection Parameters
Edit backend/src/services/ScenarioFinancialService.js:
// Line 33-39
const {
baselineYear = null, // Use latest if not specified
projectionYears = 5, // 5-year projection
periodType = 'annual', // Annual periods
discountRate = 0.1, // 10% discount rate for NPV
} = options;
Scenario Parameter Defaults
// In _projectPeriodFinancials()
const {
revenue_growth_rate = 0.05, // 5% growth
cogs_pct_revenue = null, // Use baseline
opex_growth_rate = 0.03, // 3% OpEx growth
opex_fixed_adjustment = 0, // No fixed adjustment
rd_spend_pct_revenue = null, // Use baseline % of revenue
capex_pct_revenue = 0.05, // 5% CapEx
} = scenarioParams;
Testing
Running Tests
npm test -- ScenarioFinancialService.test.js
Test Coverage
- P&L Projection: 7 tests covering revenue, COGS, OpEx, EBITDA, net income
- Working Capital: 5 tests covering AR, inventory, AP, WC change
- Cash Flow: 4 tests covering OCF, FCF, positive/negative scenarios
- Financial Ratios: 6 tests covering profitability, solvency, liquidity, efficiency
- Confidence Scoring: 3 tests for parameter-based scoring
- Summary Generation: 4 tests for CAGR, NPV, cumulative analysis
Phase 2 Roadmap
Sensitivity Analysis
- Vary parameters (±10%, ±20%, ±30%) to show impact
- Tornado diagrams showing most impactful variables
Advanced Cash Flow
- Separate working capital components
- Adjust for seasonal patterns
- Include financing activities
NPV & IRR
- Calculate Internal Rate of Return (IRR)
- Payback period analysis
- Profitability Index
Scenario Optimization
- Monte Carlo simulation on parameter uncertainty
- Scenario blending (50/50 mix, 70/30 mix, etc.)
Dashboard Integration
- Real-time scenario comparison widget
- Financial KPI tracking by scenario
- Variance analysis vs. baseline
Error Handling
Missing Baseline Financials
{
"success": false,
"error": "No baseline financial data available for scenario"
}
Solution: Ensure financial data is uploaded via Financial Intelligence Service
Scenario Not Found
{
"success": false,
"error": "Scenario not found: scenario-123"
}
Solution: Verify scenario ID exists and belongs to tenant
Division by Zero
All ratio calculations handle zero-division gracefully:
if (projection.equity && projection.equity > 0) {
ratios.roe = (projection.net_income / projection.equity) * 100;
}
Performance Considerations
Query Optimization
- Indexes on
scenario_id,tenant_id,(scenario_id, period_year) - Unique constraint on
(scenario_id, period_year, period_month, period_type)
Calculation Efficiency
- Linear time complexity: O(n) where n = projection_years
- No recursive calls or iterative algorithms
- Single-pass calculation for all metrics
Data Volume
- Assume 5-year projections = 5 rows per scenario
- 10,000 scenarios = 50,000 rows
- Estimated storage: ~3-5 MB with JSONB ratios
Example Scenario: Product Launch
// Create scenario
POST /api/internal/v1/scenarios
{
"decision_problem_id": "new-product-launch",
"name": "Premium Product Launch - Year 1",
"description": "New product capturing 8% of market by year 1",
"predicted_impact": {
"revenue_growth_rate": 0.20, // 20% growth from new product
"cogs_pct_revenue": 0.48, // Premium margins (vs. 60% baseline)
"capex_pct_revenue": 0.10, // Extra CapEx for setup
"rd_spend_pct_revenue": 0.08 // Increased R&D for innovation
},
"confidence": 70
}
// Calculate impact
POST /api/scenarios/scenario-456/calculate-financial-impact
{
"projectionYears": 5
}
// View results
GET /api/scenarios/scenario-456/financial-projection
GET /api/scenarios/scenario-456/npv-analysis?discountRate=0.08
// Compare with baseline
POST /api/scenarios/baseline-scenario/compare/scenario-456
{
"year": 2026
}
Last Updated
Date: 2025-10-23 Phase: 1 MVP (Core P&L and Cash Flow Calculation) Status: Ready for deployment
See Also: