All checks were successful
- Add 55 unit tests for hosting module (hosted site service, client service service, stats service) with full fixture setup - Fix table_empty_state macro: add x_message param for dynamic Alpine.js expressions rendered via x-text instead of server-side Jinja - Fix hosting templates (sites, clients) using message= with Alpine expressions that rendered as literal text - Fix prospecting templates (leads, scan-jobs, prospects) using nonexistent subtitle= param, migrated to x_message= - Align hosting and prospecting admin templates with shared design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
281 lines
10 KiB
TOML
281 lines
10 KiB
TOML
[build-system]
|
|
requires = ["setuptools>=45", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "letzshop-product-import"
|
|
version = "0.1.0"
|
|
description = "Multi-tenant e-commerce marketplace platform"
|
|
requires-python = ">=3.11"
|
|
|
|
[tool.setuptools.packages.find]
|
|
include = ["app*", "models*", "middleware*", "storage*"]
|
|
|
|
# =============================================================================
|
|
# RUFF - Modern All-in-One Linter & Formatter
|
|
# =============================================================================
|
|
[tool.ruff]
|
|
line-length = 88
|
|
target-version = "py311"
|
|
|
|
|
|
# Exclude directories
|
|
exclude = [
|
|
".git",
|
|
".venv",
|
|
"venv",
|
|
"__pycache__",
|
|
".mypy_cache",
|
|
".pytest_cache",
|
|
".ruff_cache",
|
|
"build",
|
|
"dist",
|
|
"alembic/versions",
|
|
"scripts/rename_terminology.py",
|
|
]
|
|
|
|
[tool.ruff.lint]
|
|
# Enable comprehensive rule sets
|
|
select = [
|
|
"E", # pycodestyle errors
|
|
"W", # pycodestyle warnings
|
|
"F", # pyflakes
|
|
"I", # isort (import sorting)
|
|
"N", # pep8-naming
|
|
"UP", # pyupgrade (modern Python syntax)
|
|
"B", # flake8-bugbear (common bugs)
|
|
"C4", # flake8-comprehensions
|
|
"SIM", # flake8-simplify
|
|
"PIE", # flake8-pie
|
|
"RET", # flake8-return
|
|
"Q", # flake8-quotes
|
|
]
|
|
|
|
# Ignore specific rules
|
|
ignore = [
|
|
"E402", # module level import not at top — late imports used for circular import avoidance
|
|
"E501", # line too long (handled by formatter)
|
|
"E711", # comparison to None — intentional in SQLAlchemy filters
|
|
"E712", # comparison to True/False — intentional in SQLAlchemy filters (e.g. col == True)
|
|
"E722", # bare except — TODO: fix incrementally
|
|
"B008", # do not perform function calls in argument defaults (FastAPI Depends)
|
|
"B904", # raise from — TODO: fix incrementally
|
|
"RET504", # unnecessary variable assignment before return
|
|
"SIM102", # use a single if statement instead of nested if (sometimes less readable)
|
|
"SIM105", # use contextlib.suppress — less readable in some cases
|
|
"SIM108", # use ternary operator — less readable in some cases
|
|
"SIM117", # combine with statements — less readable in some cases
|
|
"N806", # variable in function should be lowercase — intentional for constants
|
|
"N817", # CamelCase imported as acronym — intentional shorthand
|
|
"N803", # argument name should be lowercase — required by external APIs (e.g. Apple Wallet)
|
|
"N818", # exception name should end with Error — existing convention
|
|
"F821", # undefined name — false positives on forward-reference type hints
|
|
"F822", # undefined name in __all__ — lazy-loaded module attributes
|
|
"UP042", # str+Enum → StrEnum — requires Python 3.11+ migration, do incrementally
|
|
]
|
|
|
|
# External linter codes used in # noqa comments (architecture/security/performance validators)
|
|
external = ["SEC", "PERF", "MOD", "EXC"]
|
|
|
|
# Allow autofix for all rules
|
|
fixable = ["ALL"]
|
|
unfixable = []
|
|
|
|
# Per-file ignores
|
|
[tool.ruff.lint.per-file-ignores]
|
|
# Ignore import violations in __init__.py files (re-exports)
|
|
"__init__.py" = ["F401", "F403"]
|
|
# Base files that re-export (re-export Base from core.database)
|
|
"models/database/base.py" = ["F401"]
|
|
# Test files: late imports, unused imports, naming, assertions
|
|
"tests/**/*.py" = ["S101", "PLR2004", "E402", "F401", "F821", "F822", "N806", "N817", "N818", "B007", "B015", "B017"]
|
|
"app/modules/*/tests/**/*.py" = ["S101", "PLR2004", "E402", "F401", "F821", "F822", "N806", "N817", "N818", "B007", "B015", "B017"]
|
|
# Alembic migrations can have longer lines and specific patterns
|
|
"alembic/versions/*.py" = ["E501", "F401"]
|
|
# Scripts: late imports, intentional import-for-side-effect checks, loop vars, syntax
|
|
"scripts/**/*.py" = ["E402", "F401", "I001", "B007", "B015", "B024", "B027"]
|
|
"scripts/rename_terminology.py" = ["ALL"]
|
|
|
|
# Import sorting configuration (replaces isort)
|
|
[tool.ruff.lint.isort]
|
|
known-first-party = ["app", "models", "middleware", "tasks", "storage", "scripts"]
|
|
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
split-on-trailing-comma = true
|
|
|
|
# Formatter configuration (replaces black)
|
|
[tool.ruff.format]
|
|
quote-style = "double"
|
|
indent-style = "space"
|
|
skip-magic-trailing-comma = false
|
|
line-ending = "auto"
|
|
|
|
# =============================================================================
|
|
# MYPY - Static Type Checker
|
|
# =============================================================================
|
|
[tool.mypy]
|
|
python_version = "3.11"
|
|
warn_return_any = true
|
|
warn_unused_configs = true
|
|
disallow_untyped_defs = false
|
|
ignore_missing_imports = true
|
|
exclude = [
|
|
"^\\.venv/",
|
|
"^venv/",
|
|
"^build/",
|
|
"^dist/",
|
|
"^alembic/versions/",
|
|
]
|
|
|
|
# Per-module options
|
|
[[tool.mypy.overrides]]
|
|
module = "tests.*"
|
|
ignore_errors = true
|
|
|
|
[[tool.mypy.overrides]]
|
|
module = "alembic.*"
|
|
ignore_errors = true
|
|
|
|
# =============================================================================
|
|
# PYTEST - Testing
|
|
# =============================================================================
|
|
[tool.pytest.ini_options]
|
|
minversion = "7.0"
|
|
testpaths = [
|
|
"tests",
|
|
"app/modules/tenancy/tests",
|
|
"app/modules/catalog/tests",
|
|
"app/modules/billing/tests",
|
|
"app/modules/messaging/tests",
|
|
"app/modules/orders/tests",
|
|
"app/modules/customers/tests",
|
|
"app/modules/marketplace/tests",
|
|
"app/modules/inventory/tests",
|
|
"app/modules/loyalty/tests",
|
|
"app/modules/cms/tests",
|
|
"app/modules/core/tests",
|
|
"app/modules/payments/tests",
|
|
"app/modules/checkout/tests",
|
|
"app/modules/cart/tests",
|
|
"app/modules/dev_tools/tests",
|
|
"app/modules/monitoring/tests",
|
|
"app/modules/analytics/tests",
|
|
"app/modules/prospecting/tests",
|
|
"app/modules/hosting/tests",
|
|
]
|
|
python_files = ["test_*.py", "*_test.py"]
|
|
python_classes = ["Test*"]
|
|
python_functions = ["test_*"]
|
|
addopts = [
|
|
"-v",
|
|
"--tb=short",
|
|
"--strict-markers",
|
|
"--strict-config",
|
|
"--color=yes",
|
|
"--durations=10",
|
|
"--showlocals",
|
|
"-ra",
|
|
"--cov=app",
|
|
"--cov=models",
|
|
"--cov=middleware",
|
|
"--cov-report=term-missing",
|
|
"--cov-report=html:htmlcov",
|
|
"--cov-fail-under=0", # Temporarily disabled during test rebuild
|
|
]
|
|
markers = [
|
|
# Test level markers
|
|
"unit: marks tests as unit tests - fast, isolated components",
|
|
"integration: marks tests as integration tests - multiple components working together",
|
|
"system: marks tests as system tests - full application behavior",
|
|
"e2e: marks tests as end-to-end tests - complete user workflows",
|
|
"slow: marks tests as slow running tests (deselect with '-m \"not slow\"')",
|
|
"performance: marks tests as performance and load tests",
|
|
# Context markers
|
|
"auth: marks tests as authentication and authorization tests",
|
|
"products: marks tests as product management functionality",
|
|
"inventory: marks tests as inventory and stock management",
|
|
"stores: marks tests as store management (plural - admin context)",
|
|
"store: marks tests as store API tests (singular - store context)",
|
|
"admin: marks tests as admin functionality and permissions",
|
|
"marketplace: marks tests as marketplace import functionality",
|
|
"stats: marks tests as statistics and reporting",
|
|
"database: marks tests as tests that require database operations",
|
|
"external: marks tests as tests that require external services",
|
|
"api: marks tests as API endpoint tests",
|
|
"security: marks tests as security-related tests",
|
|
"ci: marks tests as tests that should only run in CI",
|
|
"dev: marks tests as development-specific tests",
|
|
# Module markers
|
|
"loyalty: marks tests related to loyalty program module",
|
|
"billing: marks tests related to billing and subscriptions module",
|
|
"tenancy: marks tests related to multi-tenancy and store isolation",
|
|
"orders: marks tests related to order management",
|
|
"customers: marks tests related to customer management",
|
|
"catalog: marks tests related to product catalog",
|
|
"messaging: marks tests related to email and messaging",
|
|
"letzshop: marks tests related to Letzshop marketplace integration",
|
|
"cms: marks tests related to content management system",
|
|
"core: marks tests related to core platform services",
|
|
"payments: marks tests related to payment processing",
|
|
"monitoring: marks tests related to monitoring and observability",
|
|
"storefront: marks tests for storefront/customer-facing context",
|
|
"platform: marks tests related to platform administration",
|
|
"checkout: marks tests related to checkout module",
|
|
"cart: marks tests related to shopping cart module",
|
|
"dev_tools: marks tests related to developer tools module",
|
|
"analytics: marks tests related to analytics module",
|
|
"prospecting: marks tests related to prospecting and lead generation module",
|
|
"hosting: marks tests related to hosting and POC website module",
|
|
"inventory_module: marks tests related to inventory module",
|
|
# Component markers
|
|
"service: marks tests for service layer",
|
|
"schema: marks tests for Pydantic schemas and database models",
|
|
"middleware: marks tests for middleware components",
|
|
"task: marks tests for background tasks",
|
|
"email: marks tests involving email functionality",
|
|
"invoice: marks tests for invoicing",
|
|
"features: marks tests for feature flags",
|
|
"context: marks tests for context/scope handling",
|
|
"modules: marks tests for module system",
|
|
"utils: marks tests for utility functions",
|
|
]
|
|
filterwarnings = [
|
|
"ignore::UserWarning",
|
|
"ignore::DeprecationWarning",
|
|
"ignore::PendingDeprecationWarning",
|
|
"ignore::sqlalchemy.exc.SAWarning",
|
|
]
|
|
timeout = 300
|
|
timeout_method = "thread"
|
|
log_cli = true
|
|
log_cli_level = "INFO"
|
|
log_cli_format = "%(asctime)s [%(levelname)8s] %(name)s: %(message)s"
|
|
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
|
|
|
|
# =============================================================================
|
|
# COVERAGE
|
|
# =============================================================================
|
|
[tool.coverage.run]
|
|
source = ["app", "models", "middleware", "tasks", "storage"]
|
|
omit = [
|
|
"*/tests/*",
|
|
"*/__pycache__/*",
|
|
"*/venv/*",
|
|
"*/.venv/*",
|
|
"*/alembic/*",
|
|
"*/scripts/*",
|
|
]
|
|
|
|
[tool.coverage.report]
|
|
precision = 2
|
|
show_missing = true
|
|
skip_covered = false
|
|
exclude_lines = [
|
|
"pragma: no cover",
|
|
"def __repr__",
|
|
"raise AssertionError",
|
|
"raise NotImplementedError",
|
|
"if __name__ == .__main__.:",
|
|
"if TYPE_CHECKING:",
|
|
"if typing.TYPE_CHECKING:",
|
|
]
|