New archi: domain driven development
Working but need to check out code
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
"""Movie domain value objects."""
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from ..shared.exceptions import ValidationError
|
||||
|
||||
|
||||
class Quality(Enum):
|
||||
"""Video quality levels."""
|
||||
SD = "480p"
|
||||
HD = "720p"
|
||||
FULL_HD = "1080p"
|
||||
UHD_4K = "2160p"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, quality_str: str) -> "Quality":
|
||||
"""
|
||||
Parse quality from string.
|
||||
|
||||
Args:
|
||||
quality_str: Quality string (e.g., "1080p", "720p")
|
||||
|
||||
Returns:
|
||||
Quality enum value
|
||||
"""
|
||||
quality_map = {
|
||||
"480p": cls.SD,
|
||||
"720p": cls.HD,
|
||||
"1080p": cls.FULL_HD,
|
||||
"2160p": cls.UHD_4K,
|
||||
}
|
||||
return quality_map.get(quality_str, cls.UNKNOWN)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MovieTitle:
|
||||
"""
|
||||
Value object representing a movie title.
|
||||
|
||||
Ensures the title is valid and normalized.
|
||||
"""
|
||||
value: str
|
||||
|
||||
def __post_init__(self):
|
||||
"""Validate movie title."""
|
||||
if not self.value:
|
||||
raise ValidationError("Movie title cannot be empty")
|
||||
|
||||
if not isinstance(self.value, str):
|
||||
raise ValidationError(f"Movie title must be a string, got {type(self.value)}")
|
||||
|
||||
if len(self.value) > 500:
|
||||
raise ValidationError(f"Movie title too long: {len(self.value)} characters (max 500)")
|
||||
|
||||
def normalized(self) -> str:
|
||||
"""
|
||||
Return normalized title for file system usage.
|
||||
|
||||
Removes special characters and replaces spaces with dots.
|
||||
"""
|
||||
import re
|
||||
# Remove special characters except spaces, dots, and hyphens
|
||||
cleaned = re.sub(r'[^\w\s\.\-]', '', self.value)
|
||||
# Replace spaces with dots
|
||||
normalized = cleaned.replace(' ', '.')
|
||||
return normalized
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"MovieTitle('{self.value}')"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ReleaseYear:
|
||||
"""
|
||||
Value object representing a movie release year.
|
||||
|
||||
Validates that the year is reasonable.
|
||||
"""
|
||||
value: int
|
||||
|
||||
def __post_init__(self):
|
||||
"""Validate release year."""
|
||||
if not isinstance(self.value, int):
|
||||
raise ValidationError(f"Release year must be an integer, got {type(self.value)}")
|
||||
|
||||
# Movies started around 1888, and we shouldn't have movies from the future
|
||||
if self.value < 1888 or self.value > 2100:
|
||||
raise ValidationError(f"Invalid release year: {self.value}")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.value)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ReleaseYear({self.value})"
|
||||
Reference in New Issue
Block a user