{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://dags.dk/samarbejder/v1/schema.json",
  "title": "Samarbejder V1",
  "description": "Et offentligt øjebliksbillede af en virksomhed eller person, udgivet af virksomheden eller indsamlet til en researchside.",
  "type": "object",
  "additionalProperties": false,
  "required": ["format", "version", "updated_at", "language", "origin", "entity"],
  "allOf": [
    {"if": {"properties": {"origin": {"properties": {"kind": {"const": "self"}}}}},
     "then": {"required": ["participation"]},
     "else": {"not": {"required": ["participation"]}}}
  ],
  "properties": {
    "format": {"const": "https://dags.dk/samarbejder"},
    "version": {"const": 1},
    "updated_at": {"type": "string", "format": "date-time"},
    "language": {"type": "string", "pattern": "^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"},
    "origin": {"type": "object", "additionalProperties": false,
      "required": ["kind", "publisher"],
      "properties": {
        "kind": {"enum": ["self", "research"]},
        "publisher": {"$ref": "#/$defs/shortText"},
        "collected_at": {"type": "string", "format": "date-time"},
        "source_urls": {"type": "array", "minItems": 1, "maxItems": 100, "uniqueItems": true,
          "items": {"$ref": "#/$defs/url"}}
      },
      "allOf": [{"if": {"properties": {"kind": {"const": "research"}}},
        "then": {"required": ["collected_at", "source_urls"]}}]},
    "participation": {"type": "object", "additionalProperties": false,
      "required": ["public_display", "history"],
      "properties": {"public_display": {"const": true}, "history": {"const": true}}},
    "entity": {"$ref": "#/$defs/entity"},
    "profile": {"$ref": "#/$defs/profile"},
    "contacts": {"type": "array", "maxItems": 20, "items": {"$ref": "#/$defs/contact"}},
    "locations": {"type": "array", "maxItems": 20, "items": {"$ref": "#/$defs/location"}},
    "services": {"type": "array", "maxItems": 100, "items": {"$ref": "#/$defs/service"}},
    "offers": {"type": "array", "maxItems": 200, "items": {"$ref": "#/$defs/offer"}},
    "cases": {"type": "array", "maxItems": 100, "items": {"$ref": "#/$defs/case"}},
    "positions": {"type": "array", "maxItems": 100, "items": {"$ref": "#/$defs/position"}},
    "pages": {"type": "array", "maxItems": 150, "items": {"$ref": "#/$defs/page"}},
    "links": {"type": "array", "maxItems": 50, "items": {"$ref": "#/$defs/link"}},
    "media": {"type": "array", "maxItems": 50, "items": {"$ref": "#/$defs/media"}},
    "extensions": {"$ref": "#/$defs/extensions"}
  },
  "$defs": {
    "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,79}$"},
    "url": {"type": "string", "format": "uri", "maxLength": 2048, "pattern": "^https://"},
    "shortText": {"type": "string", "minLength": 1, "maxLength": 240},
    "summary": {"type": "string", "minLength": 1, "maxLength": 2000},
    "body": {"type": "string", "minLength": 1, "maxLength": 12000},
    "extensions": {
      "type": "object", "maxProperties": 20,
      "propertyNames": {"pattern": "^[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)+$"},
      "additionalProperties": {"type": "object"}
    },
    "identifier": {
      "type": "object", "additionalProperties": false,
      "required": ["scheme", "value"],
      "properties": {
        "scheme": {"type": "string", "pattern": "^[a-z][a-z0-9:._-]{1,79}$"},
        "value": {"type": "string", "minLength": 1, "maxLength": 160}
      }
    },
    "entity": {
      "type": "object", "additionalProperties": false,
      "required": ["kind", "name", "website"],
      "properties": {
        "kind": {"enum": ["organization", "person", "other"]},
        "name": {"$ref": "#/$defs/shortText"},
        "legal_name": {"$ref": "#/$defs/shortText"},
        "website": {"$ref": "#/$defs/url"},
        "identifiers": {"type": "array", "maxItems": 20, "items": {"$ref": "#/$defs/identifier"}},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "teamSize": {
      "type": "object", "additionalProperties": false,
      "required": ["min", "max"],
      "properties": {
        "min": {"type": "integer", "minimum": 0, "maximum": 10000000},
        "max": {"type": "integer", "minimum": 0, "maximum": 10000000},
        "as_of": {"type": "string", "format": "date"}
      }
    },
    "profile": {
      "type": "object", "additionalProperties": false,
      "properties": {
        "headline": {"$ref": "#/$defs/shortText"},
        "summary": {"$ref": "#/$defs/summary"},
        "description": {"$ref": "#/$defs/body"},
        "founded_year": {"type": "integer", "minimum": 1000, "maximum": 9999},
        "team_size": {"$ref": "#/$defs/teamSize"},
        "service_area": {"$ref": "#/$defs/shortText"},
        "tags": {"type": "array", "maxItems": 30, "uniqueItems": true,
          "items": {"$ref": "#/$defs/shortText"}},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "contact": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "kind", "value"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "kind": {"enum": ["email", "phone", "url"]},
        "value": {"type": "string", "minLength": 1, "maxLength": 2048},
        "label": {"$ref": "#/$defs/shortText"},
        "extensions": {"$ref": "#/$defs/extensions"}
      },
      "allOf": [
        {"if": {"properties": {"kind": {"const": "email"}}},
          "then": {"properties": {"value": {"type": "string", "format": "email"}}}},
        {"if": {"properties": {"kind": {"const": "url"}}},
          "then": {"properties": {"value": {"$ref": "#/$defs/url"}}}},
        {"if": {"properties": {"kind": {"const": "phone"}}},
          "then": {"properties": {"value": {"type": "string", "pattern": "^\\+[1-9][0-9]{1,14}$"}}}}
      ]
    },
    "address": {
      "type": "object", "additionalProperties": false,
      "required": ["country_code"],
      "properties": {
        "street": {"$ref": "#/$defs/shortText"},
        "postal_code": {"$ref": "#/$defs/shortText"},
        "locality": {"$ref": "#/$defs/shortText"},
        "municipality": {"$ref": "#/$defs/shortText"},
        "region": {"$ref": "#/$defs/shortText"},
        "country_code": {"type": "string", "pattern": "^[A-Z]{2}$"}
      }
    },
    "coordinates": {
      "type": "object", "additionalProperties": false,
      "required": ["latitude", "longitude"],
      "properties": {
        "latitude": {"type": "number", "minimum": -90, "maximum": 90},
        "longitude": {"type": "number", "minimum": -180, "maximum": 180}
      }
    },
    "location": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "address"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "name": {"$ref": "#/$defs/shortText"},
        "address": {"$ref": "#/$defs/address"},
        "coordinates": {"$ref": "#/$defs/coordinates"},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "service": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "name"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "name": {"$ref": "#/$defs/shortText"},
        "summary": {"$ref": "#/$defs/summary"},
        "url": {"$ref": "#/$defs/url"},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "money": {"type": "string", "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]{1,2})?$"},
    "price": {
      "type": "object", "additionalProperties": false,
      "required": ["type"],
      "properties": {
        "type": {"enum": ["fixed", "from", "range", "quote"]},
        "amount": {"$ref": "#/$defs/money"},
        "min_amount": {"$ref": "#/$defs/money"},
        "max_amount": {"$ref": "#/$defs/money"},
        "currency": {"type": "string", "pattern": "^[A-Z]{3}$"},
        "unit": {"type": "string", "pattern": "^[a-z][a-z0-9_]{0,39}$"},
        "unit_label": {"$ref": "#/$defs/shortText"},
        "vat": {"enum": ["excluded", "included", "not_applicable", "unknown"]}
      },
      "allOf": [
        {"if": {"properties": {"type": {"enum": ["fixed", "from"]}}},
         "then": {"required": ["amount", "currency", "unit", "vat"],
          "not": {"anyOf": [{"required": ["min_amount"]}, {"required": ["max_amount"]}]} }},
        {"if": {"properties": {"type": {"const": "range"}}},
         "then": {"required": ["min_amount", "max_amount", "currency", "unit", "vat"],
          "not": {"required": ["amount"]}}},
        {"if": {"properties": {"type": {"const": "quote"}}},
         "then": {"not": {"anyOf": [{"required": ["amount"]}, {"required": ["min_amount"]},
                                  {"required": ["max_amount"]}]}}}
      ]
    },
    "offer": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "name"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "name": {"$ref": "#/$defs/shortText"},
        "summary": {"$ref": "#/$defs/summary"},
        "url": {"$ref": "#/$defs/url"},
        "service_ids": {"type": "array", "maxItems": 20, "uniqueItems": true,
          "items": {"$ref": "#/$defs/id"}},
        "price": {"$ref": "#/$defs/price"},
        "billing_note": {"$ref": "#/$defs/summary"},
        "includes": {"type": "array", "maxItems": 30, "items": {"$ref": "#/$defs/shortText"}},
        "excludes": {"type": "array", "maxItems": 30, "items": {"$ref": "#/$defs/shortText"}},
        "valid_from": {"type": "string", "format": "date"},
        "valid_through": {"type": "string", "format": "date"},
        "source_url": {"$ref": "#/$defs/url"},
        "observed_at": {"type": "string", "format": "date"},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "customer": {
      "type": "object", "additionalProperties": false,
      "required": ["name"],
      "properties": {
        "name": {"$ref": "#/$defs/shortText"},
        "website": {"$ref": "#/$defs/url"}
      }
    },
    "case": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "title"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "title": {"$ref": "#/$defs/shortText"},
        "summary": {"$ref": "#/$defs/summary"},
        "description": {"$ref": "#/$defs/body"},
        "customer": {"$ref": "#/$defs/customer"},
        "url": {"$ref": "#/$defs/url"},
        "published_on": {"type": "string", "format": "date"},
        "source_url": {"$ref": "#/$defs/url"},
        "observed_at": {"type": "string", "format": "date"},
        "service_ids": {"type": "array", "maxItems": 20, "uniqueItems": true,
          "items": {"$ref": "#/$defs/id"}},
        "media_ids": {"type": "array", "maxItems": 20, "uniqueItems": true,
          "items": {"$ref": "#/$defs/id"}},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "position": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "title", "status"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "title": {"$ref": "#/$defs/shortText"},
        "status": {"enum": ["open", "closed", "evergreen", "unknown"]},
        "summary": {"$ref": "#/$defs/summary"},
        "description": {"$ref": "#/$defs/body"},
        "url": {"$ref": "#/$defs/url"},
        "employment_type": {"type": "string", "maxLength": 120},
        "location_ids": {"type": "array", "maxItems": 20, "uniqueItems": true,
          "items": {"$ref": "#/$defs/id"}},
        "posted_on": {"type": "string", "format": "date"},
        "valid_through": {"type": "string", "format": "date"},
        "source_url": {"$ref": "#/$defs/url"},
        "observed_at": {"type": "string", "format": "date"},
        "extensions": {"$ref": "#/$defs/extensions"}
      },
      "allOf": [
        {"if": {"properties": {"status": {"const": "open"}}},
         "then": {"required": ["valid_through"]}}
      ]
    },
    "page": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "url", "kind", "observed_at"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "url": {"$ref": "#/$defs/url"},
        "kind": {"enum": ["homepage", "service", "price", "case", "position", "about", "contact", "article", "other"]},
        "title": {"$ref": "#/$defs/shortText"},
        "summary": {"$ref": "#/$defs/summary"},
        "text": {"$ref": "#/$defs/body"},
        "depth": {"type": "integer", "minimum": 0, "maximum": 10},
        "observed_at": {"type": "string", "format": "date"}
      }
    },
    "link": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "label", "url"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "label": {"$ref": "#/$defs/shortText"},
        "url": {"$ref": "#/$defs/url"},
        "relation": {"type": "string", "pattern": "^[a-z][a-z0-9_]{0,39}$"},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    },
    "media": {
      "type": "object", "additionalProperties": false,
      "required": ["id", "kind", "url"],
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "kind": {"enum": ["logo", "image", "video", "document"]},
        "url": {"$ref": "#/$defs/url"},
        "alt": {"$ref": "#/$defs/shortText"},
        "caption": {"$ref": "#/$defs/summary"},
        "credit": {"$ref": "#/$defs/shortText"},
        "license_url": {"$ref": "#/$defs/url"},
        "extensions": {"$ref": "#/$defs/extensions"}
      }
    }
  }
}
