{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://liftdiff.com/schema/routine-v1.json",
  "title": "LiftDiff Routine Document",
  "description": "LiftDiff routine definitions. Exercises and folders are referenced by name, not by internal ID.",
  "type": "object",
  "required": ["schema", "routines"],
  "properties": {
    "schema": { "const": "liftdiff.routine/v1" },
    "exportedAt": { "type": "string", "format": "date-time" },
    "folders": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name"],
        "properties": { "name": { "type": "string", "minLength": 1 } }
      }
    },
    "routines": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "exercises"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "folder": {
            "type": ["string", "null"],
            "description": "A name not listed in folders is created on import."
          },
          "note": { "type": ["string", "null"] },
          "exercises": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": ["exercise", "sets", "reps", "restSeconds"],
              "properties": {
                "exercise": {
                  "type": "string",
                  "description": "Exercise name. Unknown names are matched against the catalog; if nothing matches, a custom exercise is created."
                },
                "sets": { "type": "integer", "minimum": 1, "maximum": 20 },
                "reps": {
                  "type": "object",
                  "required": ["low", "high"],
                  "properties": {
                    "low": { "type": "integer", "minimum": 1 },
                    "high": { "type": "integer", "minimum": 1 }
                  }
                },
                "restSeconds": { "type": "integer", "minimum": 0, "maximum": 900 },
                "superset": {
                  "type": ["integer", "null"],
                  "description": "Exercises sharing the same integer form a superset. Use null when it stands alone."
                },
                "targetRIR": {
                  "type": ["integer", "null"],
                  "minimum": 0,
                  "maximum": 10,
                  "description": "Target reps in reserve. 0 means to failure. May be omitted."
                }
              }
            }
          }
        }
      }
    }
  }
}
