Application fully migrated to modular approach

This commit is contained in:
2025-09-13 21:30:40 +02:00
parent c7d6b33cd5
commit b9fe91ab88
38 changed files with 509 additions and 265 deletions

View File

@@ -6,7 +6,8 @@ from models.database_models import User, Shop
from middleware.auth import AuthManager
from middleware.rate_limiter import RateLimiter
security = HTTPBearer()
# Set auto_error=False to prevent automatic 403 responses
security = HTTPBearer(auto_error=False)
auth_manager = AuthManager()
rate_limiter = RateLimiter()
@@ -16,6 +17,10 @@ def get_current_user(
db: Session = Depends(get_db)
):
"""Get current authenticated user"""
# Check if credentials are provided
if not credentials:
raise HTTPException(status_code=401, detail="Authorization header required")
return auth_manager.get_current_user(db, credentials)

View File

@@ -4,10 +4,11 @@ from app.api.v1 import auth, product, stock, shop, marketplace, admin, stats
api_router = APIRouter()
# Include all route modules
api_router.include_router(auth.router, prefix="/auth", tags=["authentication"])
api_router.include_router(product.router, prefix="/product", tags=["product"])
api_router.include_router(stock.router, prefix="/stock", tags=["stock"])
api_router.include_router(shop.router, prefix="/shop", tags=["shop"])
api_router.include_router(marketplace.router, prefix="/marketplace", tags=["marketplace"])
api_router.include_router(admin.router, prefix="/admin", tags=["admin"])
api_router.include_router(stats.router, prefix="/stats", tags=["statistics"])
api_router.include_router(admin.router, tags=["admin"])
api_router.include_router(auth.router, tags=["authentication"])
api_router.include_router(marketplace.router, tags=["marketplace"])
api_router.include_router(product.router, tags=["product"])
api_router.include_router(shop.router, tags=["shop"])
api_router.include_router(stats.router, tags=["statistics"])
api_router.include_router(stock.router, tags=["stock"])

View File

@@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
# Authentication Routes
@router.post("/register", response_model=UserResponse)
@router.post("/auth/register", response_model=UserResponse)
def register_user(user_data: UserRegister, db: Session = Depends(get_db)):
"""Register a new user"""
try:
@@ -25,7 +25,7 @@ def register_user(user_data: UserRegister, db: Session = Depends(get_db)):
raise HTTPException(status_code=500, detail="Internal server error")
@router.post("/login", response_model=LoginResponse)
@router.post("/auth/login", response_model=LoginResponse)
def login_user(user_credentials: UserLogin, db: Session = Depends(get_db)):
"""Login user and return JWT token"""
try:
@@ -44,7 +44,7 @@ def login_user(user_credentials: UserLogin, db: Session = Depends(get_db)):
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/me", response_model=UserResponse)
@router.get("/auth/me", response_model=UserResponse)
def get_current_user_info(current_user: User = Depends(get_current_user)):
"""Get current user information"""
return UserResponse.model_validate(current_user)

View File

@@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
# Marketplace Import Routes (Protected)
@router.post("/import-from-marketplace", response_model=MarketplaceImportJobResponse)
@router.post("/marketplace/import-product", response_model=MarketplaceImportJobResponse)
@rate_limit(max_requests=10, window_seconds=3600) # Limit marketplace imports
async def import_products_from_marketplace(
request: MarketplaceImportRequest,
@@ -50,7 +50,7 @@ async def import_products_from_marketplace(
shop_id=import_job.shop_id,
shop_name=import_job.shop_name,
message=f"Marketplace import started from {request.marketplace}. Check status with "
f"/marketplace-import-status/{import_job.id}"
f"/import-status/{import_job.id}"
)
except ValueError as e:
@@ -62,7 +62,7 @@ async def import_products_from_marketplace(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/marketplace-import-status/{job_id}", response_model=MarketplaceImportJobResponse)
@router.get("/marketplace/import-status/{job_id}", response_model=MarketplaceImportJobResponse)
def get_marketplace_import_status(
job_id: int,
db: Session = Depends(get_db),
@@ -82,7 +82,7 @@ def get_marketplace_import_status(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/marketplace-import-jobs", response_model=List[MarketplaceImportJobResponse])
@router.get("/marketplace/import-jobs", response_model=List[MarketplaceImportJobResponse])
def get_marketplace_import_jobs(
marketplace: Optional[str] = Query(None, description="Filter by marketplace"),
shop_name: Optional[str] = Query(None, description="Filter by shop name"),
@@ -109,7 +109,7 @@ def get_marketplace_import_jobs(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/marketplace-import-stats")
@router.get("/marketplace/marketplace-import-stats")
def get_marketplace_import_stats(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
@@ -124,7 +124,7 @@ def get_marketplace_import_stats(
raise HTTPException(status_code=500, detail="Internal server error")
@router.put("/marketplace-import-jobs/{job_id}/cancel", response_model=MarketplaceImportJobResponse)
@router.put("/marketplace/import-jobs/{job_id}/cancel", response_model=MarketplaceImportJobResponse)
def cancel_marketplace_import_job(
job_id: int,
db: Session = Depends(get_db),
@@ -144,7 +144,7 @@ def cancel_marketplace_import_job(
raise HTTPException(status_code=500, detail="Internal server error")
@router.delete("/marketplace-import-jobs/{job_id}")
@router.delete("/marketplace/import-jobs/{job_id}")
def delete_marketplace_import_job(
job_id: int,
db: Session = Depends(get_db),

View File

@@ -66,25 +66,33 @@ def create_product(
"""Create a new product with validation and marketplace support (Protected)"""
try:
logger.info(f"Starting product creation for ID: {product.product_id}")
# Check if product_id already exists
logger.info("Checking for existing product...")
existing = product_service.get_product_by_id(db, product.product_id)
logger.info(f"Existing product found: {existing is not None}")
if existing:
logger.info("Product already exists, raising 400 error")
raise HTTPException(status_code=400, detail="Product with this ID already exists")
logger.info("No existing product found, proceeding to create...")
db_product = product_service.create_product(db, product)
logger.info("Product created successfully")
logger.info(
f"Created product {db_product.product_id} for marketplace {db_product.marketplace}, "
f"shop {db_product.shop_name}")
return db_product
except HTTPException as he:
logger.info(f"HTTPException raised: {he.status_code} - {he.detail}")
raise # Re-raise HTTP exceptions
except ValueError as e:
logger.error(f"ValueError: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Error creating product: {str(e)}")
logger.error(f"Unexpected error: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/product/{product_id}", response_model=ProductDetailResponse)
def get_product(
product_id: str,

View File

@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
# Shop Management Routes
@router.post("/shops", response_model=ShopResponse)
@router.post("/shop", response_model=ShopResponse)
def create_shop(
shop_data: ShopCreate,
db: Session = Depends(get_db),
@@ -35,7 +35,7 @@ def create_shop(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/shops", response_model=ShopListResponse)
@router.get("/shop", response_model=ShopListResponse)
def get_shops(
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1, le=1000),
@@ -68,7 +68,7 @@ def get_shops(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/shops/{shop_code}", response_model=ShopResponse)
@router.get("/shop/{shop_code}", response_model=ShopResponse)
def get_shop(shop_code: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
"""Get shop details (Protected)"""
try:
@@ -82,7 +82,7 @@ def get_shop(shop_code: str, db: Session = Depends(get_db), current_user: User =
# Shop Product Management
@router.post("/shops/{shop_code}/products", response_model=ShopProductResponse)
@router.post("/shop/{shop_code}/products", response_model=ShopProductResponse)
def add_product_to_shop(
shop_code: str,
shop_product: ShopProductCreate,
@@ -112,7 +112,7 @@ def add_product_to_shop(
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/shops/{shop_code}/products")
@router.get("/shop/{shop_code}/products")
def get_shop_products(
shop_code: str,
skip: int = Query(0, ge=0),

View File

@@ -39,7 +39,7 @@ def get_stats(db: Session = Depends(get_db), current_user: User = Depends(get_cu
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/marketplace-stats", response_model=List[MarketplaceStatsResponse])
@router.get("/stats/marketplace", response_model=List[MarketplaceStatsResponse])
def get_marketplace_stats(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
"""Get statistics broken down by marketplace (Protected)"""
try: