{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lernapps.net/tooling/schemas/validation-report.v1.schema.json",
  "title": "Validation report of lernapps check, version 1",
  "description": "What `lernapps check` checked and found, as YAML: on standard output when a check fails, and always in the file of `--report <file>`. The same input gives the same report. A breaking change gets a new version of this schema.",
  "type": "object",
  "properties": {
    "checked": {
      "description": "What was checked: the commit of a repo (or its directory outside git), a bundle directory, or a URL and the time it was checked.",
      "oneOf": [
        {
          "type": "object",
          "properties": { "commit": { "type": "string", "pattern": "^[0-9a-f]{40}$" } },
          "required": ["commit"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": { "directory": { "type": "string", "minLength": 1 } },
          "required": ["directory"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": { "bundle": { "type": "string", "minLength": 1 } },
          "required": ["bundle"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "url": { "type": "string", "minLength": 1 },
            "at": { "type": "string", "description": "ISO 8601 time of the check" }
          },
          "required": ["url", "at"],
          "additionalProperties": false
        }
      ]
    },
    "parts": {
      "description": "In a repo: the parts that ran, pre-commit (format, lint, types) and pre-push (unit tests, build, checks of the built app, end-to-end tests).",
      "type": "array",
      "items": { "enum": ["pre-commit", "pre-push"] },
      "uniqueItems": true
    },
    "rules": {
      "description": "The ids of the rules checked: every check that found something to check, checks-pass for the toolchain steps, and app-checkable when a built app or a URL could not be checked at all.",
      "type": "array",
      "items": { "$ref": "#/$defs/id" },
      "uniqueItems": true
    },
    "findings": {
      "description": "Every finding, sorted by rule id and place. Exit code 1 when one has severity error.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rule": { "$ref": "#/$defs/id" },
          "severity": {
            "enum": ["error", "warning", "hint"],
            "description": "The rule's severity; hint also for what a check could not decide, such as a link whose server is rate limited (429). Only error fails"
          },
          "where": {
            "type": "string",
            "minLength": 1,
            "description": "File and line, page and element, or the command"
          },
          "found": { "type": "string", "minLength": 1, "description": "What was found" },
          "fix": { "type": "string", "minLength": 1, "description": "How to fix it" },
          "link": {
            "type": "string",
            "pattern": "^https://lernapps\\.net/tooling/rules/#[a-z][a-z0-9]*(-[a-z0-9]+)*$",
            "description": "The rule's entry on the rule page"
          }
        },
        "required": ["rule", "severity", "where", "found", "fix", "link"],
        "additionalProperties": false
      }
    },
    "suppressions": {
      "description": "Warnings suppressed in place, each with its reason.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "rule": { "$ref": "#/$defs/id" },
          "where": { "type": "string", "minLength": 1 },
          "reason": { "type": "string", "minLength": 1 }
        },
        "required": ["rule", "where", "reason"],
        "additionalProperties": false
      }
    },
    "fitness": {
      "description": "The fitness values measured on the built app, without a click, in the words of the catalog entry.",
      "type": "object",
      "properties": {
        "storage": {
          "enum": ["none", "device"],
          "description": "none: nothing stored; device: only in the browser, also what the app reads on loading and keeps after an input"
        },
        "thirdParty": {
          "enum": ["none", "before-click"],
          "description": "none: no request to another host before a click; before-click: requests that keep the app from being listed"
        }
      },
      "required": ["storage", "thirdParty"],
      "additionalProperties": false
    }
  },
  "required": ["checked", "rules", "findings", "suppressions"],
  "additionalProperties": false,
  "$defs": {
    "id": { "type": "string", "pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$" }
  }
}
