{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://openwebcomics.comicopia.app/schema/comic.schema.json",
  "title": "Comic",
  "description": "A comic series available from a Comicopia registry.",
  "type": "object",
  "required": ["id", "name", "url"],
  "properties": {
    "id": {
      "type": "string",
      "description": "Unique identifier for the comic (slug-style).",
      "example": "drivecomic"
    },
    "name": {
      "type": "string",
      "description": "Display name of the comic.",
      "example": "Drive"
    },
    "description": {
      "type": ["string", "null"],
      "description": "Short description or tagline for the comic."
    },
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Canonical URL of the comic's website.",
      "example": "https://www.drivecomic.com"
    },
    "thumbnail_url": {
      "type": ["string", "null"],
      "format": "uri",
      "description": "URL of a representative thumbnail image."
    },
    "total_pages": {
      "type": ["integer", "null"],
      "description": "Total number of pages in the archive, if known.",
      "example": 487
    },
    "bluesky_url": {
      "type": ["string", "null"],
      "description": "Creator's Bluesky profile URL. Not format-validated as social media URLs may contain browser-style unencoded characters."
    },
    "patreon_url": {
      "type": ["string", "null"],
      "description": "Creator's Patreon page URL. Not format-validated as social media URLs may contain browser-style unencoded characters."
    },
    "scraper_type": {
      "type": ["string", "null"],
      "description": "Identifier for the scraper used to index this comic's pages. Registry-server-specific."
    },
    "first_page_url": {
      "type": ["string", "null"],
      "format": "uri",
      "description": "URL of the first page — used as the scrape starting point. Registry-server-specific."
    },
    "page_count": {
      "type": ["integer", "null"],
      "description": "Number of pages currently indexed in the database. Registry-server-specific.",
      "example": 487
    },
    "last_scraped_at": {
      "type": ["string", "null"],
      "format": "date-time",
      "description": "ISO 8601 timestamp of the most recent completed scrape. Registry-server-specific."
    },
    "created_at": {
      "type": ["string", "null"],
      "format": "date-time",
      "description": "ISO 8601 timestamp when this comic was added to the registry."
    },
    "last_scrape_status": {
      "description": "Status of the most recent scrape job. Registry-server-specific.",
      "enum": ["pending", "running", "completed", "failed", "cancelled", null]
    },
    "last_scrape_job_id": {
      "type": ["integer", "null"],
      "description": "ID of the most recent scrape job. Registry-server-specific."
    }
  },
  "additionalProperties": false
}
