{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/frase-io/json-schema/frase-io-comment-schema.json",
  "title": "Comment",
  "description": "A comment attached to a content article. Human-authored comments have `author.is_system_user = false`; AI-authored comments have `author.is_system_user = true` and populate `ai_suggestion`. Clients rebuild threads via `parent_comment_id` / `root_comment_id`.",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/frase-io-comments-api-openapi.yml#/components/schemas/Comment",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "body": {
      "type": "string",
      "description": "Markdown body. For AI comments, the AI-metadata prefix is already stripped."
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "resolved"
      ]
    },
    "selection_start": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Editor position (ProseMirror coordinates) where the anchored selection begins. AI comments created via the public `POST /content/{id}/ai-comments` endpoint return `null` here — use `selection_text` to locate the anchor."
    },
    "selection_end": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Editor position where the anchored selection ends. See `selection_start` for nullability notes."
    },
    "selection_text": {
      "type": [
        "string",
        "null"
      ],
      "description": "Verbatim text excerpt the comment is anchored to."
    },
    "content_version": {
      "type": [
        "integer",
        "null"
      ]
    },
    "parent_comment_id": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid"
    },
    "root_comment_id": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid"
    },
    "mentioned_user_ids": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uuid"
      }
    },
    "author": {
      "type": "object",
      "properties": {
        "id": {
          "type": [
            "string",
            "null"
          ],
          "format": "uuid"
        },
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "avatar_url": {
          "type": [
            "string",
            "null"
          ]
        },
        "is_system_user": {
          "type": "boolean"
        }
      }
    },
    "ai_suggestion": {
      "type": [
        "object",
        "null"
      ],
      "description": "Present on AI-authored comments. `suggested_text` is the replacement copy that `POST /content/{id}/ai-comments/{commentId}/apply` will splice into the article body.",
      "properties": {
        "category": {
          "type": "string",
          "enum": [
            "structure",
            "clarity",
            "seo",
            "governance",
            "engagement",
            "authority"
          ]
        },
        "suggested_text": {
          "type": "string"
        }
      }
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "resolved_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "resolved_by_id": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid"
    }
  }
}