From 79c985ee39da29d6008f904dd50359ab107b7bc1 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Thu, 12 Feb 2026 23:24:57 +0100 Subject: [PATCH] fix(lint): use plain comments for architecture validator codes Replace # noqa: SVC-006 with # SVC-006 to avoid ruff warnings about unknown codes. Updated architecture validators to match the new format by checking for the code string directly instead of the noqa: prefix. Co-Authored-By: Claude Opus 4.6 --- app/modules/analytics/routes/pages/store.py | 2 +- app/modules/checkout/routes/api/storefront.py | 2 +- app/modules/cms/routes/api/store_content_pages.py | 2 +- app/modules/cms/routes/pages/store.py | 2 +- app/modules/core/routes/api/admin_menu_config.py | 2 +- app/modules/core/services/auth_service.py | 4 ++-- .../core/services/platform_settings_service.py | 2 +- app/modules/customers/routes/api/storefront.py | 4 ++-- app/modules/inventory/services/inventory_service.py | 2 +- .../marketplace/schemas/marketplace_import_job.py | 8 ++++---- .../marketplace/services/letzshop/order_service.py | 8 ++++---- .../services/letzshop/store_sync_service.py | 2 +- .../services/marketplace_product_service.py | 2 +- .../marketplace/services/platform_signup_service.py | 4 ++-- app/modules/messaging/services/email_service.py | 6 +++--- .../monitoring/services/background_tasks_service.py | 2 +- app/modules/orders/routes/api/storefront.py | 2 +- app/modules/orders/services/order_service.py | 2 +- app/modules/tenancy/models/merchant_domain.py | 2 +- app/modules/tenancy/models/store_domain.py | 2 +- app/modules/tenancy/routes/api/admin_modules.py | 2 +- app/modules/tenancy/routes/api/admin_users.py | 2 +- app/modules/tenancy/routes/api/store.py | 2 +- app/modules/tenancy/schemas/merchant_domain.py | 2 +- app/modules/tenancy/schemas/store_domain.py | 2 +- middleware/auth.py | 2 +- pyproject.toml | 3 --- scripts/validate/validate_architecture.py | 12 ++++++------ 28 files changed, 43 insertions(+), 46 deletions(-) diff --git a/app/modules/analytics/routes/pages/store.py b/app/modules/analytics/routes/pages/store.py index 81126baf..2f7f5ddb 100644 --- a/app/modules/analytics/routes/pages/store.py +++ b/app/modules/analytics/routes/pages/store.py @@ -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, # noqa: MOD-004 - shared platform service + platform_settings_service, # MOD-004 - shared platform service ) from app.modules.tenancy.models import Store, User from app.templates_config import templates diff --git a/app/modules/checkout/routes/api/storefront.py b/app/modules/checkout/routes/api/storefront.py index 8138c340..1c8fe66e 100644 --- a/app/modules/checkout/routes/api/storefront.py +++ b/app/modules/checkout/routes/api/storefront.py @@ -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, # noqa: MOD-004 - Core email service + EmailService, # MOD-004 - Core email service ) from app.modules.orders.schemas import OrderCreate, OrderResponse from app.modules.orders.services import order_service diff --git a/app/modules/cms/routes/api/store_content_pages.py b/app/modules/cms/routes/api/store_content_pages.py index 802cd8b1..f6245725 100644 --- a/app/modules/cms/routes/api/store_content_pages.py +++ b/app/modules/cms/routes/api/store_content_pages.py @@ -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, # noqa: MOD-004 - shared platform service + StoreService, # MOD-004 - shared platform service ) store_service = StoreService() diff --git a/app/modules/cms/routes/pages/store.py b/app/modules/cms/routes/pages/store.py index d27a3b50..ae62be51 100644 --- a/app/modules/cms/routes/pages/store.py +++ b/app/modules/cms/routes/pages/store.py @@ -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, # noqa: MOD-004 - shared platform service + platform_settings_service, # MOD-004 - shared platform service ) from app.modules.tenancy.models import Store, User from app.templates_config import templates diff --git a/app/modules/core/routes/api/admin_menu_config.py b/app/modules/core/routes/api/admin_menu_config.py index 725e2313..28c4d24a 100644 --- a/app/modules/core/routes/api/admin_menu_config.py +++ b/app/modules/core/routes/api/admin_menu_config.py @@ -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 # noqa: API-007 - Enum for type safety +from app.modules.enums import FrontendType # 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 diff --git a/app/modules/core/services/auth_service.py b/app/modules/core/services/auth_service.py index 11adf758..b2dfeec1 100644 --- a/app/modules/core/services/auth_service.py +++ b/app/modules/core/services/auth_service.py @@ -61,7 +61,7 @@ class AuthService: # Update last_login timestamp user.last_login = datetime.now(UTC) - db.commit() # noqa: SVC-006 - Login must persist last_login timestamp + db.commit() # 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() # noqa: SVC-006 - Login must persist last_login timestamp + db.commit() # SVC-006 - Login must persist last_login timestamp token_data = self.auth_manager.create_access_token(user) diff --git a/app/modules/core/services/platform_settings_service.py b/app/modules/core/services/platform_settings_service.py index dc9fec88..f4e03143 100644 --- a/app/modules/core/services/platform_settings_service.py +++ b/app/modules/core/services/platform_settings_service.py @@ -133,7 +133,7 @@ class PlatformSettingsService: ) db.add(admin_setting) - db.commit() # noqa: SVC-006 - Setting change is atomic, commit is intentional + db.commit() # 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}") diff --git a/app/modules/customers/routes/api/storefront.py b/app/modules/customers/routes/api/storefront.py index de43854d..efff4e03 100644 --- a/app/modules/customers/routes/api/storefront.py +++ b/app/modules/customers/routes/api/storefront.py @@ -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, # noqa: MOD-004 - Core auth service + AuthService, # 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, # noqa: MOD-004 - Core email service + EmailService, # MOD-004 - Core email service ) from app.modules.tenancy.exceptions import StoreNotFoundException from models.schema.auth import ( diff --git a/app/modules/inventory/services/inventory_service.py b/app/modules/inventory/services/inventory_service.py index 2366392b..957c9153 100644 --- a/app/modules/inventory/services/inventory_service.py +++ b/app/modules/inventory/services/inventory_service.py @@ -754,7 +754,7 @@ class InventoryService: self, db: Session ) -> AdminStoresWithInventoryResponse: """Get list of stores that have inventory entries (admin only).""" - # noqa: SVC-005 - Admin function, intentionally cross-store + # 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) diff --git a/app/modules/marketplace/schemas/marketplace_import_job.py b/app/modules/marketplace/schemas/marketplace_import_job.py index a1d43874..966ab8b2 100644 --- a/app/modules/marketplace/schemas/marketplace_import_job.py +++ b/app/modules/marketplace/schemas/marketplace_import_job.py @@ -25,8 +25,8 @@ class MarketplaceImportJobRequest(BaseModel): @field_validator("source_url") @classmethod def validate_url(cls, v): - if not v.startswith(("http://", "https://")): # noqa: SEC-034 - raise ValueError("URL must start with http:// or https://") # noqa: SEC-034 + if not v.startswith(("http://", "https://")): # SEC-034 + raise ValueError("URL must start with http:// or https://") # 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://")): # noqa: SEC-034 - raise ValueError("URL must start with http:// or https://") # noqa: SEC-034 + if not v.startswith(("http://", "https://")): # SEC-034 + raise ValueError("URL must start with http:// or https://") # SEC-034 return v.strip() @field_validator("marketplace") diff --git a/app/modules/marketplace/services/letzshop/order_service.py b/app/modules/marketplace/services/letzshop/order_service.py index 19c57c5c..d5caa243 100644 --- a/app/modules/marketplace/services/letzshop/order_service.py +++ b/app/modules/marketplace/services/letzshop/order_service.py @@ -865,7 +865,7 @@ class LetzshopOrderService: pass if needs_update: - self.db.commit() # noqa: SVC-006 - background task needs incremental commits + self.db.commit() # 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() # noqa: SVC-006 - background task needs incremental commits + self.db.commit() # 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() # noqa: SVC-006 - job must be visible immediately before background task starts + self.db.commit() # 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() # noqa: SVC-006 - Called from API endpoint + self.db.commit() # SVC-006 - Called from API endpoint return True return False diff --git a/app/modules/marketplace/services/letzshop/store_sync_service.py b/app/modules/marketplace/services/letzshop/store_sync_service.py index 8e5a064f..328b35ae 100644 --- a/app/modules/marketplace/services/letzshop/store_sync_service.py +++ b/app/modules/marketplace/services/letzshop/store_sync_service.py @@ -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) # noqa: SVC-006 + # Mark the Letzshop store as claimed (commits internally) # SVC-006 self.mark_store_claimed(letzshop_slug, store.id) logger.info( diff --git a/app/modules/marketplace/services/marketplace_product_service.py b/app/modules/marketplace/services/marketplace_product_service.py index cc315f9d..fceafa8a 100644 --- a/app/modules/marketplace/services/marketplace_product_service.py +++ b/app/modules/marketplace/services/marketplace_product_service.py @@ -446,7 +446,7 @@ class MarketplaceProductService: InventorySummaryResponse if inventory found, None otherwise """ try: - # noqa: SVC-005 - Admin/internal function for inventory lookup by GTIN + # 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 diff --git a/app/modules/marketplace/services/platform_signup_service.py b/app/modules/marketplace/services/platform_signup_service.py index f3ca3045..7e8908e5 100644 --- a/app/modules/marketplace/services/platform_signup_service.py +++ b/app/modules/marketplace/services/platform_signup_service.py @@ -415,7 +415,7 @@ class PlatformSignupService: ) subscription.stripe_customer_id = stripe_customer_id - db.commit() # noqa: SVC-006 - Atomic account creation needs commit + db.commit() # 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() # noqa: SVC-006 - Finalize signup needs commit + db.commit() # SVC-006 - Finalize signup needs commit # Get store info store = db.query(Store).filter(Store.id == store_id).first() diff --git a/app/modules/messaging/services/email_service.py b/app/modules/messaging/services/email_service.py index 4d387fcc..4b06ea44 100644 --- a/app/modules/messaging/services/email_service.py +++ b/app/modules/messaging/services/email_service.py @@ -1336,7 +1336,7 @@ class EmailService: related_id=related_id, ) self.db.add(log) - self.db.commit() # noqa: SVC-006 - Email logs are side effects, commit immediately + self.db.commit() # 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() # noqa: SVC-006 - Email logs are side effects, commit immediately + self.db.commit() # 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() # noqa: SVC-006 - Email logs are side effects, commit immediately + self.db.commit() # SVC-006 - Email logs are side effects, commit immediately return log diff --git a/app/modules/monitoring/services/background_tasks_service.py b/app/modules/monitoring/services/background_tasks_service.py index abbb0e8d..518c4f94 100644 --- a/app/modules/monitoring/services/background_tasks_service.py +++ b/app/modules/monitoring/services/background_tasks_service.py @@ -44,7 +44,7 @@ class BackgroundTasksService: def get_running_test_runs(self, db: Session) -> list[TestRun]: """Get currently running test runs""" - # noqa: SVC-005 - Platform-level, TestRuns not store-scoped + # 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: diff --git a/app/modules/orders/routes/api/storefront.py b/app/modules/orders/routes/api/storefront.py index 8e174cb7..1ad26f07 100644 --- a/app/modules/orders/routes/api/storefront.py +++ b/app/modules/orders/routes/api/storefront.py @@ -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, # noqa: MOD-004 - Core invoice service + invoice_service, # MOD-004 - Core invoice service ) from app.modules.tenancy.exceptions import StoreNotFoundException diff --git a/app/modules/orders/services/order_service.py b/app/modules/orders/services/order_service.py index 75d52f6e..d72d62bf 100644 --- a/app/modules/orders/services/order_service.py +++ b/app/modules/orders/services/order_service.py @@ -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, # noqa: MOD-004 + admin_settings_service, # MOD-004 ) order = db.query(Order).filter(Order.id == order_id).first() diff --git a/app/modules/tenancy/models/merchant_domain.py b/app/modules/tenancy/models/merchant_domain.py index 9e6814e4..62603714 100644 --- a/app/modules/tenancy/models/merchant_domain.py +++ b/app/modules/tenancy/models/merchant_domain.py @@ -103,7 +103,7 @@ class MerchantDomain(Base, TimestampMixin): - EXAMPLE.COM -> example.com """ # Remove protocol - domain = domain.replace("https://", "").replace("http://", "") # noqa: SEC-034 + domain = domain.replace("https://", "").replace("http://", "") # SEC-034 # Remove trailing slash domain = domain.rstrip("/") diff --git a/app/modules/tenancy/models/store_domain.py b/app/modules/tenancy/models/store_domain.py index 40fd1c73..4f024638 100644 --- a/app/modules/tenancy/models/store_domain.py +++ b/app/modules/tenancy/models/store_domain.py @@ -92,7 +92,7 @@ class StoreDomain(Base, TimestampMixin): - EXAMPLE.COM -> example.com """ # Remove protocol - domain = domain.replace("https://", "").replace("http://", "") # noqa: SEC-034 + domain = domain.replace("https://", "").replace("http://", "") # SEC-034 # Remove trailing slash domain = domain.rstrip("/") diff --git a/app/modules/tenancy/routes/api/admin_modules.py b/app/modules/tenancy/routes/api/admin_modules.py index 4f7a5b4e..c942b79e 100644 --- a/app/modules/tenancy/routes/api/admin_modules.py +++ b/app/modules/tenancy/routes/api/admin_modules.py @@ -100,7 +100,7 @@ def _build_module_response( is_enabled: bool, ) -> ModuleResponse: """Build ModuleResponse from module code.""" - from app.modules.enums import FrontendType # noqa: API-007 - Enum for type safety + from app.modules.enums import FrontendType # API-007 - Enum for type safety module = MODULES.get(code) if not module: diff --git a/app/modules/tenancy/routes/api/admin_users.py b/app/modules/tenancy/routes/api/admin_users.py index 8610ec7f..d7a520bd 100644 --- a/app/modules/tenancy/routes/api/admin_users.py +++ b/app/modules/tenancy/routes/api/admin_users.py @@ -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, # noqa: API-007 - Internal helper uses User model + User, # 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 diff --git a/app/modules/tenancy/routes/api/store.py b/app/modules/tenancy/routes/api/store.py index cf4db2f0..c72554cf 100644 --- a/app/modules/tenancy/routes/api/store.py +++ b/app/modules/tenancy/routes/api/store.py @@ -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 # noqa: mod-004 +from app.modules.tenancy.services.store_service import store_service # mod-004 store_router = APIRouter() logger = logging.getLogger(__name__) diff --git a/app/modules/tenancy/schemas/merchant_domain.py b/app/modules/tenancy/schemas/merchant_domain.py index dc24fd22..a5eee29b 100644 --- a/app/modules/tenancy/schemas/merchant_domain.py +++ b/app/modules/tenancy/schemas/merchant_domain.py @@ -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://", "") # noqa: SEC-034 + domain = v.replace("https://", "").replace("http://", "") # SEC-034 # Remove trailing slash domain = domain.rstrip("/") diff --git a/app/modules/tenancy/schemas/store_domain.py b/app/modules/tenancy/schemas/store_domain.py index fde0b12f..c4319bd5 100644 --- a/app/modules/tenancy/schemas/store_domain.py +++ b/app/modules/tenancy/schemas/store_domain.py @@ -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://", "") # noqa: SEC-034 + domain = v.replace("https://", "").replace("http://", "") # SEC-034 # Remove trailing slash domain = domain.rstrip("/") diff --git a/middleware/auth.py b/middleware/auth.py index fd7be9d8..cc22c216 100644 --- a/middleware/auth.py +++ b/middleware/auth.py @@ -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") # noqa: sec-001 sec-021 + logger.info("Default admin user created") # sec-001 sec-021 return admin_user diff --git a/pyproject.toml b/pyproject.toml index c23f5896..599a18de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,9 +35,6 @@ 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 diff --git a/scripts/validate/validate_architecture.py b/scripts/validate/validate_architecture.py index 80953b77..49b655cb 100755 --- a/scripts/validate/validate_architecture.py +++ b/scripts/validate/validate_architecture.py @@ -2086,7 +2086,7 @@ class ArchitectureValidator: return # Check for noqa - if "noqa: api-007" in content.lower(): + if "api-007" in content.lower(): return # Patterns that indicate direct model imports @@ -2102,7 +2102,7 @@ class ArchitectureValidator: continue # Check for noqa on this specific line - if "noqa: api-007" in line.lower(): + if "api-007" in line.lower(): continue for pattern, message in model_import_patterns: @@ -2291,7 +2291,7 @@ class ArchitectureValidator: return # Check for file-level noqa comment - if "noqa: svc-006" in content.lower(): + if "svc-006" in content.lower(): return for i, line in enumerate(lines, 1): @@ -2302,7 +2302,7 @@ class ArchitectureValidator: continue # Skip if line has inline noqa comment - if "noqa: svc-006" in line.lower(): + if "svc-006" in line.lower(): continue self._add_violation( @@ -2313,7 +2313,7 @@ class ArchitectureValidator: line_number=i, message="Service calls db.commit() - transaction control should be at endpoint level", context=stripped, - suggestion="Remove db.commit() from service; let endpoint handle transaction. For background tasks, add # noqa: SVC-006", + suggestion="Remove db.commit() from service; let endpoint handle transaction. For background tasks, add # SVC-006", ) def _validate_models(self, target_path: Path): @@ -4097,7 +4097,7 @@ class ArchitectureValidator: for i, line in enumerate(lines, 1): if "from app.services." in line: # Skip if line has noqa comment - if "noqa: mod-004" in line.lower(): + if "mod-004" in line.lower(): continue self._add_violation( rule_id="MOD-004",