feat: add proper Pydantic response_model to all stats endpoints

- Create comprehensive stats schemas in models/schema/stats.py:
  - ImportStatsResponse, UserStatsResponse, ProductStatsResponse
  - PlatformStatsResponse, AdminDashboardResponse
  - VendorDashboardStatsResponse with nested models
  - VendorAnalyticsResponse, CodeQualityDashboardStatsResponse
- Move DashboardStatsResponse from code_quality.py to schema file
- Fix get_vendor_statistics() to return pending_vendors field
- Fix get_vendor_stats() to return flat structure matching schema
- Add response_model to all stats endpoints:
  - GET /admin/dashboard -> AdminDashboardResponse
  - GET /admin/dashboard/stats/platform -> PlatformStatsResponse
  - GET /admin/marketplace-import-jobs/stats -> ImportStatsResponse
  - GET /vendor/dashboard/stats -> VendorDashboardStatsResponse
  - GET /vendor/analytics -> VendorAnalyticsResponse
- Enhance API-001 architecture rule with detailed guidance
- Add SVC-007 rule for service/schema compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-11 17:29:35 +01:00
parent f2af3aae29
commit 22c4937779
8 changed files with 501 additions and 119 deletions

View File

@@ -15,16 +15,32 @@ from app.api.deps import get_current_vendor_api
from app.core.database import get_db
from app.services.stats_service import stats_service
from models.database.user import User
from models.schema.stats import (
VendorAnalyticsCatalog,
VendorAnalyticsImports,
VendorAnalyticsInventory,
VendorAnalyticsResponse,
)
router = APIRouter(prefix="/analytics")
logger = logging.getLogger(__name__)
@router.get("")
@router.get("", response_model=VendorAnalyticsResponse)
def get_vendor_analytics(
period: str = Query("30d", description="Time period: 7d, 30d, 90d, 1y"),
current_user: User = Depends(get_current_vendor_api),
db: Session = Depends(get_db),
):
"""Get vendor analytics data for specified time period."""
return stats_service.get_vendor_analytics(db, current_user.token_vendor_id, period)
data = stats_service.get_vendor_analytics(db, current_user.token_vendor_id, period)
return VendorAnalyticsResponse(
period=data["period"],
start_date=data["start_date"],
imports=VendorAnalyticsImports(count=data["imports"]["count"]),
catalog=VendorAnalyticsCatalog(products_added=data["catalog"]["products_added"]),
inventory=VendorAnalyticsInventory(
total_locations=data["inventory"]["total_locations"]
),
)

View File

@@ -17,12 +17,20 @@ from app.exceptions import VendorNotActiveException
from app.services.stats_service import stats_service
from app.services.vendor_service import vendor_service
from models.database.user import User
from models.schema.stats import (
VendorCustomerStats,
VendorDashboardStatsResponse,
VendorInfo,
VendorOrderStats,
VendorProductStats,
VendorRevenueStats,
)
router = APIRouter(prefix="/dashboard")
logger = logging.getLogger(__name__)
@router.get("/stats")
@router.get("/stats", response_model=VendorDashboardStatsResponse)
def get_vendor_dashboard_stats(
request: Request,
current_user: User = Depends(get_current_vendor_api),
@@ -51,27 +59,27 @@ def get_vendor_dashboard_stats(
# Get vendor-scoped statistics
stats_data = stats_service.get_vendor_stats(db=db, vendor_id=vendor_id)
return {
"vendor": {
"id": vendor.id,
"name": vendor.name,
"vendor_code": vendor.vendor_code,
},
"products": {
"total": stats_data.get("total_products", 0),
"active": stats_data.get("active_products", 0),
},
"orders": {
"total": stats_data.get("total_orders", 0),
"pending": stats_data.get("pending_orders", 0),
"completed": stats_data.get("completed_orders", 0),
},
"customers": {
"total": stats_data.get("total_customers", 0),
"active": stats_data.get("active_customers", 0),
},
"revenue": {
"total": stats_data.get("total_revenue", 0),
"this_month": stats_data.get("revenue_this_month", 0),
},
}
return VendorDashboardStatsResponse(
vendor=VendorInfo(
id=vendor.id,
name=vendor.name,
vendor_code=vendor.vendor_code,
),
products=VendorProductStats(
total=stats_data.get("total_products", 0),
active=stats_data.get("active_products", 0),
),
orders=VendorOrderStats(
total=stats_data.get("total_orders", 0),
pending=stats_data.get("pending_orders", 0),
completed=stats_data.get("completed_orders", 0),
),
customers=VendorCustomerStats(
total=stats_data.get("total_customers", 0),
active=stats_data.get("active_customers", 0),
),
revenue=VendorRevenueStats(
total=stats_data.get("total_revenue", 0),
this_month=stats_data.get("revenue_this_month", 0),
),
)