gendesign/backend/pyproject.toml
Light1YT eb251ba7e7
All checks were successful
CI / changes (push) Successful in 13s
CI / changes (pull_request) Successful in 12s
CI / frontend-tests (push) Successful in 53s
CI / openapi-codegen-check (push) Successful in 1m58s
CI / frontend-tests (pull_request) Successful in 47s
CI / openapi-codegen-check (pull_request) Successful in 1m50s
CI / backend-tests (push) Successful in 8m54s
CI / backend-tests (pull_request) Successful in 8m45s
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Successful in 2m50s
Deploy / build-frontend (push) Successful in 3m11s
Deploy / build-worker (push) Successful in 4m38s
Deploy / deploy (push) Successful in 2m1s
ci(infra): coverage-gate (#68) + OpenAPI codegen-assert (#69) + uptime monitoring (#75)
#68: pytest-cov + [tool.coverage] fail_under=65 (baseline 71%), backend-tests --cov + xml.
#69: openapi-codegen-check job (dump app.openapi() → openapi-typescript → git diff).
  Job использует node_modules-pinned openapi-typescript/prettier (НЕ npx --yes latest —
  иначе version-mismatch ложный diff). + regenerated api-types.ts из СВЕЖЕГО main openapi
  (8288 строк, включая #73 /freshness — синхронен).
#75: Uptime Kuma isolated stack + status.gendsgn.ru Caddy + external Telegram watchdog.
#77: no change — build cache достаточен.

Closes #68
Closes #69
Closes #75
Closes #77
2026-06-13 23:28:06 +05:00

136 lines
4.8 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[project]
name = "gendesign-backend"
version = "0.1.0"
description = "Generative Design + Site Finder backend (FastAPI)"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115.0",
"uvicorn[standard]>=0.30.0",
"sqlalchemy>=2.0.30",
"geoalchemy2>=0.15.0",
"alembic>=1.13.0",
"pydantic>=2.7.0",
"pydantic-settings>=2.3.0",
"psycopg[binary]>=3.2.0",
"shapely>=2.0.0",
"geopandas>=1.0.0",
"pyproj>=3.6.0",
"httpx>=0.27.0",
"redis>=5.0.0",
"celery>=5.4.0",
"playwright>=1.45.0",
"tenacity>=9.0.0",
"pillow>=10.4.0",
"weasyprint>=62.0",
"jinja2>=3.1.0",
"ezdxf>=1.3.0",
"openpyxl>=3.1.0",
"python-docx>=1.1.0", # DOCX export (import name `docx`) — §22 forecast report (#959)
"python-pptx>=1.0.0", # PPTX export (import name `pptx`) — §22 forecast report (#959)
"pandas>=2.2.0",
"numpy>=2.0.0",
"scikit-learn>=1.5.0",
"sentry-sdk[fastapi,celery,sqlalchemy,httpx]>=2.18.0",
"rosreestr2coord>=5.0.0",
"ijson>=3.2.0",
"pyyaml>=6.0.0", # RBAC roles.yaml loader (app/core/auth.py)
"pdfplumber>=0.10.0", # PDF-парсер постановлений об изъятии/резервировании (#1091)
"beautifulsoup4>=4.12.0", # HTML-парсер реестра КРТ-площадок ЕКБ (#1060)
"pymupdf>=1.24.0", # растеризация PDF→image (без poppler) для OCR (#1062)
"pytesseract>=0.3.13", # OCR сканов через Tesseract для изъятия ЕКБ (#1062)
]
[dependency-groups]
dev = [
"pytest>=8.0.0",
"pytest-asyncio>=0.23.0",
"pytest-cov>=5.0.0", # coverage gate в CI (#68): pytest --cov=app --cov-fail-under
"ruff>=0.5.0",
"mypy>=1.10.0",
"types-redis>=4.6.0",
"pre-commit>=3.7.0",
]
[tool.uv]
package = true
# Tell setuptools which directory IS the Python package.
# Without this, having both `app/`, `alembic/`, `db/` at top level confuses
# auto-discovery: "Multiple top-level packages discovered in a flat-layout".
# We only want to package `app/`. `alembic/` and `db/` are operational, not Python packages.
[tool.setuptools.packages.find]
include = ["app*"]
[tool.ruff]
target-version = "py312"
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "N", "RUF", "ASYNC"]
# RUF001/002/003 — ambiguous Unicode (Cyrillic vs Latin lookalikes).
# Off because the project is Russian-language; comments/docstrings legitimately use Cyrillic.
ignore = ["RUF001", "RUF002", "RUF003"]
[tool.mypy]
python_version = "3.12"
strict_optional = true
warn_unused_ignores = true
# strict только для core-модулей (правило из памяти Validation_Findings_Apr25)
[[tool.mypy.overrides]]
module = [
"app.services.generative.geometry",
"app.services.generative.placement",
"app.services.generative.teap",
"app.services.generative.financial",
"app.services.generative.exporters.dxf",
"app.services.generative.exporters.pdf",
"app.services.site_finder.scorer",
]
strict = true
# Геометрия/экспорт-библиотеки без type stubs (shapely/ezdxf/weasyprint не несут
# py.typed) — игнорируем missing-imports, чтобы strict-модули generative проходили.
[[tool.mypy.overrides]]
module = [
"shapely.*",
"ezdxf.*",
"weasyprint.*",
]
ignore_missing_imports = true
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
# --cov НАМЕРЕННО НЕ в addopts: локальный `pytest` остаётся быстрым/без coverage.
# Coverage-gate включается ТОЛЬКО в CI явными флагами
# (`--cov=app --cov-fail-under=65`, см. .forgejo/workflows/ci.yml backend-tests).
addopts = ["-m", "not prod_smoke"]
markers = [
"slow: marks tests as slow (need real network, deselect with -m 'not slow')",
"prod_smoke: production smoke tests against live https://gendsgn.ru (run only post-deploy with -m prod_smoke)",
"integration: phantom column gate tests requiring TEST_DATABASE_URL (SSH tunnel to prod Postgres)",
]
[tool.coverage.run]
# Меряем покрытие пакета app/. branch=true — учитываем непокрытые ветки, не только строки.
source = ["app"]
branch = true
omit = [
"app/**/__main__.py",
"tests/*",
]
[tool.coverage.report]
# Baseline gate = 65% (измерено: mock-lane CI-сьют даёт ~71% на 2026-06; 65 = floor
# с запасом под libpango-skip дельту и PR-to-PR дрейф, не ratchet'ит слишком туго).
# Поднимать постепенно по мере роста сьюта (#68 acceptance: "постепенно поднимать").
fail_under = 65
show_missing = true
skip_covered = true
exclude_also = [
"if TYPE_CHECKING:",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"@(abc\\.)?abstractmethod",
]