"""Cover-art value object — raw image bytes plus their MIME type. Crosses the domain boundary between the cover sources (embedded extractor, Cover Art Archive) and the storage/serving layers. The bytes are the encoded image as-is; we never decode/resize in Phase 1. """ from dataclasses import dataclass @dataclass(frozen=True, slots=True) class CoverArt: data: bytes content_type: str # "image/jpeg" | "image/png" | … @property def extension(self) -> str: """File extension for the content type (no leading dot).""" return _EXT_BY_TYPE.get(self.content_type.lower(), "jpg") _EXT_BY_TYPE: dict[str, str] = { "image/jpeg": "jpg", "image/jpg": "jpg", "image/png": "png", "image/webp": "webp", "image/gif": "gif", }