phase3: add normalized domain schema, admin, services, and multistage docker build

This commit is contained in:
Alfredo Di Stasio
2026-03-10 10:39:45 +01:00
parent f47ffe6c15
commit fc7289a343
30 changed files with 1548 additions and 3 deletions

71
apps/stats/models.py Normal file
View File

@ -0,0 +1,71 @@
from django.db import models
class PlayerSeason(models.Model):
player = models.ForeignKey("players.Player", on_delete=models.CASCADE, related_name="player_seasons")
season = models.ForeignKey("competitions.Season", on_delete=models.CASCADE, related_name="player_seasons")
team = models.ForeignKey(
"teams.Team",
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="player_seasons",
)
competition = models.ForeignKey(
"competitions.Competition",
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="player_seasons",
)
games_played = models.PositiveSmallIntegerField(default=0)
games_started = models.PositiveSmallIntegerField(default=0)
minutes_played = models.PositiveIntegerField(default=0)
class Meta:
ordering = ["-season__start_date", "player__full_name"]
constraints = [
models.UniqueConstraint(
fields=["player", "season", "team", "competition"],
name="uq_player_season_scope",
)
]
indexes = [
models.Index(fields=["player", "season"]),
models.Index(fields=["season", "team"]),
models.Index(fields=["season", "competition"]),
models.Index(fields=["team", "competition"]),
]
def __str__(self) -> str:
return f"{self.player} - {self.season}"
class PlayerSeasonStats(models.Model):
player_season = models.OneToOneField(
"stats.PlayerSeason", on_delete=models.CASCADE, related_name="stats"
)
points = models.DecimalField(max_digits=6, decimal_places=2, default=0)
rebounds = models.DecimalField(max_digits=6, decimal_places=2, default=0)
assists = models.DecimalField(max_digits=6, decimal_places=2, default=0)
steals = models.DecimalField(max_digits=6, decimal_places=2, default=0)
blocks = models.DecimalField(max_digits=6, decimal_places=2, default=0)
turnovers = models.DecimalField(max_digits=6, decimal_places=2, default=0)
fg_pct = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
three_pct = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
ft_pct = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
usage_rate = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
true_shooting_pct = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
player_efficiency_rating = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=["points"]),
models.Index(fields=["rebounds"]),
models.Index(fields=["assists"]),
models.Index(fields=["usage_rate"]),
models.Index(fields=["true_shooting_pct"]),
]
def __str__(self) -> str:
return f"Stats for {self.player_season}"