finance-analytics · git:20260723.58d8101 · 2026-07-23 · sha256 45ce07f060fafd41
finance-analytics git:20260723.58d8101A
Immutable. This exact content is served forever at /api/v1/blob/45ce07f060fafd41.
--- name: finance-analytics description: Use this skill when the user wants to analyze financial performance, review P&L health, monitor MRR/ARR, investigate margin or cost trends, build a finance report, check cash flow or runway, or answer questions about their accounting/billing data. Triggers include 'how is revenue trending', 'gross margin', 'MRR breakdown', 'churn impact on ARR', 'why did costs go up', 'operating expenses', 'cash runway', 'P&L review', 'EBITDA', 'cost per acquisition trend', 'pull my QuickBooks numbers', 'finance report'. --- # Finance Analytics Analyze financial performance using data from Coupler.io dataflows (QuickBooks, Xero, Stripe, NetSuite, Sage, billing systems). This skill guides you through retrieving accounting and revenue data, computing P&L, margin, subscription, and cash metrics, detecting anomalies, and presenting actionable insights a finance lead can act on. ## Step 0: Context Check (Pre-requisite) Before starting any analysis, the **Data Context Check** skill (`generate-data-set-context`) runs as a gate. It calls `get-schema` on each target dataset to determine whether meaningful context (chart of accounts mapping, entity/subsidiary structure, currency conventions, fiscal calendar, accrual vs. cash convention) is attached. - If context exists → proceed to Step 1. - If context is missing → the user is offered the option to generate it first. Do not duplicate this check in Step 1d. ## Step 1: Discover and Select Data Sources ### 1a. Discover available data Default to `search-datasets` with finance-flavored keywords — `quickbooks`, `xero`, `netsuite`, `stripe`, `sage`, `gl`, `invoice`, `revenue`, `mrr`, `arr`, `bank`, or whatever system the user named. Search keeps the response small and lands on the right dataflow when the domain is known. Fall back to `list-datasets` only when the user is genuinely browsing or hasn't given any source/keyword to anchor on. Each dataflow represents a data pipeline (e.g. "QuickBooks GL", "Stripe Charges", "NetSuite Revenue", "Xero Invoices", "Bank Transactions"). ### 1b. Select relevant datasets **Unambiguous match (1 dataflow)** → use it; mention which one. **Obvious candidates (2–3)** → state your selection with one-line reasoning, proceed but invite corrections. **Ambiguous (5+, or unclear)** → present best candidates (up to 5–7) grouped by source/scope, with reasoning, and wait for confirmation: ``` I found 3 dataflows likely relevant to your MRR question: 1. stripe_subscriptions — has plan, MRR amount, status 2. quickbooks_gl — has revenue accounts, but at journal grain 3. salesforce_opportunities — has booked ARR, less useful for recognized Should I use Stripe alone, or combine Stripe and QuickBooks for cross-check? ``` **Hard gate only when ambiguous.** If you're confident and stated reasoning, proceed. ### 1c. Get dataflow details Call `get-dataflow` for each candidate. Note `schedule` (data freshness), source health, and the close status of any GL data — finance refreshes are often slower than transactional sources. ### 1d. Understand the data structure Call `get-schema` on each target dataset. If context was generated in Step 0, use the enriched schema directly. For finance schemas, watch for these critical column families: account/account_code (chart of accounts), entity_id/subsidiary, currency, transaction_date/posting_date, amount (signed: positive = credit, varies by source), invoice_status (paid/open/voided), customer_id, plan_id, billing_period_start/end, refund flags. ### 1e. Sample the data Sample each dataset to verify contents. Watch specifically for: signed-amount conventions (debit-positive vs. credit-positive), currency mixing, journal entry duplicates, voided/reversed entries that need exclusion. Flag anything off before proceeding. ## Step 2: Compute Metrics via SQL Always compute via SQL in `get-data`. Floating-point aggregations over thousands of rows in-context are unreliable. ### Working with multiple datasets **Date alignment:** Posting date vs. transaction date vs. service date can differ — confirm which the user wants. Use fiscal calendar if the company doesn't operate on calendar months. **Currency normalization:** Multi-entity companies need consolidation; always state your conversion approach (period-end FX vs. average FX vs. native). **Cash vs. accrual:** Critical distinction. Confirm which convention the user wants. Stripe data is mostly cash; QuickBooks/NetSuite GL can be either depending on configuration. **Recognized vs. booked:** Booked = contract signed (Salesforce). Billed = invoice issued. Recognized = ASC 606 revenue recognition (subscription pro-ration). Don't conflate; ask if unclear. **Voided/reversed entries:** GL data often includes voided journals — exclude them in the WHERE clause. Don't double-count refunds as new revenue. ## Step 3: Draft Findings and Get User Feedback Before generating a full analysis, present a brief summary — the 3–5 most important numbers, anomalies, and direction. Wait for user response before continuing. ## Step 4: Build the Analysis ### P&L Review Standard structure: Revenue → COGS → Gross Profit → Operating Expenses → Operating Income → Other → Net Income. - **Gross margin %** = (Revenue − COGS) / Revenue. Track period-over-period; a 2-point compression is meaningful. - **Operating margin %** = Operating Income / Revenue. - **Expense breakdown by category** (Sales & Marketing, R&D, G&A) — flag categories growing faster than revenue. - Period-over-period and year-over-year comparisons. State the comparison basis explicitly. Flag concentration: if one customer/product is >20% of revenue, call it out as a concentration risk. ### MRR / ARR & Subscription Health For SaaS or subscription businesses: - **MRR** = sum of monthly recurring revenue across active subscriptions. ARR = MRR × 12. - **MRR movement bridge**: Starting MRR + New + Expansion + Reactivation − Contraction − Churn = Ending MRR. Always reconcile the bridge — gaps reveal data issues or missing categories. - **Net Revenue Retention (NRR)** = (Starting MRR of cohort + Expansion − Contraction − Churn) / Starting MRR. Healthy SaaS: >100%. - **Gross Revenue Retention (GRR)** = (Starting MRR − Contraction − Churn) / Starting MRR. Excludes expansion. - **Logo churn vs. revenue churn** — present both; high logo churn with stable revenue churn signals SMB churn masked by enterprise stability. ### Cash & Runway - **Cash burn (monthly)** = avg monthly net cash outflow over trailing 3 months. - **Runway** = current cash balance / monthly burn. State both calendar months and 'months at current burn'. - **Operating cash flow vs. net income** — divergences signal AR/AP timing issues. If bank/cash data isn't in scope, say so. Don't extrapolate runway from P&L data without cash data. ### Cost-Center Investigation When the user asks 'why did costs go up' or 'where is spend growing fastest': 1. Break down the cost category by sub-account or vendor. 2. Compare to prior period at the sub-account level. 3. Identify the top 3 sub-accounts driving the change. 4. Check for one-time items (annual renewals, project spikes) vs. structural increases. 5. Present: "Of the $X increase, $Y is from <vendor/account> renewing on annual cycle, $Z is structural increase in <category>, balance is distributed." ### Anomaly Detection and Metric Investigations Any time the analysis involves investigating a change, drop, or spike — apply this framework: **Severity classification:** - **Informational** — within 1 SD of trailing 4-month average, or <5% change. Note it. - **Warning** — 1–2 SD, or 5–15% change. Investigate, present hypotheses. - **Critical** — >2 SD, >15% change, or any metric crossing a covenant/threshold. Lead with this finding. Finance has tighter sensitivity than marketing/ecom — a 10% gross margin drop is a 'critical' event, not 'warning'. **Baseline comparison:** Same period prior year (annual seasonality matters in finance), trailing 3-month average, budget if available. **Root cause investigation steps:** 1. **Isolate the scope** — which entity, which account, which customer/vendor. 2. **Check posting period** — late-arriving journals, period-end accruals, reversal entries. 3. **Check upstream changes** — pricing changes, contract renewals, vendor changes, new accounting policy. 4. **Check for data issues** — duplicate journals, currency conversion errors, voided entries not excluded. 5. **Present hypotheses ranked by likelihood** — "Most likely: annual security audit fee posted to G&A in this month vs. amortized last year. Less likely: structural growth in headcount cost." ## Step 5: Present Results Lead with the headline, use plain language, ensure every finding has a 'So what?' and 'Now what?', structure for scannability. **Abbreviation expansion:** First use of MRR, ARR, NRR, GRR, EBITDA, COGS, GAAP, ASC 606, AR, AP, FX — expand it. **Currency:** Always state on first use. If multi-currency, state your normalization approach (period-end vs. average FX, source of rates). **Materiality:** Note material vs. immaterial movements. A $5 swing in a $50M revenue line is noise. ## Rules & Edge Cases - Always state data freshness and the close status (preliminary, soft-closed, hard-closed) before presenting numbers. Pre-close numbers can shift materially. - State revenue convention (cash, accrual, recognized) on first use; never silently switch. - Voided/reversed journals must be excluded from totals. If you can't tell which entries are voided, say so. - Multi-entity / multi-currency: never sum across entities without consolidation. State your consolidation approach. - Prior-period adjustments and reclassifications: if a prior month was restated, mention it — comparing current period to a restated prior gives different results than to the original. - Round to materiality: don't report margins to 4 decimals when 1 decimal is enough. Don't report dollar amounts to the cent on totals over $10K. - Tax: distinguish pre-tax and post-tax metrics explicitly when both exist. - If a dataflow's last execution failed or is stale (>2 days for a daily GL refresh), warn the user — and consider that GL data is often refreshed less frequently than transactional sources, so 'stale' definitions differ.