{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://registry.apicrafter.io/schema/datatype.schema.json",
  "title": "Metacrafter Registry semantic datatype",
  "description": "Source YAML record of a semantic datatype (data/datatypes/**/<id>.yaml). Empty values are not allowed: omit the field instead.",
  "$ref": "#/$defs/datatype",
  "$defs": {
    "id": {
      "type": "string",
      "pattern": "^[a-z0-9_]+$",
      "description": "Lowercase identifier: letters, digits and underscores"
    },
    "idList": {
      "type": "array",
      "items": {"$ref": "#/$defs/id"},
      "minItems": 1,
      "uniqueItems": true
    },
    "nonEmptyString": {"type": "string", "minLength": 1},
    "fiboPath": {"type": "string", "pattern": "^[A-Z]+/([A-Za-z0-9-]+/)+[A-Za-z0-9]+$"},
    "stringOrList": {
      "oneOf": [
        {"$ref": "#/$defs/nonEmptyString"},
        {"type": "array", "items": {"$ref": "#/$defs/nonEmptyString"}, "minItems": 1, "uniqueItems": true}
      ]
    },
    "cdmTrait": {
      "type": "string",
      "pattern": "^(means|is)(\\.[A-Za-z0-9]+)+$",
      "description": "A trait name from the CDM foundations, for example means.location.postalCode or is.dataFormat.guid"
    },
    "autotypeCase": {
      "type": "string",
      "pattern": "^[A-Za-z0-9]+([ _-]+[A-Za-z0-9]+)*$",
      "description": "An AutoType benchmark test case: the name of its data_release file without .txt, for example isbn, date-chinese or ssn - new"
    },
    "d3mType": {
      "type": "string",
      "pattern": "^(https://metadata\\.datadrivendiscovery\\.org/types/|http://schema\\.org/)[A-Za-z0-9]+$",
      "description": "A D3M semantic type URI as D3M metadata writes it, for example https://metadata.datadrivendiscovery.org/types/FileName or http://schema.org/email"
    },
    "sherlockType": {
      "description": "One of the 78 Sherlock semantic types, spelled as the trained model returns it (model_files/classes_sherlock.npy of mitmedialab/sherlock-project), for example city or birth Date",
      "enum": [
        "address", "affiliate", "affiliation", "age", "album", "area", "artist", "birth Date",
        "birth Place", "brand", "capacity", "category", "city", "class", "classification", "club",
        "code", "collection", "command", "company", "component", "continent", "country", "county",
        "creator", "credit", "currency", "day", "depth", "description", "director", "duration",
        "education", "elevation", "family", "file Size", "format", "gender", "genre", "grades",
        "industry", "isbn", "jockey", "language", "location", "manufacturer", "name", "nationality",
        "notes", "operator", "order", "organisation", "origin", "owner", "person", "plays",
        "position", "product", "publisher", "range", "rank", "ranking", "region", "religion",
        "requirement", "result", "sales", "service", "sex", "species", "state", "status",
        "symbol", "team", "team Name", "type", "weight", "year"
      ]
    },
    "ftaType": {
      "type": "string",
      "pattern": "^[A-Z][A-Z0-9_]*(\\.[A-Z0-9][A-Z0-9_-]*)?(<(LANGUAGE|COUNTRY|LOCALE)>)?$",
      "description": "An FTA (Fast Text Analysis) semantic type as FTA documents it, for example EMAIL, COUNTRY.ISO-3166-2 or MONTH.FULL_<LOCALE>"
    },
    "gs1Ai": {
      "type": "string",
      "pattern": "^[0-9]{2,4}$",
      "description": "A GS1 Application Identifier as GS1 writes it, with its leading zeros and without parentheses, for example 01, 414 or 8003"
    },
    "orgidCode": {
      "type": "string",
      "pattern": "^[A-Z]{2}(_[A-Z]{2})?-[A-Z0-9]+(_[A-Z0-9]+)?$",
      "description": "An ORG-ID.guide list code, for example GB-COH, XI-LEI or CA_ON-ONT"
    },
    "qddateKey": {
      "type": "string",
      "pattern": "^dt:date:[a-z0-9_]+$",
      "description": "The key of a qddate date pattern (ivbeg/qddate, qddate/patterns), for example dt:date:date_2. Generated variants such as dt:date:date_2:time_1 are not mapped; crosswalk resolves them to their base pattern."
    },
    "bioregistryPrefix": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9_.-]*$",
      "description": "A normalized Bioregistry prefix, lowercase, for example chebi, ncbitaxon, pubchem.compound or iso.639-3"
    },
    "stdnumModule": {
      "type": "string",
      "pattern": "^(?!stdnum\\.)[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$",
      "description": "A python-stdnum module path without the stdnum. prefix, for example br.cpf, iban or in_.aadhaar"
    },
    "fhirSystem": {
      "type": "string",
      "pattern": "^(https?://[^\\s]+|urn:oid:[0-2](\\.[0-9]+)+|urn:(?!oid:)[a-z0-9][a-z0-9-]{0,31}:[^\\s]+)$",
      "description": "An HL7 FHIR identifier system: an http(s) URI, urn:oid: or another URN, for example http://hl7.org/fhir/sid/us-ssn or urn:dicom:uid"
    },
    "record": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {"$ref": "#/$defs/id"},
        "name": {"$ref": "#/$defs/nonEmptyString"},
        "status": {
          "enum": ["draft", "stable", "deprecated"],
          "description": "draft: not reviewed yet (for example generated from a rule key); stable: reviewed; deprecated: do not use, see replaced_by"
        },
        "doc": {"$ref": "#/$defs/nonEmptyString"},
        "semantic_type": {"$ref": "#/$defs/id", "description": "Patterns only: the datatype this pattern represents"},
        "parent": {"$ref": "#/$defs/id", "description": "A broader datatype"},
        "aliases": {"$ref": "#/$defs/idList", "description": "Former IDs of this record (for example after merging duplicates). They keep resolving forever."},
        "replaced_by": {"$ref": "#/$defs/id"},
        "categories": {
          "type": "array",
          "items": {"$ref": "#/$defs/id"},
          "minItems": 1,
          "uniqueItems": true,
          "description": "IDs from data/categories.yaml"
        },
        "country": {
          "type": "array",
          "items": {"type": "string", "pattern": "^[A-Z]{2}$"},
          "minItems": 1,
          "uniqueItems": true,
          "description": "Uppercase ISO 3166-1 alpha-2 codes from data/countries.yaml"
        },
        "langs": {
          "type": "array",
          "items": {"type": "string", "pattern": "^([a-z]{2}|common)$"},
          "minItems": 1,
          "uniqueItems": true,
          "description": "ISO 639-1 codes from data/langs.yaml; 'common' means language-independent"
        },
        "is_pii": {"type": "boolean"},
        "classification": {"enum": ["identifier", "categorical"]},
        "regexp": {"$ref": "#/$defs/nonEmptyString", "description": "Python re syntax; anchored with ^...$; no possessive quantifiers or atomic groups"},
        "checksum": {"$ref": "#/$defs/id", "description": "Name of the check-digit algorithm, for example luhn or iban_mod97"},
        "examples": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["value"],
            "properties": {
              "value": {"$ref": "#/$defs/nonEmptyString"},
              "description": {"$ref": "#/$defs/nonEmptyString"},
              "valid": {"type": "boolean", "description": "false marks a negative example: it must not match"}
            }
          }
        },
        "mappings": {
          "type": "object",
          "additionalProperties": false,
          "minProperties": 1,
          "properties": {
            "wikidata": {"type": "string", "pattern": "^[PQ][0-9]+$"},
            "fibo": {
              "description": "FIBO class: its IRI without the https://spec.edmcouncil.org/fibo/ontology/ prefix, e.g. FBC/ProductsAndServices/ClientsAndAccounts/InternationalBankAccountIdentifier",
              "oneOf": [
                {"$ref": "#/$defs/fiboPath"},
                {"type": "array", "items": {"$ref": "#/$defs/fiboPath"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "schema_org": {"$ref": "#/$defs/stringOrList"},
            "dpv": {"$ref": "#/$defs/stringOrList"},
            "presidio": {"$ref": "#/$defs/stringOrList"},
            "google_dlp": {"$ref": "#/$defs/stringOrList"},
            "purview": {"$ref": "#/$defs/stringOrList"},
            "d3m": {
              "description": "D3M semantic type URIs, for example http://schema.org/email",
              "oneOf": [
                {"$ref": "#/$defs/d3mType"},
                {"type": "array", "items": {"$ref": "#/$defs/d3mType"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "sherlock": {
              "description": "Sherlock semantic type labels, for example birth Date",
              "oneOf": [
                {"$ref": "#/$defs/sherlockType"},
                {"type": "array", "items": {"$ref": "#/$defs/sherlockType"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "autotype": {
              "description": "AutoType benchmark test cases (data_release file names without .txt), for example isbn or date-chinese",
              "oneOf": [
                {"$ref": "#/$defs/autotypeCase"},
                {"type": "array", "items": {"$ref": "#/$defs/autotypeCase"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "cdm": {
              "description": "Microsoft Common Data Model trait names, for example means.identity.service.email",
              "oneOf": [
                {"$ref": "#/$defs/cdmTrait"},
                {"type": "array", "items": {"$ref": "#/$defs/cdmTrait"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "fta": {
              "description": "FTA (Fast Text Analysis) semantic types, for example EMAIL or POSTAL_CODE.ZIP5_US. Locale-bound types keep FTA's <LANGUAGE>, <COUNTRY> or <LOCALE> placeholder.",
              "oneOf": [
                {"$ref": "#/$defs/ftaType"},
                {"type": "array", "items": {"$ref": "#/$defs/ftaType"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "gs1_ai": {
              "description": "GS1 Application Identifiers (https://ref.gs1.org/ai/) that this record represents, for example 8003. Each AI maps to at most one record: the element-string record of the AI when the registry has one, otherwise the record of the value the AI carries (8007 maps to iban).",
              "oneOf": [
                {"$ref": "#/$defs/gs1Ai"},
                {"type": "array", "items": {"$ref": "#/$defs/gs1Ai"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "orgid": {
              "description": "ORG-ID.guide list codes of the organization identifier lists that use this identifier, for example GB-COH. Deprecated codes that ORG-ID.guide replaced with a listed code may follow the current ones.",
              "oneOf": [
                {"$ref": "#/$defs/orgidCode"},
                {"type": "array", "items": {"$ref": "#/$defs/orgidCode"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "qddate": {
              "description": "Keys of the qddate date patterns that read this notation, for example dt:date:date_2. Each key maps to at most one record.",
              "oneOf": [
                {"$ref": "#/$defs/qddateKey"},
                {"type": "array", "items": {"$ref": "#/$defs/qddateKey"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "bioregistry": {
              "description": "Bioregistry (https://bioregistry.io) prefixes of the identifier resources whose local identifiers this record describes, for example chebi or ncbitaxon.",
              "oneOf": [
                {"$ref": "#/$defs/bioregistryPrefix"},
                {"type": "array", "items": {"$ref": "#/$defs/bioregistryPrefix"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "stdnum": {
              "description": "python-stdnum modules that validate this identifier, as the module path after stdnum., for example br.cpf, iban or in_.aadhaar.",
              "oneOf": [
                {"$ref": "#/$defs/stdnumModule"},
                {"type": "array", "items": {"$ref": "#/$defs/stdnumModule"}, "minItems": 1, "uniqueItems": true}
              ]
            },
            "fhir": {
              "description": "HL7 FHIR identifier system URIs (Identifier.system) for this identifier, as HL7 Terminology (terminology.hl7.org) or the base implementation guide of a national HL7 affiliate publishes them, for example http://hl7.org/fhir/sid/us-ssn or https://fhir.nhs.uk/Id/nhs-number.",
              "oneOf": [
                {"$ref": "#/$defs/fhirSystem"},
                {"type": "array", "items": {"$ref": "#/$defs/fhirSystem"}, "minItems": 1, "uniqueItems": true}
              ]
            }
          }
        },
        "links": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "url"],
            "properties": {
              "type": {"enum": ["wikipedia", "wikidata", "schema.org", "doc", "dublincore", "bioschemas", "datadrivendiscovery", "other"]},
              "url": {"type": "string", "pattern": "^https?://"}
            }
          }
        },
        "translations": {
          "type": "object",
          "minProperties": 1,
          "propertyNames": {"pattern": "^[a-z]{2}$"},
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "minProperties": 1,
            "properties": {
              "name": {"$ref": "#/$defs/nonEmptyString"},
              "doc": {"$ref": "#/$defs/nonEmptyString"}
            }
          }
        }
      }
    },
    "datatype": {
      "allOf": [{"$ref": "#/$defs/record"}],
      "required": ["id", "name", "status", "doc", "langs", "is_pii"],
      "not": {"required": ["semantic_type"]}
    },
    "pattern": {
      "allOf": [{"$ref": "#/$defs/record"}],
      "required": ["id", "name", "status", "doc", "semantic_type"]
    }
  }
}
