{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://already.so/schema/v1.0/session.schema.json",
  "title": "Already Session v1.0",
  "description": "Schema for an Already session — a recording (screen, audio, or both) with timeline events, media, comments, and notes.",
  "type": "object",
  "required": ["version", "session", "timeline"],
  "properties": {
    "version": { "type": "string", "const": "1.0" },

    "session": {
      "type": "object",
      "required": ["id", "createdAt"],
      "properties": {
        "id": { "type": "string", "format": "uuid" },
        "createdAt": { "type": "string", "format": "date-time" },
        "endedAt": { "type": "string", "format": "date-time" },
        "duration": { "type": "number", "minimum": 0, "description": "Seconds." },
        "title": { "type": "string" },
        "description": { "type": "string" },
        "status": { "type": "string", "enum": ["in_session", "uploading", "todo", "in_progress", "needs_feedback", "done", "cancelled"] },
        "assigneeId": { "type": "string" },
        "assigneeUsername": { "type": "string" },
        "labels": { "type": "array", "items": { "type": "string" } },
        "priority": { "type": "integer", "minimum": 1, "maximum": 5, "description": "1 = highest, 5 = lowest." },
        "platform": { "type": "string", "enum": ["electron", "web", "ios", "android"] },
        "platformVersion": { "type": "string" },
        "hasVideo": { "type": "boolean" },
        "hasAudio": { "type": "boolean" },
        "videoCodec": { "type": "string", "enum": ["h264", "h265", "vp9", "av1"] },
        "resolutionWidth": { "type": "integer", "minimum": 1 },
        "resolutionHeight": { "type": "integer", "minimum": 1 },
        "fps": { "type": "number", "minimum": 0 },
        "os": { "type": "string", "description": "e.g. 'macOS', 'Windows', 'iOS', 'Android'." },
        "osVersion": { "type": "string" },
        "device": { "type": "string", "description": "e.g. 'MacBook Pro 16-inch', 'iPhone 15 Pro'." },
        "screenWidth": { "type": "integer", "minimum": 1 },
        "screenHeight": { "type": "integer", "minimum": 1 },
        "screenScale": { "type": "number", "minimum": 0, "description": "e.g. 2 for Retina." },
        "teamId": { "type": "string" },
        "createdBy": { "type": "string" }
      }
    },

    "timeline": {
      "type": "array",
      "description": "Capture events recorded during the session, sorted by timestamp. Every event has timestamp + type. All other fields are optional and depend on the event type.",
      "items": {
        "type": "object",
        "required": ["timestamp", "type"],
        "properties": {
          "timestamp": { "type": "number", "minimum": 0, "description": "Seconds from session start." },
          "type": {
            "type": "string",
            "enum": [
              "window_focus", "page_navigation", "screen_change", "app_state",
              "keystroke", "text_typed", "text_selected",
              "mouse_click", "click", "touch",
              "snapshot", "annotation",
              "transcription",
              "recording_started", "recording_ended",
              "console_error", "network_request"
            ]
          },

          "text": { "type": "string", "description": "Text content. Used by: text_typed, transcription, annotation, console_error." },
          "x": { "type": "number", "description": "X coordinate. Used by: mouse_click, click, touch, annotation." },
          "y": { "type": "number", "description": "Y coordinate. Used by: mouse_click, click, touch, annotation." },
          "url": { "type": "string", "description": "URL. Used by: page_navigation, click, annotation, console_error, network_request." },
          "mediaRef": { "type": "string", "description": "ID of a media item. Used by: snapshot, annotation." },

          "appName": { "type": "string", "description": "Application name. Used by: window_focus, annotation (desktop)." },
          "windowTitle": { "type": "string", "description": "Window title. Used by: window_focus, annotation (desktop)." },
          "bundleId": { "type": "string", "description": "macOS bundle ID or Windows process name. Used by: window_focus." },
          "display": { "type": "integer", "minimum": 0, "description": "Display index. Used by: window_focus." },

          "title": { "type": "string", "description": "Page title. Used by: page_navigation." },
          "referrer": { "type": "string", "description": "Referrer URL. Used by: page_navigation." },

          "screenName": { "type": "string", "description": "Current screen/activity. Used by: screen_change." },
          "previousScreen": { "type": "string", "description": "Previous screen. Used by: screen_change." },

          "state": { "type": "string", "enum": ["foreground", "background"], "description": "Used by: app_state." },

          "key": { "type": "string", "description": "Key identifier. Used by: keystroke." },

          "button": { "type": "string", "enum": ["left", "right", "middle"], "description": "Mouse button. Used by: mouse_click." },

          "elementPath": { "type": "string", "description": "CSS selector path, e.g. 'body > main > button.cta'. Used by: click, annotation (web)." },
          "element": { "type": "string", "description": "HTML tag name, e.g. 'button', 'input', 'div'. Used by: click, annotation (web)." },
          "elementText": { "type": "string", "description": "Visible text of the element. Used by: click, annotation (web)." },
          "boundingBox": {
            "type": "object",
            "description": "Element bounding box. Used by: click, annotation (web).",
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" },
              "width": { "type": "number" },
              "height": { "type": "number" }
            }
          },
          "reactComponents": { "type": "string", "description": "React component tree, e.g. 'App > Form > Button'. Used by: click, annotation (web)." },
          "cssClasses": { "type": "string", "description": "Element class list. Used by: click, annotation (web)." },
          "accessibility": { "type": "string", "description": "ARIA info, e.g. 'role=button, name=Submit'. Used by: click, annotation (web)." },
          "nearbyText": { "type": "string", "description": "Text around the element. Used by: click, annotation (web)." },
          "selectedText": { "type": "string", "description": "Text highlighted/selected by the user. Used by: text_selected." },
          "isFixed": { "type": "boolean", "description": "Element has fixed/sticky positioning. Used by: click, annotation (web)." },

          "gesture": { "type": "string", "enum": ["tap", "double_tap", "long_press", "swipe", "pinch", "rotate"], "description": "Touch gesture. Used by: touch." },
          "points": { "type": "array", "items": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 }, "description": "Multi-touch points [[x,y], ...]. Used by: touch." },

          "start": { "type": "number", "description": "Audio start time in seconds. Used by: transcription." },
          "end": { "type": "number", "description": "Audio end time in seconds. Used by: transcription." },

          "level": { "type": "string", "enum": ["error", "warn", "info"], "description": "Log level. Used by: console_error." },
          "stack": { "type": "string", "description": "Stack trace. Used by: console_error." },

          "method": { "type": "string", "enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"], "description": "HTTP method. Used by: network_request." },
          "status": { "type": "integer", "description": "HTTP status code. Used by: network_request." },
          "duration": { "type": "number", "minimum": 0, "description": "Request duration in ms. Used by: network_request." }
        }
      }
    },

    "media": {
      "type": "array",
      "description": "Media files (video, audio, images) associated with the session.",
      "items": {
        "type": "object",
        "required": ["id", "type", "filename"],
        "properties": {
          "id": { "type": "string", "description": "Referenced by timeline events via 'mediaRef'." },
          "type": { "type": "string", "enum": ["video", "audio", "image"] },
          "category": { "type": "string", "enum": ["recording", "snapshot", "annotation", "smart", "pasted", "converted"] },
          "filename": { "type": "string" },
          "mimeType": { "type": "string" },
          "cloudUrl": { "type": "string", "format": "uri" },
          "width": { "type": "integer", "minimum": 0 },
          "height": { "type": "integer", "minimum": 0 },
          "duration": { "type": "number", "minimum": 0, "description": "Seconds." },
          "sizeBytes": { "type": "integer", "minimum": 0 },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      }
    },

    "comments": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "createdAt", "authorId", "body"],
        "properties": {
          "id": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" },
          "updatedAt": { "type": "string", "format": "date-time" },
          "authorId": { "type": "string" },
          "authorUsername": { "type": "string" },
          "body": { "type": "string" },
          "parentId": { "type": "string", "description": "Parent comment ID for threaded replies." }
        }
      }
    },

    "notes": {
      "type": "object",
      "description": "Rich-text notes. Content is an array of nodes (paragraphs, headings, images, etc.).",
      "properties": {
        "content": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["type"],
            "properties": {
              "type": { "type": "string", "description": "e.g. 'paragraph', 'heading', 'image'." }
            }
          }
        }
      }
    }
  }
}
