{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://mediastash.app/schemas/mediastash-backup-v13.schema.json",
  "title": "Media Stash portable backup v13",
  "description": "The standard, portable Media Stash backup format. Provider credentials and API keys are intentionally not part of this schema.",
  "type": "object",
  "required": [
    "version",
    "timestamp",
    "userId",
    "favorites",
    "watchProgress",
    "collections",
    "collectionItems"
  ],
  "properties": {
    "version": {
      "const": 13,
      "description": "The current Media Stash backup schema version."
    },
    "timestamp": {
      "$ref": "#/$defs/dateTime"
    },
    "sourceOwner": {
      "$ref": "#/$defs/sourceOwner"
    },
    "userId": {
      "$ref": "#/$defs/nonEmptyString",
      "description": "The source owner identifier. Importers choose the destination owner explicitly; do not use this value to overwrite a local owner."
    },
    "favorites": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/favorite"
      }
    },
    "watchProgress": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/watchProgress"
      }
    },
    "readingProgress": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/readingProgress"
      }
    },
    "collections": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/collection"
      }
    },
    "collectionItems": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/collectionItem"
      }
    },
    "followedCreators": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/followedCreator"
      }
    },
    "userProfile": {
      "$ref": "#/$defs/userProfile"
    },
    "settings": {
      "$ref": "#/$defs/settings"
    }
  },
  "additionalProperties": true,
  "$defs": {
    "nonEmptyString": {
      "type": "string",
      "minLength": 1
    },
    "dateTime": {
      "type": "string",
      "format": "date-time"
    },
    "mediaDate": {
      "type": "string",
      "description": "An ISO 8601 date or date-time string."
    },
    "mediaType": {
      "type": "string",
      "enum": [
        "movie",
        "series",
        "book",
        "game"
      ]
    },
    "sourceOwner": {
      "type": "object",
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        }
      },
      "additionalProperties": true
    },
    "remoteId": {
      "type": "object",
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "sourceName": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "episode": {
      "type": "object",
      "required": [
        "seasonNumber",
        "episodeNumber",
        "name"
      ],
      "properties": {
        "seasonNumber": {
          "type": "integer",
          "minimum": 0
        },
        "episodeNumber": {
          "type": "integer",
          "minimum": 0
        },
        "name": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "airDate": {
          "$ref": "#/$defs/mediaDate"
        }
      },
      "additionalProperties": true
    },
    "favorite": {
      "type": "object",
      "required": [
        "id",
        "provider",
        "externalId",
        "mediaType",
        "title"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "userId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "provider": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "externalId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "mediaType": {
          "$ref": "#/$defs/mediaType"
        },
        "title": {
          "type": "string"
        },
        "posterUrl": {
          "type": "string"
        },
        "watchedAt": {
          "$ref": "#/$defs/mediaDate"
        },
        "archived": {
          "type": "boolean"
        },
        "releaseDate": {
          "$ref": "#/$defs/mediaDate"
        },
        "slug": {
          "type": "string"
        },
        "episodes": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/episode"
          }
        },
        "remoteIds": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/remoteId"
          }
        },
        "tmdbMatchIgnored": {
          "type": "boolean"
        },
        "resolutionStatus": {
          "enum": [
            "resolved",
            "unresolved"
          ]
        },
        "resolutionNote": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "watchProgress": {
      "type": "object",
      "required": [
        "id",
        "provider",
        "externalId",
        "mediaType",
        "progressPercent",
        "completed",
        "updatedAt"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "userId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "provider": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "externalId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "mediaType": {
          "$ref": "#/$defs/mediaType"
        },
        "seasonNumber": {
          "type": "integer",
          "minimum": 0
        },
        "episodeNumber": {
          "type": "integer",
          "minimum": 0
        },
        "progressPercent": {
          "type": "number",
          "minimum": 0,
          "maximum": 100
        },
        "completed": {
          "type": "boolean"
        },
        "updatedAt": {
          "$ref": "#/$defs/dateTime"
        },
        "watchedAt": {
          "$ref": "#/$defs/mediaDate"
        },
        "watchedHistory": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/dateTime"
          }
        }
      },
      "allOf": [
        {
          "if": {
            "required": [
              "seasonNumber"
            ]
          },
          "then": {
            "required": [
              "episodeNumber"
            ]
          }
        },
        {
          "if": {
            "required": [
              "episodeNumber"
            ]
          },
          "then": {
            "required": [
              "seasonNumber"
            ]
          }
        }
      ],
      "additionalProperties": true
    },
    "readingProgress": {
      "type": "object",
      "required": [
        "id",
        "provider",
        "externalId",
        "status",
        "updatedAt"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "userId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "provider": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "externalId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "status": {
          "enum": [
            "want_to_read",
            "reading",
            "read"
          ]
        },
        "currentPage": {
          "type": "integer",
          "minimum": 0
        },
        "totalPages": {
          "type": "integer",
          "minimum": 0
        },
        "updatedAt": {
          "$ref": "#/$defs/dateTime"
        },
        "readAt": {
          "$ref": "#/$defs/mediaDate"
        }
      },
      "additionalProperties": true
    },
    "collection": {
      "type": "object",
      "required": [
        "id",
        "userId",
        "name",
        "createdAt"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "userId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "name": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "createdAt": {
          "$ref": "#/$defs/dateTime"
        },
        "icon": {
          "enum": [
            "layers",
            "film",
            "tv",
            "book-open",
            "gamepad-2",
            "heart",
            "star",
            "bookmark",
            "trophy",
            "sparkles",
            "flame",
            "music-2",
            "globe-2",
            "clock-3",
            "coffee",
            "briefcase-business",
            "graduation-cap",
            "palette",
            "clapperboard",
            "folder-heart"
          ]
        }
      },
      "additionalProperties": true
    },
    "collectionItem": {
      "type": "object",
      "required": [
        "id",
        "collectionId",
        "provider",
        "externalId",
        "mediaType",
        "title"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "collectionId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "provider": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "externalId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "mediaType": {
          "$ref": "#/$defs/mediaType"
        },
        "title": {
          "type": "string"
        },
        "posterUrl": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "followedCreator": {
      "type": "object",
      "required": [
        "id",
        "userId",
        "provider",
        "externalId",
        "kind",
        "name",
        "createdAt",
        "updatedAt"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "userId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "provider": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "externalId": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "kind": {
          "enum": [
            "person",
            "author",
            "company"
          ]
        },
        "roles": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/nonEmptyString"
          }
        },
        "domain": {
          "enum": [
            "film-tv",
            "books",
            "games"
          ]
        },
        "name": {
          "$ref": "#/$defs/nonEmptyString"
        },
        "profileUrl": {
          "type": "string"
        },
        "createdAt": {
          "$ref": "#/$defs/dateTime"
        },
        "updatedAt": {
          "$ref": "#/$defs/dateTime"
        },
        "lastResolvedAt": {
          "$ref": "#/$defs/dateTime"
        }
      },
      "additionalProperties": true
    },
    "userProfile": {
      "type": "object",
      "properties": {
        "displayName": {
          "type": "string"
        },
        "region": {
          "type": "string"
        },
        "metadataLanguage": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "providerPreferences": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "object",
          "additionalProperties": {
            "type": "boolean"
          }
        }
      },
      "additionalProperties": true
    },
    "settings": {
      "type": "object",
      "properties": {
        "theme": {
          "type": "string"
        },
        "providers": {
          "$ref": "#/$defs/providerPreferences"
        }
      },
      "additionalProperties": true
    }
  }
}
