refactor: migrate vendor auth, profile, team, dashboard, settings to modules
Tenancy module (identity & organizational hierarchy): - vendor_auth.py: login, logout, /me endpoints - vendor_profile.py: vendor profile get/update - vendor_team.py: team management, roles, permissions, invitations Core module (foundational non-domain features): - vendor_dashboard.py: dashboard statistics - vendor_settings.py: localization, business info, letzshop settings All routes auto-discovered via is_self_contained=True. Deleted 5 legacy files from app/api/v1/vendor/. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
21
app/api/v1/vendor/__init__.py
vendored
21
app/api/v1/vendor/__init__.py
vendored
@@ -24,23 +24,18 @@ Self-contained modules (auto-discovered from app/modules/{module}/routes/api/ven
|
|||||||
- cms: Content pages management
|
- cms: Content pages management
|
||||||
- customers: Customer management
|
- customers: Customer management
|
||||||
- payments: Payment configuration, Stripe connect, transactions
|
- payments: Payment configuration, Stripe connect, transactions
|
||||||
- tenancy: Public vendor info lookup
|
- tenancy: Vendor info, auth, profile, team management
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
|
|
||||||
# Import all sub-routers (legacy routes that haven't been migrated to modules)
|
# Import all sub-routers (legacy routes that haven't been migrated to modules)
|
||||||
from . import (
|
from . import (
|
||||||
auth,
|
|
||||||
dashboard,
|
|
||||||
email_settings,
|
email_settings,
|
||||||
email_templates,
|
email_templates,
|
||||||
media,
|
media,
|
||||||
messages,
|
messages,
|
||||||
notifications,
|
notifications,
|
||||||
profile,
|
|
||||||
settings,
|
|
||||||
team,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create vendor router
|
# Create vendor router
|
||||||
@@ -51,18 +46,14 @@ router = APIRouter()
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# These routes return JSON and are mounted at /api/v1/vendor/*
|
# These routes return JSON and are mounted at /api/v1/vendor/*
|
||||||
|
|
||||||
# Authentication (no prefix, specific routes like /auth/login)
|
# Email configuration
|
||||||
router.include_router(auth.router, tags=["vendor-auth"])
|
|
||||||
|
|
||||||
# Vendor management (with prefixes: /dashboard/*, /profile/*, /settings/*)
|
|
||||||
router.include_router(dashboard.router, tags=["vendor-dashboard"])
|
|
||||||
router.include_router(profile.router, tags=["vendor-profile"])
|
|
||||||
router.include_router(settings.router, tags=["vendor-settings"])
|
|
||||||
router.include_router(email_templates.router, tags=["vendor-email-templates"])
|
router.include_router(email_templates.router, tags=["vendor-email-templates"])
|
||||||
router.include_router(email_settings.router, tags=["vendor-email-settings"])
|
router.include_router(email_settings.router, tags=["vendor-email-settings"])
|
||||||
|
|
||||||
# Business operations (with prefixes: /team/*)
|
# Services (with prefixes: /media/*, etc.)
|
||||||
router.include_router(team.router, tags=["vendor-team"])
|
router.include_router(media.router, tags=["vendor-media"])
|
||||||
|
router.include_router(notifications.router, tags=["vendor-notifications"])
|
||||||
|
router.include_router(messages.router, tags=["vendor-messages"])
|
||||||
|
|
||||||
# Services (with prefixes: /media/*, etc.)
|
# Services (with prefixes: /media/*, etc.)
|
||||||
router.include_router(media.router, tags=["vendor-media"])
|
router.include_router(media.router, tags=["vendor-media"])
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ core_module = ModuleDefinition(
|
|||||||
description="Dashboard, settings, and profile management. Required for basic operation.",
|
description="Dashboard, settings, and profile management. Required for basic operation.",
|
||||||
version="1.0.0",
|
version="1.0.0",
|
||||||
is_core=True,
|
is_core=True,
|
||||||
|
is_self_contained=True,
|
||||||
features=[
|
features=[
|
||||||
"dashboard",
|
"dashboard",
|
||||||
"settings",
|
"settings",
|
||||||
|
|||||||
4
app/modules/core/routes/__init__.py
Normal file
4
app/modules/core/routes/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# app/modules/core/routes/__init__.py
|
||||||
|
"""
|
||||||
|
Core module route registration.
|
||||||
|
"""
|
||||||
12
app/modules/core/routes/api/__init__.py
Normal file
12
app/modules/core/routes/api/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# app/modules/core/routes/api/__init__.py
|
||||||
|
"""
|
||||||
|
Core module API routes.
|
||||||
|
|
||||||
|
Vendor routes:
|
||||||
|
- /dashboard/* - Dashboard statistics
|
||||||
|
- /settings/* - Vendor settings management
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .vendor import vendor_router
|
||||||
|
|
||||||
|
__all__ = ["vendor_router"]
|
||||||
19
app/modules/core/routes/api/vendor.py
Normal file
19
app/modules/core/routes/api/vendor.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# app/modules/core/routes/api/vendor.py
|
||||||
|
"""
|
||||||
|
Core module vendor API routes.
|
||||||
|
|
||||||
|
Aggregates:
|
||||||
|
- /dashboard/* - Dashboard statistics
|
||||||
|
- /settings/* - Vendor settings management
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from .vendor_dashboard import vendor_dashboard_router
|
||||||
|
from .vendor_settings import vendor_settings_router
|
||||||
|
|
||||||
|
vendor_router = APIRouter()
|
||||||
|
|
||||||
|
# Aggregate sub-routers
|
||||||
|
vendor_router.include_router(vendor_dashboard_router, tags=["vendor-dashboard"])
|
||||||
|
vendor_router.include_router(vendor_settings_router, tags=["vendor-settings"])
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/dashboard.py
|
# app/modules/core/routes/api/vendor_dashboard.py
|
||||||
"""
|
"""
|
||||||
Vendor dashboard and statistics endpoints.
|
Vendor dashboard and statistics endpoints.
|
||||||
|
|
||||||
@@ -26,11 +26,11 @@ from app.modules.analytics.schemas import (
|
|||||||
VendorRevenueStats,
|
VendorRevenueStats,
|
||||||
)
|
)
|
||||||
|
|
||||||
router = APIRouter(prefix="/dashboard")
|
vendor_dashboard_router = APIRouter(prefix="/dashboard")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/stats", response_model=VendorDashboardStatsResponse)
|
@vendor_dashboard_router.get("/stats", response_model=VendorDashboardStatsResponse)
|
||||||
def get_vendor_dashboard_stats(
|
def get_vendor_dashboard_stats(
|
||||||
request: Request,
|
request: Request,
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/settings.py
|
# app/modules/core/routes/api/vendor_settings.py
|
||||||
"""
|
"""
|
||||||
Vendor settings and configuration endpoints.
|
Vendor settings and configuration endpoints.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ from app.services.platform_settings_service import platform_settings_service
|
|||||||
from app.services.vendor_service import vendor_service
|
from app.services.vendor_service import vendor_service
|
||||||
from models.schema.auth import UserContext
|
from models.schema.auth import UserContext
|
||||||
|
|
||||||
router = APIRouter(prefix="/settings")
|
vendor_settings_router = APIRouter(prefix="/settings")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Supported languages for dropdown
|
# Supported languages for dropdown
|
||||||
@@ -154,7 +154,7 @@ class LetzshopFeedSettingsUpdate(BaseModel):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
@router.get("")
|
@vendor_settings_router.get("")
|
||||||
def get_vendor_settings(
|
def get_vendor_settings(
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
@@ -318,7 +318,7 @@ def get_vendor_settings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.put("/business-info")
|
@vendor_settings_router.put("/business-info")
|
||||||
def update_business_info(
|
def update_business_info(
|
||||||
business_info: BusinessInfoUpdate,
|
business_info: BusinessInfoUpdate,
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
@@ -360,7 +360,7 @@ def update_business_info(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.put("/letzshop")
|
@vendor_settings_router.put("/letzshop")
|
||||||
def update_letzshop_settings(
|
def update_letzshop_settings(
|
||||||
letzshop_config: LetzshopFeedSettingsUpdate,
|
letzshop_config: LetzshopFeedSettingsUpdate,
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
@@ -394,7 +394,7 @@ def update_letzshop_settings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.put("/localization")
|
@vendor_settings_router.put("/localization")
|
||||||
def update_localization_settings(
|
def update_localization_settings(
|
||||||
localization_config: LocalizationSettingsUpdate,
|
localization_config: LocalizationSettingsUpdate,
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
@@ -2,10 +2,21 @@
|
|||||||
"""
|
"""
|
||||||
Tenancy module API routes.
|
Tenancy module API routes.
|
||||||
|
|
||||||
Includes:
|
Vendor routes:
|
||||||
- /info/{vendor_code} - Public vendor info lookup
|
- /info/{vendor_code} - Public vendor info lookup
|
||||||
|
- /auth/* - Vendor authentication (login, logout, /me)
|
||||||
|
- /profile/* - Vendor profile management
|
||||||
|
- /team/* - Team member management, roles, permissions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .vendor import vendor_router
|
from .vendor import vendor_router
|
||||||
|
from .vendor_auth import vendor_auth_router
|
||||||
|
from .vendor_profile import vendor_profile_router
|
||||||
|
from .vendor_team import vendor_team_router
|
||||||
|
|
||||||
__all__ = ["vendor_router"]
|
__all__ = [
|
||||||
|
"vendor_router",
|
||||||
|
"vendor_auth_router",
|
||||||
|
"vendor_profile_router",
|
||||||
|
"vendor_team_router",
|
||||||
|
]
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
"""
|
"""
|
||||||
Tenancy module vendor API routes.
|
Tenancy module vendor API routes.
|
||||||
|
|
||||||
Provides public vendor information lookup for:
|
Aggregates all vendor tenancy routes:
|
||||||
- Vendor login pages to display branding
|
- /info/{vendor_code} - Public vendor info lookup
|
||||||
- Public vendor profile lookup
|
- /auth/* - Vendor authentication (login, logout, /me)
|
||||||
|
- /profile/* - Vendor profile management
|
||||||
|
- /team/* - Team member management, roles, permissions
|
||||||
|
|
||||||
These endpoints do NOT require authentication - they provide
|
The tenancy module owns identity and organizational hierarchy.
|
||||||
public information about vendors.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@@ -80,3 +81,17 @@ def get_vendor_info(
|
|||||||
owner_email=vendor.company.owner.email,
|
owner_email=vendor.company.owner.email,
|
||||||
owner_username=vendor.company.owner.username,
|
owner_username=vendor.company.owner.username,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Aggregate Sub-Routers
|
||||||
|
# ============================================================================
|
||||||
|
# Include all tenancy vendor routes (auth, profile, team)
|
||||||
|
|
||||||
|
from .vendor_auth import vendor_auth_router
|
||||||
|
from .vendor_profile import vendor_profile_router
|
||||||
|
from .vendor_team import vendor_team_router
|
||||||
|
|
||||||
|
vendor_router.include_router(vendor_auth_router, tags=["vendor-auth"])
|
||||||
|
vendor_router.include_router(vendor_profile_router, tags=["vendor-profile"])
|
||||||
|
vendor_router.include_router(vendor_team_router, tags=["vendor-team"])
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/auth.py
|
# app/modules/tenancy/routes/api/vendor_auth.py
|
||||||
"""
|
"""
|
||||||
Vendor team authentication endpoints.
|
Vendor team authentication endpoints.
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ from middleware.vendor_context import get_current_vendor
|
|||||||
from models.schema.auth import UserContext
|
from models.schema.auth import UserContext
|
||||||
from models.schema.auth import LogoutResponse, UserLogin, VendorUserResponse
|
from models.schema.auth import LogoutResponse, UserLogin, VendorUserResponse
|
||||||
|
|
||||||
router = APIRouter(prefix="/auth")
|
vendor_auth_router = APIRouter(prefix="/auth")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class VendorLoginResponse(BaseModel):
|
|||||||
vendor_role: str
|
vendor_role: str
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login", response_model=VendorLoginResponse)
|
@vendor_auth_router.post("/login", response_model=VendorLoginResponse)
|
||||||
def vendor_login(
|
def vendor_login(
|
||||||
user_credentials: UserLogin,
|
user_credentials: UserLogin,
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -156,7 +156,7 @@ def vendor_login(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/logout", response_model=LogoutResponse)
|
@vendor_auth_router.post("/logout", response_model=LogoutResponse)
|
||||||
def vendor_logout(response: Response):
|
def vendor_logout(response: Response):
|
||||||
"""
|
"""
|
||||||
Vendor team member logout.
|
Vendor team member logout.
|
||||||
@@ -177,7 +177,7 @@ def vendor_logout(response: Response):
|
|||||||
return LogoutResponse(message="Logged out successfully")
|
return LogoutResponse(message="Logged out successfully")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/me", response_model=VendorUserResponse)
|
@vendor_auth_router.get("/me", response_model=VendorUserResponse)
|
||||||
def get_current_vendor_user(
|
def get_current_vendor_user(
|
||||||
user: UserContext = Depends(get_current_vendor_api), db: Session = Depends(get_db)
|
user: UserContext = Depends(get_current_vendor_api), db: Session = Depends(get_db)
|
||||||
):
|
):
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/profile.py
|
# app/modules/tenancy/routes/api/vendor_profile.py
|
||||||
"""
|
"""
|
||||||
Vendor profile management endpoints.
|
Vendor profile management endpoints.
|
||||||
|
|
||||||
@@ -17,11 +17,11 @@ from app.services.vendor_service import vendor_service
|
|||||||
from models.schema.auth import UserContext
|
from models.schema.auth import UserContext
|
||||||
from models.schema.vendor import VendorResponse, VendorUpdate
|
from models.schema.vendor import VendorResponse, VendorUpdate
|
||||||
|
|
||||||
router = APIRouter(prefix="/profile")
|
vendor_profile_router = APIRouter(prefix="/profile")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@router.get("", response_model=VendorResponse)
|
@vendor_profile_router.get("", response_model=VendorResponse)
|
||||||
def get_vendor_profile(
|
def get_vendor_profile(
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
@@ -31,7 +31,7 @@ def get_vendor_profile(
|
|||||||
return vendor
|
return vendor
|
||||||
|
|
||||||
|
|
||||||
@router.put("", response_model=VendorResponse)
|
@vendor_profile_router.put("", response_model=VendorResponse)
|
||||||
def update_vendor_profile(
|
def update_vendor_profile(
|
||||||
vendor_update: VendorUpdate,
|
vendor_update: VendorUpdate,
|
||||||
current_user: UserContext = Depends(get_current_vendor_api),
|
current_user: UserContext = Depends(get_current_vendor_api),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# app/api/v1/vendor/teams.py
|
# app/modules/tenancy/routes/api/vendor_team.py
|
||||||
"""
|
"""
|
||||||
Vendor team member management endpoints.
|
Vendor team member management endpoints.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ from models.schema.team import (
|
|||||||
UserPermissionsResponse,
|
UserPermissionsResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
router = APIRouter(prefix="/team")
|
vendor_team_router = APIRouter(prefix="/team")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ logger = logging.getLogger(__name__)
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
@router.get("/members", response_model=TeamMemberListResponse)
|
@vendor_team_router.get("/members", response_model=TeamMemberListResponse)
|
||||||
def list_team_members(
|
def list_team_members(
|
||||||
request: Request,
|
request: Request,
|
||||||
include_inactive: bool = False,
|
include_inactive: bool = False,
|
||||||
@@ -91,7 +91,7 @@ def list_team_members(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/invite", response_model=InvitationResponse)
|
@vendor_team_router.post("/invite", response_model=InvitationResponse)
|
||||||
def invite_team_member(
|
def invite_team_member(
|
||||||
invitation: TeamMemberInvite,
|
invitation: TeamMemberInvite,
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -165,7 +165,7 @@ def invite_team_member(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/accept-invitation", response_model=InvitationAcceptResponse) # public
|
@vendor_team_router.post("/accept-invitation", response_model=InvitationAcceptResponse) # public
|
||||||
def accept_invitation(acceptance: InvitationAccept, db: Session = Depends(get_db)):
|
def accept_invitation(acceptance: InvitationAccept, db: Session = Depends(get_db)):
|
||||||
"""
|
"""
|
||||||
Accept a team invitation and activate account.
|
Accept a team invitation and activate account.
|
||||||
@@ -215,7 +215,7 @@ def accept_invitation(acceptance: InvitationAccept, db: Session = Depends(get_db
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/members/{user_id}", response_model=TeamMemberResponse)
|
@vendor_team_router.get("/members/{user_id}", response_model=TeamMemberResponse)
|
||||||
def get_team_member(
|
def get_team_member(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -244,7 +244,7 @@ def get_team_member(
|
|||||||
return TeamMemberResponse(**member)
|
return TeamMemberResponse(**member)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/members/{user_id}", response_model=TeamMemberResponse)
|
@vendor_team_router.put("/members/{user_id}", response_model=TeamMemberResponse)
|
||||||
def update_team_member(
|
def update_team_member(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
update_data: TeamMemberUpdate,
|
update_data: TeamMemberUpdate,
|
||||||
@@ -288,7 +288,7 @@ def update_team_member(
|
|||||||
return TeamMemberResponse(**member)
|
return TeamMemberResponse(**member)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/members/{user_id}")
|
@vendor_team_router.delete("/members/{user_id}")
|
||||||
def remove_team_member(
|
def remove_team_member(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -320,7 +320,7 @@ def remove_team_member(
|
|||||||
return {"message": "Team member removed successfully", "user_id": user_id}
|
return {"message": "Team member removed successfully", "user_id": user_id}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/members/bulk-remove", response_model=BulkRemoveResponse)
|
@vendor_team_router.post("/members/bulk-remove", response_model=BulkRemoveResponse)
|
||||||
def bulk_remove_team_members(
|
def bulk_remove_team_members(
|
||||||
bulk_remove: BulkRemoveRequest,
|
bulk_remove: BulkRemoveRequest,
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -365,7 +365,7 @@ def bulk_remove_team_members(
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
@router.get("/roles", response_model=RoleListResponse)
|
@vendor_team_router.get("/roles", response_model=RoleListResponse)
|
||||||
def list_roles(
|
def list_roles(
|
||||||
request: Request,
|
request: Request,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
@@ -395,7 +395,7 @@ def list_roles(
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
@router.get("/me/permissions", response_model=UserPermissionsResponse)
|
@vendor_team_router.get("/me/permissions", response_model=UserPermissionsResponse)
|
||||||
def get_my_permissions(
|
def get_my_permissions(
|
||||||
request: Request,
|
request: Request,
|
||||||
permissions: list[str] = Depends(get_user_permissions),
|
permissions: list[str] = Depends(get_user_permissions),
|
||||||
@@ -434,7 +434,7 @@ def get_my_permissions(
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
@router.get("/statistics", response_model=TeamStatistics)
|
@vendor_team_router.get("/statistics", response_model=TeamStatistics)
|
||||||
def get_team_statistics(
|
def get_team_statistics(
|
||||||
request: Request,
|
request: Request,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
Reference in New Issue
Block a user