{
 "notes": "Rosa wants breadth first across all five metrics before depth on any one, and Tobias's top two asks (revenue tie-out, payout reconciliation) sit inside that same breadth pass. So tonight I'm building the global, month-grain scaffolding that lets us see, in one glance, whether revenue/orders/refunds/payouts agree with each other at the top level, before drilling into any single tenant, currency, or the B2B receivables question (saving those for night 2+ once I know where the gaps are). All three reports are global (all tenants, EUR-converted) monthly time series over the full history (2023-01 through 2025-12) so we can also see whether any gap is new/worsening or has been there all along. I convert every local-currency amount to EUR via exchange_rates (EUR is base_code, so EUR amount = local amount divided by rate) using the date of the relevant event, consistently across all three reports so discrepancies aren't an artifact of inconsistent conversion. Report 1 answers whether different parts of the business agree on revenue. Report 2 traces orders forward into captured payments. Report 3 checks payouts against gross, fees and refunds. I'm holding back tenant-level and currency-timing drill-downs, and the B2B receivables question, for later nights.",
 "requests": [
  {
   "title": "Monthly revenue by source",
   "question": "If we ask what revenue was in a given month from four different places (orders booked, payments captured, payouts settled, invoices paid), do we get the same answer, and how far apart are they?",
   "grain": "calendar month, 2023-01 through 2025-12",
   "columns": [
    "month",
    "orders_booked_revenue_eur",
    "payments_captured_eur",
    "payout_gross_eur",
    "invoice_paid_revenue_eur",
    "refunds_eur",
    "order_count",
    "payment_count"
   ],
   "details": "Scope: all tenants combined, global totals. Time window: every calendar month from 2023-01 to 2025-12 (use calendar_days to ensure months with zero activity still appear). orders_booked_revenue_eur = sum of orders.grand_total for non-cancelled orders, grouped by month of placed_at, converted to EUR. payments_captured_eur = sum of payments.amount where status='captured', grouped by month of captured_at, converted to EUR. payout_gross_eur = sum of payouts.gross_amount, grouped by month of paid_at, converted to EUR. invoice_paid_revenue_eur = sum of invoices.total where status='paid', grouped by month of paid_at, converted to EUR. refunds_eur = sum of payment_refunds.amount where status='succeeded', grouped by month of processed_at, converted to EUR. order_count = count of non-cancelled orders placed that month. payment_count = count of captured payments that month. Currency conversion: for each row's native currency_code, convert to EUR using exchange_rates where base_code='EUR', quote_code=<currency>, as_of = the event's date (cast timestamp to date); EUR amount = local amount / rate. Tables: orders, payments, payouts, invoices, payment_refunds, exchange_rates. Order by month ascending.",
   "builds_on": []
  },
  {
   "title": "Orders traced into captured payments",
   "question": "Is there a clean, traceable link from an order to the money actually collected for it, or do orders vanish (no captured payment) or multiply (captured payments exceeding order value) along the way?",
   "grain": "calendar month, 2023-01 through 2025-12, based on order placed_at month",
   "columns": [
    "month",
    "orders_count",
    "orders_grand_total_eur",
    "orders_with_captured_payment_count",
    "captured_payment_total_eur",
    "orders_without_captured_payment_count",
    "gap_eur",
    "gap_pct"
   ],
   "details": "Scope: all tenants combined. Base population: orders with status not 'cancelled', grouped by the month of placed_at. orders_count = count of such orders. orders_grand_total_eur = sum of their grand_total, converted to EUR. Join to payments on payments.order_id = orders.id and payments.status='captured' to find linked captured payments (an order can have 0, 1, or multiple captured payments). orders_with_captured_payment_count = count of distinct orders with at least one linked captured payment. captured_payment_total_eur = sum of all captured payments.amount linked to orders in that month's cohort, converted to EUR. orders_without_captured_payment_count = orders_count minus orders_with_captured_payment_count. gap_eur = orders_grand_total_eur minus captured_payment_total_eur. gap_pct = gap_eur divided by orders_grand_total_eur times 100, rounded to 1 decimal. Convert orders.grand_total using orders.currency_code and payments.amount using payments.currency_code, both via exchange_rates (EUR amount = local / rate) using the relevant event date. Tables: orders, payments, exchange_rates. Order by month ascending.",
   "builds_on": []
  },
  {
   "title": "Payout reconciliation to gross, fees and refunds",
   "question": "Do payouts consistently reconcile as net = gross minus fee, and do refunds actually reduce what we pay out, or could refunds be double-counted or missing from the payout math?",
   "grain": "calendar month, 2023-01 through 2025-12, based on payout paid_at month",
   "columns": [
    "month",
    "payout_gross_eur",
    "payout_fee_eur",
    "payout_net_eur",
    "net_check_diff_eur",
    "refunds_processed_eur",
    "net_minus_refunds_diff_eur"
   ],
   "details": "Scope: all tenants combined. Group by month of payouts.paid_at (fall back to arrival_date if paid_at is null). payout_gross_eur = sum of payouts.gross_amount, converted to EUR. payout_fee_eur = sum of payouts.fee_amount, converted to EUR. payout_net_eur = sum of payouts.net_amount, converted to EUR. net_check_diff_eur = payout_net_eur minus (payout_gross_eur minus payout_fee_eur); should be ~0 if gross/fee/net are internally consistent. refunds_processed_eur = sum of payment_refunds.amount where status='succeeded', grouped by month of processed_at, converted to EUR. net_minus_refunds_diff_eur = payout_net_eur minus (payout_gross_eur minus payout_fee_eur minus refunds_processed_eur); tests whether refunds are already reflected in the payout gross/net figures. Convert all amounts via their own currency_code using exchange_rates (EUR amount = local / rate) as of the relevant date. Tables: payouts, payment_refunds, exchange_rates. Order by month ascending.",
   "builds_on": [
    "Monthly revenue by source"
   ]
  }
 ]
}