{
  "components": {
    "parameters": {
      "DateFrom": {
        "in": "query",
        "name": "from",
        "schema": {
          "format": "date-time",
          "type": "string"
        }
      },
      "DateTo": {
        "in": "query",
        "name": "to",
        "schema": {
          "format": "date-time",
          "type": "string"
        }
      },
      "Page": {
        "in": "query",
        "name": "page",
        "schema": {
          "default": 1,
          "minimum": 1,
          "type": "integer"
        }
      },
      "PageSize": {
        "in": "query",
        "name": "page_size",
        "schema": {
          "default": 20,
          "maximum": 100,
          "minimum": 1,
          "type": "integer"
        }
      },
      "ResourceID": {
        "in": "path",
        "name": "id",
        "required": true,
        "schema": {
          "format": "uuid",
          "type": "string"
        }
      }
    },
    "responses": {
      "Forbidden": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Insufficient permissions"
      },
      "NotFound": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Resource not found"
      },
      "RateLimited": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Rate limit exceeded",
        "headers": {
          "Retry-After": {
            "description": "Seconds until rate limit resets",
            "schema": {
              "type": "integer"
            }
          }
        }
      },
      "Unauthorized": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Authentication required or token invalid"
      },
      "ValidationError": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Validation error"
      }
    },
    "schemas": {
      "Alert": {
        "properties": {
          "assigned_to": {
            "format": "uuid",
            "type": "string"
          },
          "client_id": {
            "format": "uuid",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "resolution": {
            "type": "string"
          },
          "resolved_at": {
            "format": "date-time",
            "type": "string"
          },
          "severity": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "status": {
            "enum": [
              "open",
              "assigned",
              "resolved",
              "escalated"
            ],
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "transaction_id": {
            "format": "uuid",
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "AnalysisResult": {
        "properties": {
          "decision": {
            "enum": [
              "approved",
              "blocked",
              "review"
            ],
            "type": "string"
          },
          "dimensions": {
            "description": "5-dimension score breakdown",
            "properties": {
              "behavioral": {
                "type": "number"
              },
              "compliance": {
                "type": "number"
              },
              "device": {
                "type": "number"
              },
              "network": {
                "type": "number"
              },
              "transactional": {
                "type": "number"
              }
            },
            "type": "object"
          },
          "latency_ms": {
            "type": "integer"
          },
          "risk_level": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "rules_triggered": {
            "items": {
              "properties": {
                "rule_id": {
                  "type": "string"
                },
                "rule_name": {
                  "type": "string"
                },
                "score_impact": {
                  "type": "number"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "transaction_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "AnalyzeRequest": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "blockchain": {
            "type": "string"
          },
          "client_id": {
            "format": "uuid",
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "from_address": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          },
          "to_address": {
            "type": "string"
          },
          "tx_hash": {
            "type": "string"
          },
          "type": {
            "enum": [
              "deposit",
              "withdrawal",
              "transfer",
              "swap",
              "staking"
            ],
            "type": "string"
          }
        },
        "required": [
          "client_id",
          "type",
          "amount",
          "currency"
        ],
        "type": "object"
      },
      "BillingPlan": {
        "properties": {
          "api_calls_limit": {
            "type": "integer"
          },
          "features": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "id": {
            "type": "string"
          },
          "modules": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "price_brl": {
            "type": "number"
          },
          "price_usd": {
            "type": "number"
          },
          "transactions_limit": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "BillingUsage": {
        "properties": {
          "api_calls": {
            "type": "integer"
          },
          "api_calls_limit": {
            "type": "integer"
          },
          "period": {
            "properties": {
              "from": {
                "format": "date",
                "type": "string"
              },
              "to": {
                "format": "date",
                "type": "string"
              }
            },
            "type": "object"
          },
          "plan": {
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "transactions_analyzed": {
            "type": "integer"
          },
          "transactions_limit": {
            "type": "integer"
          },
          "wallets_screened": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "BlockchainEvent": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "blockchain": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "event_type": {
            "enum": [
              "large_transfer",
              "sanctions_hit",
              "mixer_detected",
              "bridge_transfer"
            ],
            "type": "string"
          },
          "from_address": {
            "type": "string"
          },
          "risk_indicators": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "timestamp": {
            "format": "date-time",
            "type": "string"
          },
          "to_address": {
            "type": "string"
          },
          "tx_hash": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "Case": {
        "properties": {
          "assigned_to": {
            "format": "uuid",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "created_by": {
            "format": "uuid",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "findings": {
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "priority": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "related_alerts": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "related_clients": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "related_transactions": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "resolution": {
            "type": "string"
          },
          "resolved_at": {
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "enum": [
              "open",
              "in_progress",
              "resolved",
              "escalated",
              "closed"
            ],
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CatalogEntry": {
        "description": "Linha de snx_module_catalog. Fonte de verdade comercial para\npreços, quota inclusa, trial default, dependências e mapeamento\nregulatório (qual norma BR cada módulo atende).\n",
        "properties": {
          "base_price_cents": {
            "description": "Preço base mensal em centavos BRL",
            "format": "int64",
            "type": "integer"
          },
          "billing_model": {
            "enum": [
              "MONTHLY_FIXED",
              "PER_USAGE",
              "HYBRID",
              "FREE_WITH_PLAN"
            ],
            "type": "string"
          },
          "category": {
            "enum": [
              "core",
              "identity",
              "onchain",
              "regulatory",
              "compliance",
              "fraud",
              "forensics",
              "intelligence",
              "analytics",
              "operations",
              "commercial",
              "support"
            ],
            "type": "string"
          },
          "code": {
            "example": "mod_crypto_kyt",
            "type": "string"
          },
          "color_hint": {
            "nullable": true,
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "dependencies": {
            "example": [
              "mod_crypto_core",
              "mod_crypto_kyt"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "display_name": {
            "type": "string"
          },
          "feature_bullets": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "icon_hint": {
            "description": "lucide-react icon name",
            "nullable": true,
            "type": "string"
          },
          "included_quota": {
            "description": "Quantidade inclusa no base_price (0 = ilimitado)",
            "type": "integer"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_addon": {
            "type": "boolean"
          },
          "is_public_catalog": {
            "type": "boolean"
          },
          "long_description": {
            "type": "string"
          },
          "overage_price_cents": {
            "format": "int64",
            "type": "integer"
          },
          "overage_unit": {
            "example": "transacao",
            "nullable": true,
            "type": "string"
          },
          "plan_tier_minimum": {
            "enum": [
              "starter",
              "pro",
              "scale",
              "enterprise",
              "regtech"
            ],
            "nullable": true,
            "type": "string"
          },
          "regulatory_mapping": {
            "description": "Códigos das normas BR que este módulo atende",
            "example": [
              "BCB_RES_521_KYT",
              "COAF_LEI_9613_ART_10A"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "requires_super_admin_activation": {
            "type": "boolean"
          },
          "short_description": {
            "type": "string"
          },
          "sort_order": {
            "type": "integer"
          },
          "trial_days_default": {
            "maximum": 90,
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ChargebackEvent": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "reason_code": {
            "type": "string"
          },
          "timestamp": {
            "format": "date-time",
            "type": "string"
          },
          "transaction_ref": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "Client": {
        "properties": {
          "blocked": {
            "type": "boolean"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "document_hash": {
            "description": "SHA-256 hash of CPF/CNPJ (never plain text)",
            "type": "string"
          },
          "email_hash": {
            "description": "SHA-256 hash of email (never plain text)",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "kyc_status": {
            "enum": [
              "pending",
              "verified",
              "rejected",
              "expired"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "pep": {
            "type": "boolean"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "risk_tier": {
            "enum": [
              "GREEN",
              "AMBER",
              "RED"
            ],
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "type": {
            "enum": [
              "individual",
              "corporate"
            ],
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreateCaseRequest": {
        "properties": {
          "description": {
            "type": "string"
          },
          "priority": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "related_alerts": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "related_clients": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "related_transactions": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          },
          "title": {
            "type": "string"
          }
        },
        "required": [
          "title",
          "description"
        ],
        "type": "object"
      },
      "CreateClientRequest": {
        "properties": {
          "document": {
            "description": "CPF or CNPJ (will be hashed server-side)",
            "type": "string"
          },
          "email": {
            "format": "email",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "risk_tier": {
            "enum": [
              "GREEN",
              "AMBER",
              "RED"
            ],
            "type": "string"
          },
          "type": {
            "enum": [
              "individual",
              "corporate"
            ],
            "type": "string"
          }
        },
        "required": [
          "name",
          "type",
          "document",
          "email"
        ],
        "type": "object"
      },
      "CreateTenantRequest": {
        "properties": {
          "admin_email": {
            "format": "email",
            "type": "string"
          },
          "admin_name": {
            "type": "string"
          },
          "modules": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "slug": {
            "pattern": "^[a-z0-9-]+$",
            "type": "string"
          }
        },
        "required": [
          "name",
          "slug",
          "plan"
        ],
        "type": "object"
      },
      "CreateUserRequest": {
        "properties": {
          "email": {
            "format": "email",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "enum": [
              "TENANT_ADMIN",
              "COMPLIANCE",
              "ANALYST",
              "VIEWER",
              "API_SERVICE"
            ],
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "email",
          "name",
          "role",
          "tenant_id"
        ],
        "type": "object"
      },
      "DashboardMetrics": {
        "properties": {
          "daily_volume": {
            "items": {
              "properties": {
                "amount": {
                  "type": "number"
                },
                "count": {
                  "type": "integer"
                },
                "date": {
                  "format": "date",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "risk_distribution": {
            "properties": {
              "critical": {
                "type": "integer"
              },
              "high": {
                "type": "integer"
              },
              "low": {
                "type": "integer"
              },
              "medium": {
                "type": "integer"
              }
            },
            "type": "object"
          },
          "top_rules_triggered": {
            "items": {
              "properties": {
                "count": {
                  "type": "integer"
                },
                "rule_id": {
                  "type": "string"
                },
                "rule_name": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "DashboardSummary": {
        "properties": {
          "avg_risk_score": {
            "format": "float",
            "type": "number"
          },
          "open_alerts": {
            "type": "integer"
          },
          "period": {
            "properties": {
              "from": {
                "format": "date-time",
                "type": "string"
              },
              "to": {
                "format": "date-time",
                "type": "string"
              }
            },
            "type": "object"
          },
          "total_alerts": {
            "type": "integer"
          },
          "total_transactions": {
            "type": "integer"
          },
          "transactions_blocked": {
            "type": "integer"
          },
          "transactions_review": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "DeviceInfo": {
        "properties": {
          "anomalies": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "device_id": {
            "format": "uuid",
            "type": "string"
          },
          "fingerprint_hash": {
            "type": "string"
          },
          "first_seen": {
            "format": "date-time",
            "type": "string"
          },
          "ip_history": {
            "items": {
              "properties": {
                "geo": {
                  "type": "string"
                },
                "ip": {
                  "type": "string"
                },
                "seen_at": {
                  "format": "date-time",
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "last_seen": {
            "format": "date-time",
            "type": "string"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "user_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ErrorResponse": {
        "properties": {
          "code": {
            "type": "string"
          },
          "details": {
            "type": "object"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "EscalationEvent": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "escalated_by_user_id": {
            "format": "uuid",
            "type": "string"
          },
          "escalated_to_user_id": {
            "format": "uuid",
            "type": "string"
          },
          "event_type": {
            "description": "rejected = reverse-escalate (B9 Wave 3 2026-05-19)",
            "enum": [
              "escalation",
              "acceptance",
              "resolution",
              "reassignment",
              "rejected"
            ],
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "parent_escalation_id": {
            "format": "uuid",
            "nullable": true,
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "resource_id": {
            "format": "uuid",
            "type": "string"
          },
          "resource_type": {
            "enum": [
              "alert",
              "case"
            ],
            "type": "string"
          },
          "severity_after": {
            "type": "string"
          },
          "severity_before": {
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "id",
          "tenant_id",
          "resource_type",
          "resource_id",
          "escalated_by_user_id",
          "escalated_to_user_id",
          "reason",
          "event_type",
          "created_at"
        ],
        "type": "object"
      },
      "ExplainFactor": {
        "properties": {
          "description": {
            "type": "string"
          },
          "impact": {
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ExplainResponse": {
        "properties": {
          "decision": {
            "type": "string"
          },
          "dimensions": {
            "properties": {
              "behavioral": {
                "properties": {
                  "factors": {
                    "items": {
                      "$ref": "#/components/schemas/ExplainFactor"
                    },
                    "type": "array"
                  },
                  "score": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "compliance": {
                "properties": {
                  "factors": {
                    "items": {
                      "$ref": "#/components/schemas/ExplainFactor"
                    },
                    "type": "array"
                  },
                  "score": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "device": {
                "properties": {
                  "factors": {
                    "items": {
                      "$ref": "#/components/schemas/ExplainFactor"
                    },
                    "type": "array"
                  },
                  "score": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "network": {
                "properties": {
                  "factors": {
                    "items": {
                      "$ref": "#/components/schemas/ExplainFactor"
                    },
                    "type": "array"
                  },
                  "score": {
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "transactional": {
                "properties": {
                  "factors": {
                    "items": {
                      "$ref": "#/components/schemas/ExplainFactor"
                    },
                    "type": "array"
                  },
                  "score": {
                    "type": "number"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "overall_score": {
            "format": "float",
            "type": "number"
          },
          "rules_triggered": {
            "items": {
              "properties": {
                "description": {
                  "type": "string"
                },
                "evidence": {
                  "type": "string"
                },
                "rule_id": {
                  "type": "string"
                },
                "rule_name": {
                  "type": "string"
                },
                "score_impact": {
                  "type": "number"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "transaction_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "FingerprintPayload": {
        "properties": {
          "audio_hash": {
            "type": "string"
          },
          "canvas_hash": {
            "type": "string"
          },
          "font_hash": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "plugins": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "screen": {
            "properties": {
              "color_depth": {
                "type": "integer"
              },
              "height": {
                "type": "integer"
              },
              "width": {
                "type": "integer"
              }
            },
            "type": "object"
          },
          "timezone": {
            "type": "string"
          },
          "touch_support": {
            "type": "boolean"
          },
          "user_agent": {
            "type": "string"
          },
          "webgl_hash": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GenerateReportRequest": {
        "properties": {
          "filters": {
            "description": "Optional filters for report content",
            "type": "object"
          },
          "period_from": {
            "format": "date",
            "type": "string"
          },
          "period_to": {
            "format": "date",
            "type": "string"
          },
          "type": {
            "enum": [
              "sar",
              "decripto",
              "bcb_fx",
              "coaf",
              "custom"
            ],
            "type": "string"
          }
        },
        "required": [
          "type",
          "period_from",
          "period_to"
        ],
        "type": "object"
      },
      "HealthResponse": {
        "properties": {
          "checks": {
            "properties": {
              "database": {
                "type": "string"
              },
              "kafka": {
                "type": "string"
              },
              "redis": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "status": {
            "enum": [
              "healthy",
              "degraded",
              "unhealthy"
            ],
            "type": "string"
          },
          "uptime": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "LoginRequest": {
        "properties": {
          "device_fingerprint": {
            "type": "string"
          },
          "email": {
            "format": "email",
            "type": "string"
          },
          "password": {
            "format": "password",
            "type": "string"
          }
        },
        "required": [
          "email",
          "password"
        ],
        "type": "object"
      },
      "LoginResponse": {
        "properties": {
          "access_token": {
            "description": "JWT access token (when mfa_required=false)",
            "type": "string"
          },
          "mfa_required": {
            "type": "boolean"
          },
          "mfa_token": {
            "description": "Temporary token for MFA verification (when mfa_required=true)",
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MFAVerifyRequest": {
        "properties": {
          "code": {
            "pattern": "^[0-9]{6}$",
            "type": "string"
          },
          "mfa_token": {
            "type": "string"
          }
        },
        "required": [
          "mfa_token",
          "code"
        ],
        "type": "object"
      },
      "PaginatedAlerts": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Alert"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "PaginatedCases": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Case"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "PaginatedClients": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Client"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "PaginatedReports": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Report"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "PaginatedTransactions": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Transaction"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "PaginatedWallets": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Wallet"
            },
            "type": "array"
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "type": "object"
      },
      "Pagination": {
        "properties": {
          "page": {
            "type": "integer"
          },
          "page_size": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "RadarHotspots": {
        "properties": {
          "hotspots": {
            "items": {
              "properties": {
                "avg_risk_score": {
                  "format": "float",
                  "type": "number"
                },
                "event_count": {
                  "type": "integer"
                },
                "geo": {
                  "properties": {
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "lat": {
                      "type": "number"
                    },
                    "lng": {
                      "type": "number"
                    }
                  },
                  "type": "object"
                },
                "top_risk_types": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                }
              },
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "RadarLive": {
        "properties": {
          "events": {
            "items": {
              "properties": {
                "amount": {
                  "type": "number"
                },
                "currency": {
                  "type": "string"
                },
                "geo": {
                  "properties": {
                    "country": {
                      "type": "string"
                    },
                    "lat": {
                      "type": "number"
                    },
                    "lng": {
                      "type": "number"
                    }
                  },
                  "type": "object"
                },
                "risk_level": {
                  "type": "string"
                },
                "risk_score": {
                  "format": "float",
                  "type": "number"
                },
                "timestamp": {
                  "format": "date-time",
                  "type": "string"
                },
                "transaction_id": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "Report": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "created_by": {
            "format": "uuid",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "period_from": {
            "format": "date",
            "type": "string"
          },
          "period_to": {
            "format": "date",
            "type": "string"
          },
          "status": {
            "enum": [
              "generating",
              "ready",
              "submitted",
              "accepted",
              "rejected"
            ],
            "type": "string"
          },
          "submitted_at": {
            "format": "date-time",
            "type": "string"
          },
          "submitted_to": {
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "enum": [
              "sar",
              "decripto",
              "bcb_fx",
              "coaf",
              "custom"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "ReviewRequest": {
        "properties": {
          "decision": {
            "enum": [
              "approve",
              "block"
            ],
            "type": "string"
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "decision",
          "reason"
        ],
        "type": "object"
      },
      "ReviewResponse": {
        "properties": {
          "decision": {
            "type": "string"
          },
          "reviewed_at": {
            "format": "date-time",
            "type": "string"
          },
          "reviewed_by": {
            "format": "uuid",
            "type": "string"
          },
          "transaction_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Rule": {
        "properties": {
          "category": {
            "enum": [
              "base",
              "crypto",
              "advanced"
            ],
            "type": "string"
          },
          "conditions": {
            "description": "Grule DSL expression",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "score_impact": {
            "type": "number"
          },
          "severity": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "shadow": {
            "description": "Shadow mode: logs but does not enforce",
            "type": "boolean"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SystemStats": {
        "properties": {
          "active_tenants": {
            "type": "integer"
          },
          "total_alerts": {
            "type": "integer"
          },
          "total_cases": {
            "type": "integer"
          },
          "total_tenants": {
            "type": "integer"
          },
          "total_transactions": {
            "type": "integer"
          },
          "total_users": {
            "type": "integer"
          },
          "uptime": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "Tenant": {
        "properties": {
          "active": {
            "type": "boolean"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "modules": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "TenantModule": {
        "description": "Linha de snx_tenant_modules — entitlement de um módulo para um tenant.\nInclui trial sob demanda, quota override e workflow de request.\n",
        "properties": {
          "activated_at": {
            "format": "date-time",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "deactivated_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "disabled_by_user_id": {
            "format": "uuid",
            "nullable": true,
            "type": "string"
          },
          "disabled_reason": {
            "nullable": true,
            "type": "string"
          },
          "enabled_by_user_id": {
            "format": "uuid",
            "nullable": true,
            "type": "string"
          },
          "enabled_reason": {
            "nullable": true,
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "module_code": {
            "type": "string"
          },
          "notes": {
            "nullable": true,
            "type": "string"
          },
          "quota_override": {
            "description": "Sobrescreve included_quota do catalog quando preenchido",
            "nullable": true,
            "type": "integer"
          },
          "quota_reset_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "request_rejection_reason": {
            "nullable": true,
            "type": "string"
          },
          "request_status": {
            "enum": [
              "pending",
              "approved",
              "rejected"
            ],
            "nullable": true,
            "type": "string"
          },
          "requested_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "requested_by_user_id": {
            "format": "uuid",
            "nullable": true,
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "trial_converted_at": {
            "description": "Quando tenant converteu trial em assinatura paga",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "trial_expires_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "trial_started_at": {
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "TimelineEvent": {
        "properties": {
          "actor_id": {
            "format": "uuid",
            "type": "string"
          },
          "actor_name": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "metadata": {
            "type": "object"
          },
          "type": {
            "enum": [
              "created",
              "assigned",
              "commented",
              "escalated",
              "resolved",
              "closed",
              "status_changed"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "TokenResponse": {
        "properties": {
          "access_token": {
            "type": "string"
          },
          "expires_in": {
            "description": "Token TTL in seconds",
            "type": "integer"
          },
          "refresh_token": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "Transaction": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "analyzed_at": {
            "format": "date-time",
            "type": "string"
          },
          "blockchain": {
            "type": "string"
          },
          "client_id": {
            "format": "uuid",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "decision": {
            "enum": [
              "approved",
              "blocked",
              "review"
            ],
            "type": "string"
          },
          "from_address": {
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "reviewed_by": {
            "format": "uuid",
            "type": "string"
          },
          "risk_level": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "rules_triggered": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "status": {
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "to_address": {
            "type": "string"
          },
          "tx_hash": {
            "type": "string"
          },
          "type": {
            "enum": [
              "deposit",
              "withdrawal",
              "transfer",
              "swap",
              "staking"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateClientRequest": {
        "properties": {
          "email": {
            "format": "email",
            "type": "string"
          },
          "kyc_status": {
            "enum": [
              "pending",
              "verified",
              "rejected",
              "expired"
            ],
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "pep": {
            "type": "boolean"
          },
          "phone": {
            "type": "string"
          },
          "risk_tier": {
            "enum": [
              "GREEN",
              "AMBER",
              "RED"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "UserProfile": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "email": {
            "format": "email",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "last_login": {
            "format": "date-time",
            "type": "string"
          },
          "mfa_enabled": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "enum": [
              "SUPER_ADMIN",
              "TENANT_ADMIN",
              "COMPLIANCE",
              "ANALYST",
              "VIEWER",
              "API_SERVICE"
            ],
            "type": "string"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Wallet": {
        "properties": {
          "address": {
            "type": "string"
          },
          "blockchain": {
            "type": "string"
          },
          "blocklisted": {
            "type": "boolean"
          },
          "first_seen": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "last_seen": {
            "format": "date-time",
            "type": "string"
          },
          "risk_level": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "tags": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          }
        },
        "type": "object"
      },
      "WalletScreenRequest": {
        "properties": {
          "address": {
            "type": "string"
          },
          "blockchain": {
            "enum": [
              "bitcoin",
              "ethereum",
              "tron",
              "solana",
              "polygon"
            ],
            "type": "string"
          }
        },
        "required": [
          "address",
          "blockchain"
        ],
        "type": "object"
      },
      "WalletScreenResponse": {
        "properties": {
          "address": {
            "type": "string"
          },
          "blockchain": {
            "type": "string"
          },
          "labels": {
            "items": {
              "description": "Known labels (e.g., exchange, mixer, darknet, scam)",
              "type": "string"
            },
            "type": "array"
          },
          "risk_level": {
            "enum": [
              "low",
              "medium",
              "high",
              "critical"
            ],
            "type": "string"
          },
          "risk_score": {
            "format": "float",
            "type": "number"
          },
          "sanctions_match": {
            "type": "boolean"
          },
          "sources": {
            "items": {
              "description": "Data sources checked (e.g., chainalysis, trm, ofac, internal)",
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "bearerFormat": "JWT",
        "description": "RS256 JWT token obtained via /auth/login + /auth/mfa/verify",
        "scheme": "bearer",
        "type": "http"
      },
      "hmacAuth": {
        "description": "HMAC-SHA256 signature of the request body",
        "in": "header",
        "name": "X-Signature-256",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {
      "email": "dev-support@sentinexrisk.com",
      "name": "Sentinex Risk Technologies",
      "url": "https://sentinexrisk.com"
    },
    "description": "Plataforma SaaS multi-tenant de risco operacional, compliance e KYC/KYT\npara criptoativos no Brasil. Todos os endpoints protegidos operam no\nescopo do tenant extraído do token de autenticação.\n\n## Casos de uso principais\n\n- **KYT em tempo real**: pontue cada transação on/off-chain em \u003c100ms\n  e receba decisão `APPROVE` / `REVIEW` / `REJECT` com breakdown de score\n  em 5 dimensões e regras acionadas explicáveis.\n- **KYC/KYB completo**: onboarding de pessoa física e jurídica com\n  validação documental, screening em listas de sanções (OFAC, ONU, COAF,\n  União Europeia, FinCEN) e bureaus brasileiros.\n- **Análise de carteiras on-chain**: clustering proprietário, atribuição\n  a entidades conhecidas, screening de exposição a endereços sancionados.\n- **Travel Rule (IVMS101)**: troca de informações entre VASPs conforme\n  Art. 44 e Art. 89 da BCB Res. 520.\n- **Reportes regulatórios**: SAR COAF automatizado (\u003eR$100k / \u003eR$500k\n  em 7 dias), DeCripto (RFB IN 2291/2025), reporte mensal de câmbio com\n  stablecoins ao BCB.\n- **Mesa de trabalho integrada**: alertas, casos, escalonamento e audit\n  trail imutável para times de compliance.\n\n## Camadas de segurança (em ordem de aplicação)\n\n1. **Recovery middleware** — captura panics, retorna 500 padronizado\n2. **Security headers** — HSTS, CSP, X-Frame-Options, X-Content-Type-Options\n3. **API Shield** — abuse score, blocklist de IPs, detecção SQLi/XSS\n4. **Rate limiting global** — por IP e por tenant, *fail-closed*\n5. **CORS** — allowlist restritiva de origens\n6. **CSRF double-submit cookie** — em rotas autenticadas via cookie\n7. **Autenticação** — JWT RS256 (dashboard) ou API Key (B2B futuro V1)\n8. **Resolução de tenant + gating de módulo** — entitlements por plano\n\n## Compliance regulatório embarcado\n\n| Norma | Cobertura |\n|-------|-----------|\n| Lei 14.478/2022 (Marco Legal Cripto) | Toda |\n| Decreto 11.563/2023 | Toda |\n| BCB Res. 519, 520, 521, 549, 550, 553 | KYC, custódia, Travel Rule |\n| BCB IN 693, 701, 704 | Reportes operacionais |\n| RFB IN 2291/2025 (DeCripto) | Reporte mensal/anual |\n| COAF Lei 9.613/1998 + Carta-Circular 4001 | SAR automatizado |\n| CMN Res. 5280, 5281 | Câmbio com stablecoins |\n| LGPD (Lei 13.709/2018) | Hash PII, soft-delete, DSAR |\n\n## Suporte técnico\n\n- 📧 dev-support@sentinexrisk.com\n- 📖 Quickstart: https://docs.crypto.sentinexrisk.com/quickstart\n- 💬 Slack Connect (clientes Pro+)\n- 🎫 Status page: https://status.crypto.sentinexrisk.com\n",
    "license": {
      "name": "Licença Comercial Sentinex Risk",
      "url": "https://sentinexrisk.com/licenca"
    },
    "termsOfService": "https://sentinexrisk.com/termos",
    "title": "Sentinex Risk Crypto — API",
    "version": "1.0.0"
  },
  "openapi": "3.0.3",
  "paths": {
    "/admin/modules/catalog": {
      "get": {
        "description": "\nVersão SUPER_ADMIN do catálogo: inclui módulos draft/internal não-públicos, métricas de adoption (tenants ativos por módulo), MRR contribuído por módulo, churn rate. Use para decisões de pricing/packaging e identificar módulos a depreciar.\n",
        "operationId": "adminModulesCatalog",
        "parameters": [
          {
            "in": "query",
            "name": "active",
            "schema": {
              "default": true,
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "addons_only",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "category",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "exclude_internal",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/CatalogEntry"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lista filtrada do catálogo"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Catálogo completo (super_admin Sentinex)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/modules/requests/pending": {
      "get": {
        "description": "\nFila FIFO de requests de módulos aguardando decisão SUPER_ADMIN. Cada entry: tenant solicitante, módulo, quota pedida vs atual, justification, MRR potencial. Ordenado por created_at ASC. Cada request tem SLA de 24h para resposta (escalada automática para Founder se exceder).\n",
        "operationId": "adminModulesRequestsPending",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/TenantModule"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Pedidos em status pending"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Pedidos pendentes de aprovação (super_admin)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/my/modules": {
      "get": {
        "description": "\nLista módulos visíveis para o tenant atual: ativados, em request pending, disponíveis para upgrade. Cada entrada inclui quotas atuais vs limites e status do request (se aplicável).\n",
        "operationId": "myModulesList",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/TenantModule"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lista de TenantModule do tenant"
          },
          "401": {
            "description": "Token inválido ou tenant ausente"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Módulos do tenant logado",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/my/modules/usage": {
      "get": {
        "description": "\nHistórico de consumo dos últimos 30 dias por módulo, com daily breakdown. Use para mostrar trends de uso ao tenant + alertar antes de atingir hard-limit. Inclui projeção de overage no ciclo atual.\n",
        "operationId": "myModulesUsage",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "overage_cents": {
                            "type": "integer"
                          },
                          "overage_qty": {
                            "type": "integer"
                          },
                          "transactions_30d": {
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Agregação 30d com overage"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Uso por módulo nos últimos 30 dias",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/my/modules/{code}/request-upgrade": {
      "post": {
        "description": "\nCliente solicita ativação ou upgrade de quota. Cria entrada em snx_module_requests com status `pending`. Fica visível para SUPER_ADMIN em /admin/modules/requests/pending. Email + notificação Slack disparados ao Founder. Aprovação faz cobrança proporcional + ativação imediata.\n",
        "operationId": "myModulesRequestUpgrade",
        "parameters": [
          {
            "example": "mod_crypto_kyt",
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "justification": {
                    "minLength": 20,
                    "type": "string"
                  }
                },
                "required": [
                  "justification"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Pedido criado em status pending"
          },
          "400": {
            "description": "Validação falhou (justification_min_20_chars)"
          },
          "403": {
            "description": "Módulo requer ativação super_admin (ex módulos internos)"
          },
          "404": {
            "description": "Módulo não existe no catálogo"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Solicita ativação de módulo (workflow super_admin approval)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/stats": {
      "get": {
        "description": "\nMétricas técnicas globais: uptime backend/frontend, p99 latency, error rate cross-tenant, DB metrics (connections, slow queries), Redis cache hit ratio, Kafka outbox depth, jobs queue size, etc. Use para health monitoring SUPER_ADMIN e SRE.\n",
        "operationId": "getSystemStats",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemStats"
                }
              }
            },
            "description": "System stats"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna estatísticas do sistema (papel super admin)",
        "tags": [
          "Administração"
        ]
      }
    },
    "/admin/tenants": {
      "get": {
        "description": "\nVisão SUPER_ADMIN agregada da plataforma: todos os tenants ativos, suspended, dunning, KYB-pending. Filtros por status, plano, região. Cada entrada: nome legal, CNPJ hashed, plano, MRR, status, último signin, alert count agregado. Use para dashboards executivos. SUPER_ADMIN NUNCA vê operação interna de tenant — para isso, impersonar.\n",
        "operationId": "listTenants",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "tenants": {
                      "items": {
                        "$ref": "#/components/schemas/Tenant"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Tenant list"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista todos os tenants (papel super admin)",
        "tags": [
          "Administração"
        ]
      },
      "post": {
        "description": "\nCria tenant manualmente (caminho não-self-service — para sales-led onboarding). Recebe legal_name, CNPJ, plano inicial, contact_email. Diferente de /public/signup que faz wizard completo. Use SUPER_ADMIN para parceiros estratégicos sem signup público.\n",
        "operationId": "createTenant",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTenantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                }
              }
            },
            "description": "Tenant created"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cria novo tenant (papel super admin)",
        "tags": [
          "Administração"
        ]
      }
    },
    "/admin/tenants/{id}": {
      "get": {
        "description": "\nDetalhe admin do tenant: metadados, status, plano, billing health, audit trail. Equivale a /admin/tenants/{id} simplified — para SUPER_ADMIN consultar info administrativa sem entrar em operação.\n",
        "operationId": "getTenant",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                }
              }
            },
            "description": "Tenant details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna tenant por ID (papel super admin)",
        "tags": [
          "Administração"
        ]
      }
    },
    "/admin/tenants/{id}/modules": {
      "put": {
        "operationId": "updateTenantModules",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "modules": {
                    "items": {
                      "enum": [
                        "kyc",
                        "kyt",
                        "sanctions",
                        "travel_rule",
                        "coaf",
                        "decripto",
                        "bcb_fx",
                        "cases",
                        "radar",
                        "billing"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "modules"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Modules updated"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Atualiza em lote os módulos habilitados do tenant (super_admin)",
        "tags": [
          "Administração"
        ]
      }
    },
    "/admin/tenants/{tenantId}/modules": {
      "get": {
        "description": "\nVisão SUPER_ADMIN dos módulos de um tenant específico: ativos, suspended, history de mudanças. Use antes de processar request de upgrade para entender contexto do tenant. NÃO entra em operação interna (alertas/casos/transações).\n",
        "operationId": "adminTenantModulesList",
        "parameters": [
          {
            "in": "path",
            "name": "tenantId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/TenantModule"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Vínculos do tenant com module catalog"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista módulos de um tenant (super_admin)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/tenants/{tenantId}/modules/{code}/activate": {
      "post": {
        "description": "\nOperação sensitiva: ativa módulo para tenant em janela específica. Requer fresh MFA (TOTP nos últimos 5min) — defesa contra session hijacking. Audit trail completo (who/when/which_module/which_tenant/reason). Billing ajustado proporcional ao ciclo. Email + Slack disparam para Founder e tenant admin.\n",
        "operationId": "adminTenantModuleActivate",
        "parameters": [
          {
            "in": "path",
            "name": "tenantId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "notes": {
                    "type": "string"
                  },
                  "quota_override": {
                    "description": "Sobrescreve included_quota do catalog",
                    "type": "integer"
                  },
                  "reason": {
                    "minLength": 10,
                    "type": "string"
                  },
                  "trial_days": {
                    "description": "Se \u003e 0, cria trial; senão ativação definitiva",
                    "maximum": 90,
                    "minimum": 0,
                    "type": "integer"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Módulo ativado (trial iniciado se trial_days maior que 0)"
          },
          "404": {
            "description": "Módulo não existe no catálogo"
          },
          "422": {
            "description": "Dependências não satisfeitas (missing_dependencies)"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Ativa módulo para tenant (super_admin + freshMFA)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/tenants/{tenantId}/modules/{code}/deactivate": {
      "post": {
        "description": "\nDesativação imediata do módulo para o tenant. Requer fresh MFA. Se módulo tem dados ativos (e.g. casos abertos em /cases), valida que não há lock antes de aplicar. Billing cessa imediato — não há proporcional para downgrade (créditos só no próximo ciclo). Use com cautela: ação operacionalmente disruptiva.\n",
        "operationId": "adminTenantModuleDeactivate",
        "parameters": [
          {
            "in": "path",
            "name": "tenantId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "reason": {
                    "minLength": 10,
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Módulo desativado"
          },
          "404": {
            "description": "Vínculo não encontrado ou já inativo"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Desativa módulo (corte imediato, super_admin + freshMFA)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/tenants/{tenantId}/modules/{code}/quota": {
      "patch": {
        "description": "\nAumenta/diminui limite específico de um módulo para um tenant (override do plano base). Use para clientes enterprise com necessidades especiais (e.g. burst legítimo de 10x TPS durante Black Friday). Requer fresh MFA. Override é por janela temporal (start/end) — após expira, volta ao limite do plano.\n",
        "operationId": "adminTenantModuleQuotaPatch",
        "parameters": [
          {
            "in": "path",
            "name": "tenantId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "quota_override": {
                    "description": "null para voltar ao included_quota do catalog",
                    "nullable": true,
                    "type": "integer"
                  },
                  "quota_reset_at": {
                    "format": "date-time",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Quota atualizada"
          },
          "404": {
            "description": "Vínculo não encontrado"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Atualiza quota override (super_admin + freshMFA)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/tenants/{tenantId}/modules/{code}/reject": {
      "post": {
        "description": "\nRejeita request de módulo. Requer fresh MFA + reason (texto). Tenant recebe email com motivo. Não cria charge. Audit trail registra rejeição. Diferente de aprovar+cancel (que entrega temporariamente). Use quando upgrade não é compatível com perfil de risco do tenant.\n",
        "operationId": "adminTenantModuleReject",
        "parameters": [
          {
            "in": "path",
            "name": "tenantId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "reason": {
                    "minLength": 10,
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Pedido rejeitado"
          },
          "404": {
            "description": "Pedido não está em status pending"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Rejeita pedido pending (super_admin + freshMFA)",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/admin/users": {
      "get": {
        "description": "\nVisão SUPER_ADMIN dos usuários: filtros por tenant, papel RBAC, status (ativo/suspenso/locked), MFA enabled. Não retorna password hash nem TOTP secret (LGPD + segurança). Use para auditoria cross-tenant de quem tem acesso a quê. Ações disponíveis: bloquear/desbloquear (lock investigação), forçar reset MFA (em caso de device perdido confirmado).\n",
        "operationId": "listAllUsers",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "users": {
                      "items": {
                        "$ref": "#/components/schemas/UserProfile"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "User list"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista todos usuários cross-tenant (papel super admin)",
        "tags": [
          "Administração"
        ]
      },
      "post": {
        "description": "\nCriação manual de usuário em tenant existente — SUPER_ADMIN-only (geralmente para suporte/troubleshooting). Recebe email + papel RBAC + tenant_id. Dispara magic link de primeira senha. Audit trail registra quem do Sentinex criou + reason.\n",
        "operationId": "createUser",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserProfile"
                }
              }
            },
            "description": "User created"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cria usuário em um tenant (papel super admin)",
        "tags": [
          "Administração"
        ]
      }
    },
    "/alerts": {
      "get": {
        "description": "Retorna alertas do tenant atual com filtro por status\n(`open` / `assigned` / `resolved` / `escalated`) e severidade\n(`low` / `medium` / `high` / `critical`). Alertas têm SLA de\ntriagem configurável por severidade (default: critical=15min,\nhigh=1h, medium=4h, low=24h). Use este endpoint para popular\na fila de mesa de trabalho do analista. Para detalhe + ação,\nuse `/alerts/{id}` e endpoints derivados.\n",
        "operationId": "listAlerts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "open",
                "assigned",
                "resolved",
                "escalated"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "severity",
            "schema": {
              "enum": [
                "low",
                "medium",
                "high",
                "critical"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAlerts"
                }
              }
            },
            "description": "Lista paginada de alertas filtrados por status e severidade"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista alertas com filtros e paginação",
        "tags": [
          "Operações — Alertas"
        ]
      }
    },
    "/alerts/{id}": {
      "get": {
        "description": "Detalhe completo do alerta: contexto disparador (regra\nacionada + transação ou cliente origem), severity, SLA\ncountdown, assignee atual, audit trail de ações (assign,\nunassign, comment, escalate), evidências anexadas, casos\ncorrelacionados. Em alertas decorrentes de match em sanção,\ninclui referência ao item da lista (OFAC SDN list + data da\nsanção + jurisdição).\n",
        "operationId": "getAlert",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Alert"
                }
              }
            },
            "description": "Detalhe completo do alerta com contexto, evidências e audit trail"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna alerta por ID",
        "tags": [
          "Operações — Alertas"
        ]
      }
    },
    "/alerts/{id}/assign": {
      "post": {
        "description": "Atribui alerta para um usuário específico do tenant (campo\n`assignee_id`). Pode auto-atribuir (`assignee_id` = próprio\nuser). Defesa contra ping-pong: 3 reatribuições consecutivas\nsem ação automaticamente escalonam para compliance. SLA\ncountdown não reseta com reatribuição — começa a contar do\nprimeiro disparo. Atribuir já-atribuído sobrescreve o\nassignee anterior e registra no audit trail.\n",
        "operationId": "assignAlert",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "assignee_id": {
                    "format": "uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "assignee_id"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Alerta atribuído; assignee_id atualizado no audit trail"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Atribui alerta a um analista (papel analyst ou superior)",
        "tags": [
          "Operações — Alertas"
        ]
      }
    },
    "/alerts/{id}/escalate": {
      "post": {
        "description": "Escala alerta da mesa operacional para compliance/SAR.\nDispara workflow específico: cria caso compliance,\nbloqueia transações do cliente correlacionado por default\naté decisão, registra timer COAF (24h para SAR se\nconfirmar suspeição). `priority=critical` notifica DPO\nimediatamente via webhook Slack + email. Geralmente usado\nquando analista identifica padrão de lavagem (smurfing,\nlayering, mixer pattern) que excede competência da mesa.\n",
        "operationId": "escalateAlert",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "priority": {
                    "enum": [
                      "normal",
                      "urgent",
                      "critical"
                    ],
                    "type": "string"
                  },
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Alerta escalonado para compliance; workflow SAR iniciado se aplicável"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Escalona alerta para compliance (papel compliance)",
        "tags": [
          "Operações — Alertas"
        ]
      }
    },
    "/alerts/{id}/resolve": {
      "post": {
        "description": "Encerra alerta com classificação: `true_positive` (alerta\nlegítimo, fraude/lavagem confirmada), `false_positive`\n(falso alarme, alimenta tuning das regras Grule),\n`inconclusive` (sem evidência suficiente, cliente fica em\nwatchlist interna). `notes` obrigatório para audit trail.\nTrigger automático: 10+ false_positive em 30 dias na mesma\nregra dispara ticket de tuning para o time de risco.\nResolução é imutável após persistida.\n",
        "operationId": "resolveAlert",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "notes": {
                    "type": "string"
                  },
                  "resolution": {
                    "enum": [
                      "true_positive",
                      "false_positive",
                      "inconclusive"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "resolution",
                  "notes"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Alerta resolvido; classificação imutável; feedback alimenta tuning de regras"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Resolve alerta com decisão (papel analyst ou superior)",
        "tags": [
          "Operações — Alertas"
        ]
      }
    },
    "/auth/login": {
      "post": {
        "description": "Inicia o fluxo de autenticação interativo. Em sucesso retorna um\ntoken JWT de curta duração quando MFA não está habilitado para\no usuário; quando MFA está habilitado, retorna um `mfa_challenge`\nque deve ser completado em `/auth/mfa/verify`. Rate limit por\nIP + por email; falhas consecutivas incrementam a dificuldade do\npróximo proof-of-work exigido. Senhas inválidas e usuários\ninexistentes retornam a mesma resposta para evitar enumeração.\n",
        "operationId": "authLogin",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            },
            "description": "Login bem-sucedido (retorna token JWT ou challenge MFA pendente)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "security": [],
        "summary": "Autentica com email e senha",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/logout": {
      "post": {
        "description": "Adiciona o JWT atual e o refresh token correspondente a uma\nblocklist com TTL igual ao tempo de vida remanescente do token.\nApós este endpoint, todas as requests subsequentes com esses\ntokens retornam 401. Logout é idempotente — chamadas repetidas\napós sucesso continuam retornando 200.\n",
        "operationId": "authLogout",
        "responses": {
          "200": {
            "description": "Sessão encerrada com sucesso"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Encerra sessão e invalida tokens",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/me": {
      "get": {
        "description": "Retorna informações do usuário atual extraídas do JWT + dados\ncomplementares persistidos (papel RBAC, tenant, status do MFA,\ntimestamps de criação e último login). Não inclui dados\nsensíveis como hash de senha. Use este endpoint para popular\na tela de perfil e checar permissões antes de renderizar UI\nsensível.\n",
        "operationId": "authMe",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserProfile"
                }
              }
            },
            "description": "Perfil do usuário atual"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna perfil do usuário autenticado",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/mfa/confirm": {
      "post": {
        "description": "Valida o primeiro código TOTP gerado pelo app autenticador do\nusuário. Em sucesso o secret pending vira ativo e retorna 10\nrecovery codes single-use que o usuário deve salvar em local\nseguro (recovery codes permitem login se o device com TOTP for\nperdido). Cada recovery code é hashed com bcrypt antes da\npersistência. Falha aborta o setup e o secret pending é\ndescartado — usuário precisa chamar `/auth/mfa/setup` novamente.\n",
        "operationId": "authConfirmMFA",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "code": {
                    "pattern": "^[0-9]{6}$",
                    "type": "string"
                  }
                },
                "required": [
                  "code"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "recovery_codes": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "MFA habilitado com sucesso (retorna 10 recovery codes single-use)"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Confirma configuração do MFA com código TOTP",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/mfa/setup": {
      "post": {
        "description": "Gera um secret TOTP novo para o usuário e retorna em três\nformatos: secret cru (base32), QR code pronto para escaneamento\nem apps autenticadores (Google Authenticator, Authy, 1Password)\ne URL otpauth para deep-link. O secret só é persistido como\nativo após confirmação em `/auth/mfa/confirm` — até lá fica em\nestado pending e expira em 10 minutos. Se o usuário já tem MFA\nhabilitado, este endpoint requer reautenticação recente.\n",
        "operationId": "authSetupMFA",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "otpauth_url": {
                      "type": "string"
                    },
                    "qr_code": {
                      "description": "Imagem do QR code codificada em Base64",
                      "type": "string"
                    },
                    "secret": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Dados de provisionamento TOTP (secret + QR code + URL)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Inicia configuração do MFA (retorna secret TOTP e QR code)",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/mfa/verify": {
      "post": {
        "description": "Completa o segundo fator de autenticação. Recebe `mfa_challenge`\nretornado por `/auth/login` e o código TOTP de 6 dígitos do\nautenticador do usuário. Em sucesso emite o JWT final + refresh\ntoken. Para evitar fadiga do usuário, sessões do mesmo\ndevice+IP dentro de janela de 3h não exigem nova verificação MFA.\n",
        "operationId": "authVerifyMFA",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MFAVerifyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "MFA verificado, JWT emitido"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "security": [],
        "summary": "Verifica código TOTP do MFA",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/password": {
      "put": {
        "description": "Requer senha atual como prova de posse (defesa contra session\nhijacking que tentaria trocar a senha). A nova senha precisa ter\nno mínimo 12 caracteres e passa por validação de força (entropia\n+ dicionário de senhas comuns + dados pessoais do usuário). Em\nsucesso, todas as outras sessões ativas do usuário são\ninvalidadas; o JWT atual permanece válido até expiração natural.\n",
        "operationId": "authChangePassword",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "current_password": {
                    "format": "password",
                    "type": "string"
                  },
                  "new_password": {
                    "format": "password",
                    "minLength": 12,
                    "type": "string"
                  }
                },
                "required": [
                  "current_password",
                  "new_password"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Senha alterada com sucesso"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Altera senha do usuário autenticado",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/auth/refresh": {
      "post": {
        "description": "Troca um refresh token válido por um novo par (access + refresh).\nO refresh token original é invalidado (rotação obrigatória) para\nimpedir reuso. Refresh tokens têm duração de 7 dias por default;\ntenants com perfil de risco maior podem ter janelas menores\nconfiguradas. Falha se o refresh token foi rotacionado\nanteriormente — caracteriza tentativa de replay.\n",
        "operationId": "authRefresh",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "refresh_token": {
                    "type": "string"
                  }
                },
                "required": [
                  "refresh_token"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "Novo par de tokens emitido (refresh anterior invalidado)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [],
        "summary": "Renova access token usando refresh token",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/billing/change-plan": {
      "post": {
        "description": "\nUpgrade é instantâneo (novos limites aplicam imediato + cobrança proporcional do ciclo atual). Downgrade tem grace period 24h (admin pode reverter) e só aplica no próximo ciclo. Integração Stripe: dispara webhook customer.subscription.updated. Auditado em snx_billing_audit + email confirmation enviado.\n",
        "operationId": "changeBillingPlan",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "plan_id": {
                    "type": "string"
                  }
                },
                "required": [
                  "plan_id"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Plan changed"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Altera plano de billing (papel tenant admin)",
        "tags": [
          "Plataforma — Cobrança"
        ]
      }
    },
    "/billing/plans": {
      "get": {
        "description": "\nCatálogo dos 5 tiers Sentinex Risk: Starter (R$4.9k/mês — VASP pequeno), Pro (R$18.9k — médio), Scale (R$64.9k — grande), Enterprise (R$189k — multi-VASP), RegTech (R$350k+ — white-label). Cada plano lista limites de uso (TPS, alertas, KYT/KYC, storage) e features inclusas (Ficha 360°, Travel Rule, ML scoring, etc).\n",
        "operationId": "getBillingPlans",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "plans": {
                      "items": {
                        "$ref": "#/components/schemas/BillingPlan"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Available plans"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista planos de billing disponíveis",
        "tags": [
          "Plataforma — Cobrança"
        ]
      }
    },
    "/billing/portal": {
      "post": {
        "description": "\nURL signed com TTL 5min para o tenant gerenciar pagamento, downloads de fatura, atualizar cartão, ver histórico. Stripe Customer Portal é hosted pelo Stripe — não temos UI própria de billing. Após session no portal, mudanças vêm via webhook.\n",
        "operationId": "getBillingPortal",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "url": {
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Portal session URL"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna URL do Stripe Customer Portal (papel tenant admin)",
        "tags": [
          "Plataforma — Cobrança"
        ]
      }
    },
    "/billing/usage": {
      "get": {
        "description": "\nMétricas do ciclo atual: transações analisadas, alertas gerados, KYT screens, KYC pulls externos, casos abertos, storage usado. Comparado com limites do plano contratado. Inclui projeção de overage (se trend atual continuar) e dias restantes até reset. Use para alertar Founder antes de hard-limit dispar.\n",
        "operationId": "getBillingUsage",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingUsage"
                }
              }
            },
            "description": "Usage data"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna uso de billing atual do tenant",
        "tags": [
          "Plataforma — Cobrança"
        ]
      }
    },
    "/billing/webhook": {
      "post": {
        "description": "Recebe eventos do Stripe: customer.subscription.{created,updated,deleted}, invoice.{paid,failed}, payment_intent.{succeeded,failed}. Valida assinatura HMAC com STRIPE_WEBHOOK_SECRET (header Stripe-Signature — não JWT). Idempotente via event_id (Redis SETNX 7d). Atualiza snx_tenants.plan_status + dispara workflows (e.g. invoice.failed → grace 7d → suspend).\n",
        "operationId": "handleStripeWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Webhook processed"
          },
          "400": {
            "description": "Invalid signature or payload"
          }
        },
        "security": [],
        "summary": "Endpoint de webhook do Stripe",
        "tags": [
          "Plataforma — Cobrança"
        ]
      }
    },
    "/cases": {
      "get": {
        "description": "Casos são unidades de trabalho de compliance: agrupam alertas\nrelacionados (mesmo cliente, mesma typology, mesma janela\ntemporal) + evidências coletadas + audit trail completo. Use\neste endpoint para popular a mesa de trabalho de compliance.\nCasos sempre auditáveis para responses BCB/COAF (audit chain\nimutável via hash encadeado).\n",
        "operationId": "listCases",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "open",
                "in_progress",
                "resolved",
                "escalated",
                "closed"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedCases"
                }
              }
            },
            "description": "Paginated case list"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista casos de investigação",
        "tags": [
          "Operações — Casos"
        ]
      },
      "post": {
        "description": "Caso típico criado manualmente pelo analista quando padrão\nobservado em alertas excede competência da mesa operacional.\nAuto-attach: alertas correlacionados (mesma typology + janela)\nsão puxados automaticamente para o caso. Caso é versionado\n(cada modificação cria revisão). Em escalada para COAF, o\ncaso vira anexo do SAR. Não-imutável até resolve().\n",
        "operationId": "createCase",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCaseRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Case"
                }
              }
            },
            "description": "Case created"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cria caso de investigação (papel analyst ou superior)",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}": {
      "get": {
        "description": "Detalhe completo: dados do caso, lista de alertas correlatos,\nevidências coletadas (anexos S3 keys + hash SHA-256), histórico\nde comentários, audit trail de status, assignee atual,\ndeadlines (SAR COAF se aplicável). Inclui flag de\nchain-of-custody integrity (cada evidência tem hash assinado;\nviolação invalida o caso para uso em SAR).\n",
        "operationId": "getCase",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Case"
                }
              }
            },
            "description": "Case details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna caso por ID",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}/assign": {
      "post": {
        "description": "Atribuição é registrada no audit trail (who/when/why).\nReatribuições são permitidas mas não resetam SLA timers\n(deadline COAF de 24h é absoluto, conta do trigger inicial).\nAuto-notify: assignee novo recebe email + entry no inbox.\nDevolução é permitida (assignee pode unassign solicitando\nrevisão por outro com `reason`).\n",
        "operationId": "assignCase",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "assignee_id": {
                    "format": "uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "assignee_id"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Case assigned"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Atribui caso ao analista (papel compliance)",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}/comment": {
      "post": {
        "description": "Comentários são imutáveis após criados (registros de audit\ntrail). Permitem anexos via reference IDs (storage S3 com\nhash SHA-256 validado). Markdown limitado suportado (sem\nHTML/scripts). Mentions @user disparam notificação. Usado\npara registrar progresso de investigação, achados parciais,\ndecisões intermediárias.\n",
        "operationId": "addCaseComment",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "attachments": {
                    "items": {
                      "description": "Attachment reference IDs",
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "content": {
                    "type": "string"
                  }
                },
                "required": [
                  "content"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Comment added"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Adiciona comentário ao caso (papel analyst ou superior)",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}/escalate": {
      "post": {
        "description": "Target define destino: `compliance_lead` (encaminhamento\ninterno para liderança quando excede competência do\ncompliance officer), `coaf` (submissão SAR COAF — dispara\nworkflow de geração de XML + assinatura ICP-Brasil), ou\n`law_enforcement` (ordens judiciais já comunicadas — atualiza\nstatus e prepara pacote forense). `reason` obrigatório vira\nparte do audit. Em escalada para COAF, prazo 24h conta dos\ngatilhos automáticos (\u003eR$100k transação OU \u003eR$500k/7d).\n",
        "operationId": "escalateCase",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "reason": {
                    "type": "string"
                  },
                  "target": {
                    "enum": [
                      "compliance_lead",
                      "coaf",
                      "law_enforcement"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Case escalated"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Escalona caso (papel compliance)",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}/resolve": {
      "post": {
        "description": "Encerra o caso com classificação final: `confirmed_fraud`\n(suspeição confirmada — dispara SAR COAF se ainda dentro de\njanela 24h), `false_positive` (não-suspeito, alimenta tuning\nde regras), `inconclusive` (sem evidência suficiente — cliente\npermanece em watchlist por 90d), `referred_to_coaf` (SAR já\nem fila externa). `findings` (texto longo) é obrigatório\ne vira parte do SAR/audit. Resolução é imutável.\n",
        "operationId": "resolveCase",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "findings": {
                    "type": "string"
                  },
                  "resolution": {
                    "enum": [
                      "confirmed_fraud",
                      "false_positive",
                      "inconclusive",
                      "referred_to_coaf"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "resolution",
                  "findings"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Case resolved"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Resolve caso com findings (papel compliance)",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/cases/{id}/timeline": {
      "get": {
        "description": "Lista cronológica completa de todos os eventos do caso:\ncriação, atribuições, comentários, anexos, mudanças de status,\nescaladas, resolução. Cada evento tem hash encadeado com o\nanterior (audit chain integrity LGPD-compatível). Use para\nproduzir relatório forense quando solicitado por BCB/COAF/\nautoridade judicial — o JSON retornado pode ser anexado\ndiretamente ao SAR ou packaging.\n",
        "operationId": "getCaseTimeline",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "events": {
                      "items": {
                        "$ref": "#/components/schemas/TimelineEvent"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Timeline events"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna timeline auditável do caso",
        "tags": [
          "Operações — Casos"
        ]
      }
    },
    "/clients": {
      "get": {
        "description": "Retorna clientes do tenant atual com filtro por risk tier\nBCB Res. 520 (`GREEN` baixo / `AMBER` médio / `RED` alto) e\nbusca textual (nome ou identifier hashed). Identifiers (CPF,\nCNPJ, e-mail) nunca aparecem em claro nas listagens — somente\no hash SHA-256. Use search por hash quando o cliente já provou\nconhecer o identifier original.\n",
        "operationId": "listClients",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "in": "query",
            "name": "risk_tier",
            "schema": {
              "enum": [
                "GREEN",
                "AMBER",
                "RED"
              ],
              "type": "string"
            }
          },
          {
            "description": "Busca por nome ou identifier hashed (SHA-256)",
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedClients"
                }
              }
            },
            "description": "Lista paginada de clientes (identifiers sempre hashed)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista clientes com filtros e paginação",
        "tags": [
          "Identidade — Clientes"
        ]
      },
      "post": {
        "description": "Onboarding manual de cliente PF/PJ. Dispara pipeline KYC\ncompleto: validação documental + screening em listas de\nsanções (OFAC, ONU, COAF, UE, FinCEN) + bureau brasileiro +\nrisk tiering automático (GREEN/AMBER/RED conforme BCB Res.\n520 Art. 58-59). Identifiers (CPF/CNPJ/e-mail) são\npersistidos sempre como SHA-256 — payload original é\nsanitizado antes do log. Em caso de match em sanção,\ncliente é criado com status `BLOCKED` e gera alerta crítico\nautomático.\n",
        "operationId": "createClient",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Cliente criado; pipeline KYC iniciado em background"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cria novo cliente (papel compliance)",
        "tags": [
          "Identidade — Clientes"
        ]
      }
    },
    "/clients/{id}": {
      "get": {
        "description": "Detalhe completo do cliente: dados KYC (sempre hashed),\nhistórico de transações (count + volume agregado), alertas\nativos, status de screening em listas de sanções, audit\ntrail completo (LGPD Art. 18). Os identifiers em claro NUNCA\nsão retornados por este endpoint — para acessar use\n`/dpo/data-requests` (LGPD-compliant com motivo registrado).\n",
        "operationId": "getClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Detalhe do cliente (identifiers hashed)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna cliente por ID",
        "tags": [
          "Identidade — Clientes"
        ]
      },
      "put": {
        "description": "Atualiza campos não-imutáveis do cliente (nome social,\nendereço atualizado, segmento, observações de compliance).\nIdentifiers core (CPF, CNPJ) NÃO podem ser alterados via\neste endpoint — só por fluxo DPO. Cada update incrementa\nversão e registra no audit trail (who/when/which fields).\nTriggers automáticos: alteração de endereço dispara\nrecálculo de risk tier; alteração de segmento dispara\nre-screening em watchlists relevantes.\n",
        "operationId": "updateClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            },
            "description": "Cliente atualizado; audit trail registrado; triggers de re-screening disparados"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Atualiza dados do cliente (papel compliance)",
        "tags": [
          "Identidade — Clientes"
        ]
      }
    },
    "/clients/{id}/block": {
      "post": {
        "description": "Ação operacional: marca cliente como `BLOCKED` e impede\nnovas transações. Não remove dados (LGPD Art. 16: retenção\nobrigatória 5 anos para compliance financeiro mesmo após\nbloqueio). `reason` é obrigatório e registrado no audit\ntrail — usado em response a auditoria BCB/COAF. Bloqueio\ndispara workflow: alertas abertos do cliente viram\n`BLOCKED_PENDING_REVIEW`, casos em andamento são congelados\naguardando decisão final.\n",
        "operationId": "blockClient",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Cliente bloqueado; novas transações rejeitadas a partir deste ponto"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Bloqueia cliente (papel tenant admin)",
        "tags": [
          "Identidade — Clientes"
        ]
      }
    },
    "/dashboard/metrics": {
      "get": {
        "description": "Versão detalhada das métricas do dashboard, com breakdown por:\nregra acionada (top 20), faixa de score (histograma), canal\nde origem (web/mobile/API), corredor geográfico (estado, país),\nhora do dia (heatmap 24×7). Inclui métricas operacionais para\nanalistas: SLA da fila de revisão, tempo médio entre alerta e\ndecisão, taxa de override de regra, false positive rate\nestimado. Requer papel `ANALYST`, `COMPLIANCE` ou superior;\nviewers não enxergam (`403`).\n",
        "operationId": "getDashboardMetrics",
        "parameters": [
          {
            "$ref": "#/components/parameters/DateFrom"
          },
          {
            "$ref": "#/components/parameters/DateTo"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardMetrics"
                }
              }
            },
            "description": "Métricas detalhadas com breakdown por regra, faixa, canal, geografia e janela temporal"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna métricas detalhadas do painel (papel analyst ou superior)",
        "tags": [
          "Plataforma — Painel"
        ]
      }
    },
    "/dashboard/summary": {
      "get": {
        "description": "Agrega os indicadores principais do tenant: volume de transações\nno período (com comparativo mês-anterior e ano-anterior), taxa\nde aprovação/revisão/bloqueio, total de alertas abertos por\nseveridade, casos em mesa de trabalho, status agregado de\ncompliance (SAR pendentes, COAF deadline próximo, DeCripto\nmensal). Calculado em real-time via materialized views; cache\nde 60s no Redis. Use este endpoint para o card principal do\ndashboard — métricas detalhadas estão em `/dashboard/metrics`.\n",
        "operationId": "getDashboardSummary",
        "parameters": [
          {
            "$ref": "#/components/parameters/DateFrom"
          },
          {
            "$ref": "#/components/parameters/DateTo"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardSummary"
                }
              }
            },
            "description": "Resumo agregado do painel para o período solicitado"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna resumo executivo do painel para o tenant atual",
        "tags": [
          "Plataforma — Painel"
        ]
      }
    },
    "/escalations": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "escalated_to_user_id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "reason": {
                    "minLength": 10,
                    "type": "string"
                  },
                  "resource_id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "resource_type": {
                    "enum": [
                      "alert",
                      "case"
                    ],
                    "type": "string"
                  },
                  "severity_after": {
                    "enum": [
                      "low",
                      "medium",
                      "high",
                      "critical"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "resource_type",
                  "resource_id",
                  "escalated_to_user_id",
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Escalation criada com id"
          },
          "400": {
            "description": "Validação falhou (PII",
            "self-escalation": null,
            "target inválido)": null
          },
          "403": {
            "description": "Cross-tenant target ou inactive target"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cria escalation (RequireCompliance + freshMFA + PII detect)",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/escalations/by-me": {
      "get": {
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista escalations criadas pelo user logado",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/escalations/timeline/{resource_type}/{id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "resource_type",
            "required": true,
            "schema": {
              "enum": [
                "alert",
                "case"
              ],
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Timeline chronological"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Timeline completa de escalations sobre um recurso",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/escalations/to-me": {
      "get": {
        "description": "Chain imutável append-only sobre alerts+cases (mig 172). Filtra\nevent_type='escalation' + tenant RLS. RBAC AnalystOrAbove.\n",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "items": {
                      "items": {
                        "$ref": "#/components/schemas/EscalationEvent"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lista de escalations"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista escalations pendentes para o user logado",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/escalations/{id}/acknowledge": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "notes": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge persistido"
          },
          "403": {
            "description": "Apenas destinatário pode acknowledge"
          },
          "404": {
            "description": "Escalation not found (inclui cross-tenant IDOR)"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Destinatário acknowledge escalation",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/escalations/{id}/reject": {
      "post": {
        "description": "Destinatário Y devolve escalation para originante X com justificativa.\nGera nova row event_type='rejected' com from/to invertidos e\nparent_escalation_id preservado (chain integrity). PII bloqueado em\nreason e notes (DPIA-001 R-001 defense-in-depth).\n",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "notes": {
                    "type": "string"
                  },
                  "reason": {
                    "description": "Justificativa devolução (sem PII)",
                    "minLength": 10,
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Reverse-escalate persistido"
          },
          "400": {
            "description": "Reason curto OU PII detectada"
          },
          "403": {
            "description": "Caller não é destinatário do parent"
          },
          "404": {
            "description": "Parent escalation not found (inclui cross-tenant IDOR)"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Reverse-escalate (B9 — Sofia journey CX gap, Wave 3 2026-05-19)",
        "tags": [
          "Escalations"
        ]
      }
    },
    "/fingerprint/collect": {
      "post": {
        "description": "Endpoint chamado pelo client (web/mobile/API) para registrar\nfingerprint do dispositivo. SentinexPrint é proprietário (não\ncompra FingerprintJS) e coleta 7 camadas: browser (UA, canvas,\nWebGL, audio context), hardware (CPU cores, screen, timezone),\nnetwork (IP geo, ASN, VPN/Tor heuristics), behavioral (digital\npattern do form fill, click cadence), TLS fingerprint (JA3/JA4),\nfont fingerprint, plugin fingerprint. Resultado: device_id\nUUID + risk_score + flag is_known_device.\n",
        "operationId": "collectFingerprint",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FingerprintPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "device_id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "is_known_device": {
                      "type": "boolean"
                    },
                    "risk_score": {
                      "format": "float",
                      "type": "number"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Fingerprint collected and device ID returned"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Coleta dados de fingerprint do dispositivo (SentinexPrint 7-layer)",
        "tags": [
          "Sentinex — Fingerprint"
        ]
      }
    },
    "/fingerprint/device/{id}": {
      "get": {
        "description": "Retorna histórico do device_id: primeira/última observação,\ncontagem de transações associadas, lista de IPs de origem (com\nASN), flags suspeitos (rotação rápida de cookies, mismatch\ntimezone vs IP geo, UA forjada), score atual e tendência.\nUse para investigação manual de cliente — device com 100+\ntransações em 24h ou rotando 10+ IPs/dia é sinal forte.\n",
        "operationId": "getDevice",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceInfo"
                }
              }
            },
            "description": "Device fingerprint details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna detalhes do fingerprint de um device",
        "tags": [
          "Sentinex — Fingerprint"
        ]
      }
    },
    "/health": {
      "get": {
        "description": "Retorna status agregado da plataforma e dos componentes críticos\n(PostgreSQL, Redis, integrações externas). Use este endpoint em\nprobes de load balancer, monitoramento externo e dashboards de\nstatus. Não requer autenticação para permitir verificação de\nsaúde mesmo quando o serviço de auth está degradado.\n",
        "operationId": "healthCheck",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            },
            "description": "Sistema saudável"
          },
          "503": {
            "description": "Sistema degradado ou indisponível"
          }
        },
        "security": [],
        "summary": "Verifica saúde do sistema",
        "tags": [
          "Sentinex — Saúde"
        ]
      }
    },
    "/lgpd/me": {
      "get": {
        "parameters": [
          {
            "description": "UUID do client (operator-only, AnalystOrAbove)",
            "in": "query",
            "name": "id",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Confirmação + data_categories"
          },
          "404": {
            "description": "No record on file"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Confirmação de tratamento (Art. 18 II)",
        "tags": [
          "LGPD"
        ]
      }
    },
    "/lgpd/me/erase": {
      "post": {
        "description": "NÃO apaga imediatamente. Marca pending_erasure respeitando retenção\nlegal (BCB Res 520: 5 anos PJ regulada). DPO + cliente notificados.\nAudit log registra user_id do operador (B5 audit trail).\n",
        "parameters": [
          {
            "description": "UUID do client (operator-only)",
            "in": "query",
            "name": "id",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "justification": {
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Exclusão registrada em fila"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Solicitar exclusão (Art. 18 IV) — requer freshMFA",
        "tags": [
          "LGPD"
        ]
      }
    },
    "/lgpd/me/export": {
      "get": {
        "description": "Retorna JSON allowlist (DTO B4 Wave 1) com dados do titular. Campos\nsensíveis em SHA-256. format_version=1.2. Pode incluir bloco external_kyc\nou flag `external_kyc.available=false` quando query falhar.\n",
        "parameters": [
          {
            "description": "UUID do client (operator-only)",
            "in": "query",
            "name": "id",
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "JSON export attachment"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Portabilidade dos dados (Art. 18 V) — requer freshMFA",
        "tags": [
          "LGPD"
        ]
      }
    },
    "/public/catalog": {
      "get": {
        "description": "Retorna módulos com is_public_catalog=true e is_active=true.\nInclui pricing, billing model, included quota, dependencies,\nregulatory mapping (qual norma BR cada módulo atende).\n\nEndpoint sem autenticação — usado em página de pricing pré-signup.\n",
        "operationId": "publicCatalogList",
        "parameters": [
          {
            "in": "query",
            "name": "category",
            "schema": {
              "enum": [
                "core",
                "identity",
                "onchain",
                "regulatory",
                "compliance",
                "fraud",
                "forensics",
                "intelligence",
                "analytics",
                "operations",
                "commercial",
                "support"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/CatalogEntry"
                      },
                      "type": "array"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lista de módulos"
          }
        },
        "summary": "Catálogo público de módulos vendáveis",
        "tags": [
          "Plataforma — Módulos"
        ]
      }
    },
    "/public/signup": {
      "post": {
        "description": "Cadastro público sem autenticação. Cria atomicamente:\n\n- Tenant em estado TRIAL (14 dias, sem cartão)\n- Primeiro user com role TENANT_ADMIN\n- Módulos required ativados (mod_crypto_core, audit, rules, scoring, helpdesk)\n- API key sandbox (snxc_sand_*)\n\nValidações:\n- CNPJ formato válido (Mod11 checksum)\n- Email corporativo (provedores gratuitos opcionalmente bloqueados via SIGNUP_BLOCK_FREE_EMAILS)\n- Senha NIST 800-63B (mín 12 chars, letra+dígito, sem padrões comuns)\n- Aceites obrigatórios (terms + LGPD)\n- PSAVCategory enum (INTERMEDIARIA/CUSTODIANTE/CORRETORA/FINTECH/IGAMING/PSP/OUTRA)\n\nResponse inclui API key sandbox em plaintext APENAS uma vez. Cliente\ndeve copiar para uso imediato; rotação posterior via UI requer login.\n\nEmail welcome assíncrono enviado via Resend após sucesso (não bloqueia).\n",
        "operationId": "publicSignup",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "accept_lgpd": {
                    "description": "Obrigatório",
                    "type": "boolean"
                  },
                  "accept_terms": {
                    "description": "Obrigatório",
                    "type": "boolean"
                  },
                  "admin_email": {
                    "example": "fin@acme.com.br",
                    "format": "email",
                    "type": "string"
                  },
                  "admin_name": {
                    "example": "Maria Silva",
                    "minLength": 3,
                    "type": "string"
                  },
                  "admin_password": {
                    "example": "MinhaS3nhaForte!Acme",
                    "maxLength": 128,
                    "minLength": 12,
                    "type": "string"
                  },
                  "admin_phone": {
                    "example": "+55 11 99999-9999",
                    "type": "string"
                  },
                  "cnpj": {
                    "example": "11.222.333/0001-81",
                    "pattern": "^[0-9]{2}\\.?[0-9]{3}\\.?[0-9]{3}/?[0-9]{4}-?[0-9]{2}$",
                    "type": "string"
                  },
                  "company_name": {
                    "example": "Acme Tecnologia LTDA",
                    "maxLength": 200,
                    "minLength": 3,
                    "type": "string"
                  },
                  "opt_in_marketing": {
                    "default": false,
                    "type": "boolean"
                  },
                  "psav_category": {
                    "enum": [
                      "INTERMEDIARIA",
                      "CUSTODIANTE",
                      "CORRETORA",
                      "FINTECH",
                      "IGAMING",
                      "PSP",
                      "OUTRA"
                    ],
                    "type": "string"
                  },
                  "volume_band": {
                    "enum": [
                      "UNDER_1M",
                      "1M_TO_10M",
                      "10M_TO_100M",
                      "OVER_100M"
                    ],
                    "example": "1M_TO_10M",
                    "type": "string"
                  }
                },
                "required": [
                  "company_name",
                  "cnpj",
                  "psav_category",
                  "admin_name",
                  "admin_email",
                  "admin_password",
                  "accept_terms",
                  "accept_lgpd"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "email": {
                      "format": "email",
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "sandbox_api_key": {
                      "description": "API key plaintext — copie e armazene; não é recuperável",
                      "example": "snxc_sand_a1b2c3d4e5f6...",
                      "type": "string"
                    },
                    "sandbox_api_key_prefix": {
                      "example": "snxc_sand_",
                      "type": "string"
                    },
                    "success": {
                      "example": true,
                      "type": "boolean"
                    },
                    "tenant_id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "trial_ends_at": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "user_id": {
                      "format": "uuid",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Tenant criado com sucesso"
          },
          "400": {
            "description": "Validação falhou (invalid_cnpj, weak_password, terms_required, lgpd_required, etc)"
          },
          "409": {
            "description": "Conta já existe (anti-enumeration — não diferencia email vs slug)"
          }
        },
        "summary": "Cria tenant + first admin user (self-service onboarding)",
        "tags": [
          "Plataforma — Autenticação"
        ]
      }
    },
    "/radar/hotspots": {
      "get": {
        "description": "\nAgregação geo de transações suspeitas/bloqueadas no período: por país, estado BR, ASN de origem. Inclui breakdown por typology (pig butchering, drainer, SIM swap, etc) e evolução temporal. Use para identificar corredores quentes em planos de tuning regional.\n",
        "operationId": "getRadarHotspots",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RadarHotspots"
                }
              }
            },
            "description": "Hotspot data"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna hotspots geográficos de fraude",
        "tags": [
          "Sentinex — Radar"
        ]
      }
    },
    "/radar/live": {
      "get": {
        "description": "\nDiferencial Sentinex: feed live de transações sendo analisadas, decisões em tempo real, alertas disparados nos últimos 60s. WebSocket-friendly (também REST polling-friendly via cursor). Use para construir dashboards operacionais em tempo real e identificar bursts coordenados (e.g. ataque distribuído).\n",
        "operationId": "getRadarLive",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RadarLive"
                }
              }
            },
            "description": "Live radar data"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna feed de fraude em tempo real (Fraud Radar)",
        "tags": [
          "Sentinex — Radar"
        ]
      }
    },
    "/reports": {
      "get": {
        "description": "\nLista relatórios regulatórios do tenant: SAR (COAF), DeCripto (RFB IN 2291/2025), BCB FX (stablecoins mensal), reportes customizados. Cada relatório tem status (draft/generated/submitted/acknowledged) e link para o XML/PDF gerado. Filtros por tipo e período.\n",
        "operationId": "listReports",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "in": "query",
            "name": "type",
            "schema": {
              "enum": [
                "sar",
                "decripto",
                "bcb_fx",
                "coaf",
                "custom"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedReports"
                }
              }
            },
            "description": "Paginated report list"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista relatórios de compliance",
        "tags": [
          "Plataforma — Relatórios"
        ]
      }
    },
    "/reports/generate": {
      "post": {
        "description": "\nPipeline async: agregação de dados do período + geração de XML/PDF conforme schema regulatório + assinatura digital ICP-Brasil (cert A1/A3) + persistência com hash. Tipos suportados: SAR (XML COAF Manual VII), DeCripto (XSD RFB), BCB FX (XML BCB). Geração demora 30-180s; retorno imediato com job_id para polling.\n",
        "operationId": "generateReport",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateReportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "report_id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "generating"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Report generation started"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Gera relatório de compliance (papel compliance)",
        "tags": [
          "Plataforma — Relatórios"
        ]
      }
    },
    "/reports/{id}": {
      "get": {
        "description": "\nDetalhe completo do relatório: payload, status, audit trail, hash de integridade, assinatura ICP-Brasil (se signed), referência externa (protocolo COAF, ID DeCripto), histórico de envios e respostas regulatórias.\n",
        "operationId": "getReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Report"
                }
              }
            },
            "description": "Report details"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna relatório por ID",
        "tags": [
          "Plataforma — Relatórios"
        ]
      }
    },
    "/reports/{id}/submit": {
      "post": {
        "description": "\nEnvia relatório assinado ao endpoint do regulador (COAF SISCOAF, RFB DeCripto API, BCB ESTRA). Idempotente: submissões duplicadas retornam mesmo protocol_id. Em sucesso, status muda para `submitted` e timer de SLA de acknowledgement inicia. Falhas de transporte são retentadas com backoff exponencial.\n",
        "operationId": "submitReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "notes": {
                    "type": "string"
                  },
                  "target": {
                    "enum": [
                      "coaf",
                      "receita_federal",
                      "bcb"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Report submitted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Submete relatório ao órgão regulador (papel compliance)",
        "tags": [
          "Plataforma — Relatórios"
        ]
      }
    },
    "/rules": {
      "get": {
        "description": "Retorna regras ativas no Grule engine para o tenant atual:\nregras base (R-001..R-037 antifraude tradicional), regras\ncrypto-específicas (R-CRYPTO-01..R-CRYPTO-12 — pig\nbutchering, drainer, SIM swap, etc), regras avançadas\n(R-ADV-01..R-ADV-24 — typology pattern matching).\nCada regra inclui: descrição, peso no score final, status\n(active/shadow/disabled), versão, autor, métricas\nagregadas (FP rate, TP count nos últimos 30d).\n",
        "operationId": "listRules",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "rules": {
                      "items": {
                        "$ref": "#/components/schemas/Rule"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lista de regras com versão, peso, status e métricas agregadas"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista todas as regras de risco do tenant",
        "tags": [
          "Plataforma — Regras"
        ]
      }
    },
    "/rules/{id}": {
      "get": {
        "description": "Detalhe completo: DRL source (Grule rule definition\nlanguage), histórico de versões (each commit), métricas\nde execução (trigger rate, FP rate, TP count, average\nlatency contribution), exemplos de transações que\nrecentemente acionaram a regra (top 20 anonimizados),\nregras correlatas (que tendem a acionar junto).\n",
        "operationId": "getRule",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Rule"
                }
              }
            },
            "description": "Detalhe da regra com DRL source, métricas e exemplos"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna regra por ID",
        "tags": [
          "Plataforma — Regras"
        ]
      }
    },
    "/rules/{id}/shadow": {
      "post": {
        "description": "Toggle entre modo `shadow` (regra dispara mas não afeta\ndecisão final — apenas log para análise) e `enforce`\n(regra impacta decisão normalmente). Use shadow para\ntestar regras novas em produção sem risco operacional —\ncoleta FP/TP rate por N dias, valida que threshold está\nbem calibrado, depois promove para enforce. Toggle é\nhot-reloadable (não precisa restart). Mudança fica\nregistrada no audit trail com timestamp + user_id.\n",
        "operationId": "toggleRuleShadow",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "shadow": {
                    "description": "true = shadow mode (log only), false = enforce (impacta decisão)",
                    "type": "boolean"
                  }
                },
                "required": [
                  "shadow"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Modo shadow alternado; mudança hot-reload, sem restart"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Alterna modo shadow de uma regra (papel tenant admin)",
        "tags": [
          "Plataforma — Regras"
        ]
      }
    },
    "/security/challenge": {
      "get": {
        "description": "Retorna um challenge de proof-of-work que o cliente deve resolver\nantes de chamar `/auth/login` ou endpoints sensíveis. Defesa\ncontra credential stuffing e brute force distribuído: aumenta o\ncusto computacional do atacante sem onerar usuários legítimos.\nO dificuldade é ajustada dinamicamente conforme tenant_id, IP\nde origem e janela temporal de tentativas falhas.\n",
        "operationId": "getPoWChallenge",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "challenge": {
                      "type": "string"
                    },
                    "difficulty": {
                      "type": "integer"
                    },
                    "expires_at": {
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Challenge proof-of-work para o cliente resolver antes da autenticação"
          }
        },
        "security": [],
        "summary": "Obtém challenge proof-of-work para anti-abuso",
        "tags": [
          "Sentinex — Saúde"
        ]
      }
    },
    "/security/pubkey": {
      "get": {
        "description": "Retorna a chave pública RSA usada para cifrar payloads sensíveis\nno transporte (camada adicional sobre TLS). Clientes que enviam\nsecrets em request bodies (tokens, senhas em fluxo de signup)\ndevem cifrar com esta chave. O par de chaves é rotacionado em\nprod a cada 24h.\n",
        "operationId": "getPublicKey",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "public_key": {
                      "description": "Chave pública RSA codificada em PEM",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Chave pública RSA para criptografia de transporte"
          }
        },
        "security": [],
        "summary": "Obtém chave pública para criptografia de transporte",
        "tags": [
          "Sentinex — Saúde"
        ]
      }
    },
    "/transactions": {
      "get": {
        "description": "Retorna transações do tenant atual, paginadas, com filtros por\nperíodo (`from`/`to`), status (`pending` / `approved` /\n`blocked` / `review`) e nível de risco (`low` / `medium` /\n`high` / `critical`). Os resultados vêm ordenados por timestamp\ndecrescente. Páginas grandes (\u003e100) são cap-limitadas pelo\nservidor (`page_size` máximo 200). Use os links de paginação\nretornados no header `Link` para iteração estável.\n",
        "operationId": "listTransactions",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/DateFrom"
          },
          {
            "$ref": "#/components/parameters/DateTo"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "pending",
                "approved",
                "blocked",
                "review"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "risk_level",
            "schema": {
              "enum": [
                "low",
                "medium",
                "high",
                "critical"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedTransactions"
                }
              }
            },
            "description": "Lista paginada de transações filtradas"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista transações com filtros e paginação",
        "tags": [
          "Transações — Histórico"
        ]
      }
    },
    "/transactions/analyze": {
      "post": {
        "description": "Endpoint principal de KYT: recebe o payload da transação e\nretorna decisão (`APPROVE` / `REVIEW` / `REJECT`) em \u003c100ms p99\n(SLA contratual). Pipeline interno: SentinexPrint\n(fingerprint), enrichment (geo + bureau + watchlist), scoring\nem 5 dimensões, Grule rules engine (hot-reloadable), persistência.\nA transação é registrada com `transaction_id` retornado, que\npode ser usado para consultar em `/transactions/{id}` e\n`/transactions/{id}/explain`. Rate limit: por tenant, default\n100 RPS para tier Starter, escala em planos superiores.\n",
        "operationId": "analyzeTransaction",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyzeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalysisResult"
                }
              }
            },
            "description": "Resultado da análise de risco com decisão e breakdown"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Submete transação para análise de risco em tempo real",
        "tags": [
          "Transações — Histórico"
        ]
      }
    },
    "/transactions/{id}": {
      "get": {
        "description": "Detalhe completo de uma transação: payload original, decisão\nfinal, score 5-D breakdown (sentinexprint, payload, geo,\ncomportamental, contextual), regras acionadas com peso, alertas\ngerados, links para alertas/casos correlacionados, audit trail\n(quem aprovou/revisou/escalonou). Retorna `404` se ID não\npertence ao tenant atual (defesa contra enumeração cross-tenant).\n",
        "operationId": "getTransaction",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transaction"
                }
              }
            },
            "description": "Detalhe completo da transação (payload + score + regras + audit)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna transação por ID",
        "tags": [
          "Transações — Histórico"
        ]
      }
    },
    "/transactions/{id}/explain": {
      "get": {
        "description": "Diferencial Sentinex (vs Sardine, Feedzai): explicabilidade\ncompleta. Retorna decomposição do score final em 5 dimensões\n(cada uma com sub-fatores), lista de regras acionadas com\npeso individual, contrafactuais (`o que mudaria a decisão se X\nfosse diferente`), evidências on-chain (se transação crypto),\ne fatores contextuais (horário, geolocalização, padrão histórico\ndo cliente). Use para tela de detalhe + para responder\nquestionamentos LGPD do titular (decisão automatizada).\n",
        "operationId": "explainTransaction",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExplainResponse"
                }
              }
            },
            "description": "Breakdown explicável do score com dimensões, regras e contrafactuais"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna breakdown explicável do score de risco da transação",
        "tags": [
          "Sentinex — Explicabilidade"
        ]
      }
    },
    "/transactions/{id}/review": {
      "post": {
        "description": "Encerra um caso em revisão manual com decisão do analista:\n`APPROVE` (override de regra que bloqueou), `BLOCK` (escalona\npara suspeição manual) ou `ESCALATE` (envia para mesa de\ncompliance/SAR). Obrigatório incluir `justification` (audit\ntrail). A decisão é imutável após persistida; retificações\nexigem caso novo. Trigger automático: se decisão = `BLOCK` e\nvalor \u003e R$100k OU acumulado 7 dias \u003e R$500k, dispara workflow\nSAR COAF.\n",
        "operationId": "reviewTransaction",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewResponse"
                }
              }
            },
            "description": "Decisão de revisão registrada (imutável a partir deste ponto)"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Registra decisão manual de revisão (papel analyst ou superior)",
        "tags": [
          "Transações — Histórico"
        ]
      }
    },
    "/wallets": {
      "get": {
        "description": "Retorna carteiras on-chain catalogadas pelo tenant atual:\nclustering proprietário Sentinex (não compra Chainalysis/TRM),\natribuição a entidades conhecidas (exchanges, mixers, gambling,\nsanctioned), histórico de exposição agregado. Filtros por\nblockchain (Bitcoin, Ethereum, Tron, Solana, Polygon) e nível\nde risco. Endereços completos sempre retornados (são públicos\non-chain) mas qualquer link com cliente PF/PJ é hashed.\n",
        "operationId": "listWallets",
        "parameters": [
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "in": "query",
            "name": "blockchain",
            "schema": {
              "enum": [
                "bitcoin",
                "ethereum",
                "tron",
                "solana",
                "polygon"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "risk_level",
            "schema": {
              "enum": [
                "low",
                "medium",
                "high",
                "critical"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedWallets"
                }
              }
            },
            "description": "Lista paginada de carteiras filtradas por blockchain e nível de risco"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista carteiras conhecidas com filtros",
        "tags": [
          "Carteiras — Análise"
        ]
      }
    },
    "/wallets/screen": {
      "post": {
        "description": "Endpoint sob demanda: recebe endereço + blockchain e\nretorna decisão de risco em \u003c500ms. Pipeline interno:\nnormalização de endereço (checksum EIP-55 para Ethereum\netc), busca em watchlists (OFAC SDN, ONU, COAF, listas\ninternas), screening em clustering proprietário (mixers,\nsanctioned, gambling, darknet markets), exposição a N hops\nconfigurável. Decisão final + breakdown explicável. Use\nantes de aceitar depósito ou autorizar saque.\n",
        "operationId": "screenWallet",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletScreenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletScreenResponse"
                }
              }
            },
            "description": "Resultado de screening com decisão e breakdown de exposição"
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Triagem de endereço de carteira contra bases de risco",
        "tags": [
          "Carteiras — Análise"
        ]
      }
    },
    "/wallets/{id}": {
      "get": {
        "description": "Detalhe completo: endereço, blockchain, primeira/última\natividade observada, saldo atual, score de risco com\nbreakdown (exposição direta a sanção, exposição indireta a\nN hops, idade do cluster, padrões típicos detectados),\nlabels conhecidos (Binance hot wallet, Tornado Cash, etc),\ncontraparts mais frequentes (top 20), proveniência inferida\n(faucet/mining/exchange/p2p). Use para investigação manual\nde carteira específica.\n",
        "operationId": "getWallet",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Wallet"
                }
              }
            },
            "description": "Detalhe completo da carteira com clustering + labels + score breakdown"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Retorna carteira por ID",
        "tags": [
          "Carteiras — Análise"
        ]
      }
    },
    "/wallets/{id}/blocklist": {
      "post": {
        "description": "Adiciona endereço à blocklist interna do tenant. Origem\npode ser inferida de match em sanção (OFAC/COAF) ou\ndecisão manual de compliance (`internal`). `reason`\nobrigatório registra contexto para audit BCB. Após\nblocklist: (a) novas transações envolvendo o endereço são\nbloqueadas em tempo real, (b) transações históricas geram\nalertas retroativos para revisão, (c) clientes com\nexposição ao endereço passam por re-screening.\n",
        "operationId": "blocklistWallet",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "reason": {
                    "type": "string"
                  },
                  "source": {
                    "description": "Origem do bloqueio (e.g. OFAC, COAF, internal)",
                    "type": "string"
                  }
                },
                "required": [
                  "reason"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Carteira em blocklist; bloqueio retroativo + re-screening de clientes expostos disparados"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Adiciona carteira à blocklist (papel compliance)",
        "tags": [
          "Carteiras — Análise"
        ]
      }
    },
    "/wallets/{id}/transactions": {
      "get": {
        "description": "Retorna transações on-chain envolvendo a carteira (in\n+ out), enriquecidas com atribuição da contraparte (se\nconhecida) e decisão Sentinex se a transação passou pelo\ntenant atual. Útil para investigação de padrão (smurfing,\npeeling chain, mixer in/out, sweep). Para análise de\ncluster completo (todos os endereços relacionados), use\nendpoint `/wallets/{id}` que retorna o cluster_id.\n",
        "operationId": "getWalletTransactions",
        "parameters": [
          {
            "$ref": "#/components/parameters/ResourceID"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PageSize"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedTransactions"
                }
              }
            },
            "description": "Lista paginada de transações on-chain da carteira (in + out + atribuição)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Lista transações de uma carteira específica",
        "tags": [
          "Carteiras — Análise"
        ]
      }
    },
    "/webhooks/blockchain": {
      "post": {
        "operationId": "handleBlockchainEvent",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BlockchainEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Event processed"
          },
          "401": {
            "description": "Invalid HMAC signature"
          }
        },
        "security": [
          {
            "hmacAuth": []
          }
        ],
        "summary": "Receive blockchain event notification",
        "tags": [
          "Plataforma — Webhooks"
        ]
      }
    },
    "/webhooks/chargeback": {
      "post": {
        "operationId": "handleChargeback",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChargebackEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Chargeback processed"
          },
          "401": {
            "description": "Invalid HMAC signature"
          }
        },
        "security": [
          {
            "hmacAuth": []
          }
        ],
        "summary": "Receive chargeback notification",
        "tags": [
          "Plataforma — Webhooks"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "Produção (V1) — em provisionamento (Onda 1 do roadmap)",
      "url": "https://api.crypto.sentinexrisk.com/v1"
    },
    {
      "description": "Sandbox público — dados fictícios, sem custo, rate limit 10 rpm",
      "url": "https://sandbox.api.crypto.sentinexrisk.com/v1"
    },
    {
      "description": "Produção (dashboard humano — JWT) — endpoint atual",
      "url": "https://crypto.sentinexrisk.com/api/v1"
    },
    {
      "description": "Desenvolvimento local",
      "url": "http://localhost:3000/api/v1"
    }
  ],
  "tags": [
    {
      "description": "Health checks e endpoints públicos de infraestrutura (chaves de\ncriptografia, desafios proof-of-work, status do sistema).\n",
      "name": "Sentinex — Saúde"
    },
    {
      "description": "Motor de decisão antifraude. Recebe contexto de transação ou cliente,\nretorna score 0-100 com breakdown em 5 dimensões e regras acionadas.\nLatência alvo \u0026lt;100ms p95.\n",
      "name": "Sentinex — Decisão"
    },
    {
      "description": "Quebra explicável da decisão antifraude (Explainable AI). Retorna\ncontribuição de cada feature e cada regra ao score final. Suporta\nauditoria regulatória e contestação operacional.\n",
      "name": "Sentinex — Explicabilidade"
    },
    {
      "description": "Mapa em tempo real de hotspots geográficos de fraude. Agrega alertas\npor região, tipologia e janela temporal para resposta proativa.\n",
      "name": "Sentinex — Radar"
    },
    {
      "description": "Coleta e consulta do SentinexPrint™ — fingerprint de dispositivo\nem 7 camadas (canvas, audio, fonts, WebGL, comportamento, network,\nsinais avançados). Substituto proprietário de FingerprintJS.\n",
      "name": "Sentinex — Fingerprint"
    },
    {
      "description": "Cadastro, atualização, consulta e remoção (soft delete LGPD) de\nclientes. Suporta pessoa física e jurídica brasileira (CPF/CNPJ).\n",
      "name": "Identidade — Clientes"
    },
    {
      "description": "Triagem de cliente contra listas de sanções (OFAC, ONU, União\nEuropeia, FinCEN), bases brasileiras (COAF, IBAMA, PGFN, CEIS,\nCEPIM, CNEP, TSE) e PEPs.\n",
      "name": "Identidade — Screening"
    },
    {
      "description": "Pontuação e revisão de transações cripto em tempo real. Cada\ntransação retorna decisão `APPROVE` / `REVIEW` / `REJECT` com\nscore 0-100, breakdown em 5 dimensões e regras acionadas.\n",
      "name": "Transações — KYT"
    },
    {
      "description": "Consulta paginada do histórico de transações com filtros (status,\nscore, severidade, blockchain, janela temporal).\n",
      "name": "Transações — Histórico"
    },
    {
      "description": "Análise on-chain de endereços: clustering, atribuição (exchange,\nmixer, sanctions, VASP conhecido), exposição a fontes ilícitas,\ncaminhos para endereços sancionados.\n",
      "name": "Carteiras — Análise"
    },
    {
      "description": "Inclusão e remoção de endereços em blocklist do tenant.\nAplicação automática em scoring futuro.\n",
      "name": "Carteiras — Blocklist"
    },
    {
      "description": "Triagem, atribuição, resolução e escalonamento de alertas gerados\npelo motor antifraude. Integra com Mesa de Trabalho.\n",
      "name": "Operações — Alertas"
    },
    {
      "description": "Gestão de casos de investigação. Agrega alertas, evidências, notas,\ntimeline e audit trail imutável. Escalável a SAR COAF.\n",
      "name": "Operações — Casos"
    },
    {
      "description": "Visão consolidada do operador: fila de alertas pendentes, casos\natribuídos, KYB em análise, escalonamentos urgentes.\n",
      "name": "Operações — Mesa de Trabalho"
    },
    {
      "description": "Geração e submissão de Relatório de Operação Suspeita (SAR / RIF)\nao COAF. Disparo automático em transações \u0026gt;R$100k ou agregadas\n\u0026gt;R$500k em 7 dias. Conforme Lei 9.613/1998 e Carta-Circular 4001.\n",
      "name": "Compliance — COAF (SAR)"
    },
    {
      "description": "Reporte mensal e anual à Receita Federal conforme IN 2291/2025\n(Declaração de Operações com Criptoativos).\n",
      "name": "Compliance — RFB (DeCripto)"
    },
    {
      "description": "Reporte mensal de operações de câmbio com stablecoins ao Banco\nCentral, conforme CMN Res. 5280/5281 (vigência 04/05/2026).\n",
      "name": "Compliance — BCB (Câmbio)"
    },
    {
      "description": "Troca de mensagens IVMS101 entre VASPs (originador e beneficiário)\nconforme Art. 44 e Art. 89 da BCB Res. 520.\n",
      "name": "Compliance — Travel Rule"
    },
    {
      "description": "Atendimento ao titular (DSAR), soft delete, anonimização. Cobertura\nLei 13.709/2018 e regulamentações ANPD.\n",
      "name": "Compliance — LGPD"
    },
    {
      "description": "Login, MFA (TOTP), refresh de sessão, logout, gestão de senha.\nJWT RS256 com cookie HttpOnly + Secure + SameSite=Strict.\n",
      "name": "Plataforma — Autenticação"
    },
    {
      "description": "Métricas agregadas e KPIs do dashboard (volume, scores médios,\nalertas abertos, casos pendentes, conformidade regulatória).\n",
      "name": "Plataforma — Painel"
    },
    {
      "description": "Listagem de regras do motor antifraude (37 base + 12 crypto +\n24 avançadas = 73 regras totais), toggle shadow-mode, versionamento.\n",
      "name": "Plataforma — Regras"
    },
    {
      "description": "Geração de relatórios consolidados para auditoria interna e externa\n(PDF, CSV, XLSX). Suporta export assíncrono para volumes grandes.\n",
      "name": "Plataforma — Relatórios"
    },
    {
      "description": "Recebimento de webhooks de provedores externos (chargeback,\nblockchain events, billing providers). HMAC SHA-256 + replay protect.\n",
      "name": "Plataforma — Webhooks"
    },
    {
      "description": "Faturamento BR-nativo: boleto, PIX, cartão (via Asaas) e emissão\nde NFS-e (via eNotas). Faturamento recorrente por plano.\n",
      "name": "Plataforma — Cobrança"
    },
    {
      "description": "Licenciamento modular. Catálogo de módulos, entitlements por tenant,\ncontrole de quota, trial sob demanda. Mapeia obrigações regulatórias\nbrasileiras (BCB Res. 520/521, RFB IN 2291/2025, COAF Lei 9.613)\na módulos comercializáveis individualmente ou em pacotes.\n",
      "name": "Plataforma — Módulos"
    },
    {
      "description": "Endpoints exclusivos para super-administradores Sentinex. Gestão\nde tenants, usuários cross-tenant, auditoria global, configurações\ndo produto.\n",
      "name": "Administração"
    }
  ]
}