refactor: modernize code quality tooling with Ruff
- Replace black, isort, and flake8 with Ruff (all-in-one linter and formatter) - Add comprehensive pyproject.toml configuration - Simplify Makefile code quality targets - Configure exclusions for venv/.venv in pyproject.toml - Auto-fix 1,359 linting issues across codebase Benefits: - Much faster builds (Ruff is written in Rust) - Single tool replaces multiple tools - More comprehensive rule set (UP, B, C4, SIM, PIE, RET, Q) - All configuration centralized in pyproject.toml - Better import sorting and formatting consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
21
app/api/v1/vendor/__init__.py
vendored
21
app/api/v1/vendor/__init__.py
vendored
@@ -13,9 +13,24 @@ IMPORTANT:
|
||||
from fastapi import APIRouter
|
||||
|
||||
# Import all sub-routers (JSON API only)
|
||||
from . import (analytics, auth, content_pages, customers, dashboard, info,
|
||||
inventory, marketplace, media, notifications, orders, payments,
|
||||
products, profile, settings, team)
|
||||
from . import (
|
||||
analytics,
|
||||
auth,
|
||||
content_pages,
|
||||
customers,
|
||||
dashboard,
|
||||
info,
|
||||
inventory,
|
||||
marketplace,
|
||||
media,
|
||||
notifications,
|
||||
orders,
|
||||
payments,
|
||||
products,
|
||||
profile,
|
||||
settings,
|
||||
team,
|
||||
)
|
||||
|
||||
# Create vendor router
|
||||
router = APIRouter()
|
||||
|
||||
43
app/api/v1/vendor/content_pages.py
vendored
43
app/api/v1/vendor/content_pages.py
vendored
@@ -9,7 +9,6 @@ Vendors can:
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -41,10 +40,10 @@ class VendorContentPageCreate(BaseModel):
|
||||
content_format: str = Field(
|
||||
default="html", description="Content format: html or markdown"
|
||||
)
|
||||
meta_description: Optional[str] = Field(
|
||||
meta_description: str | None = Field(
|
||||
None, max_length=300, description="SEO meta description"
|
||||
)
|
||||
meta_keywords: Optional[str] = Field(
|
||||
meta_keywords: str | None = Field(
|
||||
None, max_length=300, description="SEO keywords"
|
||||
)
|
||||
is_published: bool = Field(default=False, description="Publish immediately")
|
||||
@@ -56,31 +55,31 @@ class VendorContentPageCreate(BaseModel):
|
||||
class VendorContentPageUpdate(BaseModel):
|
||||
"""Schema for updating a vendor content page."""
|
||||
|
||||
title: Optional[str] = Field(None, max_length=200)
|
||||
content: Optional[str] = None
|
||||
content_format: Optional[str] = None
|
||||
meta_description: Optional[str] = Field(None, max_length=300)
|
||||
meta_keywords: Optional[str] = Field(None, max_length=300)
|
||||
is_published: Optional[bool] = None
|
||||
show_in_footer: Optional[bool] = None
|
||||
show_in_header: Optional[bool] = None
|
||||
display_order: Optional[int] = None
|
||||
title: str | None = Field(None, max_length=200)
|
||||
content: str | None = None
|
||||
content_format: str | None = None
|
||||
meta_description: str | None = Field(None, max_length=300)
|
||||
meta_keywords: str | None = Field(None, max_length=300)
|
||||
is_published: bool | None = None
|
||||
show_in_footer: bool | None = None
|
||||
show_in_header: bool | None = None
|
||||
display_order: int | None = None
|
||||
|
||||
|
||||
class ContentPageResponse(BaseModel):
|
||||
"""Schema for content page response."""
|
||||
|
||||
id: int
|
||||
vendor_id: Optional[int]
|
||||
vendor_name: Optional[str]
|
||||
vendor_id: int | None
|
||||
vendor_name: str | None
|
||||
slug: str
|
||||
title: str
|
||||
content: str
|
||||
content_format: str
|
||||
meta_description: Optional[str]
|
||||
meta_keywords: Optional[str]
|
||||
meta_description: str | None
|
||||
meta_keywords: str | None
|
||||
is_published: bool
|
||||
published_at: Optional[str]
|
||||
published_at: str | None
|
||||
display_order: int
|
||||
show_in_footer: bool
|
||||
show_in_header: bool
|
||||
@@ -88,8 +87,8 @@ class ContentPageResponse(BaseModel):
|
||||
is_vendor_override: bool
|
||||
created_at: str
|
||||
updated_at: str
|
||||
created_by: Optional[int]
|
||||
updated_by: Optional[int]
|
||||
created_by: int | None
|
||||
updated_by: int | None
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -97,7 +96,7 @@ class ContentPageResponse(BaseModel):
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/", response_model=List[ContentPageResponse])
|
||||
@router.get("/", response_model=list[ContentPageResponse])
|
||||
def list_vendor_pages(
|
||||
include_unpublished: bool = Query(False, description="Include draft pages"),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
@@ -120,7 +119,7 @@ def list_vendor_pages(
|
||||
return [page.to_dict() for page in pages]
|
||||
|
||||
|
||||
@router.get("/overrides", response_model=List[ContentPageResponse])
|
||||
@router.get("/overrides", response_model=list[ContentPageResponse])
|
||||
def list_vendor_overrides(
|
||||
include_unpublished: bool = Query(False, description="Include draft pages"),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
@@ -284,4 +283,4 @@ def delete_vendor_page(
|
||||
# Delete
|
||||
content_page_service.delete_page(db, page_id)
|
||||
|
||||
return None
|
||||
return
|
||||
|
||||
5
app/api/v1/vendor/customers.py
vendored
5
app/api/v1/vendor/customers.py
vendored
@@ -5,7 +5,6 @@ Vendor customer management endpoints.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -24,8 +23,8 @@ logger = logging.getLogger(__name__)
|
||||
def get_vendor_customers(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
search: Optional[str] = Query(None),
|
||||
is_active: Optional[bool] = Query(None),
|
||||
search: str | None = Query(None),
|
||||
is_active: bool | None = Query(None),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
2
app/api/v1/vendor/dashboard.py
vendored
2
app/api/v1/vendor/dashboard.py
vendored
@@ -11,9 +11,7 @@ from sqlalchemy.orm import Session
|
||||
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 middleware.vendor_context import require_vendor_context
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
|
||||
router = APIRouter(prefix="/dashboard")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
2
app/api/v1/vendor/info.py
vendored
2
app/api/v1/vendor/info.py
vendored
@@ -16,7 +16,7 @@ from sqlalchemy.orm import Session
|
||||
from app.core.database import get_db
|
||||
from app.exceptions import VendorNotFoundException
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.vendor import VendorDetailResponse, VendorResponse
|
||||
from models.schema.vendor import VendorDetailResponse
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
18
app/api/v1/vendor/inventory.py
vendored
18
app/api/v1/vendor/inventory.py
vendored
@@ -1,6 +1,5 @@
|
||||
# app/api/v1/vendor/inventory.py
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -11,10 +10,15 @@ from app.services.inventory_service import inventory_service
|
||||
from middleware.vendor_context import require_vendor_context
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.inventory import (InventoryAdjust, InventoryCreate,
|
||||
InventoryListResponse, InventoryReserve,
|
||||
InventoryResponse, InventoryUpdate,
|
||||
ProductInventorySummary)
|
||||
from models.schema.inventory import (
|
||||
InventoryAdjust,
|
||||
InventoryCreate,
|
||||
InventoryListResponse,
|
||||
InventoryReserve,
|
||||
InventoryResponse,
|
||||
InventoryUpdate,
|
||||
ProductInventorySummary,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -90,8 +94,8 @@ def get_product_inventory(
|
||||
def get_vendor_inventory(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
location: Optional[str] = Query(None),
|
||||
low_stock: Optional[int] = Query(None, ge=0),
|
||||
location: str | None = Query(None),
|
||||
low_stock: int | None = Query(None, ge=0),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
14
app/api/v1/vendor/marketplace.py
vendored
14
app/api/v1/vendor/marketplace.py
vendored
@@ -5,22 +5,22 @@ Vendor context is automatically injected by middleware.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_vendor_api
|
||||
from app.core.database import get_db
|
||||
from app.services.marketplace_import_job_service import \
|
||||
marketplace_import_job_service
|
||||
from app.services.marketplace_import_job_service import marketplace_import_job_service
|
||||
from app.tasks.background_tasks import process_marketplace_import
|
||||
from middleware.decorators import rate_limit
|
||||
from middleware.vendor_context import require_vendor_context # IMPORTANT
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.marketplace_import_job import (MarketplaceImportJobRequest,
|
||||
MarketplaceImportJobResponse)
|
||||
from models.schema.marketplace_import_job import (
|
||||
MarketplaceImportJobRequest,
|
||||
MarketplaceImportJobResponse,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -93,9 +93,9 @@ def get_marketplace_import_status(
|
||||
return marketplace_import_job_service.convert_to_response_model(job)
|
||||
|
||||
|
||||
@router.get("/imports", response_model=List[MarketplaceImportJobResponse])
|
||||
@router.get("/imports", response_model=list[MarketplaceImportJobResponse])
|
||||
def get_marketplace_import_jobs(
|
||||
marketplace: Optional[str] = Query(None, description="Filter by marketplace"),
|
||||
marketplace: str | None = Query(None, description="Filter by marketplace"),
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(50, ge=1, le=100),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
|
||||
9
app/api/v1/vendor/media.py
vendored
9
app/api/v1/vendor/media.py
vendored
@@ -5,7 +5,6 @@ Vendor media and file management endpoints.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, File, Query, UploadFile
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -24,8 +23,8 @@ logger = logging.getLogger(__name__)
|
||||
def get_media_library(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
media_type: Optional[str] = Query(None, description="image, video, document"),
|
||||
search: Optional[str] = Query(None),
|
||||
media_type: str | None = Query(None, description="image, video, document"),
|
||||
search: str | None = Query(None),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
@@ -52,7 +51,7 @@ def get_media_library(
|
||||
@router.post("/upload")
|
||||
async def upload_media(
|
||||
file: UploadFile = File(...),
|
||||
folder: Optional[str] = Query(None, description="products, general, etc."),
|
||||
folder: str | None = Query(None, description="products, general, etc."),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
@@ -78,7 +77,7 @@ async def upload_media(
|
||||
@router.post("/upload/multiple")
|
||||
async def upload_multiple_media(
|
||||
files: list[UploadFile] = File(...),
|
||||
folder: Optional[str] = Query(None),
|
||||
folder: str | None = Query(None),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
3
app/api/v1/vendor/notifications.py
vendored
3
app/api/v1/vendor/notifications.py
vendored
@@ -5,7 +5,6 @@ Vendor notification management endpoints.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -24,7 +23,7 @@ logger = logging.getLogger(__name__)
|
||||
def get_notifications(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(50, ge=1, le=100),
|
||||
unread_only: Optional[bool] = Query(False),
|
||||
unread_only: bool | None = Query(False),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
17
app/api/v1/vendor/orders.py
vendored
17
app/api/v1/vendor/orders.py
vendored
@@ -4,9 +4,8 @@ Vendor order management endpoints.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_vendor_api
|
||||
@@ -14,9 +13,13 @@ from app.core.database import get_db
|
||||
from app.services.order_service import order_service
|
||||
from middleware.vendor_context import require_vendor_context
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor, VendorUser
|
||||
from models.schema.order import (OrderDetailResponse, OrderListResponse,
|
||||
OrderResponse, OrderUpdate)
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.order import (
|
||||
OrderDetailResponse,
|
||||
OrderListResponse,
|
||||
OrderResponse,
|
||||
OrderUpdate,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/orders")
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -26,8 +29,8 @@ logger = logging.getLogger(__name__)
|
||||
def get_vendor_orders(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
status: Optional[str] = Query(None, description="Filter by order status"),
|
||||
customer_id: Optional[int] = Query(None, description="Filter by customer"),
|
||||
status: str | None = Query(None, description="Filter by order status"),
|
||||
customer_id: int | None = Query(None, description="Filter by customer"),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
15
app/api/v1/vendor/products.py
vendored
15
app/api/v1/vendor/products.py
vendored
@@ -4,7 +4,6 @@ Vendor product catalog management endpoints.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -15,9 +14,13 @@ from app.services.product_service import product_service
|
||||
from middleware.vendor_context import require_vendor_context
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.product import (ProductCreate, ProductDetailResponse,
|
||||
ProductListResponse, ProductResponse,
|
||||
ProductUpdate)
|
||||
from models.schema.product import (
|
||||
ProductCreate,
|
||||
ProductDetailResponse,
|
||||
ProductListResponse,
|
||||
ProductResponse,
|
||||
ProductUpdate,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/products")
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -27,8 +30,8 @@ logger = logging.getLogger(__name__)
|
||||
def get_vendor_products(
|
||||
skip: int = Query(0, ge=0),
|
||||
limit: int = Query(100, ge=1, le=1000),
|
||||
is_active: Optional[bool] = Query(None),
|
||||
is_featured: Optional[bool] = Query(None),
|
||||
is_active: bool | None = Query(None),
|
||||
is_featured: bool | None = Query(None),
|
||||
vendor: Vendor = Depends(require_vendor_context()),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
db: Session = Depends(get_db),
|
||||
|
||||
33
app/api/v1/vendor/team.py
vendored
33
app/api/v1/vendor/team.py
vendored
@@ -11,25 +11,34 @@ Implements complete team management with:
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import (get_current_vendor_api, get_user_permissions,
|
||||
require_vendor_owner, require_vendor_permission)
|
||||
from app.api.deps import (
|
||||
get_current_vendor_api,
|
||||
get_user_permissions,
|
||||
require_vendor_owner,
|
||||
require_vendor_permission,
|
||||
)
|
||||
from app.core.database import get_db
|
||||
from app.core.permissions import VendorPermissions
|
||||
from app.services.vendor_team_service import vendor_team_service
|
||||
from models.database.user import User
|
||||
from models.database.vendor import Vendor
|
||||
from models.schema.team import (BulkRemoveRequest, BulkRemoveResponse,
|
||||
InvitationAccept, InvitationAcceptResponse,
|
||||
InvitationResponse, RoleListResponse,
|
||||
RoleResponse, TeamMemberInvite,
|
||||
TeamMemberListResponse, TeamMemberResponse,
|
||||
TeamMemberUpdate, TeamStatistics,
|
||||
UserPermissionsResponse)
|
||||
from models.schema.team import (
|
||||
BulkRemoveRequest,
|
||||
BulkRemoveResponse,
|
||||
InvitationAccept,
|
||||
InvitationAcceptResponse,
|
||||
InvitationResponse,
|
||||
RoleListResponse,
|
||||
TeamMemberInvite,
|
||||
TeamMemberListResponse,
|
||||
TeamMemberResponse,
|
||||
TeamMemberUpdate,
|
||||
TeamStatistics,
|
||||
UserPermissionsResponse,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/team")
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -382,7 +391,7 @@ def list_roles(
|
||||
@router.get("/me/permissions", response_model=UserPermissionsResponse)
|
||||
def get_my_permissions(
|
||||
request: Request,
|
||||
permissions: List[str] = Depends(get_user_permissions),
|
||||
permissions: list[str] = Depends(get_user_permissions),
|
||||
current_user: User = Depends(get_current_vendor_api),
|
||||
):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user