import { ApiProperty } from "@nestjs/swagger"; export type SignalTier = "CORE" | "VALUE" | "LEAN" | "LONGSHOT" | "PASS"; export class MatchInfoDto { @ApiProperty() match_id: string; @ApiProperty() match_name: string; @ApiProperty() home_team: string; @ApiProperty() away_team: string; @ApiProperty() league: string; @ApiProperty() match_date_ms: number; @ApiProperty({ required: false, nullable: true }) league_id?: string | null; @ApiProperty({ required: false, default: false }) is_top_league?: boolean; @ApiProperty({ required: false, enum: ["football", "basketball"], }) sport?: "football" | "basketball"; } export class DataQualityDto { @ApiProperty({ enum: ["HIGH", "MEDIUM", "LOW"] }) label: "HIGH" | "MEDIUM" | "LOW"; @ApiProperty() score: number; @ApiProperty() home_lineup_count: number; @ApiProperty() away_lineup_count: number; @ApiProperty({ required: false, default: "none" }) lineup_source?: string; @ApiProperty({ type: [String] }) flags: string[]; } export class ConfidenceIntervalDto { @ApiProperty() lower: number; @ApiProperty() upper: number; @ApiProperty() width: number; @ApiProperty({ enum: ["HIGH", "MEDIUM", "LOW"] }) band: "HIGH" | "MEDIUM" | "LOW"; @ApiProperty() threshold_met: boolean; } export class RiskDto { @ApiProperty({ enum: ["LOW", "MEDIUM", "HIGH", "EXTREME"] }) level: "LOW" | "MEDIUM" | "HIGH" | "EXTREME"; @ApiProperty() score: number; @ApiProperty() is_surprise_risk: boolean; @ApiProperty({ nullable: true }) surprise_type: string | null; @ApiProperty({ required: false, default: 0 }) surprise_score?: number; @ApiProperty({ required: false, nullable: true }) surprise_comment?: string | null; @ApiProperty({ type: [String], required: false }) surprise_reasons?: string[]; @ApiProperty({ type: [String] }) warnings: string[]; } export class EngineBreakdownDto { @ApiProperty() team: number; @ApiProperty() player: number; @ApiProperty() odds: number; @ApiProperty() referee: number; } export class MatchPickDto { @ApiProperty() market: string; @ApiProperty({ required: false, default: "standard" }) strategy_channel?: string; @ApiProperty() pick: string; @ApiProperty() probability: number; @ApiProperty() confidence: number; @ApiProperty() odds: number; @ApiProperty() raw_confidence: number; @ApiProperty() calibrated_confidence: number; @ApiProperty() min_required_confidence: number; @ApiProperty() edge: number; @ApiProperty({ required: false, default: 0 }) ev_edge?: number; @ApiProperty({ required: false, default: 0 }) implied_prob?: number; @ApiProperty({ required: false, default: 0 }) model_probability?: number; @ApiProperty({ required: false, default: 0 }) model_edge?: number; @ApiProperty({ required: false, default: 0 }) calibrated_probability?: number; @ApiProperty({ required: false, default: 0 }) odds_band_probability?: number; @ApiProperty({ required: false, default: 0 }) odds_band_sample?: number; @ApiProperty({ required: false, default: 0 }) odds_band_edge?: number; @ApiProperty({ required: false, default: false }) odds_band_aligned?: boolean; @ApiProperty() play_score: number; @ApiProperty() playable: boolean; @ApiProperty({ enum: ["A", "B", "C", "PASS"] }) bet_grade: "A" | "B" | "C" | "PASS"; @ApiProperty() stake_units: number; @ApiProperty({ type: [String] }) decision_reasons: string[]; @ApiProperty({ type: ConfidenceIntervalDto, required: false }) confidence_interval?: ConfidenceIntervalDto; @ApiProperty({ required: false, enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"], }) signal_tier?: SignalTier; @ApiProperty({ required: false, default: false }) is_guaranteed?: boolean; } export class MatchBetAdviceDto { @ApiProperty() playable: boolean; @ApiProperty() suggested_stake_units: number; @ApiProperty() reason: string; @ApiProperty({ required: false, enum: ["HIGH", "MEDIUM", "LOW"] }) confidence_band?: "HIGH" | "MEDIUM" | "LOW"; @ApiProperty({ required: false }) min_confidence_for_play?: number; @ApiProperty({ required: false, enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"], }) signal_tier?: SignalTier; } export class MatchBetSummaryItemDto { @ApiProperty() market: string; @ApiProperty() pick: string; @ApiProperty() raw_confidence: number; @ApiProperty() calibrated_confidence: number; @ApiProperty({ enum: ["A", "B", "C", "PASS"] }) bet_grade: "A" | "B" | "C" | "PASS"; @ApiProperty() playable: boolean; @ApiProperty() stake_units: number; @ApiProperty() play_score: number; @ApiProperty({ required: false, default: 0 }) ev_edge?: number; @ApiProperty({ required: false, default: 0 }) implied_prob?: number; @ApiProperty({ required: false, default: 0 }) model_probability?: number; @ApiProperty({ required: false, default: 0 }) model_edge?: number; @ApiProperty({ required: false, default: 0 }) calibrated_probability?: number; @ApiProperty({ required: false, default: 0 }) odds_band_probability?: number; @ApiProperty({ required: false, default: 0 }) odds_band_sample?: number; @ApiProperty({ required: false, default: 0 }) odds_band_edge?: number; @ApiProperty({ required: false, default: false }) odds_band_aligned?: boolean; @ApiProperty({ required: false, default: 0 }) odds?: number; @ApiProperty({ type: [String] }) reasons: string[]; @ApiProperty({ type: ConfidenceIntervalDto, required: false }) confidence_interval?: ConfidenceIntervalDto; @ApiProperty({ required: false, enum: ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"], }) signal_tier?: SignalTier; } export class HtFtPredictionDto { @ApiProperty() "1/1": number; @ApiProperty() "1/X": number; @ApiProperty() "1/2": number; @ApiProperty() "X/1": number; @ApiProperty() "X/X": number; @ApiProperty() "X/2": number; @ApiProperty() "2/1": number; @ApiProperty() "2/X": number; @ApiProperty() "2/2": number; @ApiProperty() pick: string; @ApiProperty() confidence: number; } export class AggressivePickDto { @ApiProperty() market: string; @ApiProperty() pick: string; @ApiProperty() probability: number; @ApiProperty() confidence: number; @ApiProperty() odds: number; @ApiProperty() raw_confidence: number; @ApiProperty() calibrated_confidence: number; @ApiProperty() min_required_confidence: number; @ApiProperty() edge: number; @ApiProperty({ required: false, default: 0 }) ev_edge?: number; @ApiProperty({ required: false, default: 0 }) implied_prob?: number; @ApiProperty() play_score: number; @ApiProperty() playable: boolean; @ApiProperty({ enum: ["A", "B", "C", "PASS"] }) bet_grade: "A" | "B" | "C" | "PASS"; @ApiProperty() stake_units: number; @ApiProperty({ type: [String] }) decision_reasons: string[]; @ApiProperty({ type: ConfidenceIntervalDto, required: false }) confidence_interval?: ConfidenceIntervalDto; } export class ScenarioTop5ItemDto { @ApiProperty() scenario: string; @ApiProperty() score: number; @ApiProperty() probability: number; } export class ScorePredictionDto { @ApiProperty() ft: string; @ApiProperty() ht: string; @ApiProperty() xg_home: number; @ApiProperty() xg_away: number; @ApiProperty() xg_total: number; } export class MatchPredictionDto { @ApiProperty() model_version: string; @ApiProperty({ required: false, nullable: true }) calibration_version?: string | null; @ApiProperty({ required: false, nullable: true }) shadow_engine_version?: string | null; @ApiProperty({ required: false, nullable: true }) decision_trace_id?: string | null; @ApiProperty({ type: MatchInfoDto }) match_info: MatchInfoDto; @ApiProperty({ type: DataQualityDto }) data_quality: DataQualityDto; @ApiProperty({ type: RiskDto }) risk: RiskDto; @ApiProperty({ type: EngineBreakdownDto }) engine_breakdown: EngineBreakdownDto; @ApiProperty({ type: MatchPickDto, nullable: true }) main_pick: MatchPickDto | null; @ApiProperty({ type: MatchPickDto, nullable: true }) value_pick: MatchPickDto | null; @ApiProperty({ type: MatchPickDto, nullable: true, required: false }) surprise_pick?: MatchPickDto | null; @ApiProperty({ type: MatchBetAdviceDto }) bet_advice: MatchBetAdviceDto; @ApiProperty({ type: [MatchBetSummaryItemDto] }) bet_summary: MatchBetSummaryItemDto[]; @ApiProperty({ type: [MatchPickDto] }) supporting_picks: MatchPickDto[]; @ApiProperty({ type: AggressivePickDto, nullable: true }) aggressive_pick: AggressivePickDto | null; @ApiProperty({ type: HtFtPredictionDto, required: false }) htft?: HtFtPredictionDto; @ApiProperty({ type: [ScenarioTop5ItemDto] }) scenario_top5: ScenarioTop5ItemDto[]; @ApiProperty({ type: ScorePredictionDto }) score_prediction: ScorePredictionDto; @ApiProperty({ type: Object }) market_board: Record; @ApiProperty({ type: [String] }) reasoning_factors: string[]; @ApiProperty({ type: Object, required: false }) market_reliability?: Record; @ApiProperty({ type: Object, required: false }) shadow_engine?: Record; @ApiProperty({ type: Object, required: false }) surprise_hunter?: Record; @ApiProperty({ type: Object, required: false, description: "V28 Odds-Band engine output: historical band analytics, triple-value detection, cards profiling, and HTFT 9-combo analysis", }) v27_engine?: Record; } export class ValueBetDto { @ApiProperty() matchId: string; @ApiProperty() matchName: string; @ApiProperty() betType: string; @ApiProperty() prediction: string; @ApiProperty() confidence: number; @ApiProperty() odd: number; @ApiProperty() expectedValue: number; } export class PredictionHistoryStatsDto { @ApiProperty() totalPredictions: number; @ApiProperty() totalResolved: number; @ApiProperty() correctPredictions: number; @ApiProperty() accuracyRate: number; } export class PredictionHistoryResponseDto { @ApiProperty({ type: PredictionHistoryStatsDto }) stats: PredictionHistoryStatsDto; @ApiProperty({ type: [Object] }) history: Record[]; } export class UpcomingPredictionsDto { @ApiProperty() count: number; @ApiProperty({ type: [MatchPredictionDto] }) matches: MatchPredictionDto[]; @ApiProperty() modelVersion: string; } export class AIHealthDto { @ApiProperty() status: string; @ApiProperty() modelLoaded: boolean; @ApiProperty() predictionServiceReady: boolean; @ApiProperty({ required: false, default: true }) aiEngineReachable?: boolean; @ApiProperty({ required: false, enum: ["closed", "open"] }) circuitState?: "closed" | "open"; @ApiProperty({ required: false, default: 0 }) consecutiveFailures?: number; @ApiProperty({ required: false }) endpoint?: string; @ApiProperty({ required: false, nullable: true }) detail?: string | null; @ApiProperty({ required: false, nullable: true }) mode?: string | null; } export * from "./smart-coupon.dto";