Spaces:
Running on Zero
Running on Zero
| """ | |
| schemas.py | |
| ---------- | |
| Pydantic schemas for RazorShield Public API endpoints. | |
| """ | |
| from __future__ import annotations | |
| from datetime import datetime | |
| from typing import Any, Literal, Optional | |
| from pydantic import BaseModel, Field, field_validator | |
| class TransactionApiInput(BaseModel): | |
| """Public API input payload for transaction risk analysis.""" | |
| merchant_id: str = Field(..., description="Unique merchant identifier") | |
| transaction_id: str = Field(..., description="Unique transaction identifier") | |
| customer_id: str = Field(default="C_UNKNOWN", description="Customer identifier") | |
| device_id: str = Field(default="D_UNKNOWN", description="Device identifier") | |
| event_time: datetime = Field(..., description="Event timestamp (ISO 8601)") | |
| amount: float = Field(..., ge=0.0, description="Transaction amount (>= 0.0)") | |
| payment_method: str = Field(default="card", description="Payment method") | |
| transaction_type: str = Field(default="sale", description="Transaction type") | |
| policy_mode: str = Field(default="BALANCED", description="Policy mode (CONSERVATIVE, BALANCED, HIGH_SENSITIVITY)") | |
| def check_non_empty(cls, v: str, info: Any) -> str: | |
| if not v or not v.strip(): | |
| raise ValueError(f"Field '{info.field_name}' must be a non-empty string.") | |
| return v.strip() | |
| class TransactionRiskResponse(BaseModel): | |
| fraud_probability: float = Field(..., ge=0.0, le=1.0) | |
| class MerchantRiskResponse(BaseModel): | |
| spike_probability: float = Field(..., ge=0.0, le=1.0) | |
| fraud_excess_ratio: float = Field(..., ge=0.0) | |
| velocity_ratio: float = Field(..., ge=0.0) | |
| incident_state: Literal["NORMAL", "INVESTIGATE", "ALERT"] | |
| severity: Literal["LOW", "MEDIUM", "HIGH"] | |
| incident_score: float = Field(..., ge=0.0, le=1.0) | |
| suspicious_windows: int = Field(..., ge=0) | |
| class CampaignInfoResponse(BaseModel): | |
| active: bool | |
| campaign_name: Optional[str] = None | |
| class DecisionResponse(BaseModel): | |
| action: Literal["APPROVE", "VERIFY", "ALERT"] | |
| policy_mode: str | |
| class PerformanceMetricsResponse(BaseModel): | |
| risk_engine_latency_ms: float = Field(..., ge=0.0) | |
| slm_latency_ms: float = Field(..., ge=0.0) | |
| total_latency_ms: float = Field(..., ge=0.0) | |
| class AnalyzeTransactionResponse(BaseModel): | |
| """Complete structured JSON response for transaction analysis.""" | |
| transaction_id: str | |
| merchant_id: str | |
| transaction_risk: TransactionRiskResponse | |
| merchant_risk: MerchantRiskResponse | |
| campaign: CampaignInfoResponse | |
| decision: DecisionResponse | |
| explanation: dict[str, Any] | |
| performance: PerformanceMetricsResponse | |