refactor(arch): eliminate all cross-module model imports in service layer
Some checks failed
CI / ruff (push) Successful in 9s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / pytest (push) Has been cancelled

Enforce MOD-025/MOD-026 rules: zero top-level cross-module model imports
remain in any service file. All 66 files migrated using deferred import
patterns (method-body, _get_model() helpers, instance-cached self._Model)
and new cross-module service methods in tenancy. Documentation updated
with Pattern 6 (deferred imports), migration plan marked complete, and
violations status reflects 84→0 service-layer violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 06:13:15 +01:00
parent e3a52f6536
commit 86e85a98b8
66 changed files with 2242 additions and 1295 deletions

View File

@@ -439,10 +439,129 @@ class StoreService:
logger.info(f"Store {store.store_code} set to {status}")
return store, f"Store {store.store_code} is now {status}"
# NOTE: Product catalog operations have been moved to catalog module.
# Use app.modules.catalog.services.product_service instead.
# - add_product_to_catalog -> product_service.create_product
# - get_products -> product_service.get_store_products
# ========================================================================
# Cross-module public API methods
# ========================================================================
def get_stores_by_merchant_id(
self, db: Session, merchant_id: int, active_only: bool = False
) -> list[Store]:
"""
Get all stores for a merchant.
Args:
db: Database session
merchant_id: Merchant ID
active_only: Only return active stores
Returns:
List of Store objects
"""
query = db.query(Store).filter(Store.merchant_id == merchant_id)
if active_only:
query = query.filter(Store.is_active == True) # noqa: E712
return query.order_by(Store.id).all()
def get_store_by_code_or_subdomain(
self, db: Session, code: str
) -> Store | None:
"""
Get store by store_code or subdomain.
Args:
db: Database session
code: Store code or subdomain
Returns:
Store object or None
"""
return (
db.query(Store)
.filter(
(func.upper(Store.store_code) == code.upper())
| (func.lower(Store.subdomain) == code.lower())
)
.first()
)
def get_total_store_count(
self, db: Session, active_only: bool = False
) -> int:
"""
Get total count of stores.
Args:
db: Database session
active_only: Only count active stores
Returns:
Store count
"""
query = db.query(func.count(Store.id))
if active_only:
query = query.filter(Store.is_active == True) # noqa: E712
return query.scalar() or 0
def get_store_count_by_status(
self,
db: Session,
active: bool | None = None,
verified: bool | None = None,
) -> int:
"""
Count stores filtered by active/verified status.
Args:
db: Database session
active: Filter by active status
verified: Filter by verified status
Returns:
Store count matching filters
"""
query = db.query(func.count(Store.id))
if active is not None:
query = query.filter(Store.is_active == active)
if verified is not None:
query = query.filter(Store.is_verified == verified)
return query.scalar() or 0
def list_all_stores(self, db: Session, active_only: bool = False) -> list[Store]:
"""Get all stores, optionally filtering by active status."""
query = db.query(Store)
if active_only:
query = query.filter(Store.is_active == True) # noqa: E712
return query.order_by(Store.id).all()
def is_letzshop_slug_claimed(self, db: Session, letzshop_slug: str) -> bool:
"""Check if a Letzshop store slug is already claimed."""
return (
db.query(Store)
.filter(
Store.letzshop_store_slug == letzshop_slug,
Store.is_active == True, # noqa: E712
)
.first()
is not None
)
def is_store_code_taken(self, db: Session, store_code: str) -> bool:
"""Check if a store code already exists."""
return (
db.query(Store)
.filter(Store.store_code == store_code)
.first()
is not None
)
def is_subdomain_taken(self, db: Session, subdomain: str) -> bool:
"""Check if a subdomain already exists."""
return (
db.query(Store)
.filter(Store.subdomain == subdomain)
.first()
is not None
)
# Private helper methods
def _store_code_exists(self, db: Session, store_code: str) -> bool: