Initial commit: CLEAN architecture foundation for fantasy hockey backend
Implemented CLEAN architecture with clear separation of concerns: - Domain layer with entities (Player, Team, Stats, FantasyTeam) and repository interfaces - Application layer with use case implementations - Infrastructure layer with NHL API and Yahoo Fantasy API adapters - Presentation layer with FastAPI configuration and dependency injection Key features: - Swappable data source adapters (NHL API, Yahoo Fantasy API) - Repository pattern for data access abstraction - Dependency injection for loose coupling - FastAPI framework with async support - PostgreSQL database configuration - Environment-based configuration management Technology stack: Python 3.11+, FastAPI, PostgreSQL, nhl-api-py, yfpy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
10
src/domain/repositories/__init__.py
Normal file
10
src/domain/repositories/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
"""Domain repository interfaces package."""
|
||||
from .player_repository import PlayerRepository
|
||||
from .team_repository import TeamRepository
|
||||
from .fantasy_repository import FantasyRepository
|
||||
|
||||
__all__ = [
|
||||
"PlayerRepository",
|
||||
"TeamRepository",
|
||||
"FantasyRepository",
|
||||
]
|
||||
31
src/domain/repositories/fantasy_repository.py
Normal file
31
src/domain/repositories/fantasy_repository.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""Fantasy team repository interface."""
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Optional
|
||||
|
||||
from src.domain.entities import FantasyTeam
|
||||
|
||||
|
||||
class FantasyRepository(ABC):
|
||||
"""Abstract interface for Yahoo Fantasy Hockey data access."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_fantasy_team(
|
||||
self, league_id: str, team_id: str
|
||||
) -> Optional[FantasyTeam]:
|
||||
"""Retrieves a specific fantasy team from a league."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_user_teams(self, user_id: str) -> List[FantasyTeam]:
|
||||
"""Retrieves all fantasy teams for a user."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_team_roster(self, league_id: str, team_id: str) -> List[str]:
|
||||
"""Retrieves the player IDs on a fantasy team's roster."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_league_standings(self, league_id: str) -> List[FantasyTeam]:
|
||||
"""Retrieves all teams in a league ordered by standings."""
|
||||
pass
|
||||
36
src/domain/repositories/player_repository.py
Normal file
36
src/domain/repositories/player_repository.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""Player repository interface."""
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Optional
|
||||
|
||||
from src.domain.entities import Player, SkaterStats, GoalieStats
|
||||
|
||||
|
||||
class PlayerRepository(ABC):
|
||||
"""Abstract interface for player data access."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_player_by_id(self, player_id: str) -> Optional[Player]:
|
||||
"""Retrieves a player by their unique identifier."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_players_by_team(self, team_id: str) -> List[Player]:
|
||||
"""Retrieves all players for a specific team."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def search_players(
|
||||
self, name: str, position: Optional[str] = None
|
||||
) -> List[Player]:
|
||||
"""Searches for players by name and optionally by position."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_skater_stats(self, player_id: str) -> Optional[SkaterStats]:
|
||||
"""Retrieves current season statistics for a skater."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_goalie_stats(self, player_id: str) -> Optional[GoalieStats]:
|
||||
"""Retrieves current season statistics for a goalie."""
|
||||
pass
|
||||
29
src/domain/repositories/team_repository.py
Normal file
29
src/domain/repositories/team_repository.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""Team repository interface."""
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Optional
|
||||
|
||||
from src.domain.entities import NHLTeam
|
||||
|
||||
|
||||
class TeamRepository(ABC):
|
||||
"""Abstract interface for NHL team data access."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_team_by_id(self, team_id: str) -> Optional[NHLTeam]:
|
||||
"""Retrieves a team by its unique identifier."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_all_teams(self) -> List[NHLTeam]:
|
||||
"""Retrieves all NHL teams."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_teams_by_division(self, division: str) -> List[NHLTeam]:
|
||||
"""Retrieves all teams in a specific division."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_teams_by_conference(self, conference: str) -> List[NHLTeam]:
|
||||
"""Retrieves all teams in a specific conference."""
|
||||
pass
|
||||
Reference in New Issue
Block a user