{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://finance-app.henthu.app/ai/henthu-plan-v1.schema.json",
  "title": "LëtzPay setup plan",
  "description": "An additive, user-reviewed plan for creating a budget model and one draft monthly budget.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "format",
    "version",
    "currency",
    "budgetMonth",
    "modelName",
    "income",
    "accounts",
    "recurringItems"
  ],
  "properties": {
    "format": {
      "const": "henthu-plan"
    },
    "version": {
      "const": 1
    },
    "locale": {
      "enum": [
        "en",
        "fr",
        "de"
      ]
    },
    "currency": {
      "const": "EUR"
    },
    "budgetMonth": {
      "type": "string",
      "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$"
    },
    "modelName": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "income": {
      "$ref": "#/$defs/money"
    },
    "accounts": {
      "type": "array",
      "minItems": 1,
      "maxItems": 20,
      "items": {
        "$ref": "#/$defs/account"
      }
    },
    "pockets": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "$ref": "#/$defs/pocket"
      },
      "default": []
    },
    "recurringItems": {
      "type": "array",
      "maxItems": 250,
      "items": {
        "$ref": "#/$defs/item"
      }
    },
    "oneOffItems": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "$ref": "#/$defs/oneOff"
      },
      "default": []
    },
    "incomeSources": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "description": "Optional breakdown of the income total. Amounts must sum exactly to income. Sources recur monthly; use a monthly budget for one-off income.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "key",
          "name",
          "amount",
          "account"
        ],
        "properties": {
          "key": {
            "$ref": "#/$defs/key"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "amount": {
            "$ref": "#/$defs/money"
          },
          "account": {
            "$ref": "#/$defs/key"
          }
        }
      }
    }
  },
  "$defs": {
    "key": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9_-]{0,39}$"
    },
    "money": {
      "type": "string",
      "pattern": "^(0|[1-9][0-9]{0,8})(\\.[0-9]{1,2})?$"
    },
    "account": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "key",
        "name",
        "country",
        "salary"
      ],
      "properties": {
        "key": {
          "$ref": "#/$defs/key"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "country": {
          "enum": [
            "DE",
            "FR",
            "BE",
            "LU"
          ]
        },
        "salary": {
          "type": "boolean"
        }
      }
    },
    "goal": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "target",
        "dueDate"
      ],
      "properties": {
        "target": {
          "$ref": "#/$defs/money"
        },
        "dueDate": {
          "type": "string",
          "format": "date"
        },
        "repeatMonths": {
          "enum": [
            0,
            3,
            6,
            12
          ],
          "default": 0
        }
      }
    },
    "pocket": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "key",
        "name",
        "account"
      ],
      "properties": {
        "key": {
          "$ref": "#/$defs/key"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "account": {
          "$ref": "#/$defs/key"
        },
        "goal": {
          "$ref": "#/$defs/goal"
        }
      }
    },
    "itemBase": {
      "type": "object",
      "required": [
        "key",
        "name",
        "type",
        "amount",
        "account"
      ],
      "properties": {
        "key": {
          "$ref": "#/$defs/key"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100
        },
        "type": {
          "enum": [
            "essential",
            "leisure",
            "saving",
            "project"
          ]
        },
        "amount": {
          "$ref": "#/$defs/money"
        },
        "account": {
          "$ref": "#/$defs/key"
        },
        "pocket": {
          "$ref": "#/$defs/key"
        }
      }
    },
    "item": {
      "allOf": [
        {
          "$ref": "#/$defs/itemBase"
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "key",
            "name",
            "type",
            "amount",
            "account",
            "recurrence"
          ],
          "properties": {
            "key": {
              "$ref": "#/$defs/key"
            },
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "type": {
              "enum": [
                "essential",
                "leisure",
                "saving",
                "project"
              ]
            },
            "amount": {
              "$ref": "#/$defs/money"
            },
            "account": {
              "$ref": "#/$defs/key"
            },
            "pocket": {
              "$ref": "#/$defs/key"
            },
            "recurrence": {
              "enum": [
                "monthly",
                "quarterly",
                "halfYearly",
                "yearly"
              ]
            },
            "dueDay": {
              "type": "integer",
              "minimum": 1,
              "maximum": 31
            },
            "provisionMonthly": {
              "type": "boolean",
              "default": false
            }
          }
        }
      ]
    },
    "oneOff": {
      "allOf": [
        {
          "$ref": "#/$defs/itemBase"
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "key",
            "name",
            "type",
            "amount",
            "account"
          ],
          "properties": {
            "key": {
              "$ref": "#/$defs/key"
            },
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "type": {
              "enum": [
                "essential",
                "leisure",
                "saving",
                "project"
              ]
            },
            "amount": {
              "$ref": "#/$defs/money"
            },
            "account": {
              "$ref": "#/$defs/key"
            },
            "pocket": {
              "$ref": "#/$defs/key"
            }
          }
        }
      ]
    }
  }
}
