fix: resolve architecture validation errors in media and customers APIs

- Add proper media exceptions (MediaNotFoundException, MediaUploadException, etc.)
- Update media service to use exceptions from app/exceptions/media
- Remove direct HTTPException raises from vendor/media.py and vendor/customers.py
- Move db.query from customers API to service layer (get_customer_orders)
- Fix pagination macro call in vendor/media.html template
- Update media.js: add parent init call, PlatformSettings, apiClient.postFormData
- Add try/catch error handling to media.js init method

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-06 22:40:10 +01:00
parent 8ee3f91467
commit 7b81f59eba
7 changed files with 397 additions and 248 deletions

View File

@@ -310,6 +310,50 @@ class CustomerService:
return customers, total
def get_customer_orders(
self,
db: Session,
vendor_id: int,
customer_id: int,
skip: int = 0,
limit: int = 50,
) -> tuple[list, int]:
"""
Get orders for a specific customer.
Args:
db: Database session
vendor_id: Vendor ID
customer_id: Customer ID
skip: Pagination offset
limit: Pagination limit
Returns:
Tuple of (orders, total_count)
Raises:
CustomerNotFoundException: If customer not found
"""
from models.database.order import Order
# Verify customer belongs to vendor
self.get_customer(db, vendor_id, customer_id)
# Get customer orders
query = (
db.query(Order)
.filter(
Order.customer_id == customer_id,
Order.vendor_id == vendor_id,
)
.order_by(Order.created_at.desc())
)
total = query.count()
orders = query.offset(skip).limit(limit).all()
return orders, total
def get_customer_statistics(
self, db: Session, vendor_id: int, customer_id: int
) -> dict:

View File

@@ -20,7 +20,13 @@ from pathlib import Path
from sqlalchemy import or_
from sqlalchemy.orm import Session
from app.exceptions import ValidationException
from app.exceptions.media import (
MediaNotFoundException,
MediaUploadException,
MediaValidationException,
UnsupportedMediaTypeException,
MediaFileTooLargeException,
)
from models.database.media import MediaFile, ProductMedia
logger = logging.getLogger(__name__)
@@ -63,14 +69,6 @@ MAX_FILE_SIZES = {
THUMBNAIL_SIZE = (200, 200)
class MediaNotFoundException(Exception):
"""Raised when media file is not found."""
def __init__(self, media_id: int):
self.media_id = media_id
super().__init__(f"Media file {media_id} not found")
class MediaService:
"""Service for vendor media library operations."""
@@ -105,26 +103,24 @@ class MediaService:
Tuple of (extension, media_type)
Raises:
ValidationException: If file is invalid
MediaValidationException: If file is invalid
UnsupportedMediaTypeException: If file type is not supported
MediaFileTooLargeException: If file exceeds size limit
"""
ext = self._get_file_extension(filename)
if not ext:
raise ValidationException("File must have an extension")
raise MediaValidationException("File must have an extension", field="file")
media_type = self._get_media_type(ext)
if not media_type:
allowed = ", ".join(sorted(ALLOWED_EXTENSIONS.keys()))
raise ValidationException(
f"File type '{ext}' not allowed. Allowed types: {allowed}"
raise UnsupportedMediaTypeException(
ext, allowed_types=list(ALLOWED_EXTENSIONS.keys())
)
max_size = MAX_FILE_SIZES.get(media_type, 10 * 1024 * 1024)
if file_size > max_size:
max_mb = max_size / (1024 * 1024)
raise ValidationException(
f"File too large. Maximum size for {media_type} is {max_mb:.0f} MB"
)
raise MediaFileTooLargeException(file_size, max_size, media_type)
return ext, media_type