{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:hos:schema:0.1:reference:arrival-readiness",
  "title": "Arrival-readiness reference situations",
  "description": "Non-normative. Situations produced by the reference arrival-readiness projection. They use the HOS Events envelope so they can be replayed and audited, but they are not part of the HOS Events 0.1 catalogue and may change without a HIP.",
  "allOf": [
    {
      "$ref": "urn:hos:schema:0.1:event-envelope"
    },
    {
      "properties": {
        "type": {
          "enum": ["arrival.room_readiness_at_risk", "arrival.room_readiness_resolved"]
        }
      }
    },
    {
      "if": {
        "required": ["type"],
        "properties": {
          "type": {
            "const": "arrival.room_readiness_at_risk"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/arrival.room_readiness_at_risk"
          }
        }
      }
    },
    {
      "if": {
        "required": ["type"],
        "properties": {
          "type": {
            "const": "arrival.room_readiness_resolved"
          }
        }
      },
      "then": {
        "properties": {
          "data": {
            "$ref": "#/$defs/arrival.room_readiness_resolved"
          }
        }
      }
    }
  ],
  "$defs": {
    "factRef": {
      "type": "object",
      "required": ["value", "source", "event_id", "time"],
      "properties": {
        "value": {
          "type": "string"
        },
        "source": {
          "type": "string",
          "format": "uri"
        },
        "event_id": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false,
      "description": "A value together with the fact it comes from."
    },
    "conflictRef": {
      "type": "object",
      "description": "A non-authoritative value that disagrees with the authoritative value and is not older than it.",
      "required": ["dimension", "value", "source", "event_id", "time"],
      "properties": {
        "dimension": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/unitStatusDimension"
        },
        "value": {
          "type": "string"
        },
        "source": {
          "type": "string",
          "format": "uri"
        },
        "event_id": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false
    },
    "eventRef": {
      "type": "object",
      "required": ["source", "id"],
      "properties": {
        "source": {
          "type": "string",
          "format": "uri"
        },
        "id": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "maintenanceRef": {
      "type": "object",
      "description": "A maintenance window that blocks the unit when the guest is expected, and the fact it comes from.",
      "required": [
        "maintenance_id",
        "starts_at",
        "ends_at",
        "statuses",
        "source",
        "event_id",
        "time"
      ],
      "properties": {
        "maintenance_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "starts_at": {
          "type": "string",
          "format": "date-time"
        },
        "ends_at": {
          "type": "string",
          "format": "date-time"
        },
        "statuses": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/maintenanceWindowStatuses"
        },
        "source": {
          "type": "string",
          "format": "uri"
        },
        "event_id": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false
    },
    "occupantRef": {
      "type": "object",
      "description": "Another stay still in house in the assigned unit: checked in, not checked out. planned_departure_at is its latest planned check-out, when known; source, event_id and time identify its check-in.",
      "required": ["stay_id", "planned_departure_at", "source", "event_id", "time"],
      "properties": {
        "stay_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "planned_departure_at": {
          "oneOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ]
        },
        "source": {
          "type": "string",
          "format": "uri"
        },
        "event_id": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false
    },
    "taskRef": {
      "type": "object",
      "required": ["task_id", "task_type", "status", "source", "event_id", "time"],
      "properties": {
        "task_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "task_type": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/taskType"
        },
        "status": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/taskStatus"
        },
        "source": {
          "type": "string",
          "format": "uri"
        },
        "event_id": {
          "type": "string"
        },
        "time": {
          "type": "string",
          "format": "date-time"
        }
      },
      "additionalProperties": false
    },
    "arrival.room_readiness_at_risk": {
      "title": "arrival.room_readiness_at_risk",
      "description": "The assigned unit may not be ready when the guest comes: the guest is expected before the planned check-in time and the unit is not ready, a maintenance window blocks the unit when the guest is expected, or another guest in house in the unit is not due to leave before then. A unit is not ready when its authoritative housekeeping status is not ready or unknown, a window blocks it, or another guest still holds it. expected_arrival_at is the latest arrival signal, or the planned check-in without one. Observation only.",
      "type": "object",
      "required": [
        "stay_id",
        "reservation_id",
        "unit_id",
        "planned_arrival_at",
        "expected_arrival_at",
        "housekeeping",
        "conflicts",
        "latest_task",
        "evidence"
      ],
      "properties": {
        "stay_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "reservation_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "unit_id": {
          "oneOf": [
            {
              "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
            },
            {
              "type": "null"
            }
          ]
        },
        "planned_arrival_at": {
          "type": "string",
          "format": "date-time"
        },
        "expected_arrival_at": {
          "type": "string",
          "format": "date-time"
        },
        "housekeeping": {
          "oneOf": [
            {
              "$ref": "#/$defs/factRef"
            },
            {
              "type": "null"
            }
          ]
        },
        "conflicts": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/conflictRef"
          }
        },
        "latest_task": {
          "oneOf": [
            {
              "$ref": "#/$defs/taskRef"
            },
            {
              "type": "null"
            }
          ]
        },
        "maintenance": {
          "$ref": "#/$defs/maintenanceRef"
        },
        "occupied_by": {
          "$ref": "#/$defs/occupantRef"
        },
        "evidence": {
          "type": "array",
          "description": "Facts the situation is derived from, sorted by occurrence time, then source, then id.",
          "items": {
            "$ref": "#/$defs/eventRef"
          }
        }
      },
      "additionalProperties": false
    },
    "arrival.room_readiness_resolved": {
      "title": "arrival.room_readiness_resolved",
      "description": "A previously raised room-readiness risk no longer applies.",
      "type": "object",
      "required": [
        "stay_id",
        "reservation_id",
        "unit_id",
        "reason",
        "planned_arrival_at",
        "expected_arrival_at",
        "housekeeping",
        "evidence"
      ],
      "properties": {
        "stay_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "reservation_id": {
          "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
        },
        "unit_id": {
          "oneOf": [
            {
              "$ref": "urn:hos:schema:0.1:core#/$defs/hosId"
            },
            {
              "type": "null"
            }
          ]
        },
        "reason": {
          "enum": [
            "unit_ready",
            "unit_available",
            "unit_reassigned",
            "unit_vacated",
            "departure_before_arrival",
            "arrival_not_early",
            "reservation_inactive",
            "stay_started"
          ],
          "description": "What stopped the risk: the stay was given another unit, the unit became ready, its maintenance window went, the guest in house left or is now due to leave first, the arrival is no longer early, the reservation became inactive, or the stay started."
        },
        "planned_arrival_at": {
          "type": "string",
          "format": "date-time"
        },
        "expected_arrival_at": {
          "oneOf": [
            {
              "type": "string",
              "format": "date-time"
            },
            {
              "type": "null"
            }
          ]
        },
        "housekeeping": {
          "oneOf": [
            {
              "$ref": "#/$defs/factRef"
            },
            {
              "type": "null"
            }
          ]
        },
        "evidence": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/eventRef"
          }
        }
      },
      "additionalProperties": false
    }
  }
}
