This commit is contained in:
2026-04-16 17:21:48 +03:00
parent c8fa4c442d
commit c8e7e4e927
116 changed files with 3720 additions and 4197 deletions
@@ -5,8 +5,8 @@
* Database operations using Prisma
*/
import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../../database/prisma.service";
import {
Sport,
MatchSummary,
@@ -20,8 +20,8 @@ import {
DbEventPayload,
DbMarketPayload,
BasketballTeamStats,
} from './feeder.types';
import { ImageUtils } from '../../common/utils/image.util';
} from "./feeder.types";
import { ImageUtils } from "../../common/utils/image.util";
@Injectable()
export class FeederPersistenceService {
@@ -33,7 +33,7 @@ export class FeederPersistenceService {
// HELPER FUNCTIONS
// ============================================
private safeString(value: any): string | null {
return value === null || value === undefined || value === ''
return value === null || value === undefined || value === ""
? null
: String(value);
}
@@ -51,12 +51,12 @@ export class FeederPersistenceService {
private mapPositionToEnum(position: string | null): any {
if (!position) return null;
const pos = position.toLowerCase();
if (pos.includes('kaleci') || pos.includes('goalkeeper'))
return 'goalkeeper';
if (pos.includes('defans') || pos.includes('defender')) return 'defender';
if (pos.includes('orta saha') || pos.includes('midfielder'))
return 'midfielder';
if (pos.includes('forvet') || pos.includes('striker')) return 'striker';
if (pos.includes("kaleci") || pos.includes("goalkeeper"))
return "goalkeeper";
if (pos.includes("defans") || pos.includes("defender")) return "defender";
if (pos.includes("orta saha") || pos.includes("midfielder"))
return "midfielder";
if (pos.includes("forvet") || pos.includes("striker")) return "striker";
return null;
}
@@ -93,7 +93,7 @@ export class FeederPersistenceService {
}
for (const s of market.selectionCollection) {
if (!s || s.odd === '-' || s.odd === '') continue;
if (!s || s.odd === "-" || s.odd === "") continue;
const sName = this.safeString(s.name);
const sValue = this.safeString(s.odd);
@@ -107,7 +107,7 @@ export class FeederPersistenceService {
if (existingSel) {
if (existingSel.oddValue !== sValue) {
const oldVal = parseFloat(existingSel.oddValue || '0');
const oldVal = parseFloat(existingSel.oddValue || "0");
const newVal = parseFloat(sValue);
if (!isNaN(oldVal) && !isNaN(newVal)) {
@@ -182,13 +182,13 @@ export class FeederPersistenceService {
const teamsToUpsert = [
{
id: homeTeamId,
name: matchSummary.homeTeam?.name || 'Unknown',
name: matchSummary.homeTeam?.name || "Unknown",
slug: matchSummary.homeTeam?.slug || homeTeamId,
sport: sport,
},
{
id: awayTeamId,
name: matchSummary.awayTeam?.name || 'Unknown',
name: matchSummary.awayTeam?.name || "Unknown",
slug: matchSummary.awayTeam?.slug || awayTeamId,
sport: sport,
},
@@ -221,18 +221,18 @@ export class FeederPersistenceService {
update: {},
create: {
id: countryId,
name: league.country.name || 'Unknown',
name: league.country.name || "Unknown",
},
});
} catch (error: any) {
if (error.code !== 'P2002') throw error;
if (error.code !== "P2002") throw error;
}
}
// 2. Save League (Handle ID changes by checking unique constraint)
let finalLeagueId = this.safeString(league.id);
if (finalLeagueId && countryId) {
const leagueName = league.name || 'Unknown';
const leagueName = league.name || "Unknown";
// Check if league exists by unique constraint (name + country + sport)
const existingLeague = await tx.league.findUnique({
@@ -311,32 +311,32 @@ export class FeederPersistenceService {
headerData?.htScoreAway ??
this.safeInt(matchSummary.score?.ht?.away);
let status = 'NS';
let status = "NS";
if (headerData?.matchStatus) {
if (
headerData.matchStatus === 'postGame' ||
headerData.matchStatus === 'post'
headerData.matchStatus === "postGame" ||
headerData.matchStatus === "post"
) {
status = 'FT';
status = "FT";
} else if (
headerData.matchStatus === 'live' ||
headerData.matchStatus === 'liveGame'
headerData.matchStatus === "live" ||
headerData.matchStatus === "liveGame"
) {
status = 'LIVE';
status = "LIVE";
}
}
// Handle Postponed Matches (ERT)
if (matchSummary.statusBoxContent === 'ERT') {
status = 'POSTPONED';
if (matchSummary.statusBoxContent === "ERT") {
status = "POSTPONED";
}
if (
status === 'NS' &&
status === "NS" &&
finalScoreHome !== null &&
finalScoreAway !== null
) {
status = 'FT';
status = "FT";
}
await tx.match.upsert({
@@ -455,7 +455,7 @@ export class FeederPersistenceService {
}
// 8. Save Team Stats (Football)
if (stats && sport === 'football') {
if (stats && sport === "football") {
const statsRows = [
{
matchId,
@@ -499,7 +499,7 @@ export class FeederPersistenceService {
}
// 8b. Save Team Stats (Basketball)
if (basketballTeamStats && sport === 'basketball') {
if (basketballTeamStats && sport === "basketball") {
const teams = [
{ id: homeTeamId, data: basketballTeamStats.home },
{ id: awayTeamId, data: basketballTeamStats.away },
@@ -558,7 +558,7 @@ export class FeederPersistenceService {
}
// 8c. Save Player Stats (Basketball)
if (basketballPlayerStats.length > 0 && sport === 'basketball') {
if (basketballPlayerStats.length > 0 && sport === "basketball") {
await tx.basketballPlayerStats.deleteMany({ where: { matchId } });
for (const p of basketballPlayerStats) {
@@ -592,12 +592,12 @@ export class FeederPersistenceService {
await this.saveOddsInTransaction(tx, matchId, oddsArray);
// 10. Save Officials
if (sport === 'football' && officialsData.length > 0) {
if (sport === "football" && officialsData.length > 0) {
await tx.matchOfficial.deleteMany({ where: { matchId } });
const processedOfficials = new Set<string>();
for (const o of officialsData) {
const roleName = o.role || 'Referee';
const roleName = o.role || "Referee";
const uniqueKey = `${o.name}_${roleName}`;
if (processedOfficials.has(uniqueKey)) continue;
@@ -798,10 +798,10 @@ export class FeederPersistenceService {
const history = await this.prisma.match.findMany({
where: {
OR: [{ homeTeamId: teamId }, { awayTeamId: teamId }],
status: 'FT',
status: "FT",
mstUtc: { lt: match.mstUtc },
},
orderBy: { mstUtc: 'desc' },
orderBy: { mstUtc: "desc" },
take: 5,
});
@@ -840,8 +840,8 @@ export class FeederPersistenceService {
return {
match_id: match.id,
home_team: match.homeTeam?.name || 'Unknown',
away_team: match.awayTeam?.name || 'Unknown',
home_team: match.homeTeam?.name || "Unknown",
away_team: match.awayTeam?.name || "Unknown",
home_team_id: match.homeTeamId,
away_team_id: match.awayTeamId,
league_id: match.leagueId,
@@ -934,7 +934,7 @@ export class FeederPersistenceService {
scoreHome: liveMatch.scoreHome,
scoreAway: liveMatch.scoreAway,
mstUtc: liveMatch.mstUtc,
sport: liveMatch.sport || 'football',
sport: liveMatch.sport || "football",
};
}