From 705d336e19093437cb2a3ca2f596c87441b9279a Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Wed, 28 Jan 2026 22:21:50 +0100 Subject: [PATCH] feat: add self-contained structure to remaining modules Add exceptions, models, schemas, services directories to modules: customers: - exceptions.py, models/, schemas/, services/ inventory: - exceptions.py, models/, schemas/, services/ messaging: - exceptions.py, models/, schemas/, services/ monitoring: - exceptions.py, models/, schemas/, services/ orders: - exceptions.py, models/, schemas/, services/ payments: - Updated __init__.py All modules now have the standard self-contained directory structure ready for future migration of business logic. Co-Authored-By: Claude Opus 4.5 --- app/modules/customers/__init__.py | 37 +++++++++----- app/modules/customers/definition.py | 15 +++++- app/modules/customers/exceptions.py | 37 ++++++++++++++ app/modules/customers/models/__init__.py | 18 +++++++ app/modules/customers/schemas/__init__.py | 28 +++++++++++ app/modules/customers/services/__init__.py | 28 +++++++++++ app/modules/inventory/__init__.py | 35 +++++++++----- app/modules/inventory/definition.py | 13 ++++- app/modules/inventory/exceptions.py | 26 ++++++++++ app/modules/inventory/models/__init__.py | 18 +++++++ app/modules/inventory/schemas/__init__.py | 28 +++++++++++ app/modules/inventory/services/__init__.py | 28 +++++++++++ app/modules/messaging/__init__.py | 36 +++++++++----- app/modules/messaging/definition.py | 27 +++++------ app/modules/messaging/exceptions.py | 28 +++++++++++ app/modules/messaging/models/__init__.py | 26 ++++++++++ app/modules/messaging/schemas/__init__.py | 28 +++++++++++ app/modules/messaging/services/__init__.py | 30 ++++++++++++ app/modules/monitoring/__init__.py | 45 ++++++++++------- app/modules/monitoring/definition.py | 10 +++- app/modules/monitoring/exceptions.py | 50 +++++++++++++++++++ app/modules/monitoring/models/__init__.py | 21 ++++++++ app/modules/monitoring/schemas/__init__.py | 11 +++++ app/modules/monitoring/services/__init__.py | 16 +++++++ app/modules/orders/__init__.py | 37 +++++++++----- app/modules/orders/definition.py | 14 +++++- app/modules/orders/exceptions.py | 53 +++++++++++++++++++++ app/modules/orders/models/__init__.py | 28 +++++++++++ app/modules/orders/schemas/__init__.py | 36 ++++++++++++++ app/modules/orders/services/__init__.py | 40 ++++++++++++++++ app/modules/payments/__init__.py | 12 ++++- 31 files changed, 772 insertions(+), 87 deletions(-) create mode 100644 app/modules/customers/exceptions.py create mode 100644 app/modules/customers/models/__init__.py create mode 100644 app/modules/customers/schemas/__init__.py create mode 100644 app/modules/customers/services/__init__.py create mode 100644 app/modules/inventory/exceptions.py create mode 100644 app/modules/inventory/models/__init__.py create mode 100644 app/modules/inventory/schemas/__init__.py create mode 100644 app/modules/inventory/services/__init__.py create mode 100644 app/modules/messaging/exceptions.py create mode 100644 app/modules/messaging/models/__init__.py create mode 100644 app/modules/messaging/schemas/__init__.py create mode 100644 app/modules/messaging/services/__init__.py create mode 100644 app/modules/monitoring/exceptions.py create mode 100644 app/modules/monitoring/models/__init__.py create mode 100644 app/modules/monitoring/schemas/__init__.py create mode 100644 app/modules/monitoring/services/__init__.py create mode 100644 app/modules/orders/exceptions.py create mode 100644 app/modules/orders/models/__init__.py create mode 100644 app/modules/orders/schemas/__init__.py create mode 100644 app/modules/orders/services/__init__.py diff --git a/app/modules/customers/__init__.py b/app/modules/customers/__init__.py index 3a1c129f..86693dd1 100644 --- a/app/modules/customers/__init__.py +++ b/app/modules/customers/__init__.py @@ -2,21 +2,34 @@ """ Customers Module - Customer database and management. -This module provides: +This is a self-contained core module providing: +- Customer registration and authentication - Customer profiles and contact information +- Customer address management - Customer segmentation and tags -- Purchase history tracking -- Customer exports -Routes: -- Admin: /api/v1/admin/customers/* -- Vendor: /api/v1/vendor/customers/* - -Menu Items: -- Admin: customers -- Vendor: customers +Module Structure: +- models/ - Database models (Customer, CustomerAddress, etc.) +- services/ - Business logic (CustomerService, CustomerAddressService) +- schemas/ - Pydantic DTOs +- routes/ - API routes +- exceptions.py - Module-specific exceptions """ -from app.modules.customers.definition import customers_module +# Use lazy imports to avoid circular import issues -__all__ = ["customers_module"] + +def __getattr__(name: str): + """Lazy import module components to avoid circular imports.""" + if name == "customers_module": + from app.modules.customers.definition import customers_module + + return customers_module + elif name == "get_customers_module_with_routers": + from app.modules.customers.definition import get_customers_module_with_routers + + return get_customers_module_with_routers + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +__all__ = ["customers_module", "get_customers_module_with_routers"] diff --git a/app/modules/customers/definition.py b/app/modules/customers/definition.py index ab80e176..95fcf711 100644 --- a/app/modules/customers/definition.py +++ b/app/modules/customers/definition.py @@ -3,7 +3,7 @@ Customers module definition. Defines the customers module including its features, menu items, -and route configurations. +route configurations, and self-contained module settings. """ from app.modules.base import ModuleDefinition @@ -28,12 +28,15 @@ def _get_vendor_router(): customers_module = ModuleDefinition( code="customers", name="Customer Management", - description="Customer database, profiles, and segmentation.", + description="Customer database, profiles, addresses, and segmentation.", + version="1.0.0", features=[ "customer_view", # View customer profiles "customer_export", # Export customer data "customer_profiles", # Detailed customer profiles "customer_segmentation", # Customer tagging and segments + "customer_addresses", # Address management + "customer_authentication", # Customer login/registration ], menu_items={ FrontendType.ADMIN: [ @@ -44,6 +47,14 @@ customers_module = ModuleDefinition( ], }, is_core=True, # Customers is a core module - customer data is fundamental + # ========================================================================= + # Self-Contained Module Configuration + # ========================================================================= + is_self_contained=True, + services_path="app.modules.customers.services", + models_path="app.modules.customers.models", + schemas_path="app.modules.customers.schemas", + exceptions_path="app.modules.customers.exceptions", ) diff --git a/app/modules/customers/exceptions.py b/app/modules/customers/exceptions.py new file mode 100644 index 00000000..057e8585 --- /dev/null +++ b/app/modules/customers/exceptions.py @@ -0,0 +1,37 @@ +# app/modules/customers/exceptions.py +""" +Customers module exceptions. + +Re-exports customer-related exceptions from their source locations. +""" + +from app.exceptions.customer import ( + CustomerNotFoundException, + CustomerAlreadyExistsException, + DuplicateCustomerEmailException, + CustomerNotActiveException, + InvalidCustomerCredentialsException, + CustomerValidationException, + CustomerAuthorizationException, +) + +from app.exceptions.address import ( + AddressNotFoundException, + AddressLimitExceededException, + InvalidAddressTypeException, +) + +__all__ = [ + # Customer exceptions + "CustomerNotFoundException", + "CustomerAlreadyExistsException", + "DuplicateCustomerEmailException", + "CustomerNotActiveException", + "InvalidCustomerCredentialsException", + "CustomerValidationException", + "CustomerAuthorizationException", + # Address exceptions + "AddressNotFoundException", + "AddressLimitExceededException", + "InvalidAddressTypeException", +] diff --git a/app/modules/customers/models/__init__.py b/app/modules/customers/models/__init__.py new file mode 100644 index 00000000..16c3912e --- /dev/null +++ b/app/modules/customers/models/__init__.py @@ -0,0 +1,18 @@ +# app/modules/customers/models/__init__.py +""" +Customers module database models. + +Re-exports customer-related models from their source locations. +""" + +from models.database.customer import ( + Customer, + CustomerAddress, +) +from models.database.password_reset_token import PasswordResetToken + +__all__ = [ + "Customer", + "CustomerAddress", + "PasswordResetToken", +] diff --git a/app/modules/customers/schemas/__init__.py b/app/modules/customers/schemas/__init__.py new file mode 100644 index 00000000..3d265f9c --- /dev/null +++ b/app/modules/customers/schemas/__init__.py @@ -0,0 +1,28 @@ +# app/modules/customers/schemas/__init__.py +""" +Customers module Pydantic schemas. + +Re-exports customer-related schemas from their source locations. +""" + +from models.schema.customer import ( + CustomerRegister, + CustomerUpdate, + CustomerLogin, + CustomerResponse, + CustomerListResponse, + CustomerAddressCreate, + CustomerAddressUpdate, + CustomerAddressResponse, +) + +__all__ = [ + "CustomerRegister", + "CustomerUpdate", + "CustomerLogin", + "CustomerResponse", + "CustomerListResponse", + "CustomerAddressCreate", + "CustomerAddressUpdate", + "CustomerAddressResponse", +] diff --git a/app/modules/customers/services/__init__.py b/app/modules/customers/services/__init__.py new file mode 100644 index 00000000..762005df --- /dev/null +++ b/app/modules/customers/services/__init__.py @@ -0,0 +1,28 @@ +# app/modules/customers/services/__init__.py +""" +Customers module services. + +Re-exports customer-related services from their source locations. +""" + +from app.services.customer_service import ( + customer_service, + CustomerService, +) +from app.services.admin_customer_service import ( + admin_customer_service, + AdminCustomerService, +) +from app.services.customer_address_service import ( + customer_address_service, + CustomerAddressService, +) + +__all__ = [ + "customer_service", + "CustomerService", + "admin_customer_service", + "AdminCustomerService", + "customer_address_service", + "CustomerAddressService", +] diff --git a/app/modules/inventory/__init__.py b/app/modules/inventory/__init__.py index e3ca58c1..95337dad 100644 --- a/app/modules/inventory/__init__.py +++ b/app/modules/inventory/__init__.py @@ -2,22 +2,35 @@ """ Inventory Module - Stock and product management. -This module provides: +This is a self-contained module providing: - Inventory tracking across locations - Stock level management - Low stock alerts - Inventory transactions and history -- Product catalog management +- Bulk inventory imports -Routes: -- Admin: /api/v1/admin/inventory/* -- Vendor: /api/v1/vendor/inventory/* - -Menu Items: -- Admin: inventory, vendor-products -- Vendor: products, inventory +Module Structure: +- models/ - Database models (Inventory, InventoryTransaction) +- services/ - Business logic (InventoryService, InventoryTransactionService) +- schemas/ - Pydantic DTOs +- routes/ - API routes +- exceptions.py - Module-specific exceptions """ -from app.modules.inventory.definition import inventory_module +# Use lazy imports to avoid circular import issues -__all__ = ["inventory_module"] + +def __getattr__(name: str): + """Lazy import module components to avoid circular imports.""" + if name == "inventory_module": + from app.modules.inventory.definition import inventory_module + + return inventory_module + elif name == "get_inventory_module_with_routers": + from app.modules.inventory.definition import get_inventory_module_with_routers + + return get_inventory_module_with_routers + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +__all__ = ["inventory_module", "get_inventory_module_with_routers"] diff --git a/app/modules/inventory/definition.py b/app/modules/inventory/definition.py index 12962fa6..56bbf4e2 100644 --- a/app/modules/inventory/definition.py +++ b/app/modules/inventory/definition.py @@ -3,7 +3,7 @@ Inventory module definition. Defines the inventory module including its features, menu items, -and route configurations. +route configurations, and self-contained module settings. """ from app.modules.base import ModuleDefinition @@ -30,8 +30,9 @@ inventory_module = ModuleDefinition( name="Inventory Management", description=( "Stock level tracking, inventory locations, low stock alerts, " - "and product catalog management." + "transaction history, and bulk imports." ), + version="1.0.0", features=[ "inventory_basic", # Basic stock tracking "inventory_locations", # Multiple warehouse locations @@ -52,6 +53,14 @@ inventory_module = ModuleDefinition( ], }, is_core=False, + # ========================================================================= + # Self-Contained Module Configuration + # ========================================================================= + is_self_contained=True, + services_path="app.modules.inventory.services", + models_path="app.modules.inventory.models", + schemas_path="app.modules.inventory.schemas", + exceptions_path="app.modules.inventory.exceptions", ) diff --git a/app/modules/inventory/exceptions.py b/app/modules/inventory/exceptions.py new file mode 100644 index 00000000..1c0c5edb --- /dev/null +++ b/app/modules/inventory/exceptions.py @@ -0,0 +1,26 @@ +# app/modules/inventory/exceptions.py +""" +Inventory module exceptions. + +Re-exports inventory-related exceptions from their source locations. +""" + +from app.exceptions.inventory import ( + InventoryNotFoundException, + InsufficientInventoryException, + InvalidInventoryOperationException, + InventoryValidationException, + NegativeInventoryException, + InvalidQuantityException, + LocationNotFoundException, +) + +__all__ = [ + "InventoryNotFoundException", + "InsufficientInventoryException", + "InvalidInventoryOperationException", + "InventoryValidationException", + "NegativeInventoryException", + "InvalidQuantityException", + "LocationNotFoundException", +] diff --git a/app/modules/inventory/models/__init__.py b/app/modules/inventory/models/__init__.py new file mode 100644 index 00000000..df37b955 --- /dev/null +++ b/app/modules/inventory/models/__init__.py @@ -0,0 +1,18 @@ +# app/modules/inventory/models/__init__.py +""" +Inventory module database models. + +Re-exports inventory-related models from their source locations. +""" + +from models.database.inventory import Inventory +from models.database.inventory_transaction import ( + InventoryTransaction, + TransactionType, +) + +__all__ = [ + "Inventory", + "InventoryTransaction", + "TransactionType", +] diff --git a/app/modules/inventory/schemas/__init__.py b/app/modules/inventory/schemas/__init__.py new file mode 100644 index 00000000..55e1b9aa --- /dev/null +++ b/app/modules/inventory/schemas/__init__.py @@ -0,0 +1,28 @@ +# app/modules/inventory/schemas/__init__.py +""" +Inventory module Pydantic schemas. + +Re-exports inventory-related schemas from their source locations. +""" + +from models.schema.inventory import ( + InventoryCreate, + InventoryAdjust, + InventoryReserve, + InventoryResponse, + InventoryListResponse, + InventoryTransactionResponse, + AdminInventoryItem, + AdminLowStockItem, +) + +__all__ = [ + "InventoryCreate", + "InventoryAdjust", + "InventoryReserve", + "InventoryResponse", + "InventoryListResponse", + "InventoryTransactionResponse", + "AdminInventoryItem", + "AdminLowStockItem", +] diff --git a/app/modules/inventory/services/__init__.py b/app/modules/inventory/services/__init__.py new file mode 100644 index 00000000..0cd8c671 --- /dev/null +++ b/app/modules/inventory/services/__init__.py @@ -0,0 +1,28 @@ +# app/modules/inventory/services/__init__.py +""" +Inventory module services. + +Re-exports inventory-related services from their source locations. +""" + +from app.services.inventory_service import ( + inventory_service, + InventoryService, +) +from app.services.inventory_transaction_service import ( + inventory_transaction_service, + InventoryTransactionService, +) +from app.services.inventory_import_service import ( + inventory_import_service, + InventoryImportService, +) + +__all__ = [ + "inventory_service", + "InventoryService", + "inventory_transaction_service", + "InventoryTransactionService", + "inventory_import_service", + "InventoryImportService", +] diff --git a/app/modules/messaging/__init__.py b/app/modules/messaging/__init__.py index 7310384c..c5042c18 100644 --- a/app/modules/messaging/__init__.py +++ b/app/modules/messaging/__init__.py @@ -2,21 +2,35 @@ """ Messaging Module - Internal messaging and notifications. -This module provides: +This is a self-contained module providing: - Internal messages between users - Customer communication +- Admin-vendor-customer conversations - Notification center -- Email notifications +- Message attachments -Routes: -- Admin: /api/v1/admin/messages/*, /api/v1/admin/notifications/* -- Vendor: /api/v1/vendor/messages/*, /api/v1/vendor/notifications/* - -Menu Items: -- Admin: messages, notifications -- Vendor: messages, notifications +Module Structure: +- models/ - Database models (Conversation, Message, etc.) +- services/ - Business logic (MessagingService, NotificationService) +- schemas/ - Pydantic DTOs +- routes/ - API routes +- exceptions.py - Module-specific exceptions """ -from app.modules.messaging.definition import messaging_module +# Use lazy imports to avoid circular import issues -__all__ = ["messaging_module"] + +def __getattr__(name: str): + """Lazy import module components to avoid circular imports.""" + if name == "messaging_module": + from app.modules.messaging.definition import messaging_module + + return messaging_module + elif name == "get_messaging_module_with_routers": + from app.modules.messaging.definition import get_messaging_module_with_routers + + return get_messaging_module_with_routers + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +__all__ = ["messaging_module", "get_messaging_module_with_routers"] diff --git a/app/modules/messaging/definition.py b/app/modules/messaging/definition.py index 8189c6e9..13a666d3 100644 --- a/app/modules/messaging/definition.py +++ b/app/modules/messaging/definition.py @@ -3,7 +3,7 @@ Messaging module definition. Defines the messaging module including its features, menu items, -and route configurations. +route configurations, and self-contained module settings. """ from app.modules.base import ModuleDefinition @@ -17,13 +17,6 @@ def _get_admin_router(): return admin_router -def _get_admin_notifications_router(): - """Lazy import of admin notifications router to avoid circular imports.""" - from app.modules.messaging.routes.admin import admin_notifications_router - - return admin_notifications_router - - def _get_vendor_router(): """Lazy import of vendor router to avoid circular imports.""" from app.modules.messaging.routes.vendor import vendor_router @@ -31,22 +24,18 @@ def _get_vendor_router(): return vendor_router -def _get_vendor_notifications_router(): - """Lazy import of vendor notifications router to avoid circular imports.""" - from app.modules.messaging.routes.vendor import vendor_notifications_router - - return vendor_notifications_router - - # Messaging module definition messaging_module = ModuleDefinition( code="messaging", name="Messaging & Notifications", description="Internal messages, customer communication, and notifications.", + version="1.0.0", features=[ "customer_messaging", # Customer communication "internal_messages", # Internal team messages "notification_center", # Notification management + "message_attachments", # File attachments + "admin_notifications", # System admin notifications ], menu_items={ FrontendType.ADMIN: [ @@ -59,6 +48,14 @@ messaging_module = ModuleDefinition( ], }, is_core=False, + # ========================================================================= + # Self-Contained Module Configuration + # ========================================================================= + is_self_contained=True, + services_path="app.modules.messaging.services", + models_path="app.modules.messaging.models", + schemas_path="app.modules.messaging.schemas", + exceptions_path="app.modules.messaging.exceptions", ) diff --git a/app/modules/messaging/exceptions.py b/app/modules/messaging/exceptions.py new file mode 100644 index 00000000..401e0b26 --- /dev/null +++ b/app/modules/messaging/exceptions.py @@ -0,0 +1,28 @@ +# app/modules/messaging/exceptions.py +""" +Messaging module exceptions. + +Re-exports messaging-related exceptions from their source locations. +""" + +from app.exceptions.message import ( + ConversationNotFoundException, + MessageNotFoundException, + ConversationClosedException, + MessageAttachmentException, + UnauthorizedConversationAccessException, + InvalidConversationTypeException, + InvalidRecipientTypeException, + AttachmentNotFoundException, +) + +__all__ = [ + "ConversationNotFoundException", + "MessageNotFoundException", + "ConversationClosedException", + "MessageAttachmentException", + "UnauthorizedConversationAccessException", + "InvalidConversationTypeException", + "InvalidRecipientTypeException", + "AttachmentNotFoundException", +] diff --git a/app/modules/messaging/models/__init__.py b/app/modules/messaging/models/__init__.py new file mode 100644 index 00000000..93b7a816 --- /dev/null +++ b/app/modules/messaging/models/__init__.py @@ -0,0 +1,26 @@ +# app/modules/messaging/models/__init__.py +""" +Messaging module database models. + +Re-exports messaging-related models from their source locations. +""" + +from models.database.message import ( + Conversation, + ConversationParticipant, + ConversationType, + Message, + MessageAttachment, + ParticipantType, +) +from models.database.admin import AdminNotification + +__all__ = [ + "Conversation", + "ConversationParticipant", + "ConversationType", + "Message", + "MessageAttachment", + "ParticipantType", + "AdminNotification", +] diff --git a/app/modules/messaging/schemas/__init__.py b/app/modules/messaging/schemas/__init__.py new file mode 100644 index 00000000..05217d2f --- /dev/null +++ b/app/modules/messaging/schemas/__init__.py @@ -0,0 +1,28 @@ +# app/modules/messaging/schemas/__init__.py +""" +Messaging module Pydantic schemas. + +Re-exports messaging-related schemas from their source locations. +""" + +from models.schema.message import ( + ConversationResponse, + ConversationListResponse, + MessageResponse, + MessageCreate, + AttachmentResponse, +) +from models.schema.notification import ( + NotificationResponse, + NotificationListResponse, +) + +__all__ = [ + "ConversationResponse", + "ConversationListResponse", + "MessageResponse", + "MessageCreate", + "AttachmentResponse", + "NotificationResponse", + "NotificationListResponse", +] diff --git a/app/modules/messaging/services/__init__.py b/app/modules/messaging/services/__init__.py new file mode 100644 index 00000000..10869b53 --- /dev/null +++ b/app/modules/messaging/services/__init__.py @@ -0,0 +1,30 @@ +# app/modules/messaging/services/__init__.py +""" +Messaging module services. + +Re-exports messaging-related services from their source locations. +""" + +from app.services.messaging_service import ( + messaging_service, + MessagingService, +) +from app.services.message_attachment_service import ( + message_attachment_service, + MessageAttachmentService, +) +from app.services.admin_notification_service import ( + admin_notification_service, + AdminNotificationService, +) + +# Note: notification_service is a placeholder - not yet implemented + +__all__ = [ + "messaging_service", + "MessagingService", + "message_attachment_service", + "MessageAttachmentService", + "admin_notification_service", + "AdminNotificationService", +] diff --git a/app/modules/monitoring/__init__.py b/app/modules/monitoring/__init__.py index 8fef73bd..41a32efe 100644 --- a/app/modules/monitoring/__init__.py +++ b/app/modules/monitoring/__init__.py @@ -1,25 +1,36 @@ # app/modules/monitoring/__init__.py """ -Monitoring Module - Platform monitoring and system health. +Monitoring Module - Platform monitoring and observability. -This module provides: -- Application logs -- Background tasks monitoring +This is a self-contained internal module providing: +- Background task monitoring - Import job tracking -- Platform health metrics -- Testing hub -- Code quality tools +- System capacity monitoring +- Application logs viewing +- Platform health checks -Routes: -- Admin: /api/v1/admin/logs/*, /api/v1/admin/background-tasks/*, - /api/v1/admin/tests/*, /api/v1/admin/code-quality/* -- Vendor: None - -Menu Items: -- Admin: imports, background-tasks, logs, platform-health, testing, code-quality -- Vendor: None +Module Structure: +- models/ - Database models (CapacitySnapshot, AdminNotification, etc.) +- services/ - Business logic (BackgroundTasksService) +- schemas/ - Pydantic DTOs +- routes/ - API and page routes +- exceptions.py - Module-specific exceptions """ -from app.modules.monitoring.definition import monitoring_module +# Use lazy imports to avoid circular import issues -__all__ = ["monitoring_module"] + +def __getattr__(name: str): + """Lazy import module components to avoid circular imports.""" + if name == "monitoring_module": + from app.modules.monitoring.definition import monitoring_module + + return monitoring_module + elif name == "get_monitoring_module_with_routers": + from app.modules.monitoring.definition import get_monitoring_module_with_routers + + return get_monitoring_module_with_routers + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +__all__ = ["monitoring_module", "get_monitoring_module_with_routers"] diff --git a/app/modules/monitoring/definition.py b/app/modules/monitoring/definition.py index eb3de961..db51b3a4 100644 --- a/app/modules/monitoring/definition.py +++ b/app/modules/monitoring/definition.py @@ -3,7 +3,7 @@ Monitoring module definition. Defines the monitoring module including its features, menu items, -and route configurations. +route configurations, and self-contained module settings. """ from app.modules.base import ModuleDefinition @@ -46,6 +46,14 @@ monitoring_module = ModuleDefinition( }, is_core=False, is_internal=True, # Internal module - admin-only, not customer-facing + # ========================================================================= + # Self-Contained Module Configuration + # ========================================================================= + is_self_contained=True, + services_path="app.modules.monitoring.services", + models_path="app.modules.monitoring.models", + schemas_path="app.modules.monitoring.schemas", + exceptions_path="app.modules.monitoring.exceptions", ) diff --git a/app/modules/monitoring/exceptions.py b/app/modules/monitoring/exceptions.py new file mode 100644 index 00000000..d9c4d10e --- /dev/null +++ b/app/modules/monitoring/exceptions.py @@ -0,0 +1,50 @@ +# app/modules/monitoring/exceptions.py +""" +Monitoring module exceptions. + +Module-specific exceptions for monitoring functionality. +""" + +from app.exceptions.base import ( + BusinessLogicException, + ResourceNotFoundException, +) + + +class TaskNotFoundException(ResourceNotFoundException): + """Raised when a background task is not found.""" + + def __init__(self, task_id: str): + super().__init__( + resource_type="BackgroundTask", + identifier=task_id, + error_code="TASK_NOT_FOUND", + ) + + +class CapacitySnapshotNotFoundException(ResourceNotFoundException): + """Raised when a capacity snapshot is not found.""" + + def __init__(self, snapshot_id: int): + super().__init__( + resource_type="CapacitySnapshot", + identifier=str(snapshot_id), + error_code="CAPACITY_SNAPSHOT_NOT_FOUND", + ) + + +class MonitoringServiceException(BusinessLogicException): + """Raised when a monitoring operation fails.""" + + def __init__(self, operation: str, reason: str): + super().__init__( + message=f"Monitoring operation '{operation}' failed: {reason}", + error_code="MONITORING_OPERATION_FAILED", + ) + + +__all__ = [ + "TaskNotFoundException", + "CapacitySnapshotNotFoundException", + "MonitoringServiceException", +] diff --git a/app/modules/monitoring/models/__init__.py b/app/modules/monitoring/models/__init__.py new file mode 100644 index 00000000..3f0b5682 --- /dev/null +++ b/app/modules/monitoring/models/__init__.py @@ -0,0 +1,21 @@ +# app/modules/monitoring/models/__init__.py +""" +Monitoring module database models. + +Re-exports monitoring-related models from their source locations. +""" + +# CapacitySnapshot is in billing module (tracks system capacity over time) +from app.modules.billing.models import CapacitySnapshot + +# Admin notification and logging models +from models.database.admin import ( + AdminNotification, + PlatformAlert, +) + +__all__ = [ + "CapacitySnapshot", + "AdminNotification", + "PlatformAlert", +] diff --git a/app/modules/monitoring/schemas/__init__.py b/app/modules/monitoring/schemas/__init__.py new file mode 100644 index 00000000..da3463ad --- /dev/null +++ b/app/modules/monitoring/schemas/__init__.py @@ -0,0 +1,11 @@ +# app/modules/monitoring/schemas/__init__.py +""" +Monitoring module Pydantic schemas. + +Schemas for monitoring API request/response serialization. +""" + +# Monitoring schemas are defined inline in routes or in models/schema/ +# Add re-exports here as needed + +__all__ = [] diff --git a/app/modules/monitoring/services/__init__.py b/app/modules/monitoring/services/__init__.py new file mode 100644 index 00000000..8cd42179 --- /dev/null +++ b/app/modules/monitoring/services/__init__.py @@ -0,0 +1,16 @@ +# app/modules/monitoring/services/__init__.py +""" +Monitoring module services. + +Re-exports monitoring-related services from their source locations. +""" + +from app.services.background_tasks_service import ( + background_tasks_service, + BackgroundTasksService, +) + +__all__ = [ + "background_tasks_service", + "BackgroundTasksService", +] diff --git a/app/modules/orders/__init__.py b/app/modules/orders/__init__.py index 2e1b20ab..3411787d 100644 --- a/app/modules/orders/__init__.py +++ b/app/modules/orders/__init__.py @@ -2,22 +2,35 @@ """ Orders Module - Order processing and fulfillment. -This module provides: +This is a self-contained module providing: - Order management and tracking - Order fulfillment workflow - Order item exceptions handling -- Bulk order operations -- Order export and reporting +- Invoice generation +- Customer checkout -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 +Module Structure: +- models/ - Database models (Order, OrderItem, Invoice, etc.) +- services/ - Business logic (OrderService, InvoiceService) +- schemas/ - Pydantic DTOs +- routes/ - API routes +- exceptions.py - Module-specific exceptions """ -from app.modules.orders.definition import orders_module +# Use lazy imports to avoid circular import issues -__all__ = ["orders_module"] + +def __getattr__(name: str): + """Lazy import module components to avoid circular imports.""" + if name == "orders_module": + from app.modules.orders.definition import orders_module + + return orders_module + elif name == "get_orders_module_with_routers": + from app.modules.orders.definition import get_orders_module_with_routers + + return get_orders_module_with_routers + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +__all__ = ["orders_module", "get_orders_module_with_routers"] diff --git a/app/modules/orders/definition.py b/app/modules/orders/definition.py index fb36954d..c6e02271 100644 --- a/app/modules/orders/definition.py +++ b/app/modules/orders/definition.py @@ -3,7 +3,7 @@ Orders module definition. Defines the orders module including its features, menu items, -and route configurations. +route configurations, and self-contained module settings. """ from app.modules.base import ModuleDefinition @@ -30,7 +30,7 @@ orders_module = ModuleDefinition( name="Order Management", description=( "Order processing, fulfillment tracking, customer checkout, " - "and bulk order operations. Uses the payments module for checkout." + "invoicing, and bulk order operations. Uses the payments module for checkout." ), version="1.0.0", requires=["payments"], # Depends on payments module for checkout @@ -43,6 +43,8 @@ orders_module = ModuleDefinition( "shipping_management", # Carrier integration "order_exceptions", # Order item exception handling "customer_checkout", # Customer checkout flow + "invoice_generation", # Invoice creation + "invoice_pdf", # PDF invoice generation ], menu_items={ FrontendType.ADMIN: [ @@ -53,6 +55,14 @@ orders_module = ModuleDefinition( ], }, is_core=False, + # ========================================================================= + # Self-Contained Module Configuration + # ========================================================================= + is_self_contained=True, + services_path="app.modules.orders.services", + models_path="app.modules.orders.models", + schemas_path="app.modules.orders.schemas", + exceptions_path="app.modules.orders.exceptions", ) diff --git a/app/modules/orders/exceptions.py b/app/modules/orders/exceptions.py new file mode 100644 index 00000000..2fc69f8a --- /dev/null +++ b/app/modules/orders/exceptions.py @@ -0,0 +1,53 @@ +# app/modules/orders/exceptions.py +""" +Orders module exceptions. + +Re-exports order-related exceptions from their source locations. +""" + +from app.exceptions.order import ( + OrderNotFoundException, + OrderAlreadyExistsException, + OrderValidationException, + InvalidOrderStatusException, + OrderCannotBeCancelledException, +) + +from app.exceptions.order_item_exception import ( + OrderItemExceptionNotFoundException, + OrderHasUnresolvedExceptionsException, + ExceptionAlreadyResolvedException, + InvalidProductForExceptionException, +) + +from app.exceptions.invoice import ( + InvoiceNotFoundException, + InvoiceSettingsNotFoundException, + InvoiceSettingsAlreadyExistException, + InvoiceValidationException, + InvoicePDFGenerationException, + InvoicePDFNotFoundException, + InvalidInvoiceStatusTransitionException, +) + +__all__ = [ + # Order exceptions + "OrderNotFoundException", + "OrderAlreadyExistsException", + "OrderValidationException", + "InvalidOrderStatusException", + "OrderCannotBeCancelledException", + # Order item exception exceptions + "OrderItemExceptionNotFoundException", + "OrderHasUnresolvedExceptionsException", + "ExceptionAlreadyResolvedException", + "InvalidProductForExceptionException", + # Invoice exceptions + "InvoiceNotFoundException", + "InvoiceSettingsNotFoundException", + "InvoiceSettingsAlreadyExistException", + "InvoiceValidationException", + "InvoicePDFGenerationException", + "InvoicePDFNotFoundException", + "InvalidInvoiceStatusTransitionException", +] diff --git a/app/modules/orders/models/__init__.py b/app/modules/orders/models/__init__.py new file mode 100644 index 00000000..d57f3e28 --- /dev/null +++ b/app/modules/orders/models/__init__.py @@ -0,0 +1,28 @@ +# app/modules/orders/models/__init__.py +""" +Orders module database models. + +Re-exports order-related models from their source locations. +""" + +from models.database.order import ( + Order, + OrderItem, +) +from models.database.order_item_exception import OrderItemException +from models.database.invoice import ( + Invoice, + InvoiceStatus, + VATRegime, + VendorInvoiceSettings, +) + +__all__ = [ + "Order", + "OrderItem", + "OrderItemException", + "Invoice", + "InvoiceStatus", + "VATRegime", + "VendorInvoiceSettings", +] diff --git a/app/modules/orders/schemas/__init__.py b/app/modules/orders/schemas/__init__.py new file mode 100644 index 00000000..9f9c1749 --- /dev/null +++ b/app/modules/orders/schemas/__init__.py @@ -0,0 +1,36 @@ +# app/modules/orders/schemas/__init__.py +""" +Orders module Pydantic schemas. + +Re-exports order-related schemas from their source locations. +""" + +from models.schema.order import ( + OrderCreate, + OrderItemCreate, + OrderResponse, + OrderItemResponse, + OrderListResponse, + AddressSnapshot, + CustomerSnapshot, +) +from models.schema.invoice import ( + InvoiceResponse, + InvoiceSettingsCreate, + InvoiceSettingsUpdate, + InvoiceSettingsResponse, +) + +__all__ = [ + "OrderCreate", + "OrderItemCreate", + "OrderResponse", + "OrderItemResponse", + "OrderListResponse", + "AddressSnapshot", + "CustomerSnapshot", + "InvoiceResponse", + "InvoiceSettingsCreate", + "InvoiceSettingsUpdate", + "InvoiceSettingsResponse", +] diff --git a/app/modules/orders/services/__init__.py b/app/modules/orders/services/__init__.py new file mode 100644 index 00000000..9cfbb55a --- /dev/null +++ b/app/modules/orders/services/__init__.py @@ -0,0 +1,40 @@ +# app/modules/orders/services/__init__.py +""" +Orders module services. + +Re-exports order-related services from their source locations. +""" + +from app.services.order_service import ( + order_service, + OrderService, +) +from app.services.order_inventory_service import ( + order_inventory_service, + OrderInventoryService, +) +from app.services.order_item_exception_service import ( + order_item_exception_service, + OrderItemExceptionService, +) +from app.services.invoice_service import ( + invoice_service, + InvoiceService, +) +from app.services.invoice_pdf_service import ( + invoice_pdf_service, + InvoicePDFService, +) + +__all__ = [ + "order_service", + "OrderService", + "order_inventory_service", + "OrderInventoryService", + "order_item_exception_service", + "OrderItemExceptionService", + "invoice_service", + "InvoiceService", + "invoice_pdf_service", + "InvoicePDFService", +] diff --git a/app/modules/payments/__init__.py b/app/modules/payments/__init__.py index a5d2fc7a..6d39c318 100644 --- a/app/modules/payments/__init__.py +++ b/app/modules/payments/__init__.py @@ -21,12 +21,20 @@ Menu Items: - Vendor: payment-methods (stored payment methods) """ -from app.modules.payments.definition import payments_module +# Lazy imports to avoid circular dependencies + +__all__ = ["payments_module", "get_payments_module"] def get_payments_module(): """Lazy getter to avoid circular imports.""" + from app.modules.payments.definition import payments_module return payments_module -__all__ = ["payments_module", "get_payments_module"] +def __getattr__(name: str): + """Lazy import to avoid circular dependencies.""" + if name == "payments_module": + from app.modules.payments.definition import payments_module + return payments_module + raise AttributeError(f"module {__name__!r} has no attribute {name!r}")