feat: extract inventory, orders, and marketplace modules (Phase 4)

Extract three additional modules following the billing module pattern:

Inventory Module (app/modules/inventory/):
- Stock management and tracking
- Inventory locations
- Low stock alerts
- Admin and vendor routes with module access control

Orders Module (app/modules/orders/):
- Order management and fulfillment
- Order item exceptions
- Bulk operations and export
- Admin and vendor routes with module access control

Marketplace Module (app/modules/marketplace/):
- Letzshop integration
- Product sync
- Marketplace import
- Depends on inventory module
- Admin and vendor routes with module access control

Admin router updated:
- Uses module routers with require_module_access dependency
- Legacy router includes commented out
- Routes verified: 15 inventory, 16 orders, 42 marketplace

All 31 module tests passing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-25 22:02:24 +01:00
parent c614b7d74c
commit 9d0dc51de0
17 changed files with 559 additions and 83 deletions

View File

@@ -27,12 +27,15 @@ based on platform context (not at route registration time).
Extracted modules (app/modules/{module}/routes/): Extracted modules (app/modules/{module}/routes/):
- billing: Subscription tiers, vendor billing, invoices - billing: Subscription tiers, vendor billing, invoices
- inventory: Stock management, inventory tracking
- orders: Order management, fulfillment, exceptions
- marketplace: Letzshop integration, product sync
Future extractions will follow the same pattern: Module extraction pattern:
1. Create app/modules/{module}/ directory 1. Create app/modules/{module}/ directory
2. Move routes to app/modules/{module}/routes/admin.py 2. Create routes/admin.py with require_module_access("{module}") dependency
3. Add require_module_access("{module}") to router 3. Import module router here and include it
4. Update this file to import from module instead 4. Comment out legacy router include
""" """
from fastapi import APIRouter from fastapi import APIRouter
@@ -77,6 +80,11 @@ from . import (
# Import extracted module routers # Import extracted module routers
from app.modules.billing.routes import admin_router as billing_admin_router from app.modules.billing.routes import admin_router as billing_admin_router
from app.modules.inventory.routes import admin_router as inventory_admin_router
from app.modules.orders.routes.admin import admin_router as orders_admin_router
from app.modules.orders.routes.admin import admin_exceptions_router as orders_exceptions_router
from app.modules.marketplace.routes.admin import admin_router as marketplace_admin_router
from app.modules.marketplace.routes.admin import admin_letzshop_router as letzshop_admin_router
# Create admin router # Create admin router
router = APIRouter() router = APIRouter()
@@ -141,7 +149,7 @@ router.include_router(dashboard.router, tags=["admin-dashboard"])
# ============================================================================ # ============================================================================
# Vendor Operations (Product Catalog, Inventory & Orders) # Vendor Operations (Product Catalog, Inventory & Orders) - Module-gated
# ============================================================================ # ============================================================================
# Include marketplace product catalog management endpoints # Include marketplace product catalog management endpoints
@@ -150,27 +158,26 @@ router.include_router(products.router, tags=["admin-marketplace-products"])
# Include vendor product catalog management endpoints # Include vendor product catalog management endpoints
router.include_router(vendor_products.router, tags=["admin-vendor-products"]) router.include_router(vendor_products.router, tags=["admin-vendor-products"])
# Include inventory management endpoints # Include inventory module router (with module access control)
router.include_router(inventory.router, tags=["admin-inventory"]) router.include_router(inventory_admin_router, tags=["admin-inventory"])
# Legacy: router.include_router(inventory.router, tags=["admin-inventory"])
# Include order management endpoints # Include orders module router (with module access control)
router.include_router(orders.router, tags=["admin-orders"]) router.include_router(orders_admin_router, tags=["admin-orders"])
router.include_router(orders_exceptions_router, tags=["admin-order-exceptions"])
# Include order item exception management endpoints # Legacy: router.include_router(orders.router, tags=["admin-orders"])
router.include_router( # Legacy: router.include_router(order_item_exceptions.router, tags=["admin-order-exceptions"])
order_item_exceptions.router, tags=["admin-order-exceptions"]
)
# ============================================================================ # ============================================================================
# Marketplace & Imports # Marketplace & Imports (Module-gated)
# ============================================================================ # ============================================================================
# Include marketplace monitoring endpoints # Include marketplace module router (with module access control)
router.include_router(marketplace.router, tags=["admin-marketplace"]) router.include_router(marketplace_admin_router, tags=["admin-marketplace"])
router.include_router(letzshop_admin_router, tags=["admin-letzshop"])
# Include Letzshop integration endpoints # Legacy: router.include_router(marketplace.router, tags=["admin-marketplace"])
router.include_router(letzshop.router, tags=["admin-letzshop"]) # Legacy: router.include_router(letzshop.router, tags=["admin-letzshop"])
# ============================================================================ # ============================================================================

View File

@@ -0,0 +1,23 @@
# app/modules/inventory/__init__.py
"""
Inventory Module - Stock and product management.
This module provides:
- Inventory tracking across locations
- Stock level management
- Low stock alerts
- Inventory transactions and history
- Product catalog management
Routes:
- Admin: /api/v1/admin/inventory/*
- Vendor: /api/v1/vendor/inventory/*
Menu Items:
- Admin: inventory, vendor-products
- Vendor: products, inventory
"""
from app.modules.inventory.definition import inventory_module
__all__ = ["inventory_module"]

View File

@@ -0,0 +1,70 @@
# app/modules/inventory/definition.py
"""
Inventory module definition.
Defines the inventory module including its features, menu items,
and route configurations.
"""
from app.modules.base import ModuleDefinition
from models.database.admin_menu_config import FrontendType
def _get_admin_router():
"""Lazy import of admin router to avoid circular imports."""
from app.modules.inventory.routes.admin import admin_router
return admin_router
def _get_vendor_router():
"""Lazy import of vendor router to avoid circular imports."""
from app.modules.inventory.routes.vendor import vendor_router
return vendor_router
# Inventory module definition
inventory_module = ModuleDefinition(
code="inventory",
name="Inventory Management",
description=(
"Stock level tracking, inventory locations, low stock alerts, "
"and product catalog management."
),
features=[
"inventory_basic", # Basic stock tracking
"inventory_locations", # Multiple warehouse locations
"low_stock_alerts", # Automated low stock notifications
"inventory_purchase_orders", # Purchase order management
"product_management", # Product catalog CRUD
"inventory_transactions", # Stock movement history
"inventory_import", # Bulk inventory import
],
menu_items={
FrontendType.ADMIN: [
"inventory", # Platform-wide inventory view
"vendor-products", # Product catalog management
],
FrontendType.VENDOR: [
"products", # Vendor product catalog
"inventory", # Vendor inventory management
],
},
is_core=False,
)
def get_inventory_module_with_routers() -> ModuleDefinition:
"""
Get inventory module with routers attached.
This function attaches the routers lazily to avoid circular imports
during module initialization.
"""
inventory_module.admin_router = _get_admin_router()
inventory_module.vendor_router = _get_vendor_router()
return inventory_module
__all__ = ["inventory_module", "get_inventory_module_with_routers"]

View File

@@ -0,0 +1,12 @@
# app/modules/inventory/routes/__init__.py
"""
Inventory module route registration.
This module provides functions to register inventory routes
with module-based access control.
"""
from app.modules.inventory.routes.admin import admin_router
from app.modules.inventory.routes.vendor import vendor_router
__all__ = ["admin_router", "vendor_router"]

View File

@@ -0,0 +1,26 @@
# app/modules/inventory/routes/admin.py
"""
Inventory module admin routes.
This module wraps the existing admin inventory routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original router
from app.api.v1.admin import inventory as inventory_routes
# Create module-aware router
admin_router = APIRouter(
prefix="/inventory",
dependencies=[Depends(require_module_access("inventory"))],
)
# Re-export all routes from the original module with module access control
# The routes are copied to maintain the same API structure
for route in inventory_routes.router.routes:
admin_router.routes.append(route)

View File

@@ -0,0 +1,25 @@
# app/modules/inventory/routes/vendor.py
"""
Inventory module vendor routes.
This module wraps the existing vendor inventory routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original router
from app.api.v1.vendor import inventory as inventory_routes
# Create module-aware router
vendor_router = APIRouter(
prefix="/inventory",
dependencies=[Depends(require_module_access("inventory"))],
)
# Re-export all routes from the original module with module access control
for route in inventory_routes.router.routes:
vendor_router.routes.append(route)

View File

@@ -0,0 +1,25 @@
# app/modules/marketplace/__init__.py
"""
Marketplace Module - Letzshop integration.
This module provides:
- Letzshop product sync
- Marketplace import operations
- Product catalog synchronization
- Order import from marketplace
Dependencies:
- Requires: inventory module (for product management)
Routes:
- Admin: /api/v1/admin/marketplace/*, /api/v1/admin/letzshop/*
- Vendor: /api/v1/vendor/marketplace/*, /api/v1/vendor/letzshop/*
Menu Items:
- Admin: marketplace-letzshop
- Vendor: marketplace, letzshop
"""
from app.modules.marketplace.definition import marketplace_module
__all__ = ["marketplace_module"]

View File

@@ -0,0 +1,70 @@
# app/modules/marketplace/definition.py
"""
Marketplace module definition.
Defines the marketplace module including its features, menu items,
dependencies, and route configurations.
Note: This module requires the inventory module to be enabled.
"""
from app.modules.base import ModuleDefinition
from models.database.admin_menu_config import FrontendType
def _get_admin_router():
"""Lazy import of admin router to avoid circular imports."""
from app.modules.marketplace.routes.admin import admin_router
return admin_router
def _get_vendor_router():
"""Lazy import of vendor router to avoid circular imports."""
from app.modules.marketplace.routes.vendor import vendor_router
return vendor_router
# Marketplace module definition
marketplace_module = ModuleDefinition(
code="marketplace",
name="Marketplace (Letzshop)",
description=(
"Letzshop marketplace integration for product sync, order import, "
"and catalog synchronization."
),
requires=["inventory"], # Depends on inventory module
features=[
"letzshop_sync", # Sync products with Letzshop
"marketplace_import", # Import products from marketplace
"product_sync", # Bidirectional product sync
"order_import", # Import orders from marketplace
"marketplace_analytics", # Marketplace performance metrics
],
menu_items={
FrontendType.ADMIN: [
"marketplace-letzshop", # Marketplace monitoring
],
FrontendType.VENDOR: [
"marketplace", # Vendor marketplace settings
"letzshop", # Letzshop integration
],
},
is_core=False,
)
def get_marketplace_module_with_routers() -> ModuleDefinition:
"""
Get marketplace module with routers attached.
This function attaches the routers lazily to avoid circular imports
during module initialization.
"""
marketplace_module.admin_router = _get_admin_router()
marketplace_module.vendor_router = _get_vendor_router()
return marketplace_module
__all__ = ["marketplace_module", "get_marketplace_module_with_routers"]

View File

@@ -0,0 +1,12 @@
# app/modules/marketplace/routes/__init__.py
"""
Marketplace module route registration.
This module provides functions to register marketplace routes
with module-based access control.
"""
from app.modules.marketplace.routes.admin import admin_router, admin_letzshop_router
from app.modules.marketplace.routes.vendor import vendor_router, vendor_letzshop_router
__all__ = ["admin_router", "admin_letzshop_router", "vendor_router", "vendor_letzshop_router"]

View File

@@ -0,0 +1,39 @@
# app/modules/marketplace/routes/admin.py
"""
Marketplace module admin routes.
This module wraps the existing admin marketplace routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
Includes:
- /marketplace/* - Marketplace monitoring
- /letzshop/* - Letzshop integration
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original routers
from app.api.v1.admin import marketplace as marketplace_routes
from app.api.v1.admin import letzshop as letzshop_routes
# Create module-aware router for marketplace
admin_router = APIRouter(
prefix="/marketplace",
dependencies=[Depends(require_module_access("marketplace"))],
)
# Re-export all routes from the original marketplace module
for route in marketplace_routes.router.routes:
admin_router.routes.append(route)
# Create separate router for letzshop integration
admin_letzshop_router = APIRouter(
prefix="/letzshop",
dependencies=[Depends(require_module_access("marketplace"))],
)
for route in letzshop_routes.router.routes:
admin_letzshop_router.routes.append(route)

View File

@@ -0,0 +1,39 @@
# app/modules/marketplace/routes/vendor.py
"""
Marketplace module vendor routes.
This module wraps the existing vendor marketplace routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
Includes:
- /marketplace/* - Marketplace settings
- /letzshop/* - Letzshop integration
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original routers
from app.api.v1.vendor import marketplace as marketplace_routes
from app.api.v1.vendor import letzshop as letzshop_routes
# Create module-aware router for marketplace
vendor_router = APIRouter(
prefix="/marketplace",
dependencies=[Depends(require_module_access("marketplace"))],
)
# Re-export all routes from the original marketplace module
for route in marketplace_routes.router.routes:
vendor_router.routes.append(route)
# Create separate router for letzshop integration
vendor_letzshop_router = APIRouter(
prefix="/letzshop",
dependencies=[Depends(require_module_access("marketplace"))],
)
for route in letzshop_routes.router.routes:
vendor_letzshop_router.routes.append(route)

View File

@@ -0,0 +1,23 @@
# app/modules/orders/__init__.py
"""
Orders Module - Order processing and fulfillment.
This module provides:
- Order management and tracking
- Order fulfillment workflow
- Order item exceptions handling
- Bulk order operations
- Order export and reporting
Routes:
- Admin: /api/v1/admin/orders/*, /api/v1/admin/order-item-exceptions/*
- Vendor: /api/v1/vendor/orders/*, /api/v1/vendor/order-item-exceptions/*
Menu Items:
- Admin: orders
- Vendor: orders
"""
from app.modules.orders.definition import orders_module
__all__ = ["orders_module"]

View File

@@ -0,0 +1,68 @@
# app/modules/orders/definition.py
"""
Orders module definition.
Defines the orders module including its features, menu items,
and route configurations.
"""
from app.modules.base import ModuleDefinition
from models.database.admin_menu_config import FrontendType
def _get_admin_router():
"""Lazy import of admin router to avoid circular imports."""
from app.modules.orders.routes.admin import admin_router
return admin_router
def _get_vendor_router():
"""Lazy import of vendor router to avoid circular imports."""
from app.modules.orders.routes.vendor import vendor_router
return vendor_router
# Orders module definition
orders_module = ModuleDefinition(
code="orders",
name="Order Management",
description=(
"Order processing, fulfillment tracking, order item exceptions, "
"and bulk order operations."
),
features=[
"order_management", # Basic order CRUD
"order_bulk_actions", # Bulk status updates
"order_export", # Export orders to CSV/Excel
"automation_rules", # Order automation rules
"fulfillment_tracking", # Shipping and tracking
"shipping_management", # Carrier integration
"order_exceptions", # Order item exception handling
],
menu_items={
FrontendType.ADMIN: [
"orders", # Platform-wide order management
],
FrontendType.VENDOR: [
"orders", # Vendor order management
],
},
is_core=False,
)
def get_orders_module_with_routers() -> ModuleDefinition:
"""
Get orders module with routers attached.
This function attaches the routers lazily to avoid circular imports
during module initialization.
"""
orders_module.admin_router = _get_admin_router()
orders_module.vendor_router = _get_vendor_router()
return orders_module
__all__ = ["orders_module", "get_orders_module_with_routers"]

View File

@@ -0,0 +1,12 @@
# app/modules/orders/routes/__init__.py
"""
Orders module route registration.
This module provides functions to register orders routes
with module-based access control.
"""
from app.modules.orders.routes.admin import admin_router
from app.modules.orders.routes.vendor import vendor_router
__all__ = ["admin_router", "vendor_router"]

View File

@@ -0,0 +1,40 @@
# app/modules/orders/routes/admin.py
"""
Orders module admin routes.
This module wraps the existing admin orders routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
Includes:
- /orders/* - Order management
- /order-item-exceptions/* - Exception handling
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original routers
from app.api.v1.admin import orders as orders_routes
from app.api.v1.admin import order_item_exceptions as exceptions_routes
# Create module-aware router for orders
admin_router = APIRouter(
prefix="/orders",
dependencies=[Depends(require_module_access("orders"))],
)
# Re-export all routes from the original orders module
for route in orders_routes.router.routes:
admin_router.routes.append(route)
# Create separate router for order item exceptions
# This is included separately in the admin __init__.py
admin_exceptions_router = APIRouter(
prefix="/order-item-exceptions",
dependencies=[Depends(require_module_access("orders"))],
)
for route in exceptions_routes.router.routes:
admin_exceptions_router.routes.append(route)

View File

@@ -0,0 +1,39 @@
# app/modules/orders/routes/vendor.py
"""
Orders module vendor routes.
This module wraps the existing vendor orders routes and adds
module-based access control. Routes are re-exported from the
original location with the module access dependency.
Includes:
- /orders/* - Order management
- /order-item-exceptions/* - Exception handling
"""
from fastapi import APIRouter, Depends
from app.api.deps import require_module_access
# Import original routers
from app.api.v1.vendor import orders as orders_routes
from app.api.v1.vendor import order_item_exceptions as exceptions_routes
# Create module-aware router for orders
vendor_router = APIRouter(
prefix="/orders",
dependencies=[Depends(require_module_access("orders"))],
)
# Re-export all routes from the original orders module
for route in orders_routes.router.routes:
vendor_router.routes.append(route)
# Create separate router for order item exceptions
vendor_exceptions_router = APIRouter(
prefix="/order-item-exceptions",
dependencies=[Depends(require_module_access("orders"))],
)
for route in exceptions_routes.router.routes:
vendor_exceptions_router.routes.append(route)

View File

@@ -21,6 +21,9 @@ from models.database.admin_menu_config import FrontendType
# Import extracted modules # Import extracted modules
from app.modules.billing.definition import billing_module from app.modules.billing.definition import billing_module
from app.modules.inventory.definition import inventory_module
from app.modules.marketplace.definition import marketplace_module
from app.modules.orders.definition import orders_module
# ============================================================================= # =============================================================================
@@ -84,69 +87,12 @@ MODULES: dict[str, ModuleDefinition] = {
# ========================================================================= # =========================================================================
# Billing module - imported from app/modules/billing/ # Billing module - imported from app/modules/billing/
"billing": billing_module, "billing": billing_module,
"inventory": ModuleDefinition( # Inventory module - imported from app/modules/inventory/
code="inventory", "inventory": inventory_module,
name="Inventory Management", # Orders module - imported from app/modules/orders/
description="Stock levels, locations, and low stock alerts.", "orders": orders_module,
features=[ # Marketplace module - imported from app/modules/marketplace/
"inventory_basic", "marketplace": marketplace_module,
"inventory_locations",
"low_stock_alerts",
"inventory_purchase_orders",
"product_management",
],
menu_items={
FrontendType.ADMIN: [
"inventory",
"vendor-products",
],
FrontendType.VENDOR: [
"products",
"inventory",
],
},
),
"orders": ModuleDefinition(
code="orders",
name="Order Management",
description="Order processing, fulfillment, and tracking.",
features=[
"order_management",
"order_bulk_actions",
"order_export",
"automation_rules",
"fulfillment_tracking",
"shipping_management",
],
menu_items={
FrontendType.ADMIN: [
"orders",
],
FrontendType.VENDOR: [
"orders",
],
},
),
"marketplace": ModuleDefinition(
code="marketplace",
name="Marketplace (Letzshop)",
description="Letzshop integration for product sync and order import.",
requires=["inventory"], # Depends on inventory module
features=[
"letzshop_sync",
"marketplace_import",
"product_sync",
],
menu_items={
FrontendType.ADMIN: [
"marketplace-letzshop",
],
FrontendType.VENDOR: [
"marketplace",
"letzshop",
],
},
),
"customers": ModuleDefinition( "customers": ModuleDefinition(
code="customers", code="customers",
name="Customer Management", name="Customer Management",