This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Param,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger';
|
||||
import { PredictionsService } from './predictions.service';
|
||||
import {
|
||||
MatchPredictionDto,
|
||||
PredictionHistoryResponseDto,
|
||||
UpcomingPredictionsDto,
|
||||
ValueBetDto,
|
||||
AIHealthDto,
|
||||
} from './dto';
|
||||
import {
|
||||
GeneratePredictionDto,
|
||||
SmartCouponRequestDto,
|
||||
} from './dto/predictions-request.dto';
|
||||
import { Public } from 'src/common/decorators';
|
||||
|
||||
@ApiTags('Predictions')
|
||||
@Controller('predictions')
|
||||
export class PredictionsController {
|
||||
constructor(private readonly predictionsService: PredictionsService) {}
|
||||
|
||||
/**
|
||||
* GET /predictions/health
|
||||
* Check AI Engine health status
|
||||
*/
|
||||
@Get('health')
|
||||
@ApiOperation({ summary: 'Check AI Engine health status' })
|
||||
@ApiResponse({ status: 200, type: AIHealthDto })
|
||||
async checkHealth(): Promise<AIHealthDto> {
|
||||
return this.predictionsService.checkHealth();
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /predictions/upcoming
|
||||
* Get predictions for upcoming matches
|
||||
*/
|
||||
@Get('upcoming')
|
||||
@ApiOperation({ summary: 'Get predictions for upcoming matches' })
|
||||
@ApiResponse({ status: 200, type: UpcomingPredictionsDto })
|
||||
async getUpcoming(): Promise<UpcomingPredictionsDto> {
|
||||
return this.predictionsService.getUpcomingPredictions();
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /predictions/test/:id
|
||||
* Refetch match data and get prediction
|
||||
*/
|
||||
@Get('test/:id')
|
||||
@ApiOperation({ summary: 'Refetch match data and get prediction' })
|
||||
@ApiParam({ name: 'id', description: 'Match ID' })
|
||||
async getTestPrediction(@Param('id') id: string) {
|
||||
return this.predictionsService.testPrediction(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /predictions/value-bets
|
||||
* Get EV+ betting opportunities
|
||||
*/
|
||||
@Get('value-bets')
|
||||
@ApiOperation({ summary: 'Get value betting opportunities (EV+)' })
|
||||
@ApiResponse({ status: 200, type: [ValueBetDto] })
|
||||
async getValueBets(): Promise<ValueBetDto[]> {
|
||||
return this.predictionsService.getValueBets();
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /predictions/history
|
||||
* Get prediction history and accuracy stats
|
||||
*/
|
||||
@Get('history')
|
||||
@ApiOperation({ summary: 'Get prediction history and accuracy statistics' })
|
||||
@ApiResponse({ status: 200, type: PredictionHistoryResponseDto })
|
||||
async getHistory(): Promise<PredictionHistoryResponseDto> {
|
||||
return this.predictionsService.getPredictionHistory();
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /predictions/:matchId
|
||||
* Get prediction for a specific match
|
||||
*/
|
||||
@Get(':matchId')
|
||||
@Public()
|
||||
@ApiOperation({ summary: 'Get prediction for a specific match' })
|
||||
@ApiParam({ name: 'matchId', description: 'Match ID' })
|
||||
@ApiResponse({ status: 200, type: MatchPredictionDto })
|
||||
@ApiResponse({ status: 404, description: 'Match not found' })
|
||||
async getPrediction(
|
||||
@Param('matchId') matchId: string,
|
||||
): Promise<MatchPredictionDto> {
|
||||
// Check cache first
|
||||
const cached = await this.predictionsService.getCachedPrediction(matchId);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
// Get from AI Engine
|
||||
const prediction = await this.predictionsService.getPredictionById(matchId);
|
||||
|
||||
if (!prediction) {
|
||||
throw new NotFoundException(`Match not found: ${matchId}`);
|
||||
}
|
||||
|
||||
// Cache the result
|
||||
await this.predictionsService.cachePrediction(matchId, prediction);
|
||||
|
||||
return prediction;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /predictions/generate
|
||||
* Generate prediction with provided match data
|
||||
*/
|
||||
@Post('generate')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'Generate prediction with provided match data' })
|
||||
@ApiResponse({ status: 200, type: MatchPredictionDto })
|
||||
async generatePrediction(
|
||||
@Body() dto: GeneratePredictionDto,
|
||||
): Promise<MatchPredictionDto> {
|
||||
const prediction = await this.predictionsService.getPredictionWithData({
|
||||
matchId: dto.matchId,
|
||||
});
|
||||
|
||||
if (!prediction) {
|
||||
throw new NotFoundException('Failed to generate prediction');
|
||||
}
|
||||
|
||||
return prediction;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /predictions/smart-coupon
|
||||
* Generate Smart Coupon using AI Engine V20
|
||||
*/
|
||||
@Post('smart-coupon')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({
|
||||
summary: 'Generate Smart Coupon with V20 AI recommendations',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Smart coupon generated successfully',
|
||||
})
|
||||
async generateSmartCoupon(@Body() dto: SmartCouponRequestDto): Promise<any> {
|
||||
const coupon = await this.predictionsService.getSmartCoupon(
|
||||
dto.matchIds,
|
||||
dto.strategy || 'BALANCED',
|
||||
{
|
||||
maxMatches: dto.maxMatches,
|
||||
minConfidence: dto.minConfidence,
|
||||
},
|
||||
);
|
||||
|
||||
if (!coupon) {
|
||||
throw new NotFoundException('Failed to generate Smart Coupon');
|
||||
}
|
||||
|
||||
return coupon;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user