feat(storage): S3-compatible storage adapter + storage_uri rename
Add S3FileStorage adapter (any S3-compatible backend: AWS, MinIO, Garage) alongside the local adapter, selected via STORAGE_BACKEND. Proxied range streaming via get_object+Range; as_local_path downloads to a tempfile for ffmpeg/fpcalc. Rename track.file_path -> storage_uri across domain entity, ORM, repositories, port, and services, with an Alembic migration. Adds mocked S3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ class TrackModel(UUIDPrimaryKeyMixin, TimestampMixin, Base):
|
||||
year: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
|
||||
# -- file (original, stored as-is) -----------------------------------
|
||||
file_path: Mapped[str] = mapped_column(String(2048), nullable=False)
|
||||
storage_uri: Mapped[str] = mapped_column(String(2048), nullable=False)
|
||||
file_format: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
file_size: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
bitrate: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
|
||||
@@ -30,7 +30,7 @@ def _track_to_entity(row: TrackModel) -> Track:
|
||||
title=row.title,
|
||||
artist_id=row.artist_id,
|
||||
album_id=row.album_id,
|
||||
file_path=row.file_path,
|
||||
storage_uri=row.storage_uri,
|
||||
file_format=row.file_format,
|
||||
file_size=row.file_size,
|
||||
source=row.source,
|
||||
|
||||
@@ -29,7 +29,7 @@ def _track_to_entity(row: TrackModel) -> Track:
|
||||
title=row.title,
|
||||
artist_id=row.artist_id,
|
||||
album_id=row.album_id,
|
||||
file_path=row.file_path,
|
||||
storage_uri=row.storage_uri,
|
||||
file_format=row.file_format,
|
||||
file_size=row.file_size,
|
||||
source=row.source,
|
||||
|
||||
@@ -17,7 +17,7 @@ def _to_entity(row: TrackModel) -> Track:
|
||||
title=row.title,
|
||||
artist_id=row.artist_id,
|
||||
album_id=row.album_id,
|
||||
file_path=row.file_path,
|
||||
storage_uri=row.storage_uri,
|
||||
file_format=row.file_format,
|
||||
file_size=row.file_size,
|
||||
source=row.source,
|
||||
@@ -56,7 +56,7 @@ class SqlAlchemyTrackRepository:
|
||||
id: uuid.UUID,
|
||||
title: str,
|
||||
artist_id: uuid.UUID,
|
||||
file_path: str,
|
||||
storage_uri: str,
|
||||
file_format: str,
|
||||
file_size: int,
|
||||
source: str,
|
||||
@@ -68,7 +68,7 @@ class SqlAlchemyTrackRepository:
|
||||
id=id,
|
||||
title=title,
|
||||
artist_id=artist_id,
|
||||
file_path=file_path,
|
||||
storage_uri=storage_uri,
|
||||
file_format=file_format,
|
||||
file_size=file_size,
|
||||
source=source,
|
||||
|
||||
Reference in New Issue
Block a user