fix: move database queries from API to service layer
Move direct database queries in subscriptions.py to admin_subscription_service: - Add get_vendor() method to verify vendor exists - Add get_vendor_usage_counts() method for products/team counts - Update API endpoints to use service methods - Remove unused imports (func, Product, VendorUser) Fixes architecture validation errors [API-002] 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,16 +12,13 @@ Provides endpoints for platform administrators to manage:
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Path, Query
|
from fastapi import APIRouter, Depends, Path, Query
|
||||||
from sqlalchemy import func
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.api.deps import get_current_admin_api
|
from app.api.deps import get_current_admin_api
|
||||||
from app.core.database import get_db
|
from app.core.database import get_db
|
||||||
from app.services.admin_subscription_service import admin_subscription_service
|
from app.services.admin_subscription_service import admin_subscription_service
|
||||||
from models.database.product import Product
|
|
||||||
from models.database.user import User
|
|
||||||
from models.database.vendor import VendorUser
|
|
||||||
from app.services.subscription_service import subscription_service
|
from app.services.subscription_service import subscription_service
|
||||||
|
from models.database.user import User
|
||||||
from models.schema.billing import (
|
from models.schema.billing import (
|
||||||
BillingHistoryListResponse,
|
BillingHistoryListResponse,
|
||||||
BillingHistoryWithVendor,
|
BillingHistoryWithVendor,
|
||||||
@@ -246,13 +243,8 @@ def create_vendor_subscription(
|
|||||||
Creates a new subscription with the specified tier and status.
|
Creates a new subscription with the specified tier and status.
|
||||||
Defaults to Essential tier with trial status.
|
Defaults to Essential tier with trial status.
|
||||||
"""
|
"""
|
||||||
from models.database.vendor import Vendor
|
|
||||||
|
|
||||||
# Verify vendor exists
|
# Verify vendor exists
|
||||||
vendor = db.query(Vendor).filter(Vendor.id == vendor_id).first()
|
vendor = admin_subscription_service.get_vendor(db, vendor_id)
|
||||||
if not vendor:
|
|
||||||
from app.exceptions import ResourceNotFoundException
|
|
||||||
raise ResourceNotFoundException("Vendor", str(vendor_id))
|
|
||||||
|
|
||||||
# Create subscription using the subscription service
|
# Create subscription using the subscription service
|
||||||
sub = subscription_service.get_or_create_subscription(
|
sub = subscription_service.get_or_create_subscription(
|
||||||
@@ -272,22 +264,7 @@ def create_vendor_subscription(
|
|||||||
db.refresh(sub)
|
db.refresh(sub)
|
||||||
|
|
||||||
# Get usage counts
|
# Get usage counts
|
||||||
products_count = (
|
usage = admin_subscription_service.get_vendor_usage_counts(db, vendor_id)
|
||||||
db.query(func.count(Product.id))
|
|
||||||
.filter(Product.vendor_id == vendor_id)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
team_count = (
|
|
||||||
db.query(func.count(VendorUser.id))
|
|
||||||
.filter(
|
|
||||||
VendorUser.vendor_id == vendor_id,
|
|
||||||
VendorUser.is_active == True, # noqa: E712
|
|
||||||
)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f"Admin created subscription for vendor {vendor_id}: tier={create_data.tier}")
|
logger.info(f"Admin created subscription for vendor {vendor_id}: tier={create_data.tier}")
|
||||||
|
|
||||||
@@ -295,8 +272,8 @@ def create_vendor_subscription(
|
|||||||
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
||||||
vendor_name=vendor.name,
|
vendor_name=vendor.name,
|
||||||
vendor_code=vendor.subdomain,
|
vendor_code=vendor.subdomain,
|
||||||
products_count=products_count,
|
products_count=usage["products_count"],
|
||||||
team_count=team_count,
|
team_count=usage["team_count"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -310,29 +287,14 @@ def get_vendor_subscription(
|
|||||||
sub, vendor = admin_subscription_service.get_subscription(db, vendor_id)
|
sub, vendor = admin_subscription_service.get_subscription(db, vendor_id)
|
||||||
|
|
||||||
# Get usage counts
|
# Get usage counts
|
||||||
products_count = (
|
usage = admin_subscription_service.get_vendor_usage_counts(db, vendor_id)
|
||||||
db.query(func.count(Product.id))
|
|
||||||
.filter(Product.vendor_id == vendor_id)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
team_count = (
|
|
||||||
db.query(func.count(VendorUser.id))
|
|
||||||
.filter(
|
|
||||||
VendorUser.vendor_id == vendor_id,
|
|
||||||
VendorUser.is_active == True, # noqa: E712
|
|
||||||
)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
return VendorSubscriptionWithVendor(
|
return VendorSubscriptionWithVendor(
|
||||||
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
||||||
vendor_name=vendor.name,
|
vendor_name=vendor.name,
|
||||||
vendor_code=vendor.subdomain,
|
vendor_code=vendor.subdomain,
|
||||||
products_count=products_count,
|
products_count=usage["products_count"],
|
||||||
team_count=team_count,
|
team_count=usage["team_count"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -358,27 +320,12 @@ def update_vendor_subscription(
|
|||||||
db.refresh(sub)
|
db.refresh(sub)
|
||||||
|
|
||||||
# Get usage counts
|
# Get usage counts
|
||||||
products_count = (
|
usage = admin_subscription_service.get_vendor_usage_counts(db, vendor_id)
|
||||||
db.query(func.count(Product.id))
|
|
||||||
.filter(Product.vendor_id == vendor_id)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
team_count = (
|
|
||||||
db.query(func.count(VendorUser.id))
|
|
||||||
.filter(
|
|
||||||
VendorUser.vendor_id == vendor_id,
|
|
||||||
VendorUser.is_active == True, # noqa: E712
|
|
||||||
)
|
|
||||||
.scalar()
|
|
||||||
or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
return VendorSubscriptionWithVendor(
|
return VendorSubscriptionWithVendor(
|
||||||
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
**VendorSubscriptionResponse.model_validate(sub).model_dump(),
|
||||||
vendor_name=vendor.name,
|
vendor_name=vendor.name,
|
||||||
vendor_code=vendor.subdomain,
|
vendor_code=vendor.subdomain,
|
||||||
products_count=products_count,
|
products_count=usage["products_count"],
|
||||||
team_count=team_count,
|
team_count=usage["team_count"],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ from app.exceptions import (
|
|||||||
ResourceNotFoundException,
|
ResourceNotFoundException,
|
||||||
TierNotFoundException,
|
TierNotFoundException,
|
||||||
)
|
)
|
||||||
|
from models.database.product import Product
|
||||||
from models.database.subscription import (
|
from models.database.subscription import (
|
||||||
BillingHistory,
|
BillingHistory,
|
||||||
SubscriptionStatus,
|
SubscriptionStatus,
|
||||||
SubscriptionTier,
|
SubscriptionTier,
|
||||||
VendorSubscription,
|
VendorSubscription,
|
||||||
)
|
)
|
||||||
from models.database.vendor import Vendor
|
from models.database.vendor import Vendor, VendorUser
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -197,6 +198,39 @@ class AdminSubscriptionService:
|
|||||||
|
|
||||||
return sub, vendor
|
return sub, vendor
|
||||||
|
|
||||||
|
def get_vendor(self, db: Session, vendor_id: int) -> Vendor:
|
||||||
|
"""Get a vendor by ID."""
|
||||||
|
vendor = db.query(Vendor).filter(Vendor.id == vendor_id).first()
|
||||||
|
|
||||||
|
if not vendor:
|
||||||
|
raise ResourceNotFoundException("Vendor", str(vendor_id))
|
||||||
|
|
||||||
|
return vendor
|
||||||
|
|
||||||
|
def get_vendor_usage_counts(self, db: Session, vendor_id: int) -> dict:
|
||||||
|
"""Get usage counts (products and team members) for a vendor."""
|
||||||
|
products_count = (
|
||||||
|
db.query(func.count(Product.id))
|
||||||
|
.filter(Product.vendor_id == vendor_id)
|
||||||
|
.scalar()
|
||||||
|
or 0
|
||||||
|
)
|
||||||
|
|
||||||
|
team_count = (
|
||||||
|
db.query(func.count(VendorUser.id))
|
||||||
|
.filter(
|
||||||
|
VendorUser.vendor_id == vendor_id,
|
||||||
|
VendorUser.is_active == True, # noqa: E712
|
||||||
|
)
|
||||||
|
.scalar()
|
||||||
|
or 0
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"products_count": products_count,
|
||||||
|
"team_count": team_count,
|
||||||
|
}
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# Billing History
|
# Billing History
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user