{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fingertrackid.dev/schemas/customer-outcome-request.v1.schema.json",
  "title": "CustomerOutcomeRequestV1",
  "$comment": "Generated from existing feedback OpenAPI components. Do not edit; regenerate locally. Generation does not establish validator parity, publication readiness, authentication or runtime availability.",
  "x-implementation-status": "generated-not-parity-validated",
  "x-ftid-generation": {
    "generator": "../../tools/generate-feedback-schemas.ts",
    "source_document": "../openapi/feedback.v1.yaml",
    "source_component": "#/components/schemas/CustomerOutcomeRequestV1",
    "source_openapi_version": "3.1.0",
    "source_info_version": "1.0.0",
    "source_sha256": "a1ade5a3364cd6b940eee85f84e5426eac702c47b461118ee449735320ac0789"
  },
  "x-ftid-raw-input-profile": {
    "content_encoding": "FORBIDDEN_INCLUDING_IDENTITY",
    "content_type": "application/json",
    "encoding": "UTF-8_WITHOUT_BOM",
    "lossless_effect": "../canonicalization/feedback-effect-v1.md",
    "maximum_body_bytes": 16384,
    "numeric_confidence": "A number must equal the exact decimal value of its parsed binary64 Number's\nshortest roundtrip decimal spelling. Equivalent exponent/trailing-zero forms\nare allowed; silent rounding and underflow are rejected. Positive and negative\nzero are one semantic value. The effect uses binary64 big-endian hex, not a\nrounded SQL numeric projection.\n",
    "raw_parser": "../../packages/contracts/src/feedback-raw-input-v1.ts",
    "reject": [
      "DUPLICATE_DECODED_MEMBERS",
      "UNKNOWN_MEMBERS",
      "NESTED_VALUES",
      "NUL",
      "UNPAIRED_SURROGATES",
      "TRAILING_DOCUMENT"
    ],
    "request_target": "EXACT_ORIGIN_FORM_NO_QUERY_NO_NORMALIZATION",
    "root": "ONE_CLOSED_FLAT_OBJECT"
  },
  "$ref": "#/$defs/CustomerOutcomeRequestV1",
  "$defs": {
    "CatalogCode": {
      "pattern": "^[A-Z][A-Z0-9_]{2,63}$",
      "type": "string"
    },
    "CustomerOutcomeRequestV1": {
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "truth_status": {
                "const": "PENDING"
              }
            }
          },
          "then": {
            "properties": {
              "label_maturity": {
                "const": "PROVISIONAL"
              }
            }
          }
        },
        {
          "else": {
            "properties": {
              "fraud_type": {
                "type": "null"
              }
            }
          },
          "if": {
            "properties": {
              "truth_status": {
                "const": "FRAUD_CONFIRMED"
              }
            }
          },
          "then": {
            "properties": {
              "fraud_type": {
                "$ref": "#/$defs/CatalogCode"
              }
            }
          }
        },
        {
          "oneOf": [
            {
              "properties": {
                "evidence_confidence": {
                  "type": "null"
                },
                "evidence_reference": {
                  "type": "null"
                },
                "evidence_source": {
                  "type": "null"
                }
              }
            },
            {
              "properties": {
                "evidence_confidence": {
                  "maximum": 1,
                  "minimum": 0,
                  "type": "number"
                },
                "evidence_reference": {
                  "minLength": 1,
                  "type": "string"
                },
                "evidence_source": {
                  "$ref": "#/$defs/CatalogCode"
                }
              }
            }
          ]
        },
        {
          "if": {
            "properties": {
              "truth_status": {
                "enum": ["LEGITIMATE", "FRAUD_CONFIRMED"]
              }
            }
          },
          "then": {
            "properties": {
              "evidence_confidence": {
                "type": "number"
              },
              "evidence_reference": {
                "type": "string"
              },
              "evidence_source": {
                "type": "string"
              }
            }
          }
        },
        {
          "else": {
            "properties": {
              "reason_code": {
                "not": {
                  "const": "INITIAL_OBSERVATION"
                }
              }
            }
          },
          "if": {
            "properties": {
              "corrects_external_outcome_id": {
                "type": "null"
              }
            }
          },
          "then": {
            "properties": {
              "reason_code": {
                "const": "INITIAL_OBSERVATION"
              }
            }
          }
        }
      ],
      "properties": {
        "corrects_external_outcome_id": {
          "anyOf": [
            {
              "$ref": "#/$defs/ExternalId"
            },
            {
              "type": "null"
            }
          ]
        },
        "evidence_confidence": {
          "maximum": 1,
          "minimum": 0,
          "type": ["number", "null"]
        },
        "evidence_reference": {
          "description": "Null or a string nonempty after ECMAScript trim; preserve source and never fetch this reference as a URL",
          "type": ["string", "null"],
          "x-ftid-nonempty-after-ecmascript-trim": true
        },
        "evidence_source": {
          "anyOf": [
            {
              "$ref": "#/$defs/CatalogCode"
            },
            {
              "type": "null"
            }
          ]
        },
        "external_outcome_id": {
          "$ref": "#/$defs/ExternalId"
        },
        "fraud_type": {
          "anyOf": [
            {
              "$ref": "#/$defs/CatalogCode"
            },
            {
              "type": "null"
            }
          ]
        },
        "idempotency_key": {
          "$ref": "#/$defs/IdempotencyKey"
        },
        "label_maturity": {
          "enum": ["PROVISIONAL", "MATURE"]
        },
        "observed_at": {
          "$ref": "#/$defs/SourceInstant"
        },
        "reason_code": {
          "enum": [
            "INITIAL_OBSERVATION",
            "EVIDENCE_MATURED",
            "STATUS_CORRECTED",
            "EVIDENCE_CORRECTED",
            "LABEL_RETRACTED"
          ]
        },
        "schema_version": {
          "const": "customer-outcome.v1"
        },
        "truth_status": {
          "enum": ["PENDING", "INSUFFICIENT_EVIDENCE", "LEGITIMATE", "FRAUD_CONFIRMED"]
        }
      },
      "required": [
        "schema_version",
        "external_outcome_id",
        "idempotency_key",
        "truth_status",
        "label_maturity",
        "fraud_type",
        "evidence_source",
        "evidence_reference",
        "evidence_confidence",
        "observed_at",
        "reason_code",
        "corrects_external_outcome_id"
      ],
      "type": "object",
      "x-ftid-cross-field": "external_outcome_id must differ from non-null corrects_external_outcome_id"
    },
    "ExternalId": {
      "description": "Opaque 1..255 UTF-16 code units, NOT Unicode code points. Supplementary\nscalars count as two units. Preserve whitespace and exact spelling; reject\nNUL and unpaired surrogates. maxLength alone is insufficient for this bound.\n",
      "maxLength": 255,
      "minLength": 1,
      "type": "string",
      "x-ftid-max-utf16-code-units": 255
    },
    "IdempotencyKey": {
      "maxLength": 255,
      "minLength": 8,
      "pattern": "^[\\x21-\\x7e]+$",
      "type": "string"
    },
    "SourceInstant": {
      "description": "Lossless existing Instante grammar; do not normalize, truncate or add a stricter RFC date-time format",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
      "type": "string"
    }
  }
}
