{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/joinways-app/json-schema/joinways-app-accounting-analytics-schema.json",
  "title": "AccountingAnalytics",
  "x-generated": "2026-11-13",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/joinways-app-openapi.yml#/components/schemas/AccountingAnalytics",
  "allOf": [
    {
      "$ref": "#/$defs/ReportHeader"
    },
    {
      "type": "object",
      "properties": {
        "monthly_accounting": {
          "type": "object",
          "description": "Legacy — `YYYY-MM` → events and revenue of that event month (months with events only).",
          "additionalProperties": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "revenue": {
                "type": "number"
              }
            }
          }
        },
        "kpis": {
          "type": "object",
          "properties": {
            "revenue": {
              "$ref": "#/$defs/ReportMetric"
            },
            "cancellation_fees": {
              "$ref": "#/$defs/ReportMetric"
            },
            "events": {
              "$ref": "#/$defs/ReportMetric"
            },
            "events_with_amount": {
              "$ref": "#/$defs/ReportMetric"
            },
            "average_per_event": {
              "$ref": "#/$defs/ReportMetric"
            },
            "revenue_per_guest": {
              "$ref": "#/$defs/ReportMetric"
            },
            "guests": {
              "$ref": "#/$defs/ReportMetric"
            }
          }
        },
        "monthly": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "month": {
                "type": "string"
              },
              "revenue": {
                "type": "number"
              },
              "previous_revenue": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "events": {
                "type": "integer"
              },
              "previous_events": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cancellation_fees": {
                "type": "number"
              }
            }
          }
        },
        "by_venue": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "location_id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "events": {
                "type": "integer"
              },
              "revenue": {
                "type": "number"
              },
              "share_pct": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "average_per_event": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "revenue_change_pct": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        },
        "by_type": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "event_type": {
                "type": "string"
              },
              "events": {
                "type": "integer"
              },
              "revenue": {
                "type": "number"
              },
              "share_pct": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "average_per_event": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        },
        "coverage": {
          "$ref": "#/$defs/ReportCoverage"
        },
        "year_outlook": {
          "type": "object",
          "description": "Current calendar year (workspace time zone), whatever the period.",
          "properties": {
            "year": {
              "type": "integer"
            },
            "from": {
              "type": "string",
              "format": "date"
            },
            "to": {
              "type": "string",
              "format": "date"
            },
            "realized": {
              "type": "number",
              "description": "Revenue of events up to today included."
            },
            "secured": {
              "type": "number",
              "description": "Realized + confirmed events to come this year."
            },
            "booked_ahead": {
              "type": "number",
              "description": "`secured` − `realized`."
            },
            "forecast": {
              "type": "object",
              "properties": {
                "expected": {
                  "type": "number",
                  "description": "`secured` + Σ option value × win probability."
                },
                "low": {
                  "type": "number",
                  "description": "Lower bound of the 80 % range."
                },
                "high": {
                  "type": "number",
                  "description": "Upper bound of the 80 % range."
                },
                "from_options": {
                  "type": "number",
                  "description": "Open options dated in the period × probability to sign before the event date (survival model on each option's history). An option without amount counts at its estimated amount (similar confirmed events)."
                },
                "from_unpriced_confirmed": {
                  "type": "number",
                  "description": "Confirmed events still without amount, at their estimated amount × share of past confirmed events that received one."
                },
                "from_upcoming_inquiries": {
                  "type": "number",
                  "description": "Revenue expected from inquiries not received yet (booking pace of past months)."
                },
                "options": {
                  "type": "integer"
                }
              }
            },
            "goal": {
              "type": "object",
              "description": "Annual realized-revenue goal of the venues shown, the sum of the 12 monthly goals (same rule as the monthly goal). Amount and progress are null while a month has no goal.",
              "properties": {
                "metric": {
                  "type": "string",
                  "enum": [
                    "realized_revenue"
                  ]
                },
                "amount": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "missing_months": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Months (YYYY-MM) without a goal for the venues shown."
                },
                "secured_pct": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "realized_pct": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "expected_pct": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "probability": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "remaining": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            },
            "monthly": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "month": {
                    "type": "string"
                  },
                  "booked": {
                    "type": "number"
                  },
                  "expected_from_options": {
                    "type": "number"
                  },
                  "expected_from_upcoming_inquiries": {
                    "type": "number",
                    "description": "Revenue expected from inquiries not received yet (booking pace of past months)."
                  },
                  "cumulative_secured": {
                    "type": "number"
                  },
                  "cumulative_expected": {
                    "type": "number"
                  }
                }
              }
            }
          }
        }
      }
    }
  ],
  "$defs": {
    "ReportCoverage": {
      "allOf": [
        {
          "$ref": "#/$defs/ReportRatio"
        },
        {
          "type": "object",
          "description": "Confirmed/signed events with a known amount (`numerator`) out of all of them (`denominator`), and where the amount came from.",
          "properties": {
            "from_event": {
              "type": [
                "integer",
                "null"
              ]
            },
            "from_quote": {
              "type": [
                "integer",
                "null"
              ]
            },
            "from_platform": {
              "type": [
                "integer",
                "null"
              ]
            }
          }
        }
      ]
    },
    "ReportHeader": {
      "type": "object",
      "properties": {
        "period": {
          "type": "object",
          "description": "Effective period after defaults and caps.",
          "properties": {
            "from": {
              "type": "string",
              "format": "date"
            },
            "to": {
              "type": "string",
              "format": "date"
            },
            "today": {
              "type": "string",
              "format": "date",
              "description": "Today in the workspace time zone."
            },
            "timezone": {
              "type": "string"
            }
          }
        },
        "comparison": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "year",
                "previous"
              ]
            },
            "from": {
              "type": "string",
              "format": "date"
            },
            "to": {
              "type": "string",
              "format": "date"
            }
          }
        },
        "venue_ids": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string",
            "format": "uuid"
          },
          "description": "Venue filter applied; `null` = all venues."
        },
        "currency": {
          "type": "string",
          "description": "Workspace currency of every amount (amounts are excl. tax, 2 decimals)."
        }
      }
    },
    "ReportMetric": {
      "type": "object",
      "description": "A value for the period and for the comparison period.",
      "properties": {
        "current": {
          "type": [
            "number",
            "null"
          ]
        },
        "previous": {
          "type": [
            "number",
            "null"
          ],
          "description": "Comparison period value; `null` with `compare=none` or when not computable."
        },
        "change_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Relative change in % (1 decimal); `null` when `previous` is null or 0."
        }
      }
    },
    "ReportRatio": {
      "type": "object",
      "description": "A rate with its numerator and denominator.",
      "properties": {
        "pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "0–100, 1 decimal; `null` when the denominator is 0."
        },
        "numerator": {
          "type": "integer"
        },
        "denominator": {
          "type": "integer"
        }
      }
    }
  }
}