{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://vetdatastandards.com/schemas/v0.1/common.schema.json",
  "title": "Vet Data Standard v0.1 common definitions",
  "description": "Shared definitions for the v0.1 snapshot interchange standard. These definitions are not a vendor database schema.",
  "$defs": {
    "id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "^\\S(?:.*\\S)?$",
      "description": "Identifier unique within one entity collection in this payload. Not required to be a UUID. Relationships use these ids."
    },
    "source": {
      "type": "object",
      "additionalProperties": false,
      "required": ["system", "recordId"],
      "description": "Provenance of this record in the system that produced it. See PROVENANCE.md.",
      "properties": {
        "system": {
          "type": "string",
          "minLength": 3,
          "maxLength": 253,
          "pattern": "^[a-z0-9-]+(\\.[a-z0-9-]+)+$",
          "description": "Reverse-domain identifier of the source system, such as com.example.pims."
        },
        "recordId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512,
          "pattern": "^\\S(?:.*\\S)?$",
          "description": "Native source identifier, or a syn1_ synthetic id when the source row has no native id."
        },
        "recordIdMethod": {
          "type": "string",
          "enum": ["native", "synthetic-v1"],
          "description": "How recordId was chosen. Required for new adapters."
        },
        "instance": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "description": "Optional source database, tenant, or file name when recordId is only unique inside that instance."
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        },
        "contentHash": {
          "type": "string",
          "pattern": "^sha256:[a-f0-9]{64}$"
        },
        "exportedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    "matchKeys": {
      "type": "array",
      "description": "Optional duplicate-detection hints. Each entry is kind:value.",
      "items": {
        "type": "string",
        "minLength": 3,
        "maxLength": 512,
        "pattern": "^[a-z0-9-]+:\\S(?:.*\\S)?$"
      }
    },
    "extensions": {
      "type": "object",
      "description": "Vendor-specific data. Keys are reverse-domain names. The core validator does not interpret values.",
      "propertyNames": {
        "pattern": "^[a-z0-9-]+(\\.[a-z0-9-]+)+$"
      },
      "additionalProperties": true
    },
    "date": {
      "type": "string",
      "format": "date"
    },
    "dateTime": {
      "type": "string",
      "format": "date-time"
    },
    "decimal": {
      "type": "string",
      "pattern": "^-?\\d+(\\.\\d{1,4})?$",
      "description": "Decimal amount as a string, up to 4 decimal places. JSON numbers are rejected."
    },
    "nonNegativeDecimal": {
      "type": "string",
      "pattern": "^\\d+(\\.\\d{1,4})?$"
    },
    "taxPercent": {
      "type": "string",
      "pattern": "^\\d+(\\.\\d{1,4})?$",
      "description": "Tax rate as a percentage. 20 means 20 percent."
    },
    "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "description": "ISO 4217 alphabetic code."
    },
    "country": {
      "type": "string",
      "pattern": "^[A-Z]{2}$",
      "description": "ISO 3166-1 alpha-2."
    },
    "money": {
      "type": "object",
      "additionalProperties": false,
      "required": ["amount", "currency"],
      "properties": {
        "amount": { "$ref": "#/$defs/decimal" },
        "currency": { "$ref": "#/$defs/currency" },
        "currencyRaw": {
          "type": "string",
          "minLength": 1,
          "maxLength": 32
        }
      }
    },
    "address": {
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "addressLine1": { "type": "string", "minLength": 1, "maxLength": 128 },
        "addressLine2": { "type": "string", "minLength": 1, "maxLength": 128 },
        "locality": { "type": "string", "minLength": 1, "maxLength": 128 },
        "region": { "type": "string", "minLength": 1, "maxLength": 128 },
        "postalCode": { "type": "string", "minLength": 1, "maxLength": 32 },
        "country": { "$ref": "#/$defs/country" },
        "countryRaw": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        }
      }
    },
    "rawText": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "recordBaseProperties": {
      "id": { "$ref": "#/$defs/id" },
      "source": { "$ref": "#/$defs/source" },
      "matchKeys": { "$ref": "#/$defs/matchKeys" },
      "createdAt": { "$ref": "#/$defs/dateTime" },
      "updatedAt": { "$ref": "#/$defs/dateTime" },
      "deletedAt": { "$ref": "#/$defs/dateTime" },
      "active": { "type": "boolean" },
      "extensions": { "$ref": "#/$defs/extensions" }
    }
  }
}
