Schema for Heimdall Discovery Settings

From DiscoverySettings.schema.yaml (heimdall/DiscoverySettings.schema)

---
$id: https://skeleton.botmd.io/heimdall/DiscoverySettings.schema
$schema: http://json-schema.org/draft-07/schema#

title: Discovery Settings
description: |-
  Heimdall discovery is a simple pattern used by frontend to discover _basic_ application settings from a universal endpoint based on simple URL rules.
  This is useful for retrieving settings such as GQL endpoints and language options.

  Discovery settings are organized as a sequence of _URL matching_ **rules**.
  Each rule defines how a URL is matched and if matched, what the settings are.
  There are several ways to match rules:

  1. Exact match of URL
  2. Regex match of URL
  3. Exact match of host
  4. Regex match of host
  5. Exact match of path (with `/` prefix)
  6. Regex match of path (with `/` prefix)

  Regex are based on [Python style regexes](https://pythex.org/) using [re.search](https://docs.python.org/3/library/re.html#re.search).
  URL nomenclatures are based on definitions in [RFC 3986: Uniform Resource Identifier (URI): Generic Syntax](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2).
  We normalize URI using our implementation loosely based on guidelines described in [URI normalization (Wikipedia)](https://en.wikipedia.org/wiki/URI_normalization).
  The actual implementation can be found in [scalpel.common.uri code](https://gitlab.com/fivehealth/hippocrates/-/blob/4aff2ed0c6d9359eb1d0b61b1e5265dbe08e29c2/hippocrates/scalpel/common/uri.py#L58) and examples of the URI normalization can be found in [scalpel.tests.common.uri test cases](https://gitlab.com/fivehealth/hippocrates/-/blob/4aff2ed0c6d9359eb1d0b61b1e5265dbe08e29c2/hippocrates/scalpel/tests/common/uri.py#L100).
  URL, host, and path rules may be used together.

  Rule settings are simple objects/dictionaries/maps with an opinionated convention based on segregation by applications.
  Example:

  ```yaml
  hippocrates:
    gql_endpoint: https://example.com/gql

  login:
    url: https://login.com/

  care:
    language: id
  ```

  When a URL match multiple rules, the individual rule settings are merged recursively in order of preference from the first matched rule to the last.
  That is, rule settings objects are union-ized with earlier rule settings retaining their values.

  The pseudo-code for generating the discovery setting is as follows:

  ```
  url ← normalize_uri('https://subdomain.example.com/a/b/c')

  matched_settings ← []
  for each rule in rules
    if url matches rule
      matched_settings ← matched_settings + [rule settings]

  return deep_merge(reversed(matched_settings))
  ```

type: object
additionalProperties: false
required: [rules]
properties:
  rules:
    title: Rules
    description: An array of rules.

    type: array
    minItems: 1
    items:
      title: Rule
      description: A single rule for matching URL along with the resulting settings object.

      type: object
      additionalProperties: false
      required: [description, match, settings]

      properties:
        description:
          title: Description
          description: Use this field to describe the rule and its reason for being here.

          type: string
          minLength: 1

        match:
          title: Match
          description: Defines how we match the URL.

          type: object
          additionalProperties: false
          anyOf:
            - required: [all]
            - required: [url]
            - required: [host]
            - required: [path]

          properties:
            all:
              title: All
              description: Always match regardless. This is useful for defining a _default_ rule. The value for this should always be `true`.

              type: boolean

            url:
              title: URL
              description: Matches based on URL. URLs are normalized using our implementation of the [URI Normalization rules](https://gitlab.com/fivehealth/hippocrates/-/blob/staging/hippocrates/scalpel/common/uri.py).

              $ref: "#/definitions/ExactOrRegex"

            host:
              title: Host
              description: Matches based on `host` component of the URL. As defined in [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2), `host` does not include ports. Hosts are normalized using using our implementation of the [URI Normalization rules](https://gitlab.com/fivehealth/hippocrates/-/blob/staging/hippocrates/scalpel/common/uri.py).

              $ref: "#/definitions/ExactOrRegex"

            path:
              title: Path
              description: Matches based on the `path` component of the URL. Paths are normalized using percent encoding based on rule defined in the RFC. Paths are normalized using our implementation of the [URI Normalization rules](https://gitlab.com/fivehealth/hippocrates/-/blob/staging/hippocrates/scalpel/common/uri.py).

              $ref: "#/definitions/ExactOrRegex"
          #end properties
        #end match

        settings:
          title: Settings
          description: An object relevant to this rule.

          type: object
          additionalProperties: false
          required: []

          properties:
            hippocrates:
              $ref: "#/definitions/Hippocrates Settings"

            care:
              $ref: "#/definitions/Care Settings"

            login:
              $ref: "#/definitions/Login Settings"
          #end properties
        #end settings

        enabled:
          title: Enabled
          description: Rules that are not `enabled` will be ignored. Defaults to `true`.

          type: boolean
      #end properties
    #end items
  #end rules
#end properties

definitions:
  Hippocrates Settings:
    title: Hippocrates
    description: Hippocrates settings.

    type: object
    additionalProperties: false
    required: [region, gql_endpoint]

    properties:
      region:
        title: Region
        description: Region where Hippocrates is hosted.
        enum: [id, sg]

      gql_endpoint:
        title: GQL Endpoint
        description: The fully qualified GQL endpoint to use.

        type: string
        format: uri
  #end Hippocrates Settings

  Login Settings:
    title: Login
    description: Login settings.

    type: object
    additionalProperties: false
    required: [url]

    properties:
      url:
        title: URL
        description: The URL to the login application.

        type: string
        format: uri
  #end Login Settings

  Care Settings:
    title: Care
    description: Care settings.

    type: object
    additionalProperties: false
    required: [clinic_domain_regex]

    properties:
      clinic_domain_regex:
        title: Clinic Domain Regex
        description: Javascript-based regular expression to extract clinic `domain` from URL `path`. There will be a named capturing group `domain` to denote the domain within the `path`. Note that for consistency, `path` will always include a `/` at the beginning. Empty `path`s will be denoted by just `/`.

        type: string
        minLength: 1

      language:
        title: Language
        description: Default language for this URL. This is used prior to any clinic settings. Defaults to `en` if not set.

        type: string
        minLength: 1
  #end Care Settings

  ExactOrRegex:
    type: object
    additionalProperties: false
    oneOf:
      - required: [exact]
      - required: [regex]

    properties:
      exact:
        title: Exact
        description: Exact string matching using Python `==`.

        type: string
        minLength: 1

      regex:
        title: Regex
        description: Regex string matching based on [Python style regexes](https://pythex.org/) using [re.search](https://docs.python.org/3/library/re.html#re.search).

        type: string
        minLength: 1
    #end properties
  #end ExactOrRegex
#end definitions

[Main Page] [Schema Documentation] [Examples]