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:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user