gg
Deploy Iddaai Frontend / build-and-deploy (push) Successful in 2m41s

This commit is contained in:
2026-05-12 03:03:49 +03:00
parent e6e58b4433
commit b2ccc98226
24 changed files with 814 additions and 164 deletions
+4
View File
@@ -8,6 +8,8 @@ export interface AdminPaginationParams extends PaginationDto {
sortBy?: string;
sortOrder?: "asc" | "desc";
search?: string;
role?: string;
subscriptionStatus?: string;
}
// ========================
@@ -50,6 +52,7 @@ export interface AdminUserDto {
isActive: boolean;
subscription?: string;
subscriptionStatus?: string;
subscriptionExpiresAt?: string | null;
createdAt: string;
[key: string]: unknown;
}
@@ -60,6 +63,7 @@ export interface UpdateUserRoleDto {
export interface UpdateUserSubscriptionDto {
plan: string;
expiresAt?: string | null;
}
// ========================
+6 -5
View File
@@ -13,8 +13,9 @@ export const AdminQueryKeys = {
settings: () => [...AdminQueryKeys.all, "settings"] as const,
usageLimits: (params?: AdminPaginationParams) =>
[...AdminQueryKeys.all, "usageLimits", params] as const,
usersList: () => [...AdminQueryKeys.all, "users"] as const,
users: (params?: AdminPaginationParams) =>
[...AdminQueryKeys.all, "users", params] as const,
[...AdminQueryKeys.usersList(), params] as const,
user: (id: string) => [...AdminQueryKeys.all, "user", id] as const,
};
@@ -104,7 +105,7 @@ export const useDeleteUser = () => {
return useMutation({
mutationFn: (id: string) => adminService.deleteUser(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.users() });
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.usersList() });
},
});
};
@@ -116,7 +117,7 @@ export const useUpdateUserRole = () => {
mutationFn: ({ id, dto }: { id: string; dto: UpdateUserRoleDto }) =>
adminService.updateUserRole(id, dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.users() });
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.usersList() });
},
});
};
@@ -128,7 +129,7 @@ export const useUpdateUserSubscription = () => {
mutationFn: ({ id, dto }: { id: string; dto: UpdateUserSubscriptionDto }) =>
adminService.updateUserSubscription(id, dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.users() });
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.usersList() });
},
});
};
@@ -139,7 +140,7 @@ export const useToggleUserActive = () => {
return useMutation({
mutationFn: (id: string) => adminService.toggleUserActive(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.users() });
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.usersList() });
},
});
};
+6 -1
View File
@@ -65,7 +65,12 @@ export interface MatchResponseDto {
// Scores
scoreHome?: number;
scoreAway?: number;
score?: { home: number; away: number };
score?: {
home: number;
away: number;
htHome?: number | null;
htAway?: number | null;
};
htScoreHome?: number;
htScoreAway?: number;
+69
View File
@@ -14,9 +14,27 @@ export interface MatchInfoDto {
league_id?: string | null;
is_top_league?: boolean;
sport?: SportType;
// Live snapshot — set when the match is in play (used to detect stale predictions)
status?: string | null;
state?: string | null;
is_live?: boolean;
current_score_home?: number | null;
current_score_away?: number | null;
[key: string]: unknown;
}
export interface PredictionFreshnessDto {
generated_at_ms: number;
is_pre_match_snapshot: boolean;
is_stale_for_live: boolean;
}
export interface SurpriseBreakdownEntryDto {
code: string;
points: number;
label: string;
}
export interface DataQualityDto {
label: "HIGH" | "MEDIUM" | "LOW";
score: number;
@@ -43,14 +61,29 @@ export interface RiskDto {
surprise_score?: number;
surprise_comment?: string | null;
surprise_reasons?: string[];
surprise_breakdown?: SurpriseBreakdownEntryDto[];
warnings: string[];
}
export interface EngineBreakdownDetailEntryDto {
score: number;
label: "YUKSEK" | "ORTA" | "DUSUK" | "COK_DUSUK" | string;
display_name: string;
interpretation: string;
}
export interface EngineBreakdownDto {
team: number;
player: number;
odds: number;
referee: number;
detail?: {
team?: EngineBreakdownDetailEntryDto;
player?: EngineBreakdownDetailEntryDto;
odds?: EngineBreakdownDetailEntryDto;
referee?: EngineBreakdownDetailEntryDto;
[key: string]: EngineBreakdownDetailEntryDto | undefined;
};
[key: string]: unknown;
}
@@ -86,10 +119,34 @@ export interface MatchPickDto {
is_guaranteed?: boolean;
}
export type BettingBrainAction =
| "BET"
| "WATCH"
| "WATCH_NO_VALUE"
| "REJECT";
export interface BettingBrainEntryDto {
action: BettingBrainAction;
score: number;
summary: string;
positives: string[];
issues: string[];
vetoes: string[];
sniper_bypassed?: string[];
trap_market_flag?: boolean;
trap_market_gap?: number | null;
model_prob?: number | null;
implied_prob?: number;
model_market_gap?: number | null;
triple_key?: string | null;
triple_value?: Record<string, unknown> | null;
}
export interface MatchBetAdviceDto {
playable: boolean;
suggested_stake_units: number;
reason: string;
decision?: "BET" | "WATCHLIST" | "WATCH_NO_VALUE" | "NO_BET" | string;
confidence_band?: "HIGH" | "MEDIUM" | "LOW";
min_confidence_for_play?: number;
signal_tier?: SignalTier;
@@ -118,6 +175,9 @@ export interface MatchBetSummaryItemDto {
reasons: string[];
confidence_interval?: ConfidenceIntervalDto;
signal_tier?: SignalTier;
// New (post-engine-upgrade)
is_underdog_reference?: boolean;
betting_brain?: BettingBrainEntryDto;
}
export interface AggressivePickDto {
@@ -266,6 +326,15 @@ export interface MatchPredictionDto {
reasoning_factors: string[];
ai_commentary?: string | null;
v27_engine?: V27EngineDto;
prediction_freshness?: PredictionFreshnessDto;
match_commentary?: {
action?: string;
headline?: string;
summary?: string;
notes?: string[];
contradictions?: string[];
confidence_label?: string;
};
}
export interface ValueBetDto {