{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://settlement-sandbox.com/case.schema.json",
  "title": "Settlement Sandbox case file",
  "description": "A case for the Settlement Sandbox (settlement-sandbox/1). See CASE-FILE-FORMAT.md for the meaning of every field. The importer is more forgiving than this schema (it accepts and reports common mistakes); a file that passes this schema imports with no warnings.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "assets"
  ],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "schema": {
      "const": "settlement-sandbox/1",
      "description": "Format version. Optional but recommended."
    },
    "id": {
      "type": "string",
      "description": "Any identifier for the case. Generated if missing."
    },
    "name": {
      "type": "string",
      "description": "Name shown in the app and on the MOU. Default: \"Untitled case\"."
    },
    "asOf": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date the values are as of, YYYY-MM-DD. Default: today."
    },
    "notes": {
      "type": "string"
    },
    "updatedAt": {
      "type": "string",
      "description": "Written by the app (ISO 8601). Leave it out when writing by hand."
    },
    "parties": {
      "type": "array",
      "minItems": 2,
      "maxItems": 2,
      "items": {
        "$ref": "#/$defs/party"
      },
      "description": "Exactly two people, ids \"A\" and \"B\". Default: \"Party A\" and \"Party B\"."
    },
    "settings": {
      "$ref": "#/$defs/settings"
    },
    "assets": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/asset"
      }
    },
    "scenarios": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/scenario"
      },
      "description": "Default: one scenario with everything as titled."
    },
    "activeScenario": {
      "type": "string",
      "description": "id of the scenario shown when the file opens. Default: the first."
    },
    "revisions": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/revision"
      },
      "description": "Written by the app. Leave it out when writing by hand."
    },
    "marriedOn": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "Date of marriage, YYYY-MM-DD. Optional; used for the Social Security note."
    }
  },
  "$defs": {
    "fraction": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "money": {
      "type": "number",
      "description": "Dollars as a plain number: 103400, not \"$103,400\"."
    },
    "partyId": {
      "enum": [
        "A",
        "B"
      ]
    },
    "party": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/partyId"
        },
        "name": {
          "type": "string"
        },
        "tax": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "income": {
              "$ref": "#/$defs/fraction",
              "description": "Income tax rate on retirement withdrawals and interest received. Default 0.22."
            },
            "gains": {
              "$ref": "#/$defs/fraction",
              "description": "Capital gains rate, federal plus state. Default 0.20."
            },
            "withdraw": {
              "oneOf": [
                {
                  "$ref": "#/$defs/fraction"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Tax rate expected when pre-tax retirement money comes out. Default: same as income."
            },
            "borrow": {
              "oneOf": [
                {
                  "$ref": "#/$defs/fraction"
                },
                {
                  "type": "null"
                }
              ],
              "description": "What this person would pay to borrow, e.g. a buyout loan rate. Optional."
            }
          }
        }
      }
    },
    "settings": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "target": {
          "$ref": "#/$defs/fraction",
          "description": "Party A's target share of the total. Default 0.5."
        },
        "discount": {
          "$ref": "#/$defs/fraction",
          "description": "Yearly rate for valuing later payments in today's dollars. Default 0.045."
        },
        "warn": {
          "type": "number",
          "minimum": 0,
          "description": "Gap that raises a warning, dollars. Default 5000."
        },
        "bad": {
          "type": "number",
          "minimum": 0,
          "description": "Gap that raises a serious flag, dollars. Default 20000."
        },
        "cashFloor": {
          "type": "number",
          "minimum": 0,
          "description": "Cash each party should keep after the split, dollars. Default 40000."
        },
        "refLabel": {
          "type": "string",
          "description": "Name for reference values, e.g. \"FIF\". Default \"Reported\"."
        },
        "horizon": {
          "type": "number",
          "minimum": 0,
          "description": "Years ahead to compare how each side's share grows. Default 5."
        },
        "measure": {
          "enum": ["after-tax", "face"],
          "description": "The main measure: the board shows it, Balance aims for it and its bar comes first. Both are always shown. Default \"after-tax\"."
        }
      }
    },
    "qualities": {
      "type": "object",
      "additionalProperties": false,
      "description": "Anything left out comes from the asset's kind, then from the general defaults.",
      "properties": {
        "tax": {
          "enum": [
            "none",
            "income",
            "gain"
          ]
        },
        "rate": {
          "oneOf": [
            {
              "$ref": "#/$defs/fraction"
            },
            {
              "type": "null"
            }
          ]
        },
        "basis": {
          "oneOf": [
            {
              "type": "number",
              "minimum": 0
            },
            {
              "type": "null"
            }
          ]
        },
        "exclusion": {
          "type": "number",
          "minimum": 0
        },
        "cost": {
          "$ref": "#/$defs/fraction"
        },
        "realize": {
          "type": "boolean"
        },
        "liquid": {
          "type": "boolean"
        },
        "penalty": {
          "$ref": "#/$defs/fraction"
        },
        "divisible": {
          "type": "boolean"
        },
        "growth": {
          "type": "number",
          "minimum": -1,
          "maximum": 1
        },
        "estimate": {
          "type": "boolean"
        },
        "titled": {
          "enum": [
            "A",
            "B",
            "joint"
          ]
        },
        "separate": {
          "enum": [
            "A",
            "B",
            "other",
            null
          ]
        },
        "volatile": {
          "type": "boolean"
        },
        "divideBy": {
          "enum": [
            "qdro",
            "ira",
            "retitle",
            "sale",
            null
          ]
        },
        "splitWhenPaid": {
          "type": "boolean"
        },
        "realizeMonths": {
          "type": "number",
          "minimum": 0
        }
      }
    },
    "asset": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "value"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique. Scenarios refer to assets by id. Generated from the name if missing."
        },
        "name": {
          "type": "string"
        },
        "kind": {
          "enum": [
            "cash",
            "brokerage",
            "pretax",
            "ira",
            "roth",
            "pension",
            "home",
            "vehicle",
            "metal",
            "personal",
            "business",
            "receivable",
            "debt",
            "custom"
          ]
        },
        "group": {
          "type": "string",
          "description": "Type for the money-by-type summary: liquid, realestate, retirement, vehicles, other, debts, or any name of your own (which gets its own row). Leave out to use the kind's default. Descriptive only; it doesn't change any value."
        },
        "value": {
          "$ref": "#/$defs/money"
        },
        "ref": {
          "oneOf": [
            {
              "$ref": "#/$defs/money"
            },
            {
              "type": "null"
            }
          ],
          "description": "Reference value, e.g. what the financial disclosure says."
        },
        "note": {
          "type": "string"
        },
        "source": {
          "type": "string"
        },
        "updatedAt": {
          "type": "string"
        },
        "history": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "at",
              "value"
            ],
            "properties": {
              "at": {
                "type": "string"
              },
              "value": {
                "type": "number"
              }
            },
            "additionalProperties": false
          }
        },
        "q": {
          "$ref": "#/$defs/qualities"
        }
      }
    },
    "allocation": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "in": {
              "type": "boolean"
            },
            "a": {
              "$ref": "#/$defs/fraction"
            }
          }
        },
        {
          "enum": [
            "A",
            "B",
            "split",
            "out"
          ]
        },
        {
          "$ref": "#/$defs/fraction"
        }
      ]
    },
    "transfer": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "from",
        "amount"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "from": {
          "$ref": "#/$defs/partyId"
        },
        "amount": {
          "type": "number",
          "minimum": 0
        },
        "months": {
          "type": "number",
          "minimum": 0,
          "description": "0 = at signing."
        },
        "rate": {
          "$ref": "#/$defs/fraction",
          "description": "Yearly interest on a later payment."
        },
        "secured": {
          "type": "boolean"
        },
        "funding": {
          "enum": [
            "cash",
            "borrowed",
            "retirement",
            "other"
          ]
        },
        "trigger": {
          "enum": [
            "date",
            "sale"
          ],
          "description": "\"date\" = due after `months`; \"sale\" = due when something sells (`months` is the expected timing)."
        },
        "deadline": {
          "oneOf": [
            {
              "type": "number",
              "minimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "Latest month it must be paid by, for a payment due on sale."
        },
        "insured": {
          "type": "boolean"
        }
      }
    },
    "scenario": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "notes": {
          "type": "string"
        },
        "alloc": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/allocation"
          },
          "description": "Keyed by asset id. Leave out entirely to start everything as titled."
        },
        "transfers": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/transfer"
          }
        },
        "createdAt": {
          "type": "number"
        },
        "updatedAt": {
          "type": "number"
        },
        "costs": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/cost"
          }
        },
        "terms": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "marketAdjust": {
              "type": [
                "boolean",
                "null"
              ]
            }
          }
        }
      }
    },
    "revision": {
      "type": "object",
      "required": [
        "data"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "kind": {
          "enum": [
            "manual",
            "share",
            "mou",
            "backup",
            "import"
          ]
        },
        "at": {
          "type": "string"
        },
        "scenarioId": {
          "type": "string"
        },
        "scenarioName": {
          "type": "string"
        },
        "asOf": {
          "type": "string"
        },
        "link": {
          "type": "string"
        },
        "linkInfo": {
          "type": "object"
        },
        "data": {
          "type": "object",
          "required": [
            "assets",
            "scenario"
          ],
          "properties": {
            "parties": {
              "type": "array"
            },
            "settings": {
              "type": "object"
            },
            "assets": {
              "type": "array"
            },
            "scenario": {
              "type": "object"
            }
          }
        }
      }
    },
    "cost": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "amount"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "amount": {
          "type": "number",
          "minimum": 0
        },
        "paidBy": {
          "enum": [
            "A",
            "B",
            "split"
          ]
        },
        "funding": {
          "enum": [
            "cash",
            "other"
          ]
        }
      }
    }
  }
}
