{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://w4politics.org/spending/data/state-spending-v1.schema.json",
  "title": "W4POLITICS state spending release",
  "description": "Normalized public projection for source-linked state campaign finance records.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "release_id",
    "state_code",
    "cycle",
    "checked_at",
    "published_at",
    "sources",
    "entities",
    "filing_accounts",
    "identity_matches",
    "reports",
    "transactions",
    "limitations"
  ],
  "properties": {
    "schema_version": {"const": "1.0"},
    "directory_kind": {"enum": ["source_registry"]},
    "release_id": {"type": "string", "minLength": 1},
    "state_code": {"type": "string", "pattern": "^[A-Z]{2}$"},
    "cycle": {"type": "integer", "minimum": 2000},
    "checked_at": {"type": "string", "format": "date-time"},
    "published_at": {"type": "string", "format": "date-time"},
    "coverage_start": {"type": ["string", "null"], "format": "date"},
    "coverage_end": {"type": ["string", "null"], "format": "date"},
    "supersedes_release_id": {"type": ["string", "null"]},
    "sources": {
      "type": "array",
      "items": {"$ref": "#/$defs/source"}
    },
    "entities": {
      "type": "array",
      "items": {"$ref": "#/$defs/entity"}
    },
    "filing_accounts": {
      "type": "array",
      "items": {"$ref": "#/$defs/filing_account"}
    },
    "identity_matches": {
      "type": "array",
      "items": {"$ref": "#/$defs/identity_match"}
    },
    "reports": {
      "type": "array",
      "items": {"$ref": "#/$defs/report"}
    },
    "transactions": {
      "type": "array",
      "items": {"$ref": "#/$defs/transaction"}
    },
    "limitations": {
      "type": "array",
      "items": {"type": "string", "minLength": 1}
    }
  },
  "$defs": {
    "source": {
      "type": "object",
      "additionalProperties": false,
      "required": ["source_id", "agency", "system_name", "source_type", "canonical_url", "retrieved_at", "link_status"],
      "properties": {
        "source_id": {"type": "string", "minLength": 1},
        "agency": {"type": "string", "minLength": 1},
        "system_name": {"type": "string", "minLength": 1},
        "source_type": {"enum": ["api", "bulk_export", "query_export", "pdf", "manual_transcription"]},
        "canonical_url": {"type": "string", "format": "uri"},
        "retrieved_at": {"type": "string", "format": "date-time"},
        "source_updated_at": {"type": ["string", "null"], "format": "date-time"},
        "content_sha256": {"type": ["string", "null"], "pattern": "^[a-f0-9]{64}$"},
        "extractor_name": {"type": ["string", "null"]},
        "extractor_version": {"type": ["string", "null"]},
        "link_status": {"enum": ["verified_original", "official_search", "unavailable"]},
        "known_limits": {"type": "array", "items": {"type": "string"}}
      }
    },
    "entity": {
      "type": "object",
      "additionalProperties": false,
      "required": ["entity_id", "entity_type", "display_name", "names_as_filed", "public_source_identifiers"],
      "properties": {
        "entity_id": {"type": "string", "minLength": 1},
        "entity_type": {"enum": ["candidate", "candidate_committee", "pac", "party_committee", "ballot_group", "vendor", "organization", "person_as_filed"]},
        "display_name": {"type": "string", "minLength": 1},
        "names_as_filed": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "public_source_identifiers": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "jurisdiction_id": {"type": ["string", "null"]},
        "roles": {"type": "array", "items": {"type": "string", "minLength": 1}}
      }
    },
    "filing_account": {
      "type": "object",
      "additionalProperties": false,
      "required": ["account_id", "entity_id", "source_system", "source_account_id", "account_type_raw", "account_type_normalized", "source_ids"],
      "properties": {
        "account_id": {"type": "string", "minLength": 1},
        "entity_id": {"type": "string", "minLength": 1},
        "source_system": {"type": "string", "minLength": 1},
        "source_account_id": {"type": "string", "minLength": 1},
        "account_type_raw": {"type": "string", "minLength": 1},
        "account_type_normalized": {"enum": ["candidate_committee", "pac", "party_committee", "ballot_group", "independent_spender", "other"]},
        "registration_status": {"type": ["string", "null"]},
        "status_as_of": {"type": ["string", "null"], "format": "date"},
        "source_ids": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "source_profile": {
          "type": ["object", "null"],
          "additionalProperties": false,
          "properties": {
            "filer_type": {"type": ["string", "null"]},
            "committee_category": {"type": ["string", "null"]},
            "political_committee_type": {"type": ["string", "null"]},
            "reporting_option": {"type": ["string", "null"]},
            "has_reports": {"type": ["boolean", "null"]},
            "ballot_committee": {"type": ["boolean", "null"]},
            "ballot_proposal_count": {"type": ["integer", "null"], "minimum": 0},
            "office": {"type": ["string", "null"]},
            "jurisdiction": {"type": ["string", "null"]},
            "jurisdiction_type": {"type": ["string", "null"]},
            "legislative_district": {"type": ["string", "null"]},
            "party": {"type": ["string", "null"]},
            "organization_date_local": {"type": ["string", "null"]},
            "termination_date_local": {"type": ["string", "null"]},
            "source_updated_at_local": {
              "type": ["string", "null"],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:\\.[0-9]+)?$"
            }
          }
        }
      }
    },
    "identity_match": {
      "type": "object",
      "additionalProperties": false,
      "required": ["match_id", "left_ref", "right_ref", "relationship_type", "status", "evidence", "reviewed_at", "public_note"],
      "properties": {
        "match_id": {"type": "string", "minLength": 1},
        "left_ref": {"type": "string", "minLength": 1},
        "right_ref": {"type": "string", "minLength": 1},
        "relationship_type": {"enum": ["ballot_entry_to_filer", "candidate_to_authorized_committee", "transaction_counterparty_to_entity"]},
        "status": {"enum": ["verified", "probable", "name_only", "rejected", "unresolved"]},
        "evidence": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "reviewed_at": {"type": "string", "format": "date-time"},
        "valid_from": {"type": ["string", "null"], "format": "date"},
        "valid_to": {"type": ["string", "null"], "format": "date"},
        "public_note": {"type": "string", "minLength": 1}
      }
    },
    "observation": {
      "type": "object",
      "additionalProperties": false,
      "required": ["value_status", "source_field", "source_ref", "checked_at"],
      "properties": {
        "value_status": {"enum": ["reported", "reported_zero", "not_reported", "not_available", "not_applicable", "not_yet_due", "unverified", "withheld_by_source"]},
        "amount": {
          "type": ["object", "null"],
          "additionalProperties": false,
          "required": ["currency", "decimal"],
          "properties": {
            "currency": {"const": "USD"},
            "decimal": {"type": "string", "pattern": "^-?[0-9]+(?:\\.[0-9]{1,2})?$"}
          }
        },
        "source_field": {"type": "string", "minLength": 1},
        "source_ref": {"type": "string", "minLength": 1},
        "checked_at": {"type": "string", "format": "date-time"}
      },
      "allOf": [
        {
          "if": {"properties": {"value_status": {"enum": ["reported", "reported_zero"]}}},
          "then": {"required": ["amount"]}
        },
        {
          "if": {"properties": {"value_status": {"not": {"enum": ["reported", "reported_zero"]}}}},
          "then": {"properties": {"amount": {"type": "null"}}}
        }
      ]
    },
    "report": {
      "type": "object",
      "additionalProperties": false,
      "required": ["report_id", "source_report_id", "account_id", "report_type_raw", "period_start", "period_end", "filed_at", "version_status", "source_url", "source_link_status", "metrics"],
      "properties": {
        "report_id": {"type": "string", "minLength": 1},
        "source_report_id": {"type": "string", "minLength": 1},
        "account_id": {"type": "string", "minLength": 1},
        "report_type_raw": {"type": "string", "minLength": 1},
        "report_type_normalized": {"type": ["string", "null"]},
        "period_start": {"type": ["string", "null"], "format": "date"},
        "period_end": {"type": ["string", "null"], "format": "date"},
        "period_label": {"type": ["string", "null"]},
        "filed_at": {"type": ["string", "null"], "format": "date-time"},
        "version_sequence": {"type": ["integer", "null"], "minimum": 1},
        "version_status": {"enum": ["current", "amended", "superseded", "unresolved"]},
        "source_url": {"type": "string", "format": "uri"},
        "source_link_status": {"enum": ["verified_original", "official_search", "unavailable"]},
        "metrics": {"type": "object", "additionalProperties": {"$ref": "#/$defs/observation"}}
      }
    },
    "transaction": {
      "type": "object",
      "additionalProperties": false,
      "required": ["record_id", "report_id", "account_id", "ledger", "transaction_date", "amount", "counterparty_name_as_filed", "record_status", "source_id"],
      "properties": {
        "record_id": {"type": "string", "minLength": 1},
        "source_transaction_id": {"type": ["string", "null"]},
        "report_id": {"type": "string", "minLength": 1},
        "account_id": {"type": "string", "minLength": 1},
        "ledger": {"enum": ["candidate_receipt", "committee_receipt", "committee_expense", "loan", "commitment", "independent_expenditure", "in_kind", "transfer", "other"]},
        "transaction_date": {"type": ["string", "null"], "format": "date"},
        "amount": {"$ref": "#/$defs/observation"},
        "category_raw": {"type": ["string", "null"]},
        "category_normalized": {"type": ["string", "null"]},
        "counterparty_name_as_filed": {"type": "string", "minLength": 1},
        "counterparty_entity_id": {"type": ["string", "null"]},
        "support_or_oppose": {"enum": ["support", "oppose", "not_reported", null]},
        "beneficiary_ref": {"type": ["string", "null"]},
        "record_status": {"enum": ["current", "amended", "superseded", "unresolved"]},
        "source_locator": {"type": ["string", "null"]},
        "source_id": {"type": "string", "minLength": 1}
      }
    }
  }
}
