added team overview
This commit is contained in:
@@ -2,6 +2,7 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
@@ -72,3 +73,149 @@ func (t *Team) InSeason(seasonID int) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TeamSeasonInfo holds information about a team's participation in a specific season+league.
|
||||
type TeamSeasonInfo struct {
|
||||
Season *Season
|
||||
League *League
|
||||
Record *TeamRecord
|
||||
TotalTeams int
|
||||
Position int
|
||||
}
|
||||
|
||||
// GetTeamSeasonParticipation returns all season+league combos the team participated in,
|
||||
// with computed records, positions, and total team counts.
|
||||
func GetTeamSeasonParticipation(
|
||||
ctx context.Context,
|
||||
tx bun.Tx,
|
||||
teamID int,
|
||||
) ([]*TeamSeasonInfo, error) {
|
||||
if teamID == 0 {
|
||||
return nil, errors.New("teamID not provided")
|
||||
}
|
||||
|
||||
// Get all participations for this team
|
||||
var participations []*TeamParticipation
|
||||
err := tx.NewSelect().
|
||||
Model(&participations).
|
||||
Where("team_id = ?", teamID).
|
||||
Relation("Season", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||
return q.Relation("Leagues")
|
||||
}).
|
||||
Relation("League").
|
||||
Scan(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect participations")
|
||||
}
|
||||
|
||||
var results []*TeamSeasonInfo
|
||||
|
||||
for _, p := range participations {
|
||||
// Get all teams in this season+league for position calculation
|
||||
var teams []*Team
|
||||
err := tx.NewSelect().
|
||||
Model(&teams).
|
||||
Join("INNER JOIN team_participations AS tp ON tp.team_id = t.id").
|
||||
Where("tp.season_id = ? AND tp.league_id = ?", p.SeasonID, p.LeagueID).
|
||||
Scan(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect teams")
|
||||
}
|
||||
|
||||
// Get all fixtures for this season+league
|
||||
fixtures, err := GetAllocatedFixtures(ctx, tx, p.SeasonID, p.LeagueID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetAllocatedFixtures")
|
||||
}
|
||||
|
||||
fixtureIDs := make([]int, len(fixtures))
|
||||
for i, f := range fixtures {
|
||||
fixtureIDs[i] = f.ID
|
||||
}
|
||||
|
||||
resultMap, err := GetFinalizedResultsForFixtures(ctx, tx, fixtureIDs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetFinalizedResultsForFixtures")
|
||||
}
|
||||
|
||||
// Compute leaderboard to get position
|
||||
leaderboard := ComputeLeaderboard(teams, fixtures, resultMap)
|
||||
|
||||
var position int
|
||||
var record *TeamRecord
|
||||
for _, entry := range leaderboard {
|
||||
if entry.Team.ID == teamID {
|
||||
position = entry.Position
|
||||
record = entry.Record
|
||||
break
|
||||
}
|
||||
}
|
||||
if record == nil {
|
||||
record = &TeamRecord{}
|
||||
}
|
||||
|
||||
results = append(results, &TeamSeasonInfo{
|
||||
Season: p.Season,
|
||||
League: p.League,
|
||||
Record: record,
|
||||
TotalTeams: len(teams),
|
||||
Position: position,
|
||||
})
|
||||
}
|
||||
|
||||
// Sort by season start date descending (newest first)
|
||||
sort.Slice(results, func(i, j int) bool {
|
||||
return results[i].Season.StartDate.After(results[j].Season.StartDate)
|
||||
})
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// TeamAllTimePlayerStats holds aggregated all-time stats for a player on a team.
|
||||
type TeamAllTimePlayerStats struct {
|
||||
PlayerID int `bun:"player_id"`
|
||||
PlayerName string `bun:"player_name"`
|
||||
SeasonsPlayed int `bun:"seasons_played"`
|
||||
PeriodsPlayed int `bun:"total_periods_played"`
|
||||
Goals int `bun:"total_goals"`
|
||||
Assists int `bun:"total_assists"`
|
||||
Saves int `bun:"total_saves"`
|
||||
}
|
||||
|
||||
// GetTeamAllTimePlayerStats returns aggregated all-time stats for all players
|
||||
// who have ever played for a given team across all seasons.
|
||||
func GetTeamAllTimePlayerStats(
|
||||
ctx context.Context,
|
||||
tx bun.Tx,
|
||||
teamID int,
|
||||
) ([]*TeamAllTimePlayerStats, error) {
|
||||
if teamID == 0 {
|
||||
return nil, errors.New("teamID not provided")
|
||||
}
|
||||
|
||||
var stats []*TeamAllTimePlayerStats
|
||||
err := tx.NewRaw(`
|
||||
SELECT
|
||||
frps.player_id AS player_id,
|
||||
COALESCE(p.name, frps.player_username) AS player_name,
|
||||
COUNT(DISTINCT s.id) AS seasons_played,
|
||||
COALESCE(SUM(frps.periods_played), 0) AS total_periods_played,
|
||||
COALESCE(SUM(frps.goals), 0) AS total_goals,
|
||||
COALESCE(SUM(frps.assists), 0) AS total_assists,
|
||||
COALESCE(SUM(frps.saves), 0) AS total_saves
|
||||
FROM fixture_result_player_stats frps
|
||||
JOIN fixture_results fr ON fr.id = frps.fixture_result_id
|
||||
JOIN fixtures f ON f.id = fr.fixture_id
|
||||
JOIN seasons s ON s.id = f.season_id
|
||||
LEFT JOIN players p ON p.id = frps.player_id
|
||||
WHERE fr.finalized = true
|
||||
AND frps.team_id = ?
|
||||
AND frps.period_num = 3
|
||||
AND frps.player_id IS NOT NULL
|
||||
GROUP BY frps.player_id, COALESCE(p.name, frps.player_username)
|
||||
`, teamID).Scan(ctx, &stats)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "tx.NewRaw")
|
||||
}
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user