PayrollManagementSystem/backend/pyproject.toml
liuwenxin 1461a8d113 feat(后端): 添加授权体系、系统监控与试用期计提
按 2026-11-02 需求补齐计划交付后端能力:
- 角色授权:权限目录化,接口统一准入校验,未登记默认拒绝;
  管理员判断改为按数据库角色重新判定,防止权限码持有者绕过
- 系统监控:单进程采集资源、请求与异常指标,分钟级聚合,
  阈值配置化;敏感配置增加 repr 保护,Redis 密码 URL 转义
- 试用期计提:按回款日判定并写入快照,年度结清与调整单联动;
  人员模型补试用期、离职日期与工资版本历史字段
- 计提模板:公式骨架受控,页面维护名称与参数绑定
- T+ 采集:自动化配置表与进度查询

内置角色禁停用保护对齐模块注释;核算规则版本提为常量并
补充批量核算失败堆栈日志。

影响范围:后端全部模块、数据库迁移 V22-V28
验证:uv run ruff check 通过;922 个单元测试全部通过;
集成测试因本机 MySQL 数据卷被其他容器锁定暂未运行
2026-11-03 11:20:55 +08:00

116 lines
4.4 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 = "payroll-backend"
version = "0.1.0"
description = "衍水集团营销人员工资管理系统 —— 后端服务"
readme = "README.md"
# 锁定 3.12:系统默认是 3.14,第三方库轮子覆盖不如 3.12 完备
requires-python = ">=3.12,<3.13"
dependencies = [
"fastapi>=0.115",
# starlette 已进入 1.x(当前 1.7.0)。FastAPI 对它的约束是 `starlette>=0.46.0`,
# **没有上界** —— uv lock --upgrade 时可能漂移到未验证的大版本。
# 我们的异常处理器与 TestClient 直接依赖其 API,故显式限定主版本。
# 当前组合(fastapi 0.143 + starlette 1.7.0)已实测通过全部用例。
"starlette>=1.7,<2",
"uvicorn[standard]>=0.32",
"pydantic>=2.9",
"pydantic-settings>=2.6",
# ORM 与驱动:采用同步 —— 本项目并发极低,异步无吞吐收益;
# 而重活(绩效批量核算、pandas 报表、Excel 导出)全是同步阻塞代码,
# 在异步路由里跑会卡死事件循环。同步路由由 FastAPI 自动放入线程池执行。
"sqlalchemy>=2.0.36",
# 必须带 [rsa]:MySQL 8.0 默认 caching_sha2_password,容器重启后首次连接走
# 全量认证需要 cryptography 做 RSA 交换,缺失时 PyMySQL 直接抛 RuntimeError
# (报错出现在建连阶段,极易被误读成"密码错误")
"pymysql[rsa]>=1.2.3",
"alembic>=1.14",
# 验证码、登录限流、Token 黑名单
"redis[hiredis]>=5.2",
# 鉴权与密码哈希
# 注意:不用 passlib —— 它与 bcrypt>=4.1 存在 __about__ 属性缺失的不兼容问题
"pyjwt>=2.10",
"pwdlib[bcrypt]>=0.2",
# 图形验证码(纯 Python,依赖 Pillow)
"captcha>=0.6",
"pillow>=11.0",
"openpyxl>=3.1.5",
"python-multipart>=0.0.32",
"psutil>=7.2,<8",
]
[project.optional-dependencies]
tplus = [
"pyodbc>=5.2,<6",
]
[dependency-groups]
dev = [
"pytest>=8.3",
"pytest-cov>=7",
"httpx>=0.28,<1.0",
# 用假 Redis 做单测,无需起容器即可覆盖 GETDEL 一次性语义
"fakeredis>=2.30",
# lint + format 二合一,替代 flake8 + isort + black
"ruff>=0.14",
]
# 本项目按应用而非库来管理,不打包安装自身
[tool.uv]
package = false
[tool.pytest.ini_options]
testpaths = ["tests"]
markers = [
"integration: 需要 MySQL/Redis 容器或完整应用实例的测试",
]
# ==================== 代码检查与格式化 ====================
[tool.ruff]
# 与项目根 .editorconfig 保持一致:Python 用 4 空格(缩进由 formatter 控制)
target-version = "py312"
line-length = 100
src = ["app", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle 错误
"W", # pycodestyle 警告
"F", # pyflakes:未使用的导入、未定义的名称等
"I", # isort:导入顺序
"B", # flake8-bugbear:常见陷阱(可变默认参数、循环引用等)
"C4", # flake8-comprehensions:推导式可简化处
"UP", # pyupgrade:按目标 Python 版本升级旧写法
"SIM", # flake8-simplify:可简化的分支与判断
"RUF", # ruff 自有规则
]
ignore = [
# 行宽已由 formatter 控制,lint 不再重复报——长中文注释很容易触发
"E501",
# FastAPI 的依赖注入要求在参数默认值处调用 Depends(),是框架约定而非缺陷。
# 项目内已尽量改用 Annotated 形式(见 api/deps.py),此处兜底。
"B008",
# RUF001/002/003 检查「易混淆的 Unicode 字符」,分别针对字符串字面量、
# 文档字符串、注释 —— 这套规则的默认前提是英文文本。
# 对中文会把全角逗号、句号、括号、冒号全部判定为混淆字符(本项目实测 800+ 条),
# 而中文里全角标点正是规范写法,故一并关闭。
"RUF001",
"RUF002",
"RUF003",
]
[tool.ruff.lint.isort]
# 必须显式声明:本项目 `[tool.uv] package = false`(不作为包安装),
# ruff 无法从项目布局推断出 `app` 是第一方包,否则会把第三方依赖
# 排到 `app.*` 之后(按字母序把两者当成同一组)。
known-first-party = ["app", "tests"]
[tool.ruff.lint.per-file-ignores]
# Alembic 自动生成的迁移脚本不按手写代码的标准要求。
# 这些文件由 `alembic revision --autogenerate` 产出,手工修 lint 会在下次生成时被覆盖。
"alembic/versions/*.py" = ["E501", "I001", "W291"]
[tool.ruff.format]
quote-style = "double"