fix(lint): restore noqa directives and register custom codes with ruff
Reverts the noqa: removal — the architecture validators (SVC-006, SEC-034, MOD-004, API-007) use these to skip known-safe violations. Added ruff lint.external config so ruff treats them as valid codes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_store_from_cookie_or_header, get_db
|
||||
from app.modules.core.services.platform_settings_service import (
|
||||
platform_settings_service, # MOD-004 - shared platform service
|
||||
platform_settings_service, # noqa: MOD-004 - shared platform service
|
||||
)
|
||||
from app.modules.tenancy.models import Store, User
|
||||
from app.templates_config import templates
|
||||
|
||||
@@ -27,7 +27,7 @@ from app.modules.checkout.schemas import (
|
||||
from app.modules.checkout.services import checkout_service
|
||||
from app.modules.customers.schemas import CustomerContext
|
||||
from app.modules.messaging.services.email_service import (
|
||||
EmailService, # MOD-004 - Core email service
|
||||
EmailService, # noqa: MOD-004 - Core email service
|
||||
)
|
||||
from app.modules.orders.schemas import OrderCreate, OrderResponse
|
||||
from app.modules.orders.services import order_service
|
||||
|
||||
@@ -27,7 +27,7 @@ from app.modules.cms.schemas import (
|
||||
from app.modules.cms.services import content_page_service
|
||||
from app.modules.tenancy.models import User
|
||||
from app.modules.tenancy.services.store_service import (
|
||||
StoreService, # MOD-004 - shared platform service
|
||||
StoreService, # noqa: MOD-004 - shared platform service
|
||||
)
|
||||
|
||||
store_service = StoreService()
|
||||
|
||||
@@ -14,7 +14,7 @@ from sqlalchemy.orm import Session
|
||||
from app.api.deps import get_current_store_from_cookie_or_header, get_db
|
||||
from app.modules.cms.services import content_page_service
|
||||
from app.modules.core.services.platform_settings_service import (
|
||||
platform_settings_service, # MOD-004 - shared platform service
|
||||
platform_settings_service, # noqa: MOD-004 - shared platform service
|
||||
)
|
||||
from app.modules.tenancy.models import Store, User
|
||||
from app.templates_config import templates
|
||||
|
||||
@@ -28,7 +28,7 @@ from app.api.deps import (
|
||||
get_db,
|
||||
)
|
||||
from app.modules.core.services.menu_service import MenuItemConfig, menu_service
|
||||
from app.modules.enums import FrontendType # API-007 - Enum for type safety
|
||||
from app.modules.enums import FrontendType # noqa: API-007 - Enum for type safety
|
||||
from app.modules.tenancy.services.platform_service import platform_service
|
||||
from app.utils.i18n import DEFAULT_LANGUAGE, translate
|
||||
from models.schema.auth import UserContext
|
||||
|
||||
@@ -61,7 +61,7 @@ class AuthService:
|
||||
|
||||
# Update last_login timestamp
|
||||
user.last_login = datetime.now(UTC)
|
||||
db.commit() # SVC-006 - Login must persist last_login timestamp
|
||||
db.commit() # noqa: SVC-006 - Login must persist last_login timestamp
|
||||
|
||||
token_data = self.auth_manager.create_access_token(user)
|
||||
|
||||
@@ -176,7 +176,7 @@ class AuthService:
|
||||
|
||||
# Update last_login timestamp
|
||||
user.last_login = datetime.now(UTC)
|
||||
db.commit() # SVC-006 - Login must persist last_login timestamp
|
||||
db.commit() # noqa: SVC-006 - Login must persist last_login timestamp
|
||||
|
||||
token_data = self.auth_manager.create_access_token(user)
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ class PlatformSettingsService:
|
||||
)
|
||||
db.add(admin_setting)
|
||||
|
||||
db.commit() # SVC-006 - Setting change is atomic, commit is intentional
|
||||
db.commit() # noqa: SVC-006 - Setting change is atomic, commit is intentional
|
||||
db.refresh(admin_setting)
|
||||
|
||||
logger.info(f"Platform setting '{key}' set to '{value}' by user {user_id}")
|
||||
|
||||
@@ -25,7 +25,7 @@ from app.core.database import get_db
|
||||
from app.core.environment import should_use_secure_cookies
|
||||
from app.exceptions import ValidationException
|
||||
from app.modules.core.services.auth_service import (
|
||||
AuthService, # MOD-004 - Core auth service
|
||||
AuthService, # noqa: MOD-004 - Core auth service
|
||||
)
|
||||
from app.modules.customers.models import PasswordResetToken
|
||||
from app.modules.customers.schemas import (
|
||||
@@ -44,7 +44,7 @@ from app.modules.customers.services import (
|
||||
customer_service,
|
||||
)
|
||||
from app.modules.messaging.services.email_service import (
|
||||
EmailService, # MOD-004 - Core email service
|
||||
EmailService, # noqa: MOD-004 - Core email service
|
||||
)
|
||||
from app.modules.tenancy.exceptions import StoreNotFoundException
|
||||
from models.schema.auth import (
|
||||
|
||||
@@ -754,7 +754,7 @@ class InventoryService:
|
||||
self, db: Session
|
||||
) -> AdminStoresWithInventoryResponse:
|
||||
"""Get list of stores that have inventory entries (admin only)."""
|
||||
# SVC-005 - Admin function, intentionally cross-store
|
||||
# noqa: SVC-005 - Admin function, intentionally cross-store
|
||||
# Use subquery to avoid DISTINCT on JSON columns (PostgreSQL can't compare JSON)
|
||||
store_ids_subquery = (
|
||||
db.query(Inventory.store_id)
|
||||
|
||||
@@ -25,8 +25,8 @@ class MarketplaceImportJobRequest(BaseModel):
|
||||
@field_validator("source_url")
|
||||
@classmethod
|
||||
def validate_url(cls, v):
|
||||
if not v.startswith(("http://", "https://")): # SEC-034
|
||||
raise ValueError("URL must start with http:// or https://") # SEC-034
|
||||
if not v.startswith(("http://", "https://")): # noqa: SEC-034
|
||||
raise ValueError("URL must start with http:// or https://") # noqa: SEC-034
|
||||
return v.strip()
|
||||
|
||||
@field_validator("marketplace")
|
||||
@@ -64,8 +64,8 @@ class AdminMarketplaceImportJobRequest(BaseModel):
|
||||
@field_validator("source_url")
|
||||
@classmethod
|
||||
def validate_url(cls, v):
|
||||
if not v.startswith(("http://", "https://")): # SEC-034
|
||||
raise ValueError("URL must start with http:// or https://") # SEC-034
|
||||
if not v.startswith(("http://", "https://")): # noqa: SEC-034
|
||||
raise ValueError("URL must start with http:// or https://") # noqa: SEC-034
|
||||
return v.strip()
|
||||
|
||||
@field_validator("marketplace")
|
||||
|
||||
@@ -865,7 +865,7 @@ class LetzshopOrderService:
|
||||
pass
|
||||
|
||||
if needs_update:
|
||||
self.db.commit() # SVC-006 - background task needs incremental commits
|
||||
self.db.commit() # noqa: SVC-006 - background task needs incremental commits
|
||||
stats["updated"] += 1
|
||||
else:
|
||||
stats["skipped"] += 1
|
||||
@@ -881,7 +881,7 @@ class LetzshopOrderService:
|
||||
# Create new order using unified service
|
||||
try:
|
||||
self.create_order(store_id, shipment)
|
||||
self.db.commit() # SVC-006 - background task needs incremental commits
|
||||
self.db.commit() # noqa: SVC-006 - background task needs incremental commits
|
||||
stats["imported"] += 1
|
||||
|
||||
# Decrement remaining count for batch efficiency
|
||||
@@ -1093,7 +1093,7 @@ class LetzshopOrderService:
|
||||
status="pending",
|
||||
)
|
||||
self.db.add(job)
|
||||
self.db.commit() # SVC-006 - job must be visible immediately before background task starts
|
||||
self.db.commit() # noqa: SVC-006 - job must be visible immediately before background task starts
|
||||
self.db.refresh(job)
|
||||
return job
|
||||
|
||||
@@ -1134,6 +1134,6 @@ class LetzshopOrderService:
|
||||
)
|
||||
if job:
|
||||
job.celery_task_id = celery_task_id
|
||||
self.db.commit() # SVC-006 - Called from API endpoint
|
||||
self.db.commit() # noqa: SVC-006 - Called from API endpoint
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -498,7 +498,7 @@ class LetzshopStoreSyncService:
|
||||
# Create store
|
||||
store = admin_service.create_store(self.db, store_data)
|
||||
|
||||
# Mark the Letzshop store as claimed (commits internally) # SVC-006
|
||||
# Mark the Letzshop store as claimed (commits internally) # noqa: SVC-006
|
||||
self.mark_store_claimed(letzshop_slug, store.id)
|
||||
|
||||
logger.info(
|
||||
|
||||
@@ -446,7 +446,7 @@ class MarketplaceProductService:
|
||||
InventorySummaryResponse if inventory found, None otherwise
|
||||
"""
|
||||
try:
|
||||
# SVC-005 - Admin/internal function for inventory lookup by GTIN
|
||||
# noqa: SVC-005 - Admin/internal function for inventory lookup by GTIN
|
||||
inventory_entries = db.query(Inventory).filter(Inventory.gtin == gtin).all()
|
||||
if not inventory_entries:
|
||||
return None
|
||||
|
||||
@@ -415,7 +415,7 @@ class PlatformSignupService:
|
||||
)
|
||||
subscription.stripe_customer_id = stripe_customer_id
|
||||
|
||||
db.commit() # SVC-006 - Atomic account creation needs commit
|
||||
db.commit() # noqa: SVC-006 - Atomic account creation needs commit
|
||||
|
||||
# Update session
|
||||
self.update_session(session_id, {
|
||||
@@ -603,7 +603,7 @@ class PlatformSignupService:
|
||||
if subscription:
|
||||
subscription.card_collected_at = datetime.now(UTC)
|
||||
subscription.stripe_payment_method_id = payment_method_id
|
||||
db.commit() # SVC-006 - Finalize signup needs commit
|
||||
db.commit() # noqa: SVC-006 - Finalize signup needs commit
|
||||
|
||||
# Get store info
|
||||
store = db.query(Store).filter(Store.id == store_id).first()
|
||||
|
||||
@@ -1336,7 +1336,7 @@ class EmailService:
|
||||
related_id=related_id,
|
||||
)
|
||||
self.db.add(log)
|
||||
self.db.commit() # SVC-006 - Email logs are side effects, commit immediately
|
||||
self.db.commit() # noqa: SVC-006 - Email logs are side effects, commit immediately
|
||||
return log
|
||||
|
||||
# Inject branding variables if requested
|
||||
@@ -1471,7 +1471,7 @@ class EmailService:
|
||||
if not email_enabled:
|
||||
log.status = EmailStatus.FAILED.value
|
||||
log.error_message = "Email sending is disabled"
|
||||
self.db.commit() # SVC-006 - Email logs are side effects, commit immediately
|
||||
self.db.commit() # noqa: SVC-006 - Email logs are side effects, commit immediately
|
||||
logger.info(f"Email sending disabled, skipping: {to_email}")
|
||||
return log
|
||||
|
||||
@@ -1497,7 +1497,7 @@ class EmailService:
|
||||
log.mark_failed(error or "Unknown error")
|
||||
logger.error(f"Email failed to {to_email}: {error}")
|
||||
|
||||
self.db.commit() # SVC-006 - Email logs are side effects, commit immediately
|
||||
self.db.commit() # noqa: SVC-006 - Email logs are side effects, commit immediately
|
||||
return log
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class BackgroundTasksService:
|
||||
|
||||
def get_running_test_runs(self, db: Session) -> list[TestRun]:
|
||||
"""Get currently running test runs"""
|
||||
# SVC-005 - Platform-level, TestRuns not store-scoped
|
||||
# noqa: SVC-005 - Platform-level, TestRuns not store-scoped
|
||||
return db.query(TestRun).filter(TestRun.status == "running").all()
|
||||
|
||||
def get_import_stats(self, db: Session) -> dict:
|
||||
|
||||
@@ -32,7 +32,7 @@ from app.modules.orders.schemas import (
|
||||
)
|
||||
from app.modules.orders.services import order_service
|
||||
from app.modules.orders.services.invoice_service import (
|
||||
invoice_service, # MOD-004 - Core invoice service
|
||||
invoice_service, # noqa: MOD-004 - Core invoice service
|
||||
)
|
||||
from app.modules.tenancy.exceptions import StoreNotFoundException
|
||||
|
||||
|
||||
@@ -1292,7 +1292,7 @@ class OrderService:
|
||||
) -> dict[str, Any]:
|
||||
"""Get shipping label information for an order (admin only)."""
|
||||
from app.modules.core.services.admin_settings_service import (
|
||||
admin_settings_service, # MOD-004
|
||||
admin_settings_service, # noqa: MOD-004
|
||||
)
|
||||
|
||||
order = db.query(Order).filter(Order.id == order_id).first()
|
||||
|
||||
@@ -103,7 +103,7 @@ class MerchantDomain(Base, TimestampMixin):
|
||||
- EXAMPLE.COM -> example.com
|
||||
"""
|
||||
# Remove protocol
|
||||
domain = domain.replace("https://", "").replace("http://", "") # SEC-034
|
||||
domain = domain.replace("https://", "").replace("http://", "") # noqa: SEC-034
|
||||
|
||||
# Remove trailing slash
|
||||
domain = domain.rstrip("/")
|
||||
|
||||
@@ -92,7 +92,7 @@ class StoreDomain(Base, TimestampMixin):
|
||||
- EXAMPLE.COM -> example.com
|
||||
"""
|
||||
# Remove protocol
|
||||
domain = domain.replace("https://", "").replace("http://", "") # SEC-034
|
||||
domain = domain.replace("https://", "").replace("http://", "") # noqa: SEC-034
|
||||
|
||||
# Remove trailing slash
|
||||
domain = domain.rstrip("/")
|
||||
|
||||
@@ -100,7 +100,7 @@ def _build_module_response(
|
||||
is_enabled: bool,
|
||||
) -> ModuleResponse:
|
||||
"""Build ModuleResponse from module code."""
|
||||
from app.modules.enums import FrontendType # API-007 - Enum for type safety
|
||||
from app.modules.enums import FrontendType # noqa: API-007 - Enum for type safety
|
||||
|
||||
module = MODULES.get(code)
|
||||
if not module:
|
||||
|
||||
@@ -22,7 +22,7 @@ from app.api.deps import get_current_super_admin, get_current_super_admin_api
|
||||
from app.core.database import get_db
|
||||
from app.exceptions import ValidationException
|
||||
from app.modules.tenancy.models import (
|
||||
User, # API-007 - Internal helper uses User model
|
||||
User, # noqa: API-007 - Internal helper uses User model
|
||||
)
|
||||
from app.modules.tenancy.services.admin_platform_service import admin_platform_service
|
||||
from models.schema.auth import UserContext
|
||||
|
||||
@@ -18,7 +18,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.modules.tenancy.schemas.store import StoreDetailResponse
|
||||
from app.modules.tenancy.services.store_service import store_service # mod-004
|
||||
from app.modules.tenancy.services.store_service import store_service # noqa: mod-004
|
||||
|
||||
store_router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -34,7 +34,7 @@ class MerchantDomainCreate(BaseModel):
|
||||
def validate_domain(cls, v: str) -> str:
|
||||
"""Validate and normalize domain."""
|
||||
# Remove protocol if present
|
||||
domain = v.replace("https://", "").replace("http://", "") # SEC-034
|
||||
domain = v.replace("https://", "").replace("http://", "") # noqa: SEC-034
|
||||
|
||||
# Remove trailing slash
|
||||
domain = domain.rstrip("/")
|
||||
|
||||
@@ -35,7 +35,7 @@ class StoreDomainCreate(BaseModel):
|
||||
def validate_domain(cls, v: str) -> str:
|
||||
"""Validate and normalize domain."""
|
||||
# Remove protocol if present
|
||||
domain = v.replace("https://", "").replace("http://", "") # SEC-034
|
||||
domain = v.replace("https://", "").replace("http://", "") # noqa: SEC-034
|
||||
|
||||
# Remove trailing slash
|
||||
domain = domain.rstrip("/")
|
||||
|
||||
@@ -502,6 +502,6 @@ class AuthManager:
|
||||
db.refresh(admin_user)
|
||||
|
||||
# Log creation for audit trail (credentials redacted for security)
|
||||
logger.info("Default admin user created") # sec-001 sec-021
|
||||
logger.info("Default admin user created") # noqa: sec-001 sec-021
|
||||
|
||||
return admin_user
|
||||
|
||||
@@ -18,6 +18,7 @@ include = ["app*", "models*", "middleware*", "storage*"]
|
||||
line-length = 88
|
||||
target-version = "py311"
|
||||
|
||||
|
||||
# Exclude directories
|
||||
exclude = [
|
||||
".git",
|
||||
@@ -34,6 +35,9 @@ exclude = [
|
||||
]
|
||||
|
||||
[tool.ruff.lint]
|
||||
# Allow custom architecture validator codes in # noqa directives (e.g., SEC-034, SVC-006)
|
||||
external = ["SEC", "SVC", "MOD", "API", "ARCH", "PERF"]
|
||||
|
||||
# Enable comprehensive rule sets
|
||||
select = [
|
||||
"E", # pycodestyle errors
|
||||
|
||||
Reference in New Issue
Block a user