[project]
name = "fuellhorn"
dynamic = ["version"]
description = "Lebensmittelvorrats-Verwaltung - Self-hosted inventory management for food storage"
license = {text = "AGPL-3.0-or-later"}
authors = [
    {name = "Jens W. Klein", email = "jk@kleinundpartner.at"}
]
requires-python = ">=3.14"
classifiers = [
    "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
    "Development Status :: 3 - Alpha",
    "Intended Audience :: End Users/Desktop",
    "Environment :: Web Environment",
    "Framework :: FastAPI",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.14",
]
dependencies = [
    "alembic>=1.14.0",
    "bcrypt>=5.0.0",
    "nicegui>=3.3.1",
    "psycopg[binary,pool]>=3",
    "pydantic>=2.12.4",
    "python-dateutil>=2.9.0.post0",
    "python-dotenv>=1.2.1",
    "sqlmodel>=0.0.27",
]

[dependency-groups]
dev = [
    "mypy>=1.18.2",
    "pyupgrade>=3.19.0",
    "pytest>=9.0.1",
    "pytest-asyncio>=1.3.0",
    "pytest-cov>=7.0.0",
    "ruff>=0.14.5",
    "selenium>=4.0.0",
    "types-python-dateutil>=2.9.0.20251115",
    "pre-commit>=4.4.0",
    "pytest-xdist>=3.8.0",
    "pytest-playwright>=0.7.2",
    "freezegun>=1.5.5",
]

[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
main_file = "main.py"
testpaths = ["tests"]
markers = [
    "e2e: End-to-End tests with Playwright (run with --run-e2e)",
]
filterwarnings = [
    "ignore:cannot collect test class 'User':pytest.PytestCollectionWarning",
]

[tool.mypy]
python_version = "3.14"
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
plugins = ["pydantic.mypy"]

[[tool.mypy.overrides]]
module = ["nicegui.*"]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "alembic.*"
ignore_errors = true

[[tool.mypy.overrides]]
module = "main"
disallow_untyped_defs = false

[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
disable_error_code = ["arg-type", "union-attr", "attr-defined"]

[tool.coverage.run]
parallel = true
branch = true
source = ["app"]
relative_files = true
omit = [
    "app/ui/pages/demo_chips.py",
    "app/ui/test_pages/*",
]

[tool.coverage.report]
skip_covered = true
skip_empty = true
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
    "if __name__ == .__main__.:",
]

[tool.ruff]
line-length = 120

[tool.ruff.lint]
extend-select = ["I"]

[tool.ruff.lint.isort]
known-local-folder = ["app/"]
force-single-line = true
force-sort-within-sections = true
case-sensitive = false
lines-after-imports = 2
no-sections = true

[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[tool.hatch.version]
source = "vcs"
raw-options = { local_scheme = "no-local-version" }

[tool.hatch.build.hooks.vcs]
version-file = "app/_version.py"

[tool.hatch.build.targets.wheel]
packages = ["app"]

[tool.hatch.build.targets.wheel.force-include]
"alembic.ini" = "app/alembic.ini"

[project.scripts]
fuellhorn = "app.cli:main"
