{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://bedquitter.app/data/alarm-checker.schema.json",
  "title": "Bed Quitter alarm fixes",
  "description": "The format of https://bedquitter.app/data/alarm-checker.json, version 1.0.0. Fields may be added within version 1; none is renamed or removed.",
  "type": "object",
  "required": [
    "$schema",
    "schemaVersion",
    "name",
    "description",
    "url",
    "generated",
    "lastChecked",
    "licence",
    "attribution",
    "notice",
    "creator",
    "publisher",
    "kinds",
    "symptoms",
    "settings",
    "phones"
  ],
  "properties": {
    "$schema": {
      "type": "string",
      "format": "uri",
      "pattern": "^https://",
      "description": "This schema."
    },
    "schemaVersion": {
      "type": "string",
      "pattern": "^1\\.\\d+\\.\\d+$",
      "description": "The format version."
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "minLength": 1
    },
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^https://",
      "description": "The page that explains the data."
    },
    "generated": {
      "type": "string",
      "format": "date-time",
      "description": "When the file was built."
    },
    "lastChecked": {
      "type": "string",
      "format": "date",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      "description": "The latest day any of it was checked against its sources."
    },
    "licence": {
      "type": "object",
      "required": [
        "name",
        "id",
        "url"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "id": {
          "type": "string",
          "minLength": 1,
          "description": "SPDX identifier."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        }
      }
    },
    "attribution": {
      "type": "string",
      "minLength": 1,
      "description": "The credit line to show."
    },
    "notice": {
      "type": "string",
      "minLength": 1,
      "description": "What the licence covers, and the trademarks."
    },
    "creator": {
      "type": "object",
      "required": [
        "name",
        "url"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        }
      }
    },
    "publisher": {
      "type": "object",
      "required": [
        "name",
        "url"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        }
      }
    },
    "kinds": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "meaning"
        ],
        "properties": {
          "id": {
            "enum": [
              "ok",
              "catch",
              "depends",
              "unsure",
              "no"
            ]
          },
          "meaning": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "symptoms": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "enum": [
              "ring",
              "vib",
              "quiet",
              "late"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "settings": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "enum": [
              "dnd",
              "sleep",
              "silent",
              "airplane",
              "call",
              "power",
              "ears",
              "off"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "phones": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/phone"
      },
      "description": "iPhone, Samsung, other Android, then each Android maker with a public fix page."
    }
  },
  "$defs": {
    "step": {
      "type": "object",
      "required": [
        "type",
        "label"
      ],
      "properties": {
        "type": {
          "enum": [
            "menu",
            "yours",
            "search"
          ],
          "description": "menu: a screen or button to tap · yours: the reader's own item, such as your alarm app · search: a screen to find by searching Settings."
        },
        "label": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "source": {
      "type": "object",
      "required": [
        "name",
        "url"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Who published it."
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        }
      }
    },
    "answer": {
      "type": "object",
      "required": [
        "id",
        "kind",
        "tag",
        "line",
        "path",
        "pathText",
        "notConfirmed",
        "sources"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "description": "Stable: <phone>/<setting>/<clock or app>, or <phone>/apps/app."
        },
        "kind": {
          "enum": [
            "ok",
            "catch",
            "depends",
            "unsure",
            "no"
          ],
          "description": "ok rings · catch rings, with a catch · depends · unsure not confirmed · no won't ring."
        },
        "tag": {
          "type": "string",
          "minLength": 1,
          "description": "The short verdict the checker shows, such as \"Rings\" or \"Not confirmed\"."
        },
        "line": {
          "type": "string",
          "minLength": 1,
          "description": "What happens, and what to check."
        },
        "path": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/step"
          },
          "description": "The screens to tap, in order. Empty when there is nothing to tap."
        },
        "pathText": {
          "type": "string",
          "description": "The path on one line: \"Settings > Apps > [your alarm app]\"."
        },
        "notConfirmed": {
          "type": "boolean",
          "description": "True when no source we read settles it (kind unsure)."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/source"
          },
          "description": "The pages it rests on."
        }
      }
    },
    "appAnswer": {
      "type": "object",
      "required": [
        "id",
        "kind",
        "tag",
        "line",
        "path",
        "pathText",
        "notConfirmed",
        "sources",
        "sameAsClock"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "description": "Stable: <phone>/<setting>/<clock or app>, or <phone>/apps/app."
        },
        "kind": {
          "enum": [
            "ok",
            "catch",
            "depends",
            "unsure",
            "no"
          ],
          "description": "ok rings · catch rings, with a catch · depends · unsure not confirmed · no won't ring."
        },
        "tag": {
          "type": "string",
          "minLength": 1,
          "description": "The short verdict the checker shows, such as \"Rings\" or \"Not confirmed\"."
        },
        "line": {
          "type": "string",
          "minLength": 1,
          "description": "What happens, and what to check."
        },
        "path": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/step"
          },
          "description": "The screens to tap, in order. Empty when there is nothing to tap."
        },
        "pathText": {
          "type": "string",
          "description": "The path on one line: \"Settings > Apps > [your alarm app]\"."
        },
        "notConfirmed": {
          "type": "boolean",
          "description": "True when no source we read settles it (kind unsure)."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/source"
          },
          "description": "The pages it rests on."
        },
        "sameAsClock": {
          "type": "boolean",
          "description": "True when other alarm apps get the Clock app's answer."
        }
      }
    },
    "otherApps": {
      "type": "object",
      "description": "The extra row for other alarm apps, on phones where battery limits hold them back.",
      "required": [
        "id",
        "kind",
        "tag",
        "line",
        "path",
        "pathText",
        "notConfirmed",
        "sources",
        "name"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "description": "Stable: <phone>/<setting>/<clock or app>, or <phone>/apps/app."
        },
        "kind": {
          "enum": [
            "ok",
            "catch",
            "depends",
            "unsure",
            "no"
          ],
          "description": "ok rings · catch rings, with a catch · depends · unsure not confirmed · no won't ring."
        },
        "tag": {
          "type": "string",
          "minLength": 1,
          "description": "The short verdict the checker shows, such as \"Rings\" or \"Not confirmed\"."
        },
        "line": {
          "type": "string",
          "minLength": 1,
          "description": "What happens, and what to check."
        },
        "path": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/step"
          },
          "description": "The screens to tap, in order. Empty when there is nothing to tap."
        },
        "pathText": {
          "type": "string",
          "description": "The path on one line: \"Settings > Apps > [your alarm app]\"."
        },
        "notConfirmed": {
          "type": "boolean",
          "description": "True when no source we read settles it (kind unsure)."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/source"
          },
          "description": "The pages it rests on."
        },
        "name": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "setting": {
      "type": "object",
      "required": [
        "setting",
        "name",
        "clock",
        "app"
      ],
      "properties": {
        "setting": {
          "enum": [
            "dnd",
            "sleep",
            "silent",
            "airplane",
            "call",
            "power",
            "ears",
            "off"
          ]
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "The setting as this phone's menus name it."
        },
        "clock": {
          "$ref": "#/$defs/answer"
        },
        "app": {
          "$ref": "#/$defs/appAnswer"
        }
      }
    },
    "fix": {
      "type": "object",
      "required": [
        "id",
        "fixId",
        "number",
        "title",
        "why",
        "path",
        "pathText",
        "symptoms",
        "clockOnly",
        "appOnly",
        "notConfirmed",
        "sources",
        "url"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z]+/[a-z0-9]+(-[a-z0-9]+)*$",
          "description": "Stable: <phone>/<fixId>."
        },
        "fixId": {
          "type": "string",
          "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
          "description": "Unique within the phone, from the title."
        },
        "number": {
          "type": "integer",
          "minimum": 1,
          "description": "Its place in the list, most likely first. Can change."
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "why": {
          "type": "string",
          "minLength": 1
        },
        "path": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/step"
          }
        },
        "pathText": {
          "type": "string"
        },
        "symptoms": {
          "type": "array",
          "items": {
            "enum": [
              "ring",
              "vib",
              "quiet",
              "late"
            ]
          },
          "description": "What went wrong that it helps with."
        },
        "clockOnly": {
          "type": "boolean",
          "description": "Only for the phone's own Clock app."
        },
        "appOnly": {
          "type": "boolean",
          "description": "Only for other alarm apps."
        },
        "notConfirmed": {
          "type": "boolean",
          "description": "No source settles the setting's name or place, or what it does to alarms."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/source"
          },
          "minItems": 1
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://",
          "description": "The fix on its phone's fix page, with ?s= set to one of its symptoms so the page shows it."
        }
      }
    },
    "bug": {
      "type": "object",
      "required": [
        "id",
        "url",
        "title",
        "what",
        "versions",
        "status",
        "statusName",
        "fix",
        "todo",
        "fixes",
        "sources",
        "checkedOn"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
        },
        "url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "what": {
          "type": "string",
          "minLength": 1
        },
        "versions": {
          "type": "string",
          "minLength": 1
        },
        "status": {
          "enum": [
            "open",
            "unknown",
            "fixed",
            "design"
          ]
        },
        "statusName": {
          "type": "string",
          "minLength": 1
        },
        "fix": {
          "type": "string",
          "minLength": 1,
          "description": "Whether it is fixed, and who says so."
        },
        "todo": {
          "type": "string",
          "minLength": 1,
          "description": "What to do."
        },
        "fixes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Ids of the fixes on its phone that cover it."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/source"
          },
          "minItems": 1
        },
        "checkedOn": {
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "description": "When it was checked."
        }
      }
    },
    "phone": {
      "type": "object",
      "required": [
        "id",
        "name",
        "note",
        "checked",
        "checkedOn",
        "fixPage",
        "answers",
        "otherAlarmApps",
        "fixes",
        "knownBugs",
        "knownBugsNote"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z]+$",
          "examples": [
            "iphone",
            "samsung",
            "android"
          ]
        },
        "name": {
          "type": "string",
          "minLength": 1
        },
        "note": {
          "type": [
            "string",
            "null"
          ]
        },
        "checked": {
          "type": "string",
          "minLength": 1,
          "description": "How and when its answers were checked."
        },
        "checkedOn": {
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "description": "The latest day they were checked."
        },
        "fixPage": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://"
        },
        "answers": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/setting"
          },
          "minItems": 8,
          "maxItems": 8
        },
        "otherAlarmApps": {
          "oneOf": [
            {
              "$ref": "#/$defs/otherApps"
            },
            {
              "type": "null"
            }
          ]
        },
        "fixes": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/fix"
          }
        },
        "knownBugs": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/bug"
          }
        },
        "knownBugsNote": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    }
  }
}
