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>
95 lines
3.3 KiB
Markdown
95 lines
3.3 KiB
Markdown
# Architecture Documentation
|
|
|
|
## CLEAN Architecture Overview
|
|
|
|
This application implements CLEAN architecture principles to ensure maintainability, testability, and flexibility.
|
|
|
|
## Layer Responsibilities
|
|
|
|
### 1. Domain Layer (`src/domain/`)
|
|
**Purpose**: Contains enterprise business rules and core entities.
|
|
|
|
- **Entities** (`entities/`): Core business objects that represent the problem domain
|
|
- `Player`: NHL player information
|
|
- `SkaterStats`, `GoalieStats`: Player statistics
|
|
- `NHLTeam`: NHL team information
|
|
- `FantasyTeam`: Yahoo Fantasy team data
|
|
|
|
- **Repository Interfaces** (`repositories/`): Abstract contracts for data access
|
|
- `PlayerRepository`: Interface for player data operations
|
|
- `TeamRepository`: Interface for team data operations
|
|
- `FantasyRepository`: Interface for fantasy team operations
|
|
|
|
**Dependencies**: None. This layer is completely independent.
|
|
|
|
### 2. Application Layer (`src/application/`)
|
|
**Purpose**: Contains application-specific business rules.
|
|
|
|
- **Use Cases** (`use_cases/`): Application business logic
|
|
- `GetPlayerStatsUseCase`: Example use case for retrieving player statistics
|
|
- Future: `AnalyzeFantasyRosterUseCase`, `ComparePlayersUseCase`, etc.
|
|
|
|
- **DTOs** (`dto/`): Data transfer objects for cross-layer communication
|
|
|
|
**Dependencies**: Depends only on Domain layer abstractions.
|
|
|
|
### 3. Infrastructure Layer (`src/infrastructure/`)
|
|
**Purpose**: Contains implementations of external interfaces and frameworks.
|
|
|
|
- **Adapters** (`adapters/`): Implementations of repository interfaces
|
|
- `nhl/NHLPlayerAdapter`: Implements PlayerRepository using nhl-api-py
|
|
- `nhl/NHLTeamAdapter`: Implements TeamRepository using nhl-api-py
|
|
- `yahoo_fantasy/YahooFantasyAdapter`: Implements FantasyRepository using yfpy
|
|
|
|
- **Database** (`database/`): Database models and ORM configurations
|
|
- **Config** (`config/`): Application configuration and settings
|
|
|
|
**Dependencies**: Implements Domain interfaces using external libraries.
|
|
|
|
### 4. Presentation Layer (`src/presentation/`)
|
|
**Purpose**: Contains API routes and controllers.
|
|
|
|
- **API Routes** (`api/routes/`): FastAPI endpoint definitions
|
|
- **Dependencies** (`api/dependencies.py`): Dependency injection configuration
|
|
|
|
**Dependencies**: Uses Application use cases and Infrastructure implementations.
|
|
|
|
## Dependency Flow
|
|
|
|
```
|
|
Presentation Layer
|
|
↓
|
|
Application Layer
|
|
↓
|
|
Domain Layer (Abstractions)
|
|
↑
|
|
Infrastructure Layer (Implementations)
|
|
```
|
|
|
|
**Key Principle**: Dependencies point inward. Outer layers depend on inner layers, never the reverse.
|
|
|
|
## Swapping Data Sources
|
|
|
|
To replace the NHL API with a different data source:
|
|
|
|
1. Create a new adapter implementing `PlayerRepository` or `TeamRepository`
|
|
2. Update the dependency injection in `src/presentation/api/dependencies.py`
|
|
3. **No changes required** to domain entities, use cases, or API routes
|
|
|
|
Example:
|
|
|
|
```python
|
|
# In dependencies.py
|
|
def get_player_repository() -> PlayerRepository:
|
|
# Change this line to use a different implementation
|
|
return AlternativePlayerAdapter() # Instead of NHLPlayerAdapter()
|
|
```
|
|
|
|
## Testing Strategy
|
|
|
|
- **Unit Tests**: Test domain entities and use cases in isolation
|
|
- **Integration Tests**: Test adapters against real or mocked external APIs
|
|
- **API Tests**: Test FastAPI routes using TestClient
|
|
|
|
All business logic can be tested without external dependencies by using mock repository implementations.
|