Generates a client-facing executive KPI dashboard from QuickBooks Online data. Produces an Excel workbook with traffic-light scoring, 6-month trend sparklines, client-specific watch items, and a CDC log tracking KPI changes month-over-month.
scripts/pipelines/client-dashboard.py#bash
pip install openpyxl
# Node.js qbo-client must be authenticated for the target slug
bash
# Example — March 2026
python3 scripts/pipelines/client-dashboard.py --slug <client-slug> --month 2026-03
# Custom output directory
python3 scripts/pipelines/client-dashboard.py --slug <client-slug> --month 2026-03 --out ~/Desktop/reports
# QBO sandbox
python3 scripts/pipelines/client-dashboard.py --slug <client-slug> --month 2026-03 --sandbox
ArgumentRequiredDescription--slug✅Company slug (must match qbo-client connection)--month✅Report month: YYYY-MM format--out❌Output directory (default: ~/Desktop)--sandbox❌Use QBO sandbox environment
Filename: KPI_Dashboard_{slug}_{YYYY_MM}.xlsx
TabContentsExecutive SummaryHeadline numbers + traffic-light KPI table with benchmarksKPI ScorecardFull KPI detail with definitions, thresholds, and scoreTrends6-month KPI trend with sparklines (↑↗→↘↓ + block chars)Cash PositionBalance sheet cash, CF summary, liquidity ratios, runwayWatch ItemsSOP-driven priority items surfaced prominentlyCDC LogMonth-over-month KPI delta (what changed since last run)
KPIFormulaUnitRevenue MoM Growth(curr_rev - prior_rev) / prior_rev × 100%Revenue YoY Growth(curr_rev - yoy_rev) / yoy_rev × 100%Gross Margin %gross_profit / revenue × 100%Gross Margin (3-Mo Avg)Rolling 3-month GP/Revenue%Net Margin %net_income / revenue × 100%OpEx Ratiototal_opex / revenue × 100%Interest Expense Ratiointerest_expense / revenue × 100%Current Ratiocurrent_assets / current_liabilitiesxQuick Ratio(current_assets - inventory) / current_liabilitiesxDebt-to-Equitytotal_liabilities / total_equityxDSOar / (revenue / days)daysDPOap / (cogs / days)daysCash Runwaycash / monthly_burnmonthsRetail % of Revenueretail_revenue / total_revenue × 100%
All math uses Python Decimal for precision.
Each KPI is scored GREEN / YELLOW / RED based on configurable thresholds per client SOP.
text
🟢 GREEN = On target (within green band)
🟡 WATCH = Approaching threshold (yellow band)
🔴 ACTION = Below/above acceptable range (outside yellow band)
⬜ N/A = KPI not applicable or not configured
Thresholds are defined in CLIENT_CONFIGS in the script — one config block per client slug.
Add a block to CLIENT_CONFIGS in the script:
python
"new-slug": {
"company_name": "Company Name",
"industry": "Industry",
"has_ar": True,
"has_headcount": False,
"kpis_enabled": ["revenue_mom", "gross_margin", ...],
"thresholds": {
"gross_margin": {"green": (Decimal("45"), None), "yellow": (Decimal("35"), Decimal("45"))},
...
},
"watch_items": [...],
"benchmarks": {...},
"benchmark_source": "Source description",
}
Cache stored at: .cache/client-dashboard/{slug}.json
6-month trend for each KPI uses two formats:
↑↑ ↑ ↗ → ↘ ↓ ↓↓ (based on % change over period)█▇▅▃▁_ (relative to max value — in Trends tab mini-chart section)Manual config only. Benchmark values live in CLIENT_CONFIGS[slug]["benchmarks"].
Source attribution displayed in every tab footer.
To update: edit benchmarks dict and benchmark_source string per client.
This pipeline is designed to run after monthly close is complete:
text
1. Bank Reconciliation (bank-reconciliation.py)
2. P&L Quick Compare (pl-quick-compare.py)
3. P&L Deep Analysis (pl-deep-analysis.py) ← optional for controller level
4. Client Dashboard (client-dashboard.py) ← this script
5. Cash Flow Forecast (cash-flow-forecast.py) ← quarterly advisory
FilePathPipeline scriptscripts/pipelines/client-dashboard.pySkill fileskills/client-dashboard/SKILL.mdCDC cache.cache/client-dashboard/{slug}.jsonOutput (default)~/Desktop/KPI_Dashboard_{slug}_{YYYY_MM}.xlsx
QBO CLI error: Ensure your QBO integration is authenticated for the slug.
Missing KPIs: If Balance Sheet accounts don't match expected labels, values default to 0. Check extract_bs_metrics() candidates list for account name variants.
New client config: Add slug to CLIENT_CONFIGS before first run. Default config uses generic thresholds (not client-specific).
Decimal errors: All financial math uses Python Decimal. Do not mix float — use to_d() helper for any external values.