cr
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { PrismaService } from '../../database/prisma.service';
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { PrismaService } from "../../database/prisma.service";
|
||||
import {
|
||||
Sport,
|
||||
MatchQueryDto,
|
||||
LeagueWithMatchesDto,
|
||||
ActiveLeagueDto,
|
||||
} from './dto';
|
||||
import { Prisma } from '@prisma/client';
|
||||
} from "./dto";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
@Injectable()
|
||||
export class MatchesService {
|
||||
@@ -21,9 +21,9 @@ export class MatchesService {
|
||||
|
||||
private loadTopLeagues() {
|
||||
try {
|
||||
const topLeaguesPath = path.join(process.cwd(), 'top_leagues.json');
|
||||
const topLeaguesPath = path.join(process.cwd(), "top_leagues.json");
|
||||
if (fs.existsSync(topLeaguesPath)) {
|
||||
this.topLeagueIds = JSON.parse(fs.readFileSync(topLeaguesPath, 'utf8'));
|
||||
this.topLeagueIds = JSON.parse(fs.readFileSync(topLeaguesPath, "utf8"));
|
||||
this.logger.log(
|
||||
`Loaded ${this.topLeagueIds.length} top leagues for filtering.`,
|
||||
);
|
||||
@@ -39,22 +39,22 @@ export class MatchesService {
|
||||
{
|
||||
status: {
|
||||
in: [
|
||||
'LIVE',
|
||||
'1H',
|
||||
'2H',
|
||||
'HT',
|
||||
'1Q',
|
||||
'2Q',
|
||||
'3Q',
|
||||
'4Q',
|
||||
'Playing',
|
||||
'Half Time',
|
||||
"LIVE",
|
||||
"1H",
|
||||
"2H",
|
||||
"HT",
|
||||
"1Q",
|
||||
"2Q",
|
||||
"3Q",
|
||||
"4Q",
|
||||
"Playing",
|
||||
"Half Time",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
state: {
|
||||
in: ['live', 'firsthalf', 'secondhalf'],
|
||||
in: ["live", "firsthalf", "secondhalf"],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -66,12 +66,12 @@ export class MatchesService {
|
||||
OR: [
|
||||
{
|
||||
status: {
|
||||
in: ['Finished', 'Played', 'FT', 'AET', 'PEN', 'Ended'],
|
||||
in: ["Finished", "Played", "FT", "AET", "PEN", "Ended"],
|
||||
},
|
||||
},
|
||||
{
|
||||
state: {
|
||||
in: ['Finished', 'post', 'FT', 'postGame'],
|
||||
in: ["Finished", "post", "FT", "postGame"],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -134,16 +134,16 @@ export class MatchesService {
|
||||
|
||||
if (leagueId) {
|
||||
where.leagueId = leagueId;
|
||||
} else if (status === 'LIVE' && this.topLeagueIds.length > 0) {
|
||||
} else if (status === "LIVE" && this.topLeagueIds.length > 0) {
|
||||
// Filter live matches by top leagues by default if no leagueId is provided
|
||||
where.leagueId = { in: this.topLeagueIds };
|
||||
}
|
||||
|
||||
if (status === 'LIVE') {
|
||||
if (status === "LIVE") {
|
||||
andConditions.push(this.getLiveFilter());
|
||||
} else if (status === 'UPCOMING' || status === 'NOT_STARTED') {
|
||||
} else if (status === "UPCOMING" || status === "NOT_STARTED") {
|
||||
andConditions.push(this.getUpcomingFilter(Date.now()));
|
||||
} else if (status === 'FINISHED') {
|
||||
} else if (status === "FINISHED") {
|
||||
andConditions.push(this.getFinishedFilter());
|
||||
} else if (status) {
|
||||
where.status = status;
|
||||
@@ -170,9 +170,9 @@ export class MatchesService {
|
||||
|
||||
// Team filter
|
||||
if (team) {
|
||||
if (team.role === 'home') {
|
||||
if (team.role === "home") {
|
||||
where.homeTeamId = team.id;
|
||||
} else if (team.role === 'away') {
|
||||
} else if (team.role === "away") {
|
||||
where.awayTeamId = team.id;
|
||||
} else {
|
||||
andConditions.push({
|
||||
@@ -197,7 +197,7 @@ export class MatchesService {
|
||||
const matches = await this.prisma.liveMatch.findMany({
|
||||
where,
|
||||
select: { id: true },
|
||||
orderBy: { mstUtc: 'asc' }, // Sort by nearest match first
|
||||
orderBy: { mstUtc: "asc" }, // Sort by nearest match first
|
||||
take: limit,
|
||||
});
|
||||
|
||||
@@ -220,7 +220,7 @@ export class MatchesService {
|
||||
AND: [this.getUpcomingFilter(Date.now())],
|
||||
},
|
||||
select: { id: true },
|
||||
orderBy: { mstUtc: 'asc' },
|
||||
orderBy: { mstUtc: "asc" },
|
||||
take: limit,
|
||||
});
|
||||
console.log(
|
||||
@@ -283,16 +283,16 @@ export class MatchesService {
|
||||
const leaguesMap = new Map<string, LeagueWithMatchesDto>();
|
||||
|
||||
for (const match of matches) {
|
||||
const leagueId = match.leagueId || 'unknown';
|
||||
const leagueId = match.leagueId || "unknown";
|
||||
|
||||
if (!leaguesMap.has(leagueId)) {
|
||||
leaguesMap.set(leagueId, {
|
||||
id: leagueId,
|
||||
name: match.league?.name || 'Unknown League',
|
||||
name: match.league?.name || "Unknown League",
|
||||
code: match.league?.code || undefined,
|
||||
country: {
|
||||
id: match.league?.country?.id || '',
|
||||
name: match.league?.country?.name || '',
|
||||
id: match.league?.country?.id || "",
|
||||
name: match.league?.country?.name || "",
|
||||
flagUrl: match.league?.country?.flagUrl || undefined,
|
||||
},
|
||||
sport: sport,
|
||||
@@ -306,13 +306,13 @@ export class MatchesService {
|
||||
const structuredOdds: any[] = [];
|
||||
if (
|
||||
match.odds &&
|
||||
typeof match.odds === 'object' &&
|
||||
typeof match.odds === "object" &&
|
||||
!Array.isArray(match.odds)
|
||||
) {
|
||||
const oddsObj = match.odds as Record<string, Record<string, number>>;
|
||||
for (const [marketName, selections] of Object.entries(oddsObj)) {
|
||||
const structuredSelections: Record<string, { odd: string }> = {};
|
||||
if (selections && typeof selections === 'object') {
|
||||
if (selections && typeof selections === "object") {
|
||||
for (const [selName, selOdd] of Object.entries(selections)) {
|
||||
structuredSelections[selName] = { odd: String(selOdd) };
|
||||
}
|
||||
@@ -325,15 +325,15 @@ export class MatchesService {
|
||||
}
|
||||
|
||||
// Map status for frontend
|
||||
let displayStatus = match.status || 'NS';
|
||||
if (match.state === 'live') {
|
||||
displayStatus = 'LIVE';
|
||||
let displayStatus = match.status || "NS";
|
||||
if (match.state === "live") {
|
||||
displayStatus = "LIVE";
|
||||
} else if (
|
||||
match.state === 'post' ||
|
||||
match.state === 'FT' ||
|
||||
match.status === 'Finished'
|
||||
match.state === "post" ||
|
||||
match.state === "FT" ||
|
||||
match.status === "Finished"
|
||||
) {
|
||||
displayStatus = 'Finished';
|
||||
displayStatus = "Finished";
|
||||
}
|
||||
|
||||
league.matches.push({
|
||||
@@ -349,11 +349,11 @@ export class MatchesService {
|
||||
scoreAway: match.scoreAway ?? undefined,
|
||||
htScoreHome: undefined, // LiveMatch table doesn't have HT scores separately usually
|
||||
htScoreAway: undefined,
|
||||
homeTeamName: match.homeTeam?.name || 'Unknown',
|
||||
homeTeamName: match.homeTeam?.name || "Unknown",
|
||||
homeTeamLogo: match.homeTeamId
|
||||
? `https://file.mackolikfeeds.com/teams/${match.homeTeamId}`
|
||||
: undefined,
|
||||
awayTeamName: match.awayTeam?.name || 'Unknown',
|
||||
awayTeamName: match.awayTeam?.name || "Unknown",
|
||||
awayTeamLogo: match.awayTeamId
|
||||
? `https://file.mackolikfeeds.com/teams/${match.awayTeamId}`
|
||||
: undefined,
|
||||
@@ -390,15 +390,15 @@ export class MatchesService {
|
||||
|
||||
// Priority sorting (Mackolik style)
|
||||
const PRIORITY = [
|
||||
'Trendyol Süper Lig',
|
||||
'Süper Lig',
|
||||
'Trendyol 1. Lig',
|
||||
'1. Lig',
|
||||
'Premier Lig',
|
||||
'LaLiga',
|
||||
'Serie A',
|
||||
'Bundesliga',
|
||||
'Ligue 1',
|
||||
"Trendyol Süper Lig",
|
||||
"Süper Lig",
|
||||
"Trendyol 1. Lig",
|
||||
"1. Lig",
|
||||
"Premier Lig",
|
||||
"LaLiga",
|
||||
"Serie A",
|
||||
"Bundesliga",
|
||||
"Ligue 1",
|
||||
];
|
||||
|
||||
return leagues
|
||||
@@ -410,7 +410,7 @@ export class MatchesService {
|
||||
const bPriority = bIdx === -1 ? 999 : bIdx;
|
||||
|
||||
if (aPriority !== bPriority) return aPriority - bPriority;
|
||||
return (a.name || '').localeCompare(b.name || '');
|
||||
return (a.name || "").localeCompare(b.name || "");
|
||||
})
|
||||
.map((l) => ({
|
||||
id: l.id,
|
||||
@@ -439,7 +439,7 @@ export class MatchesService {
|
||||
include: { country: true },
|
||||
},
|
||||
},
|
||||
orderBy: { mstUtc: 'desc' },
|
||||
orderBy: { mstUtc: "desc" },
|
||||
skip,
|
||||
take: limit,
|
||||
}),
|
||||
@@ -482,7 +482,7 @@ export class MatchesService {
|
||||
createdAt: stat.createdAt,
|
||||
};
|
||||
|
||||
if ((sport || '').toLowerCase() === 'basketball') {
|
||||
if ((sport || "").toLowerCase() === "basketball") {
|
||||
return {
|
||||
...base,
|
||||
points: stat.points,
|
||||
@@ -532,7 +532,7 @@ export class MatchesService {
|
||||
basketballTeamStats: true,
|
||||
playerParticipations: {
|
||||
include: { player: true },
|
||||
orderBy: [{ isStarting: 'desc' }, { position: 'asc' }],
|
||||
orderBy: [{ isStarting: "desc" }, { position: "asc" }],
|
||||
},
|
||||
playerEvents: {
|
||||
include: {
|
||||
@@ -540,7 +540,7 @@ export class MatchesService {
|
||||
assistPlayer: true,
|
||||
substitutedOut: true,
|
||||
},
|
||||
orderBy: [{ periodId: 'asc' }, { timeMinute: 'asc' }],
|
||||
orderBy: [{ periodId: "asc" }, { timeMinute: "asc" }],
|
||||
},
|
||||
oddCategories: {
|
||||
include: { selections: true },
|
||||
@@ -562,15 +562,15 @@ export class MatchesService {
|
||||
|
||||
if (liveMatch) {
|
||||
// Map liveMatch status
|
||||
let displayStatus = liveMatch.status || 'NS';
|
||||
if (liveMatch.state === 'live') {
|
||||
displayStatus = 'LIVE';
|
||||
let displayStatus = liveMatch.status || "NS";
|
||||
if (liveMatch.state === "live") {
|
||||
displayStatus = "LIVE";
|
||||
} else if (
|
||||
liveMatch.state === 'post' ||
|
||||
liveMatch.state === 'FT' ||
|
||||
liveMatch.status === 'Finished'
|
||||
liveMatch.state === "post" ||
|
||||
liveMatch.state === "FT" ||
|
||||
liveMatch.status === "Finished"
|
||||
) {
|
||||
displayStatus = 'Finished';
|
||||
displayStatus = "Finished";
|
||||
}
|
||||
|
||||
match = {
|
||||
@@ -607,14 +607,14 @@ export class MatchesService {
|
||||
if (
|
||||
match.isLiveSource &&
|
||||
match.odds &&
|
||||
typeof match.odds === 'object' &&
|
||||
typeof match.odds === "object" &&
|
||||
!Array.isArray(match.odds)
|
||||
) {
|
||||
// Parse JSON odds from LiveMatch
|
||||
const oddsObj = match.odds as Record<string, Record<string, number>>;
|
||||
for (const [marketName, selections] of Object.entries(oddsObj)) {
|
||||
odds[marketName] = {};
|
||||
if (selections && typeof selections === 'object') {
|
||||
if (selections && typeof selections === "object") {
|
||||
for (const [selName, selOdd] of Object.entries(selections)) {
|
||||
odds[marketName][selName] = { odd: String(selOdd) };
|
||||
}
|
||||
@@ -628,7 +628,7 @@ export class MatchesService {
|
||||
for (const sel of cat.selections) {
|
||||
if (sel.name) {
|
||||
odds[cat.name][sel.name] = {
|
||||
odd: sel.oddValue || '',
|
||||
odd: sel.oddValue || "",
|
||||
sov: sel.sov ?? undefined,
|
||||
};
|
||||
}
|
||||
@@ -637,7 +637,7 @@ export class MatchesService {
|
||||
}
|
||||
|
||||
const sportStats =
|
||||
match.sport === 'basketball'
|
||||
match.sport === "basketball"
|
||||
? match.basketballTeamStats || []
|
||||
: match.footballTeamStats || [];
|
||||
const normalizedTeamStats = sportStats.map((s: any) =>
|
||||
@@ -692,7 +692,7 @@ export class MatchesService {
|
||||
// Fuzzy search
|
||||
team = await this.prisma.team.findFirst({
|
||||
where: {
|
||||
name: { contains: trimmedName, mode: 'insensitive' },
|
||||
name: { contains: trimmedName, mode: "insensitive" },
|
||||
sport: sport as any,
|
||||
},
|
||||
select: { id: true },
|
||||
|
||||
Reference in New Issue
Block a user