Files
orion/app/modules/cms/schemas/media.py
Samir Boulahtit 8968e7d9cd refactor: remove backward compatibility code for pre-launch baseline
Clean up accumulated backward-compat shims, deprecated wrappers, unused
aliases, and legacy code across the codebase. Since the platform is not
live yet, this establishes a clean baseline.

Changes:
- Delete deprecated middleware/context.py (RequestContext, get_request_context)
- Remove unused factory get_store_email_settings_service()
- Remove deprecated pagination_full macro, /admin/platform-homepage route
- Remove ConversationResponse, InvoiceSettings* unprefixed aliases
- Simplify celery_config.py (remove empty LEGACY_TASK_MODULES)
- Standardize billing exceptions: *Error aliases → *Exception names
- Consolidate duplicate TierNotFoundError/FeatureNotFoundError classes
- Remove deprecated is_admin_request() from Store/PlatformContextManager
- Remove is_platform_default field, MediaUploadResponse legacy flat fields
- Remove MediaItemResponse.url alias, update JS to use file_url
- Update all affected tests and documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:58:59 +01:00

185 lines
5.2 KiB
Python

# app/modules/cms/schemas/media.py
"""
Media/file management Pydantic schemas for API validation and responses.
This module provides schemas for:
- Media library listing
- File upload responses
- Media metadata operations
- Media usage tracking
"""
from datetime import datetime
from typing import Any
from pydantic import BaseModel, Field
# ============================================================================
# SHARED RESPONSE SCHEMAS
# ============================================================================
class MessageResponse(BaseModel):
"""Generic message response for simple operations."""
message: str
# ============================================================================
# MEDIA ITEM SCHEMAS
# ============================================================================
class MediaItemResponse(BaseModel):
"""Single media item response."""
id: int
filename: str
original_filename: str | None = None
file_url: str
thumbnail_url: str | None = None
media_type: str # image, video, document
mime_type: str | None = None
file_size: int | None = None # bytes
width: int | None = None # for images/videos
height: int | None = None # for images/videos
alt_text: str | None = None
description: str | None = None
folder: str | None = None
extra_metadata: dict[str, Any] | None = None
created_at: datetime
updated_at: datetime | None = None
model_config = {"from_attributes": True}
class MediaListResponse(BaseModel):
"""Paginated list of media items."""
media: list[MediaItemResponse] = []
total: int = 0
skip: int = 0
limit: int = 100
message: str | None = None
# ============================================================================
# UPLOAD RESPONSE SCHEMAS
# ============================================================================
class MediaUploadResponse(BaseModel):
"""Response for single file upload."""
success: bool = True
message: str | None = None
media: MediaItemResponse | None = None
class UploadedFileInfo(BaseModel):
"""Information about a successfully uploaded file."""
id: int
filename: str
file_url: str
thumbnail_url: str | None = None
class FailedFileInfo(BaseModel):
"""Information about a failed file upload."""
filename: str
error: str
class MultipleUploadResponse(BaseModel):
"""Response for multiple file upload."""
uploaded_files: list[UploadedFileInfo] = []
failed_files: list[FailedFileInfo] = []
total_uploaded: int = 0
total_failed: int = 0
message: str | None = None
# ============================================================================
# MEDIA DETAIL SCHEMAS
# ============================================================================
class MediaDetailResponse(BaseModel):
"""Detailed media item response with usage info."""
id: int | None = None
filename: str | None = None
original_filename: str | None = None
file_url: str | None = None
thumbnail_url: str | None = None
media_type: str | None = None
mime_type: str | None = None
file_size: int | None = None
width: int | None = None
height: int | None = None
alt_text: str | None = None
description: str | None = None
folder: str | None = None
extra_metadata: dict[str, Any] | None = None
created_at: datetime | None = None
updated_at: datetime | None = None
message: str | None = None
model_config = {"from_attributes": True}
# ============================================================================
# MEDIA UPDATE SCHEMAS
# ============================================================================
class MediaMetadataUpdate(BaseModel):
"""Request model for updating media metadata."""
filename: str | None = Field(None, max_length=255)
alt_text: str | None = Field(None, max_length=500)
description: str | None = None
folder: str | None = Field(None, max_length=100)
metadata: dict[str, Any] | None = None # Named 'metadata' in API, stored as 'extra_metadata'
# ============================================================================
# MEDIA USAGE SCHEMAS
# ============================================================================
class MediaUsageItem(BaseModel):
"""Information about an entity using this media."""
entity_type: str # Defined by provider (e.g. "product")
entity_id: int
entity_name: str
usage_type: str # Defined by provider (e.g. "main_image", "gallery")
class MediaUsageResponse(BaseModel):
"""Response showing where media is being used."""
media_id: int | None = None
usage: list[MediaUsageItem] = []
total_usage_count: int = 0
# ============================================================================
# MEDIA OPTIMIZATION SCHEMAS
# ============================================================================
class OptimizationResultResponse(BaseModel):
"""Response for media optimization operation."""
media_id: int | None = None
original_size: int | None = None
optimized_size: int | None = None
savings_percent: float | None = None
optimized_url: str | None = None
message: str | None = None