219 lines
5.3 KiB
TypeScript
Executable File
219 lines
5.3 KiB
TypeScript
Executable File
import {
|
|
Controller,
|
|
Get,
|
|
Param,
|
|
Query,
|
|
NotFoundException,
|
|
} from "@nestjs/common";
|
|
import {
|
|
ApiTags,
|
|
ApiOperation,
|
|
ApiResponse,
|
|
ApiQuery,
|
|
ApiParam,
|
|
} from "@nestjs/swagger";
|
|
import { LeaguesService } from "./leagues.service";
|
|
import { Sport } from "@prisma/client";
|
|
import { Public } from "../../common/decorators";
|
|
|
|
@ApiTags("Leagues")
|
|
@Controller("leagues")
|
|
export class LeaguesController {
|
|
constructor(private readonly leaguesService: LeaguesService) {}
|
|
|
|
/**
|
|
* GET /leagues/countries
|
|
* Get all countries
|
|
*/
|
|
@Get("countries")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get all countries" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "List of countries",
|
|
schema: { type: "array", items: { type: "object" } },
|
|
})
|
|
async getCountries() {
|
|
return this.leaguesService.findAllCountries();
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/countries/:id
|
|
* Get country by ID with leagues
|
|
*/
|
|
@Get("countries/:id")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get country by ID with leagues" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Country details",
|
|
schema: { type: "object" },
|
|
})
|
|
@ApiParam({ name: "id", description: "Country ID" })
|
|
async getCountryById(@Param("id") id: string) {
|
|
const country = await this.leaguesService.findCountryById(id);
|
|
if (!country) throw new NotFoundException("Country not found");
|
|
return country;
|
|
}
|
|
|
|
/**
|
|
* GET /leagues
|
|
* Get all leagues
|
|
*/
|
|
@Get()
|
|
@Public()
|
|
@ApiOperation({ summary: "Get all leagues" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "List of leagues",
|
|
schema: { type: "array", items: { type: "object" } },
|
|
})
|
|
@ApiQuery({
|
|
name: "sport",
|
|
required: false,
|
|
enum: ["football", "basketball"],
|
|
})
|
|
async getLeagues(@Query("sport") sport?: string) {
|
|
return this.leaguesService.findAllLeagues(sport as Sport);
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/teams/h2h
|
|
* Get head-to-head matches between two teams
|
|
* NOTE: Must come before /teams/:id to avoid route conflict
|
|
*/
|
|
@Get("teams/h2h")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get head-to-head matches between two teams" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Head-to-head matches",
|
|
schema: { type: "array", items: { type: "object" } },
|
|
})
|
|
@ApiQuery({ name: "team1", required: true })
|
|
@ApiQuery({ name: "team2", required: true })
|
|
@ApiQuery({ name: "limit", required: false, type: Number })
|
|
async getHeadToHead(
|
|
@Query("team1") team1: string,
|
|
@Query("team2") team2: string,
|
|
@Query("limit") limit?: string,
|
|
) {
|
|
return this.leaguesService.getHeadToHead(
|
|
team1,
|
|
team2,
|
|
parseInt(limit || "10", 10),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/teams/search
|
|
* Search teams by name
|
|
*/
|
|
@Get("teams/search")
|
|
@Public()
|
|
@ApiOperation({ summary: "Search teams by name" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "List of teams matching search",
|
|
schema: { type: "array", items: { type: "object" } },
|
|
})
|
|
@ApiQuery({ name: "q", required: true, description: "Search query" })
|
|
@ApiQuery({
|
|
name: "sport",
|
|
required: false,
|
|
enum: ["football", "basketball"],
|
|
})
|
|
async searchTeams(@Query("q") query: string, @Query("sport") sport?: string) {
|
|
return this.leaguesService.searchTeams(query, sport as Sport);
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/teams/:id
|
|
* Get team by ID
|
|
*/
|
|
@Get("teams/:id")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get team by ID" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Team details",
|
|
schema: { type: "object" },
|
|
})
|
|
@ApiParam({ name: "id", description: "Team ID" })
|
|
async getTeamById(@Param("id") id: string) {
|
|
const team = await this.leaguesService.findTeamById(id);
|
|
if (!team) throw new NotFoundException("Team not found");
|
|
return team;
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/teams/:id/matches
|
|
* Get team's recent matches (paginated)
|
|
*/
|
|
@Get("teams/:id/matches")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get team's recent matches (paginated)" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Paginated list of matches",
|
|
schema: {
|
|
type: "object",
|
|
properties: {
|
|
data: { type: "array", items: { type: "object" } },
|
|
meta: { type: "object" },
|
|
},
|
|
},
|
|
})
|
|
@ApiParam({ name: "id", description: "Team ID" })
|
|
@ApiQuery({
|
|
name: "page",
|
|
required: false,
|
|
type: Number,
|
|
description: "Page number (default: 1)",
|
|
})
|
|
@ApiQuery({
|
|
name: "limit",
|
|
required: false,
|
|
type: Number,
|
|
description: "Items per page (default: 20)",
|
|
})
|
|
@ApiQuery({
|
|
name: "season",
|
|
required: false,
|
|
type: String,
|
|
description: "Season (e.g. 2024-2025)",
|
|
})
|
|
async getTeamMatches(
|
|
@Param("id") id: string,
|
|
@Query("page") page?: string,
|
|
@Query("limit") limit?: string,
|
|
@Query("season") season?: string,
|
|
) {
|
|
return this.leaguesService.getTeamRecentMatches(
|
|
id,
|
|
parseInt(page || "1", 10),
|
|
parseInt(limit || "20", 10),
|
|
season,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* GET /leagues/:id
|
|
* Get league by ID
|
|
*/
|
|
@Get(":id")
|
|
@Public()
|
|
@ApiOperation({ summary: "Get league by ID" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "League details",
|
|
schema: { type: "object" },
|
|
})
|
|
@ApiParam({ name: "id", description: "League ID" })
|
|
async getLeagueById(@Param("id") id: string) {
|
|
const league = await this.leaguesService.findLeagueById(id);
|
|
if (!league) throw new NotFoundException("League not found");
|
|
return league;
|
|
}
|
|
}
|