{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://polivor.com/schema/financial-mandate.v0.json",
  "title": "Polivor Financial Mandate v0",
  "description": "Native, machine-readable, versioned, revocable delegated financial authority. An enterprise delegation object, not a payment protocol. Money is integer minor units + ISO 4217; no floats.",
  "type": "object",
  "additionalProperties": false,
  "required": ["schema", "principal", "authorizer", "agent", "authority", "scope", "beneficiaries", "limits", "approval", "validity"],
  "properties": {
    "schema": { "const": "polivor.financial-mandate/v0" },
    "principal": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "legal_name"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "legal_name": { "type": "string", "minLength": 1, "maxLength": 200 }
      }
    },
    "authorizer": {
      "type": "object", "additionalProperties": false,
      "required": ["name", "role", "email"],
      "properties": {
        "name": { "type": "string", "minLength": 1, "maxLength": 200 },
        "role": { "type": "string", "minLength": 1, "maxLength": 100 },
        "email": { "type": "string", "format": "email", "maxLength": 254 }
      }
    },
    "agent": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "allowed_versions"],
      "properties": {
        "id": { "$ref": "#/$defs/uuid" },
        "allowed_versions": {
          "type": "array", "minItems": 1, "maxItems": 50, "uniqueItems": true,
          "items": { "type": "string", "minLength": 1, "maxLength": 64 }
        }
      }
    },
    "authority": { "type": "string", "minLength": 1, "maxLength": 500 },
    "scope": {
      "type": "object", "additionalProperties": false,
      "required": ["debtor_accounts", "currencies", "beneficiary_countries", "payment_types"],
      "properties": {
        "debtor_accounts": {
          "type": "array", "minItems": 1, "maxItems": 100, "uniqueItems": true,
          "items": { "$ref": "#/$defs/iban" }
        },
        "currencies": {
          "type": "array", "minItems": 1, "maxItems": 20, "uniqueItems": true,
          "items": { "$ref": "#/$defs/currency" }
        },
        "beneficiary_countries": {
          "type": "array", "minItems": 1, "maxItems": 100, "uniqueItems": true,
          "items": { "$ref": "#/$defs/country" }
        },
        "payment_types": {
          "type": "array", "minItems": 1, "uniqueItems": true,
          "items": { "enum": ["SEPA_CT", "SEPA_INST"] }
        }
      }
    },
    "beneficiaries": {
      "type": "object", "additionalProperties": false,
      "required": ["rule"],
      "properties": { "rule": { "const": "ALLOWLIST" } }
    },
    "limits": {
      "type": "object", "additionalProperties": false,
      "required": ["per_transaction_minor", "daily_minor", "monthly_minor"],
      "properties": {
        "per_transaction_minor": { "$ref": "#/$defs/positiveMinor" },
        "daily_minor": { "$ref": "#/$defs/positiveMinor" },
        "monthly_minor": { "$ref": "#/$defs/positiveMinor" }
      }
    },
    "approval": {
      "type": "object", "additionalProperties": false,
      "required": ["threshold_minor"],
      "properties": { "threshold_minor": { "$ref": "#/$defs/nonNegativeMinor" } }
    },
    "validity": {
      "type": "object", "additionalProperties": false,
      "required": ["from", "until"],
      "properties": {
        "from": { "type": "string", "format": "date-time" },
        "until": { "type": "string", "format": "date-time" }
      }
    },
    "policy_refs": {
      "type": "array", "maxItems": 50, "uniqueItems": true,
      "items": { "type": "string", "minLength": 1, "maxLength": 100 }
    }
  },
  "$defs": {
    "uuid": { "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" },
    "iban": { "type": "string", "pattern": "^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$" },
    "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
    "country": { "type": "string", "pattern": "^[A-Z]{2}$" },
    "positiveMinor": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
    "nonNegativeMinor": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
  }
}
