{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://xn--jonas-gebudereinigung-e2b.de/ressourcen/reinigungsplan-datenschema/schema/reinigungsplan.schema.json",
  "title": "Offenes Reinigungsplan-Datenschema",
  "description": "Maschinenlesbarer Datenvertrag für Reinigungspläne und Leistungsverzeichnisse.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "recordId",
    "title",
    "language",
    "dataOrigin",
    "createdAt",
    "updatedAt",
    "object",
    "areas"
  ],
  "properties": {
    "schemaVersion": {
      "const": "1.0.0"
    },
    "recordId": {
      "$ref": "#/$defs/id"
    },
    "title": {
      "type": "string",
      "minLength": 5,
      "maxLength": 160
    },
    "language": {
      "const": "de"
    },
    "dataOrigin": {
      "type": "string",
      "enum": [
        "synthetic",
        "real-authorized"
      ]
    },
    "createdAt": {
      "type": "string",
      "format": "date"
    },
    "updatedAt": {
      "type": "string",
      "format": "date"
    },
    "object": {
      "$ref": "#/$defs/cleaningObject"
    },
    "areas": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/area"
      }
    }
  },
  "$defs": {
    "id": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]{2,63}$"
    },
    "cleaningObject": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "objectId",
        "label",
        "objectType",
        "dataOrigin"
      ],
      "properties": {
        "objectId": {
          "$ref": "#/$defs/id"
        },
        "label": {
          "type": "string",
          "minLength": 3,
          "maxLength": 120
        },
        "objectType": {
          "type": "string",
          "enum": [
            "office",
            "healthcare",
            "education",
            "retail-gastronomy",
            "warehouse-production",
            "mixed"
          ]
        },
        "dataOrigin": {
          "type": "string",
          "enum": [
            "synthetic",
            "real-authorized"
          ]
        },
        "notes": {
          "type": "string",
          "maxLength": 500
        }
      }
    },
    "area": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "areaId",
        "name",
        "roomGroup",
        "quantity",
        "cleanableAreaM2",
        "useIntensity",
        "access",
        "services"
      ],
      "properties": {
        "areaId": {
          "$ref": "#/$defs/id"
        },
        "name": {
          "type": "string",
          "minLength": 2,
          "maxLength": 120
        },
        "roomGroup": {
          "type": "string",
          "enum": [
            "work-office",
            "sanitary",
            "traffic",
            "meeting-common",
            "kitchen-catering",
            "treatment-care",
            "storage-production",
            "other"
          ]
        },
        "quantity": {
          "type": "integer",
          "minimum": 1
        },
        "cleanableAreaM2": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "floorSurface": {
          "type": "string",
          "enum": [
            "textile",
            "resilient",
            "stone-ceramic",
            "wood-laminate",
            "concrete-industrial",
            "mixed",
            "not-specified"
          ]
        },
        "useIntensity": {
          "type": "string",
          "enum": [
            "low",
            "normal",
            "high"
          ]
        },
        "access": {
          "$ref": "#/$defs/access"
        },
        "services": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/service"
          }
        },
        "notes": {
          "type": "string",
          "maxLength": 500
        }
      }
    },
    "access": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "mode"
      ],
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "freely-schedulable",
            "fixed-window",
            "during-operation",
            "restricted"
          ]
        },
        "timeWindow": {
          "type": "string",
          "pattern": "^([01]\\d|2[0-3]):[0-5]\\d-([01]\\d|2[0-3]):[0-5]\\d$"
        }
      }
    },
    "service": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "serviceId",
        "cleaningType",
        "description",
        "frequency",
        "qualityCriterion",
        "responsibleRole",
        "included"
      ],
      "properties": {
        "serviceId": {
          "$ref": "#/$defs/id"
        },
        "cleaningType": {
          "type": "string",
          "enum": [
            "maintenance",
            "periodic",
            "basic",
            "glass",
            "special"
          ]
        },
        "description": {
          "type": "string",
          "minLength": 10,
          "maxLength": 500
        },
        "frequency": {
          "$ref": "#/$defs/frequency"
        },
        "qualityCriterion": {
          "$ref": "#/$defs/qualityCriterion"
        },
        "responsibleRole": {
          "type": "string",
          "enum": [
            "contractor",
            "client",
            "shared"
          ]
        },
        "included": {
          "type": "boolean"
        },
        "exclusions": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string",
            "minLength": 3,
            "maxLength": 160
          }
        }
      }
    },
    "frequency": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "mode"
      ],
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "fixed",
            "interval",
            "on-demand",
            "event-triggered"
          ]
        },
        "occurrences": {
          "type": "integer",
          "minimum": 1,
          "maximum": 365
        },
        "period": {
          "type": "string",
          "enum": [
            "day",
            "week",
            "month",
            "year"
          ]
        },
        "trigger": {
          "type": "string",
          "minLength": 5,
          "maxLength": 240
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "mode": {
                "enum": [
                  "fixed",
                  "interval"
                ]
              }
            }
          },
          "then": {
            "required": [
              "occurrences",
              "period"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "mode": {
                "const": "event-triggered"
              }
            }
          },
          "then": {
            "required": [
              "trigger"
            ]
          }
        }
      ]
    },
    "qualityCriterion": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "target",
        "inspectionMethod",
        "evidenceType"
      ],
      "properties": {
        "target": {
          "type": "string",
          "minLength": 10,
          "maxLength": 300
        },
        "inspectionMethod": {
          "type": "string",
          "enum": [
            "visual-check",
            "document-check",
            "functional-check",
            "measurement"
          ]
        },
        "evidenceType": {
          "type": "string",
          "enum": [
            "inspection-record",
            "photo-record",
            "measurement-record",
            "none"
          ]
        },
        "tolerance": {
          "type": "string",
          "maxLength": 200
        }
      }
    }
  }
}
