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

@@ -13,7 +13,6 @@ from sqlalchemy.orm import Session
from app.modules.customers.exceptions import CustomerNotFoundException
from app.modules.customers.models import Customer
from app.modules.tenancy.models import Store
logger = logging.getLogger(__name__)
@@ -44,8 +43,10 @@ class AdminCustomerService:
Returns:
Tuple of (customers list, total count)
"""
from app.modules.tenancy.services.store_service import store_service
# Build query
query = db.query(Customer).join(Store, Customer.store_id == Store.id)
query = db.query(Customer)
# Apply filters
if store_id:
@@ -66,21 +67,26 @@ class AdminCustomerService:
# Get total count
total = query.count()
# Get paginated results with store info
# Get paginated results
customers = (
query.add_columns(Store.name.label("store_name"), Store.store_code)
.order_by(Customer.created_at.desc())
query.order_by(Customer.created_at.desc())
.offset(skip)
.limit(limit)
.all()
)
# Batch-resolve store names
store_ids = {c.store_id for c in customers}
store_map = {}
for sid in store_ids:
store = store_service.get_store_by_id_optional(db, sid)
if store:
store_map[sid] = (store.name, store.store_code)
# Format response
result = []
for row in customers:
customer = row[0]
store_name = row[1]
store_code = row[2]
for customer in customers:
store_name, store_code = store_map.get(customer.store_id, (None, None))
customer_dict = {
"id": customer.id,
@@ -167,18 +173,18 @@ class AdminCustomerService:
Raises:
CustomerNotFoundException: If customer not found
"""
result = (
from app.modules.tenancy.services.store_service import store_service
customer = (
db.query(Customer)
.join(Store, Customer.store_id == Store.id)
.add_columns(Store.name.label("store_name"), Store.store_code)
.filter(Customer.id == customer_id)
.first()
)
if not result:
if not customer:
raise CustomerNotFoundException(str(customer_id))
customer = result[0]
store = store_service.get_store_by_id_optional(db, customer.store_id)
return {
"id": customer.id,
"store_id": customer.store_id,
@@ -195,8 +201,8 @@ class AdminCustomerService:
"is_active": customer.is_active,
"created_at": customer.created_at,
"updated_at": customer.updated_at,
"store_name": result[1],
"store_code": result[2],
"store_name": store.name if store else None,
"store_code": store.store_code if store else None,
}
def toggle_customer_status(