220 lines
4.7 KiB
TypeScript
220 lines
4.7 KiB
TypeScript
import { apiRequest } from "@/lib/api/api-service";
|
|
import { ApiResponse } from "@/types/api-response";
|
|
|
|
/**
|
|
* Spor Toto Service
|
|
* Backend: /api/spor-toto/*
|
|
*/
|
|
|
|
// ========================
|
|
// Request DTOs
|
|
// ========================
|
|
|
|
export interface CreateBulletinDto {
|
|
gameCycleNo: number;
|
|
drawDate: string;
|
|
matches: {
|
|
matchId: string;
|
|
homeTeam: string;
|
|
awayTeam: string;
|
|
matchDate: string;
|
|
}[];
|
|
}
|
|
|
|
export interface UpdateResultsDto {
|
|
results: {
|
|
matchIndex: number;
|
|
homeScore: number;
|
|
awayScore: number;
|
|
}[];
|
|
}
|
|
|
|
export interface GenerateColumnsDto {
|
|
selections: { matchIndex: number; picks: ("1" | "X" | "2")[] }[];
|
|
strategy?: "FULL" | "REDUCED";
|
|
maxColumns?: number;
|
|
}
|
|
|
|
export interface EvaluateColumnsDto {
|
|
bulletinId: string;
|
|
columns: string[];
|
|
}
|
|
|
|
export interface GenerateSporTotoPredictionDto {
|
|
bulletinId: string;
|
|
strategy?: "CONSERVATIVE" | "BALANCED" | "AGGRESSIVE" | "FORMULA_6PCT";
|
|
}
|
|
|
|
// ========================
|
|
// Response DTOs
|
|
// ========================
|
|
|
|
export interface SporTotoMatchDto {
|
|
id: string;
|
|
matchIndex: number;
|
|
homeTeam: string;
|
|
awayTeam: string;
|
|
matchDate: string;
|
|
result?: string;
|
|
homeScore?: number;
|
|
awayScore?: number;
|
|
prediction?: {
|
|
pick: string;
|
|
confidence: number;
|
|
odds: Record<string, number>;
|
|
};
|
|
}
|
|
|
|
export interface SporTotoBulletinDto {
|
|
id: string;
|
|
gameCycleNo: number;
|
|
drawDate: string;
|
|
status: string;
|
|
matches: SporTotoMatchDto[];
|
|
totalPool?: number;
|
|
dividends?: Record<string, number>;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface SporTotoStatsDto {
|
|
poolDistribution: Record<string, number>;
|
|
expectedValue: Record<string, number>;
|
|
rolloverAmount: number;
|
|
consecutiveRollovers: number;
|
|
}
|
|
|
|
export interface ColumnGenerationResultDto {
|
|
columns: string[];
|
|
totalCost: number;
|
|
strategy: string;
|
|
}
|
|
|
|
export interface ColumnEvaluationResultDto {
|
|
results: { column: string; correct: number }[];
|
|
summary: Record<string, number>;
|
|
}
|
|
|
|
export interface SporTotoPredictionResultDto {
|
|
bulletin: SporTotoBulletinDto;
|
|
matchAnalysis: Record<string, unknown>;
|
|
systemCoupon: {
|
|
columns: string[];
|
|
cost: number;
|
|
};
|
|
evReport: {
|
|
expectedValue: number;
|
|
playRecommendation: string;
|
|
};
|
|
}
|
|
|
|
export interface RolloverHistoryItemDto {
|
|
bulletinId: string;
|
|
gameCycleNo: number;
|
|
rolloverAmount: number;
|
|
drawDate: string;
|
|
}
|
|
|
|
// ========================
|
|
// Service Methods
|
|
// ========================
|
|
|
|
const syncFromApi = () => {
|
|
return apiRequest<ApiResponse<unknown>>({
|
|
url: "/spor-toto/sync",
|
|
client: "core",
|
|
method: "post",
|
|
});
|
|
};
|
|
|
|
const listBulletins = (status?: string, limit?: number) => {
|
|
return apiRequest<ApiResponse<SporTotoBulletinDto[]>>({
|
|
url: "/spor-toto/bulletins",
|
|
client: "core",
|
|
method: "get",
|
|
params: { status, limit },
|
|
});
|
|
};
|
|
|
|
const getBulletinById = (id: string) => {
|
|
return apiRequest<ApiResponse<SporTotoBulletinDto>>({
|
|
url: `/spor-toto/bulletins/${id}`,
|
|
client: "core",
|
|
method: "get",
|
|
});
|
|
};
|
|
|
|
const createBulletin = (dto: CreateBulletinDto) => {
|
|
return apiRequest<ApiResponse<SporTotoBulletinDto>>({
|
|
url: "/spor-toto/bulletins",
|
|
client: "core",
|
|
method: "post",
|
|
data: dto,
|
|
});
|
|
};
|
|
|
|
const updateResults = (id: string, dto: UpdateResultsDto) => {
|
|
return apiRequest<ApiResponse<SporTotoBulletinDto>>({
|
|
url: `/spor-toto/bulletins/${id}/results`,
|
|
client: "core",
|
|
method: "patch",
|
|
data: dto,
|
|
});
|
|
};
|
|
|
|
const getBulletinStats = (id: string) => {
|
|
return apiRequest<ApiResponse<SporTotoStatsDto>>({
|
|
url: `/spor-toto/bulletins/${id}/stats`,
|
|
client: "core",
|
|
method: "get",
|
|
});
|
|
};
|
|
|
|
const getRolloverHistory = (limit?: number) => {
|
|
return apiRequest<ApiResponse<RolloverHistoryItemDto[]>>({
|
|
url: "/spor-toto/history",
|
|
client: "core",
|
|
method: "get",
|
|
params: { limit },
|
|
});
|
|
};
|
|
|
|
const generateColumns = (dto: GenerateColumnsDto) => {
|
|
return apiRequest<ApiResponse<ColumnGenerationResultDto>>({
|
|
url: "/spor-toto/columns/generate",
|
|
client: "core",
|
|
method: "post",
|
|
data: dto,
|
|
});
|
|
};
|
|
|
|
const evaluateColumns = (dto: EvaluateColumnsDto) => {
|
|
return apiRequest<ApiResponse<ColumnEvaluationResultDto>>({
|
|
url: "/spor-toto/columns/evaluate",
|
|
client: "core",
|
|
method: "post",
|
|
data: dto,
|
|
});
|
|
};
|
|
|
|
const generatePrediction = (dto: GenerateSporTotoPredictionDto) => {
|
|
return apiRequest<ApiResponse<SporTotoPredictionResultDto>>({
|
|
url: "/spor-toto/predict",
|
|
client: "core",
|
|
method: "post",
|
|
data: dto,
|
|
});
|
|
};
|
|
|
|
export const sporTotoService = {
|
|
syncFromApi,
|
|
listBulletins,
|
|
getBulletinById,
|
|
createBulletin,
|
|
updateResults,
|
|
getBulletinStats,
|
|
getRolloverHistory,
|
|
generateColumns,
|
|
evaluateColumns,
|
|
generatePrediction,
|
|
};
|