Close the gaps between the documented contract (API-STANDARD, TENANCY, ENTITLEMENTS) and the implementation, and remove committed build artifacts. Security: - verify + process inbound webhooks (HMAC/handler verify, size limit, timestamp tolerance, idempotency via InboundEvent.external_id) - real 2FA login flow (pre-auth challenge; tokens only after verify/recovery) - wire HybridPermission into security/audit views; add API-key rotate and users/<id>/permissions|roles endpoints - tenant-scoped throttling on by default; webhook replay protection - verify MercadoPago webhook signatures - login brute-force guard, configurable password policy, real ALTCHA PoW Correctness: - apply verified billing webhooks idempotently (subscription/entitlement/ invoice/PaymentTransaction); scheduled payment lifecycle jobs - capture audit update diffs automatically; add audit retention purge - working notification retries, per-channel rate limits, log retention - pluggable virus scanner, upload-size limit, pipeline toggle - feature rollout %/environment targeting; settings-driven registrations - workflow guards (instance cap, route depth, self-assignment, clone on re-entry) - wire every previously-dead INFRASYNTH_* setting; drop truly dead ones Delivery: - README + CHANGELOG; CI format check + coverage gate - keep test media out of the tree; untrack .coverage, __pycache__, egg-info, docs/ and invoice artifacts
131 lines
4.1 KiB
TOML
131 lines
4.1 KiB
TOML
[project]
|
|
name = "infrasynth-base"
|
|
version = "1.0.0"
|
|
description = "InfraSynth Base — reusable Django infrastructure kit"
|
|
requires-python = ">=3.12"
|
|
license = { text = "MIT" }
|
|
|
|
dependencies = [
|
|
"django>=5.2,<6.0", # the framework the whole kit targets
|
|
"djangorestframework>=3.16,<4.0", # API layer, viewsets, serializers
|
|
"django-cors-headers>=4.7", # CORS for the SPA frontends
|
|
"djangorestframework-simplejwt>=5.5", # JWT minting/validation behind the cookie auth
|
|
"djangorestframework-camel-case>=1.4", # wire-format camelCase (API-STANDARD §3)
|
|
"drf-spectacular>=0.28", # live OpenAPI schema at /api/v1/schema/ (API-STANDARD §12)
|
|
"django-filter>=25.1", # per-view FilterSets
|
|
"psycopg2-binary>=2.9", # PostgreSQL driver
|
|
"python-dotenv>=1.0", # local .env loading
|
|
"cryptography>=44.0", # Fernet encryption for secrets at rest
|
|
"pydantic>=2.0", # settings/validation helpers
|
|
"pyotp>=2.10", # TOTP 2FA
|
|
"qrcode[pil]>=8.1", # 2FA provisioning QR codes
|
|
"celery[redis]>=5.4", # background tasks
|
|
"django-celery-results>=2.5", # Celery result backend models
|
|
"django-celery-beat>=2.7", # periodic task scheduling
|
|
"boto3>=1.35", # S3 storage backend
|
|
"django-storages>=1.14", # cloud storage backends (S3/GCS)
|
|
"Pillow>=11.0", # image processing pipelines
|
|
"reportlab>=4.2", # invoice PDF generation
|
|
"twilio>=9.0", # SMS notification channel
|
|
"stripe>=10.0", # Stripe payment gateway
|
|
"mercadopago>=3.0", # MercadoPago payment gateway
|
|
"requests>=2.32", # outbound webhook delivery
|
|
"flower>=2.0", # Celery monitoring dashboard
|
|
"gunicorn>=23.0", # production WSGI server
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
dev = [
|
|
"pytest>=8.0",
|
|
"pytest-django>=4.8",
|
|
"pytest-cov>=5.0",
|
|
"factory-boy>=3.3",
|
|
"faker>=28.0",
|
|
"ruff>=0.6",
|
|
"mypy>=1.11",
|
|
"pre-commit>=3.8",
|
|
"django-stubs[compatible-mypy]>=5.2",
|
|
"djangorestframework-stubs[compatible-mypy]>=3.16",
|
|
"types-requests",
|
|
"hypothesis>=6.0", # property tests for time/token/billing math (AGENTS §11)
|
|
"schemathesis>=3.0", # contract tests against the live OpenAPI schema (API-STANDARD §15)
|
|
]
|
|
# Enable with INFRASYNTH_FILES["VIRUS_SCANNER"]="clamav".
|
|
clamav = ["clamd>=0.5"] # ClamAV client for the files virus-scan step
|
|
|
|
[tool.setuptools.packages.find]
|
|
include = ["infrasynth*"]
|
|
|
|
[tool.setuptools.package-data]
|
|
infrasynth = ["**/*.py", "**/migrations/*.py"]
|
|
|
|
[tool.ruff]
|
|
target-version = "py312"
|
|
line-length = 120
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "N", "W", "UP"]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"**/migrations/*.py" = ["E501"]
|
|
"config/settings/*.py" = ["F403", "F405"]
|
|
|
|
[tool.ruff.format]
|
|
quote-style = "double"
|
|
|
|
[tool.mypy]
|
|
python_version = "3.12"
|
|
plugins = ["mypy_django_plugin.main"]
|
|
strict_equality = true
|
|
no_implicit_optional = true
|
|
disallow_untyped_defs = false
|
|
disallow_any_generics = false
|
|
disallow_subclassing_any = false
|
|
disallow_untyped_calls = false
|
|
disallow_untyped_decorators = false
|
|
disallow_incomplete_defs = false
|
|
check_untyped_defs = false
|
|
no_implicit_reexport = true
|
|
warn_redundant_casts = true
|
|
warn_return_any = false
|
|
warn_unused_ignores = false
|
|
disable_error_code = ["var-annotated", "no-any-return", "import-untyped"]
|
|
|
|
[[tool.mypy.overrides]]
|
|
module = [
|
|
"mercadopago.*",
|
|
"mercadopago",
|
|
"twilio.*",
|
|
"twilio",
|
|
"stripe.*",
|
|
"stripe",
|
|
"cloudinary.*",
|
|
"cloudinary",
|
|
"storages.*",
|
|
"rest_framework_simplejwt.*",
|
|
]
|
|
ignore_missing_imports = true
|
|
|
|
[[tool.mypy.overrides]]
|
|
module = "infrasynth.billing.gateways.stripe"
|
|
disable_error_code = ["attr-defined"]
|
|
|
|
[tool.django-stubs]
|
|
django_settings_module = "config.settings.test"
|
|
|
|
[tool.pytest.ini_options]
|
|
DJANGO_SETTINGS_MODULE = "config.settings.test"
|
|
testpaths = ["tests"]
|
|
python_files = ["test_*.py"]
|
|
|
|
[tool.coverage.run]
|
|
source = ["infrasynth"]
|
|
omit = ["*/migrations/*", "*/__init__.py"]
|
|
|
|
[tool.coverage.report]
|
|
show_missing = true
|
|
skip_covered = true
|
|
# Gate for the whole package. The binding bar is ≥95% on the *public API
|
|
# surface* plus 100% branch coverage on security-relevant code (AGENTS §11);
|
|
# this floor keeps total coverage from regressing while that surface grows.
|
|
fail_under = 85
|