{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://api.wealthglider.com/schemas/common-v1.json",
  "title": "WealthGlider Agent API common types",
  "$defs": {
    "RequestId": {
      "type": "string",
      "minLength": 8,
      "maxLength": 128
    },
    "Disclosure": {
      "type": "object",
      "additionalProperties": false,
      "required": ["code", "summary", "url"],
      "properties": {
        "code": { "type": "string", "minLength": 1, "maxLength": 64 },
        "summary": { "type": "string", "minLength": 1, "maxLength": 500 },
        "url": { "type": "string", "format": "uri" }
      }
    },
    "EditionMetadata": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "edition_id",
        "edition_date",
        "revision",
        "status",
        "published_at",
        "corrected_at",
        "methodology_version"
      ],
      "properties": {
        "edition_id": {
          "type": "string",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}\\.r[1-9][0-9]*$"
        },
        "edition_date": { "type": "string", "format": "date" },
        "revision": { "type": "integer", "minimum": 1 },
        "status": { "type": "string", "enum": ["published", "corrected"] },
        "published_at": { "type": "string", "format": "date-time" },
        "corrected_at": {
          "type": ["string", "null"],
          "format": "date-time"
        },
        "methodology_version": { "type": "string", "minLength": 1, "maxLength": 100 },
        "correction_reason": { "type": "string", "minLength": 1, "maxLength": 1000 }
      },
      "allOf": [
        {
          "if": { "properties": { "status": { "const": "corrected" } } },
          "then": {
            "required": ["correction_reason"],
            "properties": {
              "corrected_at": { "type": "string", "format": "date-time" },
              "correction_reason": { "type": "string", "minLength": 1, "maxLength": 1000 }
            }
          }
        }
      ]
    },
    "Access": {
      "type": "object",
      "additionalProperties": false,
      "required": ["level", "limits_applied", "served_count", "total_available"],
      "properties": {
        "level": { "type": "string", "enum": ["public", "free", "trial", "premium", "commercial"] },
        "limits_applied": { "type": "boolean" },
        "served_count": { "type": "integer", "minimum": 0 },
        "total_available": { "type": "integer", "minimum": 0 }
      }
    },
    "Evidence": {
      "type": "object",
      "additionalProperties": false,
      "required": ["signal_score"],
      "properties": {
        "historical_hit": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "direction": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
        "signal_score": { "type": "number", "minimum": 0, "maximum": 1 }
      }
    },
    "Driver": {
      "type": "object",
      "additionalProperties": false,
      "required": ["key", "label", "value", "interpretation"],
      "properties": {
        "key": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "maxLength": 100 },
        "label": { "type": "string", "minLength": 1, "maxLength": 160 },
        "value": { "type": "number", "minimum": 0, "maximum": 1 },
        "interpretation": { "type": "string", "minLength": 1, "maxLength": 500 }
      }
    },
    "Outcome": {
      "type": "object",
      "additionalProperties": false,
      "required": ["status", "evaluated_at"],
      "properties": {
        "status": { "type": "string", "enum": ["pending", "hit", "miss", "unscorable"] },
        "evaluated_at": { "type": ["string", "null"], "format": "date-time" },
        "checked_through": { "type": "string", "format": "date" },
        "sessions_elapsed": { "type": "integer", "minimum": 0, "maximum": 500 },
        "horizon_sessions": { "type": "integer", "minimum": 1, "maximum": 500 },
        "hit_date": { "type": "string", "format": "date" },
        "time_to_target_sessions": { "type": "integer", "minimum": 1, "maximum": 500 },
        "reason": { "type": "string", "minLength": 1, "maxLength": 500 }
      },
      "allOf": [
        {
          "if": { "properties": { "status": { "enum": ["hit", "miss", "unscorable"] } } },
          "then": { "properties": { "evaluated_at": { "type": "string", "format": "date-time" } } }
        }
      ]
    },
    "ReferencePrice": {
      "type": "object",
      "additionalProperties": false,
      "required": ["amount", "currency", "price_date", "price_type", "adjustment", "dividends_included"],
      "properties": {
        "amount": { "type": "number", "exclusiveMinimum": 0 },
        "currency": { "const": "USD" },
        "price_date": { "type": "string", "format": "date" },
        "price_type": { "const": "official_close" },
        "adjustment": { "const": "split_adjusted_price_return" },
        "dividends_included": { "const": false }
      }
    },
    "TargetPrice": {
      "type": "object",
      "additionalProperties": false,
      "required": ["amount", "currency"],
      "properties": {
        "amount": { "type": "number", "exclusiveMinimum": 0 },
        "currency": { "const": "USD" }
      }
    },
    "Recommendation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "signal_id",
        "edition_id",
        "edition_date",
        "symbol",
        "exchange",
        "classification",
        "category",
        "target_move_pct",
        "horizon_business_days",
        "signal_summary",
        "evidence",
        "drivers",
        "outcome"
      ],
      "properties": {
        "signal_id": { "type": "string", "minLength": 8, "maxLength": 160 },
        "edition_id": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}\\.r[1-9][0-9]*$" },
        "edition_date": { "type": "string", "format": "date" },
        "symbol": { "type": "string", "pattern": "^[A-Z0-9.\\-]{1,20}$" },
        "exchange": { "type": "string", "pattern": "^[A-Z0-9._\\-]{1,20}$" },
        "classification": { "type": "string", "enum": ["buy", "sell"] },
        "category": { "type": "string", "minLength": 1, "maxLength": 100 },
        "target_move_pct": {
          "type": "number",
          "minimum": -1,
          "maximum": 1,
          "not": { "const": 0 }
        },
        "reference_price": { "$ref": "#/$defs/ReferencePrice" },
        "target_price": { "$ref": "#/$defs/TargetPrice" },
        "horizon_business_days": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "description": "Legacy field name for the number of later observed trading sessions in the evaluation window."
        },
        "signal_summary": { "type": "string", "minLength": 1, "maxLength": 2000 },
        "evidence": { "$ref": "#/$defs/Evidence" },
        "drivers": {
          "type": "array",
          "minItems": 1,
          "maxItems": 10,
          "items": { "$ref": "#/$defs/Driver" }
        },
        "outcome": { "$ref": "#/$defs/Outcome" }
      }
    },
    "CursorPage": {
      "type": "object",
      "additionalProperties": false,
      "required": ["next_cursor", "has_more"],
      "properties": {
        "next_cursor": { "type": ["string", "null"], "minLength": 1, "maxLength": 1000 },
        "has_more": { "type": "boolean" }
      }
    },
    "AgentResolution": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "message_for_user", "requires_human_action"],
      "properties": {
        "kind": {
          "type": "string",
          "enum": ["subscribe", "renew_subscription", "upgrade_plan", "authorize_scope", "wait_or_upgrade"]
        },
        "message_for_user": { "type": "string", "minLength": 1, "maxLength": 1000 },
        "pricing_url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://www\\.wealthglider\\.com/pricing\\?source=agent_api&reason=(premium_required|trial_expired|quota_exceeded)$"
        },
        "sign_in_url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://www\\.wealthglider\\.com/login\\?source=agent_api&reason=(premium_required|trial_expired)$"
        },
        "sample_url": { "const": "https://api.wealthglider.com/v1/samples/latest" },
        "account_url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://www\\.wealthglider\\.com/(pricing|apikey)\\?source=agent_api&reason=(trial_expired|quota_exceeded)$"
        },
        "credential_url": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://www\\.wealthglider\\.com/apikey\\?source=agent_api&reason=scope_required$"
        },
        "required_scopes": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "type": "string",
            "enum": ["daily_recommendations:read", "historical_recommendations:read", "account:read"]
          }
        },
        "retry_after_seconds": { "type": "integer", "minimum": 1, "maximum": 604800 },
        "requires_human_action": { "const": true }
      }
    },
    "Problem": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type", "title", "status", "code", "detail", "request_id", "retryable"],
      "properties": {
        "type": { "type": "string", "format": "uri" },
        "title": { "type": "string", "minLength": 1, "maxLength": 200 },
        "status": { "type": "integer", "minimum": 400, "maximum": 599 },
        "code": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "maxLength": 100 },
        "detail": { "type": "string", "minLength": 1, "maxLength": 2000 },
        "request_id": { "$ref": "#/$defs/RequestId" },
        "retryable": { "type": "boolean" },
        "resolution": { "$ref": "#/$defs/AgentResolution" },
        "invalid_parameters": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": ["name", "reason"],
            "properties": {
              "name": { "type": "string", "minLength": 1, "maxLength": 200 },
              "reason": { "type": "string", "minLength": 1, "maxLength": 500 }
            }
          }
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "code": {
                "enum": ["premium_required", "trial_expired", "quota_exceeded", "scope_required"]
              }
            },
            "required": ["code"]
          },
          "then": {
            "required": ["resolution"],
            "properties": {
              "resolution": { "$ref": "#/$defs/AgentResolution" }
            }
          }
        },
        {
          "if": { "properties": { "code": { "const": "premium_required" } }, "required": ["code"] },
          "then": {
            "properties": {
              "resolution": {
                "type": "object",
                "required": ["kind", "pricing_url", "sign_in_url", "sample_url", "requires_human_action"],
                "properties": {
                  "kind": { "const": "subscribe" },
                  "pricing_url": { "type": "string" },
                  "sign_in_url": { "type": "string" },
                  "sample_url": { "type": "string" },
                  "requires_human_action": { "const": true }
                }
              }
            }
          }
        },
        {
          "if": { "properties": { "code": { "const": "trial_expired" } }, "required": ["code"] },
          "then": {
            "properties": {
              "resolution": {
                "type": "object",
                "required": ["kind", "pricing_url", "account_url", "sample_url", "requires_human_action"],
                "properties": {
                  "kind": { "const": "renew_subscription" },
                  "pricing_url": { "type": "string" },
                  "account_url": { "type": "string" },
                  "sample_url": { "type": "string" },
                  "requires_human_action": { "const": true }
                }
              }
            }
          }
        },
        {
          "if": { "properties": { "code": { "const": "quota_exceeded" } }, "required": ["code"] },
          "then": {
            "properties": {
              "resolution": {
                "type": "object",
                "required": ["kind", "pricing_url", "account_url", "retry_after_seconds", "requires_human_action"],
                "properties": {
                  "kind": { "const": "wait_or_upgrade" },
                  "pricing_url": { "type": "string" },
                  "account_url": { "type": "string" },
                  "retry_after_seconds": { "type": "integer" },
                  "requires_human_action": { "const": true }
                }
              }
            }
          }
        },
        {
          "if": { "properties": { "code": { "const": "scope_required" } }, "required": ["code"] },
          "then": {
            "properties": {
              "resolution": {
                "type": "object",
                "required": ["kind", "credential_url", "required_scopes", "requires_human_action"],
                "properties": {
                  "kind": { "const": "authorize_scope" },
                  "credential_url": { "type": "string" },
                  "required_scopes": { "type": "array" },
                  "requires_human_action": { "const": true }
                }
              }
            }
          }
        }
      ]
    }
  }
}
