175 lines
8.7 KiB
JSON
175 lines
8.7 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://go-sip.local/contracts/proposals/config-read-v0.2.schema.json",
|
|
"title": "Project-local F01 contract: read-only configuration responses; external SaaS compatibility unverified",
|
|
"oneOf": [
|
|
{"$ref": "#/$defs/sip_response"},
|
|
{"$ref": "#/$defs/task_response"},
|
|
{"$ref": "#/$defs/tenant_quota_response"},
|
|
{"$ref": "#/$defs/error_response"}
|
|
],
|
|
"$defs": {
|
|
"sip_response": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["schema_version", "resource", "dispatcher_id", "revision", "approved_at", "trunks"],
|
|
"properties": {
|
|
"schema_version": {"const": "config-read.v0.2"},
|
|
"resource": {"const": "sip_config"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"revision": {"type": "integer", "minimum": 1},
|
|
"approved_at": {"type": "string", "format": "date-time"},
|
|
"trunks": {
|
|
"type": "array", "minItems": 1, "maxItems": 32,
|
|
"items": {"$ref": "#/$defs/trunk"}
|
|
}
|
|
}
|
|
},
|
|
"task_response": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["schema_version", "resource", "dispatcher_id", "tenant_id", "tenant_key", "task_id", "task_revision", "status", "max_concurrent_calls", "ring_timeout_ms", "max_call_duration_ms", "route_policy_id", "caller_profile_id", "allowed_trunk_ids", "schedule", "agent"],
|
|
"properties": {
|
|
"schema_version": {"const": "config-read.v0.1"},
|
|
"resource": {"const": "task_config"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"tenant_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"tenant_key": {"type": "string", "minLength": 1, "maxLength": 196, "$comment": "Validate <=196 UTF-8 bytes in business logic; preserve the original value and do not place tenant_key in queue/routing names."},
|
|
"task_id": {"type": "string", "pattern": "^[A-Za-z0-9_-]{1,128}$"},
|
|
"task_revision": {"type": "integer", "minimum": 1},
|
|
"status": {"enum": ["running", "paused", "stopped", "finished"]},
|
|
"name": {"type": "string", "minLength": 1, "maxLength": 256},
|
|
"group_id": {"type": ["string", "null"], "maxLength": 128},
|
|
"max_concurrent_calls": {"type": "integer", "minimum": 1},
|
|
"ring_timeout_ms": {"type": "integer", "minimum": 1},
|
|
"max_call_duration_ms": {"type": "integer", "minimum": 1},
|
|
"route_policy_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"caller_profile_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"allowed_trunk_ids": {"type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": {"type": "string", "minLength": 1, "maxLength": 128}},
|
|
"schedule": {"$ref": "#/$defs/task_schedule"},
|
|
"agent": {"$ref": "#/$defs/agent"}
|
|
}
|
|
},
|
|
"tenant_quota_response": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["schema_version", "resource", "dispatcher_id", "tenant_id", "tenant_key", "quota_revision", "max_concurrent_calls", "valid_until"],
|
|
"properties": {
|
|
"schema_version": {"const": "config-read.v0.1"},
|
|
"resource": {"const": "tenant_quota"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"tenant_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"tenant_key": {"type": "string", "minLength": 1, "maxLength": 196},
|
|
"quota_revision": {"type": "integer", "minimum": 1},
|
|
"max_concurrent_calls": {"type": "integer", "minimum": 0},
|
|
"valid_until": {"type": "string", "format": "date-time"}
|
|
},
|
|
"$comment": "Project-local response: assigned share for this Dispatcher, aggregated across all tasks of the tenant. Validate tenant_id/tenant_key mapping and valid_until in business logic."
|
|
},
|
|
"error_response": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["schema_version", "resource", "error"],
|
|
"properties": {
|
|
"schema_version": {"const": "config-read.v0.1"},
|
|
"resource": {"const": "error"},
|
|
"error": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["code", "message"],
|
|
"properties": {
|
|
"code": {"enum": ["invalid_request", "unauthorized", "dispatcher_not_authorized", "resource_not_found", "tenant_quota_unavailable", "service_unavailable"]},
|
|
"message": {"type": "string", "minLength": 1, "maxLength": 256}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"dispatcher_id": {
|
|
"type": "string", "format": "uuid",
|
|
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
|
},
|
|
"trunk": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["trunk_id", "provider_id", "egress_pool_id", "codec", "dial_prefix", "enabled", "server_host", "server_port", "transport", "auth_mode", "registration_required", "max_concurrent_calls", "caller_profiles", "schedule"],
|
|
"properties": {
|
|
"trunk_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"provider_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"egress_pool_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"codec": {"const": "PCMA"},
|
|
"dial_prefix": {"type": "string", "maxLength": 32},
|
|
"enabled": {"type": "boolean"},
|
|
"server_host": {"type": "string", "minLength": 1, "maxLength": 255},
|
|
"server_port": {"type": "integer", "minimum": 1, "maximum": 65535},
|
|
"transport": {"enum": ["udp", "tcp", "tls", null]},
|
|
"auth_mode": {"enum": ["ip", "digest", "none", null]},
|
|
"registration_required": {"type": ["boolean", "null"]},
|
|
"max_concurrent_calls": {"type": ["integer", "null"], "minimum": 1},
|
|
"caller_profiles": {
|
|
"type": "array", "minItems": 1, "maxItems": 32,
|
|
"items": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["caller_profile_id", "caller_id"],
|
|
"properties": {
|
|
"caller_profile_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"caller_id": {"type": "string", "minLength": 1, "maxLength": 64}
|
|
}
|
|
}
|
|
},
|
|
"schedule": {"$ref": "#/$defs/weekly_schedule"}
|
|
}
|
|
},
|
|
"agent": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["agent_version_id", "authorization_id", "authorization_expires_at", "config"],
|
|
"properties": {
|
|
"agent_version_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"authorization_id": {"type": "string", "minLength": 1, "maxLength": 128},
|
|
"authorization_expires_at": {"type": "string", "format": "date-time"},
|
|
"config": {"$ref": "https://go-sip.local/contracts/v1/ai-config.schema.json"}
|
|
}
|
|
},
|
|
"task_schedule": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["time_zone", "starts_at", "ends_at", "weekly_windows", "excluded_dates"],
|
|
"properties": {
|
|
"time_zone": {"const": "Asia/Shanghai"},
|
|
"starts_at": {"type": ["string", "null"], "format": "date-time"},
|
|
"ends_at": {"type": ["string", "null"], "format": "date-time"},
|
|
"weekly_windows": {"$ref": "#/$defs/weekly_windows"},
|
|
"excluded_dates": {
|
|
"type": "array", "uniqueItems": true,
|
|
"items": {"type": "string", "format": "date"}
|
|
}
|
|
}
|
|
},
|
|
"weekly_schedule": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["time_zone", "weekly_windows"],
|
|
"properties": {
|
|
"time_zone": {"const": "Asia/Shanghai"},
|
|
"weekly_windows": {"$ref": "#/$defs/weekly_windows"}
|
|
}
|
|
},
|
|
"weekly_windows": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
|
|
"properties": {
|
|
"monday": {"$ref": "#/$defs/windows"},
|
|
"tuesday": {"$ref": "#/$defs/windows"},
|
|
"wednesday": {"$ref": "#/$defs/windows"},
|
|
"thursday": {"$ref": "#/$defs/windows"},
|
|
"friday": {"$ref": "#/$defs/windows"},
|
|
"saturday": {"$ref": "#/$defs/windows"},
|
|
"sunday": {"$ref": "#/$defs/windows"}
|
|
}
|
|
},
|
|
"windows": {"type": "array", "items": {"$ref": "#/$defs/window"}, "$comment": "Each window is left-closed/right-open, start < end, and windows within a day must not overlap. Cross-midnight windows are split across two weekdays; 24:00 is allowed only as end."},
|
|
"window": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["start", "end"],
|
|
"properties": {
|
|
"start": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"},
|
|
"end": {"type": "string", "pattern": "^(?:(?:[01][0-9]|2[0-3]):[0-5][0-9]|24:00)$"}
|
|
}
|
|
}
|
|
}
|
|
}
|