refactor(arch): eliminate all cross-module model imports in service layer
Some checks failed
Some checks failed
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:
@@ -53,17 +53,16 @@ class SubscriptionService:
|
||||
Raises:
|
||||
ResourceNotFoundException: If store not found or has no platform
|
||||
"""
|
||||
from app.modules.tenancy.models import Store, StorePlatform
|
||||
from app.modules.tenancy.services.platform_service import platform_service
|
||||
from app.modules.tenancy.services.store_service import store_service
|
||||
|
||||
store = db.query(Store).filter(Store.id == store_id).first()
|
||||
store = store_service.get_store_by_id_optional(db, store_id)
|
||||
if not store or not store.merchant_id:
|
||||
raise ResourceNotFoundException("Store", str(store_id))
|
||||
sp = db.query(StorePlatform.platform_id).filter(
|
||||
StorePlatform.store_id == store_id
|
||||
).first()
|
||||
if not sp:
|
||||
platform_id = platform_service.get_primary_platform_id_for_store(db, store_id)
|
||||
if not platform_id:
|
||||
raise ResourceNotFoundException("StorePlatform", f"store_id={store_id}")
|
||||
return store.merchant_id, sp[0]
|
||||
return store.merchant_id, platform_id
|
||||
|
||||
def get_store_code(self, db: Session, store_id: int) -> str:
|
||||
"""Get the store_code for a given store_id.
|
||||
@@ -71,9 +70,9 @@ class SubscriptionService:
|
||||
Raises:
|
||||
ResourceNotFoundException: If store not found
|
||||
"""
|
||||
from app.modules.tenancy.models import Store
|
||||
from app.modules.tenancy.services.store_service import store_service
|
||||
|
||||
store = db.query(Store).filter(Store.id == store_id).first()
|
||||
store = store_service.get_store_by_id_optional(db, store_id)
|
||||
if not store:
|
||||
raise ResourceNotFoundException("Store", str(store_id))
|
||||
return store.store_code
|
||||
@@ -175,9 +174,10 @@ class SubscriptionService:
|
||||
The merchant subscription, or None if the store, merchant,
|
||||
or platform cannot be resolved.
|
||||
"""
|
||||
from app.modules.tenancy.models import Store
|
||||
from app.modules.tenancy.services.platform_service import platform_service
|
||||
from app.modules.tenancy.services.store_service import store_service
|
||||
|
||||
store = db.query(Store).filter(Store.id == store_id).first()
|
||||
store = store_service.get_store_by_id_optional(db, store_id)
|
||||
if not store:
|
||||
return None
|
||||
|
||||
@@ -185,17 +185,7 @@ class SubscriptionService:
|
||||
if merchant_id is None:
|
||||
return None
|
||||
|
||||
# Get platform_id from store
|
||||
platform_id = getattr(store, "platform_id", None)
|
||||
if platform_id is None:
|
||||
from app.modules.tenancy.models import StorePlatform
|
||||
sp = (
|
||||
db.query(StorePlatform.platform_id)
|
||||
.filter(StorePlatform.store_id == store_id)
|
||||
.first()
|
||||
)
|
||||
platform_id = sp[0] if sp else None
|
||||
|
||||
platform_id = platform_service.get_primary_platform_id_for_store(db, store_id)
|
||||
if platform_id is None:
|
||||
return None
|
||||
|
||||
@@ -394,5 +384,60 @@ class SubscriptionService:
|
||||
return subscription
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# Cross-module public API methods
|
||||
# =========================================================================
|
||||
|
||||
def get_active_subscription_platform_ids(
|
||||
self, db: Session, merchant_id: int
|
||||
) -> list[int]:
|
||||
"""
|
||||
Get platform IDs where merchant has active subscriptions.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
merchant_id: Merchant ID
|
||||
|
||||
Returns:
|
||||
List of platform IDs with active subscriptions
|
||||
"""
|
||||
active_statuses = [
|
||||
SubscriptionStatus.ACTIVE,
|
||||
SubscriptionStatus.TRIAL,
|
||||
]
|
||||
results = (
|
||||
db.query(MerchantSubscription.platform_id)
|
||||
.filter(
|
||||
MerchantSubscription.merchant_id == merchant_id,
|
||||
MerchantSubscription.status.in_(active_statuses),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return [r[0] for r in results]
|
||||
|
||||
def get_all_active_subscriptions(
|
||||
self, db: Session
|
||||
) -> list[MerchantSubscription]:
|
||||
"""
|
||||
Get all active/trial subscriptions with tier and feature limits.
|
||||
|
||||
Returns:
|
||||
List of MerchantSubscription objects with eager-loaded tier data
|
||||
"""
|
||||
active_statuses = [
|
||||
SubscriptionStatus.ACTIVE,
|
||||
SubscriptionStatus.TRIAL,
|
||||
]
|
||||
return (
|
||||
db.query(MerchantSubscription)
|
||||
.options(
|
||||
joinedload(MerchantSubscription.tier)
|
||||
.joinedload(SubscriptionTier.feature_limits),
|
||||
)
|
||||
.filter(MerchantSubscription.status.in_(active_statuses))
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance
|
||||
subscription_service = SubscriptionService()
|
||||
|
||||
Reference in New Issue
Block a user