{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/arkrel-com/json-schema/arkrel-com-year-overview-schema.json",
  "title": "YearOverview",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/arkrel-com-openapi.yaml#/components/schemas/YearOverview",
  "type": "object",
  "required": [
    "year",
    "accounts",
    "months_covered",
    "months_expected",
    "income_total",
    "spending_total",
    "spending_by_category",
    "needs_review_documents",
    "failed_documents",
    "processing_documents",
    "uncategorized_transactions",
    "open_items",
    "next_step"
  ],
  "properties": {
    "year": {
      "type": "integer"
    },
    "accounts": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/AccountOverview"
      }
    },
    "months_covered": {
      "type": "integer"
    },
    "months_expected": {
      "type": "integer"
    },
    "income_total": {
      "type": "number"
    },
    "spending_total": {
      "type": "number"
    },
    "spending_by_category": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/CategoryTotal"
      }
    },
    "needs_review_documents": {
      "type": "integer"
    },
    "failed_documents": {
      "type": "integer"
    },
    "processing_documents": {
      "type": "integer"
    },
    "uncategorized_transactions": {
      "type": "integer"
    },
    "open_items": {
      "type": "integer"
    },
    "next_step": {
      "type": [
        "object",
        "null"
      ],
      "required": [
        "message",
        "action",
        "document_id",
        "account_number",
        "month"
      ],
      "properties": {
        "message": {
          "type": "string"
        },
        "action": {
          "type": "string",
          "enum": [
            "upload",
            "review_document",
            "categorize",
            "none"
          ]
        },
        "document_id": {
          "type": [
            "string",
            "null"
          ]
        },
        "account_number": {
          "type": [
            "string",
            "null"
          ],
          "description": "Only set for action \"upload\": the account the missing statement belongs to, so a client can carry it into the upload flow."
        },
        "month": {
          "type": [
            "string",
            "null"
          ],
          "description": "Only set for action \"upload\": the missing month, \"YYYY-MM\"."
        }
      }
    }
  },
  "$defs": {
    "AccountOverview": {
      "type": "object",
      "required": [
        "account_number",
        "label",
        "months",
        "months_covered",
        "months_expected",
        "document_ids",
        "findings"
      ],
      "properties": {
        "account_number": {
          "type": [
            "string",
            "null"
          ],
          "description": "As extracted from the statement (masked if the statement itself was masked). Never a stored client identity."
        },
        "label": {
          "type": "string",
          "description": "\"Checking ending 4471\", \"Credit card ending 9902\", or the generic \"Account ending 4471\" when the statement's account_type could not be determined. Matches BalanceSheetLine's own label for the same account, on the tax report."
        },
        "months": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/MonthCoverage"
          }
        },
        "months_covered": {
          "type": "integer"
        },
        "months_expected": {
          "type": "integer"
        },
        "document_ids": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "findings": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/StatementSetFinding"
          },
          "description": "Reuses the same continuity engine as POST /v1/statement-sets (GAP/BREAK/OVERLAP/...)."
        }
      }
    },
    "CategoryTotal": {
      "type": "object",
      "required": [
        "category",
        "label",
        "total"
      ],
      "properties": {
        "category": {
          "$ref": "#/$defs/TaxReportCategory"
        },
        "label": {
          "type": "string"
        },
        "total": {
          "type": "number"
        }
      }
    },
    "MonthCoverage": {
      "type": "object",
      "required": [
        "month",
        "label",
        "covered",
        "document_id"
      ],
      "properties": {
        "month": {
          "type": "string",
          "description": "YYYY-MM"
        },
        "label": {
          "type": "string"
        },
        "covered": {
          "type": "boolean"
        },
        "document_id": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "StatementSetFinding": {
      "type": "object",
      "required": [
        "type",
        "message",
        "document_ids"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "GAP",
            "BREAK",
            "OVERLAP",
            "POSSIBLE_DUPLICATE",
            "DUPLICATE_UPLOAD",
            "DUPLICATE_UPLOAD_CONFLICT",
            "UNIDENTIFIED_MEMBER",
            "ACCOUNT_UNPROVEN",
            "MIXED_ACCOUNTS",
            "CURRENCY_MISMATCH",
            "FAILED_CHECKS",
            "MISSING_PERIOD",
            "DATE_UNRESOLVED",
            "AMOUNT_UNRESOLVED",
            "RESULT_UNAVAILABLE"
          ]
        },
        "message": {
          "type": "string",
          "description": "Plain-language, ready to show a bookkeeper directly."
        },
        "document_ids": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "TaxReportCategory": {
      "type": "string",
      "enum": [
        "business_income",
        "transfer_excluded",
        "balance_sheet_excluded",
        "advertising",
        "car_and_truck",
        "commissions_and_fees",
        "contract_labor",
        "depletion",
        "depreciation",
        "employee_benefit_programs",
        "mortgage_interest",
        "pension_and_profit_sharing",
        "rent_or_lease_vehicles_equipment",
        "insurance",
        "interest",
        "legal_and_professional",
        "office_expense",
        "rent_or_lease",
        "repairs_and_maintenance",
        "supplies",
        "taxes_and_licenses",
        "travel",
        "meals",
        "utilities",
        "wages",
        "other_expenses",
        "personal_not_deductible",
        "uncategorized",
        "equipment_needs_review"
      ]
    }
  }
}