{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://trove.local/schemas/service-contract.schema.json",
  "title": "Trove Service Contract v1",
  "type": "object",
  "required": ["schemaVersion", "service", "version", "methods"],
  "properties": {
    "schemaVersion": { "const": 1 },
    "service": {
      "type": "string",
      "minLength": 3,
      "maxLength": 240,
      "pattern": "^[a-z0-9][a-z0-9.-]*[a-z0-9]$"
    },
    "version": {
      "type": "string",
      "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
    },
    "description": { "type": "string", "maxLength": 2000 },
    "methods": {
      "type": "object",
      "propertyNames": { "pattern": "^[A-Za-z][A-Za-z0-9_]*$" },
      "additionalProperties": { "$ref": "#/$defs/method" }
    },
    "events": {
      "type": "object",
      "propertyNames": { "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$" },
      "additionalProperties": { "$ref": "#/$defs/event" },
      "default": {}
    }
  },
  "additionalProperties": false,
  "$defs": {
    "jsonSchema": {
      "type": "object"
    },
    "method": {
      "type": "object",
      "required": ["params", "result"],
      "properties": {
        "description": { "type": "string", "maxLength": 2000 },
        "params": { "$ref": "#/$defs/jsonSchema" },
        "result": { "$ref": "#/$defs/jsonSchema" },
        "timeoutMs": {
          "type": "integer",
          "minimum": 1,
          "maximum": 86400000
        },
        "idempotent": { "type": "boolean", "default": false }
      },
      "additionalProperties": false
    },
    "event": {
      "type": "object",
      "required": ["params", "payload"],
      "properties": {
        "description": { "type": "string", "maxLength": 2000 },
        "params": { "$ref": "#/$defs/jsonSchema" },
        "payload": { "$ref": "#/$defs/jsonSchema" },
        "coalesce": {
          "type": "string",
          "enum": ["none", "latest"],
          "default": "none"
        }
      },
      "additionalProperties": false
    }
  }
}
