Renaming models/api/ folder to models/schemas/
This commit is contained in:
8
.env
8
.env
@@ -10,6 +10,14 @@ VERSION=0.0.1
|
||||
# For development, you can use SQLite:
|
||||
DATABASE_URL=sqlite:///./ecommerce.db
|
||||
|
||||
# Documentation
|
||||
# .env.development
|
||||
DOCUMENTATION_URL=http://localhost:8001
|
||||
# .env.production
|
||||
# DOCUMENTATION_URL=https://yourdomain.com/docs
|
||||
# .env.staging
|
||||
# DOCUMENTATION_URL=https://staging-docs.yourdomain.com
|
||||
|
||||
# JWT Configuration
|
||||
JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production
|
||||
JWT_EXPIRE_HOURS=24
|
||||
|
||||
29
TODO
29
TODO
@@ -1,29 +0,0 @@
|
||||
Best Practice Recommendation
|
||||
For production applications, consider using database migrations (like Alembic) to manage schema changes including index
|
||||
creation, rather than creating them programmatically at startup. This provides better control and tracking of database changes.
|
||||
|
||||
|
||||
https://letzshop-google-shopping-product-exports-production.s3.eu-west-1.amazonaws.com/city_zones/strassen/vendors/wizard-cloud-marketing-s-a-r-l/google_shopping/products_fr.csv
|
||||
|
||||
what are those?
|
||||
INFO: ('192.168.1.125', 53912) - "WebSocket /" 403
|
||||
INFO: connection rejected (403 Forbidden)
|
||||
INFO: connection closed
|
||||
INFO: 192.168.1.125:53913 - "GET /loginMsg.js HTTP/1.1" 404 Not Found
|
||||
INFO: 192.168.1.125:53914 - "GET /cgi/get.cgi?cmd=home_login HTTP/1.1" 404 Not Found
|
||||
INFO: 192.168.1.125:53915 - "POST /boaform/admin/formTracert HTTP/1.1" 404 Not Found
|
||||
|
||||
|
||||
when creating a stock the gtin has to exist inthe product table
|
||||
|
||||
|
||||
FAILED tests\test_admin.py::TestAdminAPI::test_admin_endpoints_require_authentication - assert 403 == 401
|
||||
FAILED tests\test_background_tasks.py::TestBackgroundTasks::test_marketplace_import_success - AssertionError: assert 'pending' == 'completed'
|
||||
FAILED tests\test_background_tasks.py::TestBackgroundTasks::test_marketplace_import_failure - AssertionError: assert 'pending' == 'failed'
|
||||
FAILED tests\test_error_handling.py::TestErrorHandling::test_invalid_authentication - assert 401 == 403
|
||||
FAILED tests\test_error_handling.py::TestErrorHandling::test_duplicate_resource_creation - assert 500 == 400
|
||||
FAILED tests\test_marketplace.py::TestMarketplaceAPI::test_import_from_marketplace - sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 1 - probably unsupported type.
|
||||
FAILED tests\test_product.py::TestProductsAPI::test_get_products_empty - assert 404 == 200
|
||||
FAILED tests\test_product.py::TestProductsAPI::test_create_product_duplicate_id - assert 500 == 400
|
||||
FAILED tests\test_security.py::TestSecurity::test_protected_endpoint_with_invalid_token - assert 401 == 403
|
||||
FAILED tests\test_security.py::TestSecurity::test_input_validation - assert '<script>' not in "<script>ale...s')</script>"
|
||||
@@ -16,9 +16,9 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_admin_user
|
||||
from app.core.database import get_db
|
||||
from app.services.admin_service import admin_service
|
||||
from models.api.auth import UserResponse
|
||||
from models.api.marketplace import MarketplaceImportJobResponse
|
||||
from models.api.shop import ShopListResponse
|
||||
from models.schemas.auth import UserResponse
|
||||
from models.schemas.marketplace import MarketplaceImportJobResponse
|
||||
from models.schemas.shop import ShopListResponse
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -15,8 +15,8 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_user
|
||||
from app.core.database import get_db
|
||||
from app.services.auth_service import auth_service
|
||||
from models.api.auth import (LoginResponse, UserLogin, UserRegister,
|
||||
UserResponse)
|
||||
from models.schemas.auth import (LoginResponse, UserLogin, UserRegister,
|
||||
UserResponse)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -18,8 +18,8 @@ from app.core.database import get_db
|
||||
from app.services.marketplace_service import marketplace_service
|
||||
from app.tasks.background_tasks import process_marketplace_import
|
||||
from middleware.decorators import rate_limit
|
||||
from models.api.marketplace import (MarketplaceImportJobResponse,
|
||||
MarketplaceImportRequest)
|
||||
from models.schemas.marketplace import (MarketplaceImportJobResponse,
|
||||
MarketplaceImportRequest)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -17,9 +17,9 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_user
|
||||
from app.core.database import get_db
|
||||
from app.services.product_service import product_service
|
||||
from models.api.product import (ProductCreate, ProductDetailResponse,
|
||||
ProductListResponse, ProductResponse,
|
||||
ProductUpdate)
|
||||
from models.schemas.product import (ProductCreate, ProductDetailResponse,
|
||||
ProductListResponse, ProductResponse,
|
||||
ProductUpdate)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -15,8 +15,8 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_user, get_user_shop
|
||||
from app.core.database import get_db
|
||||
from app.services.shop_service import shop_service
|
||||
from models.api.shop import (ShopCreate, ShopListResponse, ShopProductCreate,
|
||||
ShopProductResponse, ShopResponse)
|
||||
from models.schemas.shop import (ShopCreate, ShopListResponse, ShopProductCreate,
|
||||
ShopProductResponse, ShopResponse)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -16,7 +16,7 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_user
|
||||
from app.core.database import get_db
|
||||
from app.services.stats_service import stats_service
|
||||
from models.api.stats import MarketplaceStatsResponse, StatsResponse
|
||||
from models.schemas.stats import MarketplaceStatsResponse, StatsResponse
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -16,8 +16,8 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_user
|
||||
from app.core.database import get_db
|
||||
from app.services.stock_service import stock_service
|
||||
from models.api.stock import (StockAdd, StockCreate, StockResponse,
|
||||
StockSummaryResponse, StockUpdate)
|
||||
from models.schemas.stock import (StockAdd, StockCreate, StockResponse,
|
||||
StockSummaryResponse, StockUpdate)
|
||||
from models.database.user import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -18,42 +18,21 @@ class Settings(BaseSettings):
|
||||
|
||||
# Project information
|
||||
project_name: str = "Ecommerce Backend API with Marketplace Support"
|
||||
# Documentation
|
||||
documentation_url: str = "http://localhost:8001" # Development default
|
||||
|
||||
# Clean description without HTML
|
||||
description: str = """
|
||||
## 🚀 Letzshop Import API
|
||||
|
||||
Complete marketplace product import and management system built with FastAPI.
|
||||
|
||||
### 📚 Documentation Links
|
||||
|
||||
- **[Complete Documentation Site](#)** - Full project documentation
|
||||
- **[Getting Started Guide](#)** - Installation and setup
|
||||
- **[User Guides](#)** - How-to guides and tutorials
|
||||
- **[API Authentication Guide](#)** - Security and authentication
|
||||
- **[Testing Documentation](#)** - Test suite and conventions
|
||||
|
||||
### 🔗 Quick Links
|
||||
|
||||
- **[Alternative API Docs](/redoc)** - ReDoc interface
|
||||
- **[Health Check](/health)** - System status
|
||||
- **[OpenAPI Spec](/openapi.json)** - Machine-readable API spec
|
||||
|
||||
### 📖 Key Features
|
||||
|
||||
- **Product Management** - Complete CRUD operations with validation
|
||||
- **Multi-Shop Support** - Independent shop configurations
|
||||
- **CSV Import System** - Bulk import from various marketplace formats
|
||||
- **Stock Management** - Inventory tracking across locations
|
||||
- **User Management** - Role-based access control
|
||||
- **Marketplace Integration** - Import from multiple platforms
|
||||
|
||||
### 🏗️ Architecture
|
||||
|
||||
Built with modern Python stack:
|
||||
- **FastAPI** - High-performance async API framework
|
||||
- **SQLAlchemy** - Powerful ORM with PostgreSQL
|
||||
- **Pydantic** - Data validation and serialization
|
||||
- **JWT Authentication** - Secure token-based auth
|
||||
- **pytest** - Comprehensive test suite
|
||||
Marketplace product import and management system with multi-shop support.
|
||||
|
||||
**Features:**
|
||||
- JWT Authentication with role-based access
|
||||
- Multi-marketplace product import (CSV processing)
|
||||
- Inventory management across multiple locations
|
||||
- Shop management with individual configurations
|
||||
|
||||
**Documentation:** Visit /documentation for complete guides
|
||||
**API Testing:** Use /docs for interactive API exploration
|
||||
"""
|
||||
version: str = "2.2.0"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ from typing import List, Optional, Tuple
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.api.marketplace import MarketplaceImportJobResponse
|
||||
from models.schemas.marketplace import MarketplaceImportJobResponse
|
||||
from models.database.marketplace import MarketplaceImportJob
|
||||
from models.database.shop import Shop
|
||||
from models.database.user import User
|
||||
|
||||
@@ -14,7 +14,7 @@ from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from middleware.auth import AuthManager
|
||||
from models.api.auth import UserLogin, UserRegister
|
||||
from models.schemas.auth import UserLogin, UserRegister
|
||||
from models.database.user import User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -14,8 +14,8 @@ from typing import List, Optional
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.api.marketplace import (MarketplaceImportJobResponse,
|
||||
MarketplaceImportRequest)
|
||||
from models.schemas.marketplace import (MarketplaceImportJobResponse,
|
||||
MarketplaceImportRequest)
|
||||
from models.database.marketplace import MarketplaceImportJob
|
||||
from models.database.shop import Shop
|
||||
from models.database.user import User
|
||||
|
||||
@@ -14,8 +14,8 @@ from typing import Generator, List, Optional
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.api.product import ProductCreate, ProductUpdate
|
||||
from models.api.stock import StockLocationResponse, StockSummaryResponse
|
||||
from models.schemas.product import ProductCreate, ProductUpdate
|
||||
from models.schemas.stock import StockLocationResponse, StockSummaryResponse
|
||||
from models.database.product import Product
|
||||
from models.database.stock import Stock
|
||||
from utils.data_processing import GTINProcessor, PriceProcessor
|
||||
|
||||
@@ -14,7 +14,7 @@ from fastapi import HTTPException
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.api.shop import ShopCreate, ShopProductCreate
|
||||
from models.schemas.shop import ShopCreate, ShopProductCreate
|
||||
from models.database.product import Product
|
||||
from models.database.shop import Shop, ShopProduct
|
||||
from models.database.user import User
|
||||
|
||||
@@ -13,8 +13,8 @@ from typing import List, Optional
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.api.stock import (StockAdd, StockCreate, StockLocationResponse,
|
||||
StockSummaryResponse, StockUpdate)
|
||||
from models.schemas.stock import (StockAdd, StockCreate, StockLocationResponse,
|
||||
StockSummaryResponse, StockUpdate)
|
||||
from models.database.product import Product
|
||||
from models.database.stock import Stock
|
||||
from utils.data_processing import GTINProcessor
|
||||
|
||||
92
main.py
92
main.py
@@ -57,7 +57,7 @@ def health_check(db: Session = Depends(get_db)):
|
||||
"swagger": "/docs",
|
||||
"redoc": "/redoc",
|
||||
"openapi": "/openapi.json",
|
||||
"complete": "Documentation site URL here",
|
||||
"complete": "/documentation",
|
||||
},
|
||||
"features": [
|
||||
"JWT Authentication",
|
||||
@@ -79,89 +79,13 @@ def health_check(db: Session = Depends(get_db)):
|
||||
|
||||
# Documentation redirect endpoints
|
||||
@app.get("/documentation", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def documentation_page():
|
||||
"""Enhanced documentation hub page"""
|
||||
return """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Letzshop Import - Documentation</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.header { text-align: center; margin-bottom: 40px; }
|
||||
.logo { font-size: 2em; margin-bottom: 10px; }
|
||||
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 30px 0; }
|
||||
.card {
|
||||
border: 1px solid #e1e5e9;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: box-shadow 0.2s;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
.card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
||||
.card h3 { margin-top: 0; color: #1976d2; }
|
||||
.badge {
|
||||
display: inline-block;
|
||||
background: #1976d2;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.8em;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="logo">📚 Letzshop Import Documentation</div>
|
||||
<p>Choose your documentation experience</p>
|
||||
</div>
|
||||
|
||||
<div class="cards">
|
||||
<a href="/docs" class="card">
|
||||
<h3>🔧 Interactive API Docs <span class="badge">LIVE</span></h3>
|
||||
<p>Swagger UI interface for testing API endpoints directly in your browser. Perfect for development and API exploration.</p>
|
||||
</a>
|
||||
|
||||
<a href="/redoc" class="card">
|
||||
<h3>📖 API Reference</h3>
|
||||
<p>Clean, readable API documentation with ReDoc. Great for understanding API structure and parameters.</p>
|
||||
</a>
|
||||
|
||||
<a href="#" class="card">
|
||||
<h3>📚 Complete Documentation</h3>
|
||||
<p>Comprehensive project documentation with guides, tutorials, architecture, and development info.</p>
|
||||
</a>
|
||||
|
||||
<a href="#" class="card">
|
||||
<h3>🚀 Getting Started</h3>
|
||||
<p>Step-by-step installation and setup guide to get you up and running quickly.</p>
|
||||
</a>
|
||||
|
||||
<a href="#" class="card">
|
||||
<h3>🧪 Testing Guide</h3>
|
||||
<p>Testing conventions, how to run tests, and contribute to the test suite.</p>
|
||||
</a>
|
||||
|
||||
<a href="/health" class="card">
|
||||
<h3>💚 System Health</h3>
|
||||
<p>Check the current status and health of the API and its dependencies.</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top: 40px; color: #666;">
|
||||
<p>Need help? Check our <a href="https://github.com/yourusername/letzshop-import/issues">GitHub Issues</a></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
async def documentation():
|
||||
"""Redirect to MkDocs documentation"""
|
||||
# Development
|
||||
if settings.debug:
|
||||
return RedirectResponse(url="http://localhost:8001")
|
||||
# Production
|
||||
return RedirectResponse(url=settings.documentation_url)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -10,7 +10,7 @@ from .database.shop import Shop, ShopProduct
|
||||
from .database.marketplace import MarketplaceImportJob
|
||||
|
||||
# API models (Pydantic) - import the modules, not all classes
|
||||
from . import api
|
||||
from . import schemas
|
||||
|
||||
# Export database models for Alembic
|
||||
__all__ = [
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator
|
||||
|
||||
from models.api.stock import StockSummaryResponse
|
||||
from models.schemas.stock import StockSummaryResponse
|
||||
|
||||
|
||||
class ProductBase(BaseModel):
|
||||
@@ -4,7 +4,7 @@ from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator
|
||||
|
||||
from models.api.product import ProductResponse
|
||||
from models.schemas.product import ProductResponse
|
||||
|
||||
|
||||
class ShopCreate(BaseModel):
|
||||
@@ -144,7 +144,7 @@ def verify_model_structure():
|
||||
|
||||
# Test API models
|
||||
try:
|
||||
import models.api
|
||||
import models.schemas
|
||||
print("[OK] API models package imported")
|
||||
|
||||
# Test specific API model imports
|
||||
|
||||
@@ -3,7 +3,7 @@ import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.services.auth_service import AuthService
|
||||
from models.api.auth import UserLogin, UserRegister
|
||||
from models.schemas.auth import UserLogin, UserRegister
|
||||
from models.database.user import User
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from datetime import datetime
|
||||
import pytest
|
||||
|
||||
from app.services.marketplace_service import MarketplaceService
|
||||
from models.api.marketplace import MarketplaceImportRequest
|
||||
from models.schemas.marketplace import MarketplaceImportRequest
|
||||
from models.database.marketplace import MarketplaceImportJob
|
||||
from models.database.shop import Shop
|
||||
from models.database.user import User
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import pytest
|
||||
|
||||
from app.services.product_service import ProductService
|
||||
from models.api.product import ProductCreate
|
||||
from models.schemas.product import ProductCreate
|
||||
from models.database.product import Product
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.services.shop_service import ShopService
|
||||
from models.api.shop import ShopCreate, ShopProductCreate
|
||||
from models.schemas.shop import ShopCreate, ShopProductCreate
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
import pytest
|
||||
|
||||
from app.services.stock_service import StockService
|
||||
from models.api.stock import StockAdd, StockCreate, StockUpdate
|
||||
from models.schemas.stock import StockAdd, StockCreate, StockUpdate
|
||||
from models.database.product import Product
|
||||
from models.database.stock import Stock
|
||||
|
||||
|
||||
Reference in New Issue
Block a user