{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Appétit App Store",
  "description": "Schema for apps.json — the data file powering an Appétit app store.",
  "type": "object",
  "required": ["store", "categories", "apps"],
  "properties": {
    "store": {
      "type": "object",
      "description": "Store-level metadata.",
      "required": ["name", "developer"],
      "properties": {
        "name": { "type": "string", "description": "Store display name." },
        "developer": { "type": "string", "description": "Default developer name shown on app detail pages." },
        "tagline": { "type": "string", "description": "Short tagline for the store." },
        "url": { "type": "string", "format": "uri", "description": "The store's live URL." },
        "github": { "type": "string", "format": "uri", "description": "GitHub profile or org URL." }
      }
    },
    "featured": {
      "type": "array",
      "description": "Apps to feature in the carousel banner on the Discover page.",
      "items": {
        "type": "object",
        "required": ["id", "headline", "title", "subtitle"],
        "properties": {
          "id": { "type": "string", "description": "Must match an app id in the apps array." },
          "headline": { "type": "string", "description": "Small label above the title (e.g. 'NEW APP')." },
          "title": { "type": "string", "description": "Large banner title." },
          "subtitle": { "type": "string", "description": "Banner description text." }
        }
      }
    },
    "categories": {
      "type": "array",
      "description": "Sidebar categories for filtering apps.",
      "items": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id": { "type": "string", "description": "Category identifier used in app category arrays." },
          "name": { "type": "string", "description": "Display name in the sidebar." }
        }
      }
    },
    "apps": {
      "type": "array",
      "description": "The list of apps in the store.",
      "items": {
        "$ref": "#/definitions/app"
      }
    }
  },
  "definitions": {
    "iconStyle": {
      "type": "object",
      "description": "Per-app icon display settings to handle different icon formats.",
      "properties": {
        "scale": { "type": "number", "description": "CSS transform scale (e.g. 1.3 to zoom in on padded macOS icons)." },
        "objectFit": { "type": "string", "enum": ["cover", "contain", "fill"], "description": "CSS object-fit for the icon image." },
        "borderRadius": { "type": "string", "description": "CSS border-radius for the icon container (e.g. '22%')." },
        "bgColor": { "type": "string", "description": "Background color for the icon container (e.g. '#000000')." },
        "padding": { "type": "string", "description": "CSS padding inside the icon container (e.g. '18%')." },
        "objectPosition": { "type": "string", "description": "CSS object-position to focus a specific area of the icon (e.g. 'top', '30% 20%', 'center right')." }
      }
    },
    "app": {
      "type": "object",
      "required": ["id", "name", "subtitle", "description", "category", "platform", "price", "github"],
      "properties": {
        "id": { "type": "string", "description": "Unique app identifier. Used in URLs and deduplication." },
        "name": { "type": "string", "description": "App display name." },
        "developer": { "type": "string", "description": "Override the store-level developer name for this app." },
        "subtitle": { "type": "string", "description": "Short tagline shown in list rows." },
        "description": { "type": "string", "description": "One-liner for list views and search." },
        "longDescription": { "type": "string", "description": "Full description for the detail page." },
        "icon": { "type": ["string", "null"], "format": "uri", "description": "URL to the app icon image (PNG or SVG)." },
        "iconEmoji": { "type": "string", "description": "Fallback emoji when icon is null or fails to load." },
        "iconStyle": { "$ref": "#/definitions/iconStyle" },
        "category": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Category IDs this app belongs to (e.g. ['macos', 'productivity'])."
        },
        "platform": { "type": "string", "description": "Platform label (e.g. 'macOS', 'Web', 'Node.js', 'CLI')." },
        "price": { "type": "string", "description": "Price label (e.g. 'Free')." },
        "github": { "type": "string", "format": "uri", "description": "GitHub repository URL." },
        "homepage": { "type": ["string", "null"], "format": "uri", "description": "Project homepage URL." },
        "language": { "type": "string", "description": "Primary programming language." },
        "stars": { "type": "integer", "minimum": 0, "description": "GitHub star count." },
        "forks": { "type": "integer", "minimum": 0, "description": "GitHub fork count." },
        "brew": { "type": "string", "description": "Homebrew install command. Triggers the install modal." },
        "installCommand": { "type": "string", "description": "Alternative install command (e.g. 'npx my-app'). Triggers the install modal." },
        "downloadUrl": { "type": "string", "format": "uri", "description": "Direct download URL (e.g. GitHub Releases latest). Shown as secondary button in install modal." },
        "buyUrl": { "type": "string", "format": "uri", "description": "Purchase URL for paid apps. When price is not 'Free', a Buy button links here. If omitted, falls back to homepage or github." },
        "requirements": { "type": "string", "description": "System requirements (e.g. 'macOS 15 Sequoia or later')." },
        "features": {
          "type": "array",
          "items": { "type": "string" },
          "description": "Feature list shown on the detail page."
        },
        "screenshots": {
          "type": "array",
          "items": { "type": "string", "format": "uri" },
          "description": "Screenshot URLs shown in the detail page preview section."
        },
        "_comments": {
          "type": "array",
          "description": "Auto-populated by build.sh from GitHub Issues API. Not meant to be set manually.",
          "items": {
            "type": "object",
            "properties": {
              "user": { "type": "string", "description": "GitHub username of the issue author." },
              "avatar": { "type": "string", "format": "uri", "description": "Avatar URL of the issue author." },
              "title": { "type": "string", "description": "Issue title, shown as review title." },
              "body": { "type": "string", "description": "Issue body (truncated to 300 chars)." },
              "url": { "type": "string", "format": "uri", "description": "Link to the GitHub issue." },
              "created_at": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp." },
              "reactions": {
                "type": "object",
                "description": "Reaction emoji counts from the issue.",
                "properties": {
                  "total": { "type": "integer" },
                  "thumbsUp": { "type": "integer" },
                  "thumbsDown": { "type": "integer" },
                  "laugh": { "type": "integer" },
                  "hooray": { "type": "integer" },
                  "confused": { "type": "integer" },
                  "heart": { "type": "integer" },
                  "rocket": { "type": "integer" },
                  "eyes": { "type": "integer" }
                }
              }
            }
          }
        }
      }
    }
  }
}
