refactor: move letzshop endpoints to marketplace module and add vendor service tests

Move letzshop-related functionality from tenancy to marketplace module:
- Move admin letzshop routes to marketplace/routes/api/admin_letzshop.py
- Move letzshop schemas to marketplace/schemas/letzshop.py
- Remove letzshop code from tenancy module (admin_vendors, vendor_service)
- Update model exports and imports

Add comprehensive unit tests for vendor services:
- test_company_service.py: Company management operations
- test_platform_service.py: Platform management operations
- test_vendor_domain_service.py: Vendor domain operations
- test_vendor_team_service.py: Vendor team management

Update module definitions:
- billing, messaging, payments: Minor definition updates

Add architecture proposals documentation:
- Module dependency redesign session notes
- Decouple modules implementation plan
- Module decoupling proposal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 19:25:00 +01:00
parent 37942ae02b
commit 0583dd2cc4
29 changed files with 3643 additions and 650 deletions

View File

@@ -1,13 +1,14 @@
# app/modules/tenancy/services/admin_service.py
"""
Admin service for managing users, vendors, and import jobs.
Admin service for managing users and vendors.
This module provides classes and functions for:
- User management and status control
- Vendor creation with owner user generation
- Vendor verification and activation
- Marketplace import job monitoring
- Platform statistics
Note: Marketplace import job monitoring has been moved to the marketplace module.
"""
import logging
@@ -33,11 +34,9 @@ from app.modules.tenancy.exceptions import (
)
from middleware.auth import AuthManager
from app.modules.tenancy.models import Company
from app.modules.marketplace.models import MarketplaceImportJob
from app.modules.tenancy.models import Platform
from app.modules.tenancy.models import User
from app.modules.tenancy.models import Role, Vendor
from app.modules.marketplace.schemas import MarketplaceImportJobResponse
from app.modules.tenancy.schemas.vendor import VendorCreate
logger = logging.getLogger(__name__)
@@ -703,48 +702,8 @@ class AdminService:
# NOTE: Vendor ownership transfer is now handled at the Company level.
# Use company_service.transfer_ownership() instead.
# ============================================================================
# MARKETPLACE IMPORT JOBS
# ============================================================================
def get_marketplace_import_jobs(
self,
db: Session,
marketplace: str | None = None,
vendor_name: str | None = None,
status: str | None = None,
skip: int = 0,
limit: int = 100,
) -> list[MarketplaceImportJobResponse]:
"""Get filtered and paginated marketplace import jobs."""
try:
query = db.query(MarketplaceImportJob)
if marketplace:
query = query.filter(
MarketplaceImportJob.marketplace.ilike(f"%{marketplace}%")
)
if vendor_name:
query = query.filter(
MarketplaceImportJob.vendor_name.ilike(f"%{vendor_name}%")
)
if status:
query = query.filter(MarketplaceImportJob.status == status)
jobs = (
query.order_by(MarketplaceImportJob.created_at.desc())
.offset(skip)
.limit(limit)
.all()
)
return [self._convert_job_to_response(job) for job in jobs]
except Exception as e:
logger.error(f"Failed to retrieve marketplace import jobs: {str(e)}")
raise AdminOperationException(
operation="get_marketplace_import_jobs", reason="Database query failed"
)
# NOTE: Marketplace import job operations have been moved to the marketplace module.
# Use app.modules.marketplace routes for import job management.
# ============================================================================
# STATISTICS
@@ -773,30 +732,7 @@ class AdminService:
logger.error(f"Failed to get recent vendors: {str(e)}")
return []
def get_recent_import_jobs(self, db: Session, limit: int = 10) -> list[dict]:
"""Get recent marketplace import jobs."""
try:
jobs = (
db.query(MarketplaceImportJob)
.order_by(MarketplaceImportJob.created_at.desc())
.limit(limit)
.all()
)
return [
{
"id": j.id,
"marketplace": j.marketplace,
"vendor_name": j.vendor_name,
"status": j.status,
"total_processed": j.total_processed or 0,
"created_at": j.created_at,
}
for j in jobs
]
except Exception as e:
logger.error(f"Failed to get recent import jobs: {str(e)}")
return []
# NOTE: get_recent_import_jobs has been moved to the marketplace module
# ============================================================================
# PRIVATE HELPER METHODS
@@ -868,28 +804,6 @@ class AdminService:
)
db.add(role)
def _convert_job_to_response(
self, job: MarketplaceImportJob
) -> MarketplaceImportJobResponse:
"""Convert database model to response schema."""
return MarketplaceImportJobResponse(
job_id=job.id,
status=job.status,
marketplace=job.marketplace,
source_url=job.source_url,
vendor_id=job.vendor.id if job.vendor else None,
vendor_code=job.vendor.vendor_code if job.vendor else None,
vendor_name=job.vendor.name if job.vendor else None,
imported=job.imported_count or 0,
updated=job.updated_count or 0,
total_processed=job.total_processed or 0,
error_count=job.error_count or 0,
error_message=job.error_message,
created_at=job.created_at,
started_at=job.started_at,
completed_at=job.completed_at,
)
# Create service instance
admin_service = AdminService()