# app/api/v1/vendor/marketplace.py # Note: Should be under /vendor/ route """ Marketplace import endpoints for vendors. Vendor context is automatically injected by middleware. """ import logging from typing import List, Optional from fastapi import APIRouter, BackgroundTasks, Depends, Query from sqlalchemy.orm import Session from app.api.deps import get_current_user from app.core.database import get_db from middleware.vendor_context import require_vendor_context # IMPORTANT from app.services.marketplace_import_job_service import marketplace_import_job_service from app.tasks.background_tasks import process_marketplace_import from middleware.decorators import rate_limit from models.schema.marketplace_import_job import ( MarketplaceImportJobResponse, MarketplaceImportJobRequest ) from models.database.user import User from models.database.vendor import Vendor router = APIRouter() logger = logging.getLogger(__name__) @router.post("/import", response_model=MarketplaceImportJobResponse) @rate_limit(max_requests=10, window_seconds=3600) async def import_products_from_marketplace( request: MarketplaceImportJobRequest, background_tasks: BackgroundTasks, vendor: Vendor = Depends(require_vendor_context()), # ADDED: Vendor from middleware current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """Import products from marketplace CSV with background processing (Protected).""" logger.info( f"Starting marketplace import: {request.marketplace} for vendor {vendor.vendor_code} " f"by user {current_user.username}" ) # Create import job (vendor comes from middleware) import_job = marketplace_import_job_service.create_import_job( db, request, vendor, current_user ) # Process in background background_tasks.add_task( process_marketplace_import, import_job.id, request.source_url, # FIXED: was request.url request.marketplace, vendor.id, # Pass vendor_id instead of vendor_code request.batch_size or 1000, ) return MarketplaceImportJobResponse( job_id=import_job.id, status="pending", marketplace=request.marketplace, vendor_id=import_job.vendor_id, vendor_code=vendor.vendor_code, vendor_name=vendor.name, # FIXED: from vendor object source_url=request.source_url, message=f"Marketplace import started from {request.marketplace}. " f"Check status with /import-status/{import_job.id}", imported=0, updated=0, total_processed=0, error_count=0, created_at=import_job.created_at, ) @router.get("/imports/{job_id}", response_model=MarketplaceImportJobResponse) def get_marketplace_import_status( job_id: int, vendor: Vendor = Depends(require_vendor_context()), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """Get status of marketplace import job (Protected).""" job = marketplace_import_job_service.get_import_job_by_id(db, job_id, current_user) # Verify job belongs to current vendor if job.vendor_id != vendor.id: from app.exceptions import UnauthorizedVendorAccessException raise UnauthorizedVendorAccessException(vendor.vendor_code, current_user.id) return marketplace_import_job_service.convert_to_response_model(job) @router.get("/imports", response_model=List[MarketplaceImportJobResponse]) def get_marketplace_import_jobs( marketplace: Optional[str] = Query(None, description="Filter by marketplace"), skip: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=100), vendor: Vendor = Depends(require_vendor_context()), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """Get marketplace import jobs for current vendor (Protected).""" jobs = marketplace_import_job_service.get_import_jobs( db=db, vendor=vendor, user=current_user, marketplace=marketplace, skip=skip, limit=limit, ) return [marketplace_import_job_service.convert_to_response_model(job) for job in jobs]