{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.uniroom.it/partner-docs/feed-schema.json",
  "title": "UniRoom Partner Feed",
  "description": "Schema del feed JSON che i partner UniRoom espongono per l'integrazione degli annunci.",
  "type": "object",
  "required": [ "feed_version", "partner_id", "generated_at", "listings" ],
  "additionalProperties": false,
  "properties": {
    "feed_version": {
      "type": "string",
      "enum": [ "1.0" ],
      "description": "Versione dello schema. Attualmente supportata: 1.0"
    },
    "partner_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "Identificativo del partner assegnato da UniRoom."
    },
    "generated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp ISO 8601 di generazione del feed."
    },
    "listings": {
      "type": "array",
      "maxItems": 10000,
      "items": { "$ref": "#/$defs/listing" }
    }
  },

  "$defs": {
    "listing": {
      "type": "object",
      "required": [
        "id",
        "title",
        "url",
        "price",
        "city",
        "address",
        "room_type",
        "updated_at"
      ],
      "dependentRequired": {
        "latitude": [ "longitude" ],
        "longitude": [ "latitude" ]
      },
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "description": "ID univoco e stabile dell'annuncio nel sistema del partner."
        },
        "title": {
          "type": "string",
          "minLength": 5,
          "maxLength": 200,
          "description": "Titolo breve dell'annuncio."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "maxLength": 500,
          "description": "Link diretto all'annuncio sul sito del partner."
        },
        "price": {
          "type": "number",
          "minimum": 50,
          "maximum": 5000,
          "description": "Prezzo mensile in euro."
        },
        "city": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "description": "Comune amministrativo dell'immobile. Per comuni limitrofi alle città universitarie, scrivere il nome reale del comune (es. 'Sesto San Giovanni')."
        },
        "address": {
          "type": "string",
          "minLength": 1,
          "maxLength": 250,
          "description": "Indirizzo dell'immobile o zona descrittiva."
        },
        "room_type": {
          "type": "string",
          "enum": [ "single", "double", "bed" ],
          "description": "Tipo di stanza: singola, doppia, posto letto."
        },
        "updated_at": {
          "type": "string",
          "format": "date-time",
          "description": "Timestamp ISO 8601 dell'ultimo aggiornamento dell'annuncio."
        },

        "latitude": {
          "type": [ "number", "null" ],
          "minimum": -90,
          "maximum": 90,
          "description": "Latitudine WGS84. Se valorizzata, deve esserlo anche longitude."
        },
        "longitude": {
          "type": [ "number", "null" ],
          "minimum": -180,
          "maximum": 180,
          "description": "Longitudine WGS84. Se valorizzata, deve esserlo anche latitude."
        },
        "description": {
          "type": [ "string", "null" ],
          "maxLength": 2000,
          "description": "Descrizione testuale dell'annuncio. Solo plain text."
        },
        "available_from": {
          "type": [ "string", "null" ],
          "format": "date",
          "description": "Data di disponibilità (YYYY-MM-DD)."
        },
        "images": {
          "type": [ "array", "null" ],
          "maxItems": 10,
          "items": {
            "type": "string",
            "format": "uri",
            "maxLength": 500
          },
          "description": "Array di URL immagini pubblicamente accessibili via HTTPS."
        },

        "bills_included": {
          "type": [ "boolean", "null" ],
          "description": "Se true, il prezzo include le utenze."
        }
      }
    }
  }
}