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:
@@ -1,10 +1,13 @@
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class StatsResponse(BaseModel):
|
||||
"""Comprehensive platform statistics response schema."""
|
||||
|
||||
total_products: int
|
||||
unique_brands: int
|
||||
unique_categories: int
|
||||
@@ -15,6 +18,8 @@ class StatsResponse(BaseModel):
|
||||
|
||||
|
||||
class MarketplaceStatsResponse(BaseModel):
|
||||
"""Statistics per marketplace response schema."""
|
||||
|
||||
marketplace: str
|
||||
total_products: int
|
||||
unique_vendors: int
|
||||
@@ -22,7 +27,246 @@ class MarketplaceStatsResponse(BaseModel):
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Customer Statistics
|
||||
# Import Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class ImportStatsResponse(BaseModel):
|
||||
"""Import job statistics response schema.
|
||||
|
||||
Used by: GET /api/v1/admin/marketplace-import-jobs/stats
|
||||
"""
|
||||
|
||||
total: int = Field(..., description="Total number of import jobs")
|
||||
pending: int = Field(..., description="Jobs waiting to start")
|
||||
processing: int = Field(..., description="Jobs currently running")
|
||||
completed: int = Field(..., description="Successfully completed jobs")
|
||||
failed: int = Field(..., description="Failed jobs")
|
||||
success_rate: float = Field(..., description="Percentage of successful imports")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# User Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class UserStatsResponse(BaseModel):
|
||||
"""User statistics response schema.
|
||||
|
||||
Used by: Platform statistics endpoints
|
||||
"""
|
||||
|
||||
total_users: int = Field(..., description="Total number of users")
|
||||
active_users: int = Field(..., description="Number of active users")
|
||||
inactive_users: int = Field(..., description="Number of inactive users")
|
||||
admin_users: int = Field(..., description="Number of admin users")
|
||||
activation_rate: float = Field(..., description="Percentage of active users")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Vendor Statistics (Admin)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class VendorStatsResponse(BaseModel):
|
||||
"""Vendor statistics response schema for admin dashboard.
|
||||
|
||||
Used by: GET /api/v1/admin/vendors/stats
|
||||
"""
|
||||
|
||||
total: int = Field(..., description="Total number of vendors")
|
||||
verified: int = Field(..., description="Number of verified vendors")
|
||||
pending: int = Field(..., description="Number of pending verification vendors")
|
||||
inactive: int = Field(..., description="Number of inactive vendors")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Product Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class ProductStatsResponse(BaseModel):
|
||||
"""Product statistics response schema.
|
||||
|
||||
Used by: Platform statistics endpoints
|
||||
"""
|
||||
|
||||
total_products: int = Field(0, description="Total number of products")
|
||||
active_products: int = Field(0, description="Number of active products")
|
||||
out_of_stock: int = Field(0, description="Number of out-of-stock products")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Platform Statistics (Combined)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class PlatformStatsResponse(BaseModel):
|
||||
"""Combined platform statistics response schema.
|
||||
|
||||
Used by: GET /api/v1/admin/dashboard/stats/platform
|
||||
"""
|
||||
|
||||
users: UserStatsResponse
|
||||
vendors: VendorStatsResponse
|
||||
products: ProductStatsResponse
|
||||
orders: "OrderStatsBasicResponse"
|
||||
imports: ImportStatsResponse
|
||||
|
||||
|
||||
class OrderStatsBasicResponse(BaseModel):
|
||||
"""Basic order statistics (stub until Order model is fully implemented).
|
||||
|
||||
Used by: Platform statistics endpoints
|
||||
"""
|
||||
|
||||
total_orders: int = Field(0, description="Total number of orders")
|
||||
pending_orders: int = Field(0, description="Number of pending orders")
|
||||
completed_orders: int = Field(0, description="Number of completed orders")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Admin Dashboard Response
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class AdminDashboardResponse(BaseModel):
|
||||
"""Admin dashboard response schema.
|
||||
|
||||
Used by: GET /api/v1/admin/dashboard
|
||||
"""
|
||||
|
||||
platform: dict[str, Any] = Field(..., description="Platform information")
|
||||
users: UserStatsResponse
|
||||
vendors: VendorStatsResponse
|
||||
recent_vendors: list[dict[str, Any]] = Field(
|
||||
default_factory=list, description="Recent vendors"
|
||||
)
|
||||
recent_imports: list[dict[str, Any]] = Field(
|
||||
default_factory=list, description="Recent import jobs"
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Vendor Dashboard Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class VendorProductStats(BaseModel):
|
||||
"""Vendor product statistics."""
|
||||
|
||||
total: int = Field(0, description="Total products in catalog")
|
||||
active: int = Field(0, description="Active products")
|
||||
|
||||
|
||||
class VendorOrderStats(BaseModel):
|
||||
"""Vendor order statistics."""
|
||||
|
||||
total: int = Field(0, description="Total orders")
|
||||
pending: int = Field(0, description="Pending orders")
|
||||
completed: int = Field(0, description="Completed orders")
|
||||
|
||||
|
||||
class VendorCustomerStats(BaseModel):
|
||||
"""Vendor customer statistics."""
|
||||
|
||||
total: int = Field(0, description="Total customers")
|
||||
active: int = Field(0, description="Active customers")
|
||||
|
||||
|
||||
class VendorRevenueStats(BaseModel):
|
||||
"""Vendor revenue statistics."""
|
||||
|
||||
total: float = Field(0, description="Total revenue")
|
||||
this_month: float = Field(0, description="Revenue this month")
|
||||
|
||||
|
||||
class VendorInfo(BaseModel):
|
||||
"""Vendor basic info for dashboard."""
|
||||
|
||||
id: int
|
||||
name: str
|
||||
vendor_code: str
|
||||
|
||||
|
||||
class VendorDashboardStatsResponse(BaseModel):
|
||||
"""Vendor dashboard statistics response schema.
|
||||
|
||||
Used by: GET /api/v1/vendor/dashboard/stats
|
||||
"""
|
||||
|
||||
vendor: VendorInfo
|
||||
products: VendorProductStats
|
||||
orders: VendorOrderStats
|
||||
customers: VendorCustomerStats
|
||||
revenue: VendorRevenueStats
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Vendor Analytics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class VendorAnalyticsImports(BaseModel):
|
||||
"""Vendor import analytics."""
|
||||
|
||||
count: int = Field(0, description="Number of imports in period")
|
||||
|
||||
|
||||
class VendorAnalyticsCatalog(BaseModel):
|
||||
"""Vendor catalog analytics."""
|
||||
|
||||
products_added: int = Field(0, description="Products added in period")
|
||||
|
||||
|
||||
class VendorAnalyticsInventory(BaseModel):
|
||||
"""Vendor inventory analytics."""
|
||||
|
||||
total_locations: int = Field(0, description="Total inventory locations")
|
||||
|
||||
|
||||
class VendorAnalyticsResponse(BaseModel):
|
||||
"""Vendor analytics response schema.
|
||||
|
||||
Used by: GET /api/v1/vendor/analytics
|
||||
"""
|
||||
|
||||
period: str = Field(..., description="Analytics period (e.g., '30d')")
|
||||
start_date: str = Field(..., description="Period start date")
|
||||
imports: VendorAnalyticsImports
|
||||
catalog: VendorAnalyticsCatalog
|
||||
inventory: VendorAnalyticsInventory
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Code Quality Dashboard Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class CodeQualityDashboardStatsResponse(BaseModel):
|
||||
"""Code quality dashboard statistics response schema.
|
||||
|
||||
Used by: GET /api/v1/admin/code-quality/stats
|
||||
"""
|
||||
|
||||
total_violations: int
|
||||
errors: int
|
||||
warnings: int
|
||||
open: int
|
||||
assigned: int
|
||||
resolved: int
|
||||
ignored: int
|
||||
technical_debt_score: int
|
||||
trend: list[dict[str, Any]] = Field(default_factory=list)
|
||||
by_severity: dict[str, Any] = Field(default_factory=dict)
|
||||
by_rule: dict[str, Any] = Field(default_factory=dict)
|
||||
by_module: dict[str, Any] = Field(default_factory=dict)
|
||||
top_files: list[dict[str, Any]] = Field(default_factory=list)
|
||||
last_scan: str | None = None
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Customer Statistics (Coming Soon)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@@ -39,7 +283,7 @@ class CustomerStatsResponse(BaseModel):
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Order Statistics
|
||||
# Order Statistics (Coming Soon)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@@ -54,17 +298,3 @@ class OrderStatsResponse(BaseModel):
|
||||
cancelled_orders: int
|
||||
total_revenue: Decimal
|
||||
average_order_value: Decimal
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Vendor Statistics
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class VendorStatsResponse(BaseModel):
|
||||
"""Vendor statistics response schema."""
|
||||
|
||||
total: int = Field(..., description="Total number of vendors")
|
||||
verified: int = Field(..., description="Number of verified vendors")
|
||||
pending: int = Field(..., description="Number of pending verification vendors")
|
||||
inactive: int = Field(..., description="Number of inactive vendors")
|
||||
|
||||
Reference in New Issue
Block a user