{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://theamateur.co.uk/ai-journalism/api/v1/schema/feature.schema.json",
  "title": "AI Journalism feature",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "slug",
    "edition",
    "kind",
    "section",
    "title",
    "kicker",
    "standfirst",
    "body",
    "word_count",
    "reading_minutes",
    "url",
    "api_url",
    "published_at",
    "updated_at",
    "sources",
    "images",
    "anchors",
    "rights"
  ],
  "properties": {
    "schema": {
      "type": "string",
      "minLength": 1,
      "format": "uri"
    },
    "api_version": {
      "const": "1.0"
    },
    "slug": {
      "type": "string",
      "minLength": 1
    },
    "edition": {
      "type": "string",
      "minLength": 1,
      "pattern": "^\\d{4}-\\d{2}-\\d{2}(-dryrun)?$"
    },
    "kind": {
      "const": "feature"
    },
    "section": {
      "const": "AI Journalism"
    },
    "title": {
      "type": "string",
      "minLength": 1
    },
    "kicker": {
      "type": "string",
      "minLength": 1
    },
    "standfirst": {
      "type": "string",
      "minLength": 1
    },
    "body": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "string",
        "minLength": 1
      }
    },
    "word_count": {
      "type": "integer",
      "minimum": 1
    },
    "reading_minutes": {
      "type": "integer",
      "minimum": 1
    },
    "url": {
      "type": "string",
      "minLength": 1,
      "format": "uri"
    },
    "api_url": {
      "type": "string",
      "minLength": 1,
      "format": "uri"
    },
    "published_at": {
      "type": "string",
      "minLength": 1,
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "minLength": 1,
      "format": "date-time"
    },
    "sources": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "role",
          "label",
          "url"
        ],
        "properties": {
          "role": {
            "enum": [
              "primary",
              "independent",
              "discovery",
              "reference"
            ]
          },
          "label": {
            "type": "string",
            "minLength": 1
          },
          "url": {
            "type": "string",
            "minLength": 1,
            "format": "uri"
          }
        }
      }
    },
    "images": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/image"
      }
    },
    "anchors": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "fragment",
          "label"
        ],
        "properties": {
          "fragment": {
            "type": "string",
            "minLength": 1
          },
          "label": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "rights": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "text",
        "images_url"
      ],
      "properties": {
        "text": {
          "const": "Stories © THE AMATEUR LIMITED. You may quote short extracts with a credit and a link; ask before any other reuse (support@theamateur.co.uk)."
        },
        "images_url": {
          "type": "string",
          "minLength": 1,
          "format": "uri"
        }
      }
    }
  },
  "$defs": {
    "image": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "role",
        "editorial_role",
        "url",
        "variants",
        "width",
        "height",
        "format",
        "sha256",
        "alt",
        "caption",
        "credit_line",
        "provenance_type",
        "photorealistic",
        "creator",
        "rights_holder",
        "copyright_notice",
        "licence",
        "attribution_required",
        "attribution_text",
        "reuse_by_agents",
        "source_url",
        "source_terms_url",
        "modifications",
        "depicts_real_event",
        "rights_checked"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "role": {
          "enum": [
            "hero",
            "inline",
            "teaser"
          ]
        },
        "editorial_role": {
          "enum": [
            "evidence",
            "identity",
            "geography",
            "mechanism",
            "contrast",
            "atmosphere"
          ]
        },
        "url": {
          "type": "string",
          "minLength": 1,
          "format": "uri"
        },
        "variants": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "url",
              "width",
              "height",
              "format"
            ],
            "properties": {
              "url": {
                "type": "string",
                "minLength": 1,
                "format": "uri"
              },
              "width": {
                "type": "integer",
                "minimum": 1
              },
              "height": {
                "type": "integer",
                "minimum": 1
              },
              "format": {
                "enum": [
                  "svg",
                  "webp",
                  "jpeg",
                  "png"
                ]
              }
            }
          }
        },
        "width": {
          "type": "integer",
          "minimum": 1
        },
        "height": {
          "type": "integer",
          "minimum": 1
        },
        "format": {
          "enum": [
            "svg",
            "webp",
            "jpeg",
            "png"
          ]
        },
        "sha256": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-f0-9]{64}$"
        },
        "alt": {
          "type": "string",
          "minLength": 1
        },
        "caption": {
          "type": "string",
          "minLength": 1
        },
        "credit_line": {
          "type": "string",
          "minLength": 1
        },
        "provenance_type": {
          "enum": [
            "original_diagram",
            "original_illustration",
            "original_illustration_generated",
            "original_photograph",
            "press_kit",
            "creative_commons",
            "public_domain"
          ]
        },
        "photorealistic": {
          "type": "boolean"
        },
        "digital_source_type": {
          "type": "string",
          "minLength": 1,
          "format": "uri"
        },
        "generated": {
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "tool",
                "requested_by"
              ],
              "properties": {
                "tool": {
                  "type": "string",
                  "minLength": 1
                },
                "requested_by": {
                  "const": "Justin Emmanuel"
                }
              }
            }
          ]
        },
        "creator": {
          "type": "string",
          "minLength": 1
        },
        "rights_holder": {
          "type": "string",
          "minLength": 1
        },
        "copyright_notice": {
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "minLength": 1
            }
          ]
        },
        "licence": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "id",
            "name",
            "url"
          ],
          "properties": {
            "id": {
              "type": "string",
              "minLength": 1
            },
            "name": {
              "type": "string",
              "minLength": 1
            },
            "url": {
              "type": "string",
              "minLength": 1,
              "format": "uri"
            },
            "statement": {
              "const": "© THE AMATEUR LIMITED · Reuse only with permission (support@theamateur.co.uk)"
            }
          }
        },
        "attribution_required": {
          "type": "boolean"
        },
        "attribution_text": {
          "type": "string",
          "minLength": 1
        },
        "reuse_by_agents": {
          "enum": [
            "permission_required",
            "per_source_licence",
            "not_granted"
          ]
        },
        "source_url": {
          "type": "string",
          "minLength": 1,
          "format": "uri"
        },
        "source_terms_url": {
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string",
              "minLength": 1,
              "format": "uri"
            }
          ]
        },
        "modifications": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          }
        },
        "depicts_real_event": {
          "type": "boolean"
        },
        "rights_checked": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "by",
            "on"
          ],
          "properties": {
            "by": {
              "const": "Editor (AI agent)"
            },
            "on": {
              "type": "string",
              "minLength": 1,
              "pattern": "^\\d{4}-\\d{2}-\\d{2}(-dryrun)?$"
            }
          }
        },
        "edition": {
          "type": "string",
          "minLength": 1,
          "pattern": "^\\d{4}-\\d{2}-\\d{2}(-dryrun)?$"
        },
        "story_id": {
          "type": "string",
          "minLength": 1
        },
        "feature_slug": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  }
}
