- 资质库(FR-M6-08):增删改、证书扫描件(PDF/JPG/PNG,企业级密钥加密、签名下载)、 late_for 按进行中项目的投标截止日提醒、审计;前端资质库页和对话框,侧栏入口 - 资质匹配(FR-M3-05):证书类别词表(16 类,产品证书、人员证书不进匹配), QUAL.EXPIRED / LEVEL_LOW / NOT_COVERED;投标文字层按清单项定级,只有资质库记录的降一级, 出处显示「依据:资质库记录」(查标页、报告模板 v2);一类证书一个问题;评分项不逐条找响应的也查 - 响应错位规则不再把资质表的证书名称格当成照抄的要求 - 评测:qual_defects.py 派生资质情况表,D12 3/3、D18 2/2、规矩的资质表 0 误报;开发集不退化 - 决策 QL1–QL7;方案和落地记录 docs/architecture/qualification-plan.md,评测 check-eval.md §13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
2.6 KiB
TOML
94 lines
2.6 KiB
TOML
[project]
|
||
name = "bid-doctor"
|
||
version = "0.1.0"
|
||
description = "标博士服务端:业务接口(api)和后台任务(worker)是同一套代码、两种进程"
|
||
requires-python = ">=3.12"
|
||
dependencies = [
|
||
"fastapi>=0.115",
|
||
"uvicorn[standard]>=0.32",
|
||
"pydantic>=2.9",
|
||
"pydantic-settings>=2.6",
|
||
"sqlalchemy[asyncio]>=2.0.36",
|
||
"psycopg[binary,pool]>=3.2",
|
||
"alembic>=1.14",
|
||
"procrastinate>=3.10,<4", # core/queue.py 直接调用它的 SQL 函数,升级大版本前要核对
|
||
"redis>=5.2",
|
||
"httpx>=0.28",
|
||
"pypdfium2>=4.30",
|
||
"pdfplumber>=0.11",
|
||
"python-multipart>=0.0.18",
|
||
"cryptography>=44",
|
||
]
|
||
|
||
[dependency-groups]
|
||
dev = [
|
||
"pytest>=8.3",
|
||
"pytest-asyncio>=0.25",
|
||
"ruff>=0.8",
|
||
"pyright>=1.1.390",
|
||
"import-linter>=2.1",
|
||
"pyyaml>=6",
|
||
]
|
||
|
||
[project.scripts]
|
||
bid-doctor = "bid_doctor.cli:main"
|
||
|
||
[build-system]
|
||
requires = ["hatchling>=1.26"]
|
||
build-backend = "hatchling.build"
|
||
|
||
[tool.hatch.build.targets.wheel]
|
||
packages = ["src/bid_doctor"]
|
||
|
||
[tool.ruff]
|
||
line-length = 120
|
||
target-version = "py312"
|
||
src = ["src", "tests"]
|
||
|
||
[tool.ruff.lint]
|
||
select = ["E", "F", "W", "I", "B", "UP", "SIM", "RUF", "ASYNC", "S", "BLE", "PT"]
|
||
ignore = [
|
||
"RUF001", "RUF002", "RUF003", # 中文全角标点是有意的
|
||
"S101", # assert 用来表达不变量
|
||
]
|
||
|
||
[tool.ruff.lint.per-file-ignores]
|
||
"tests/**" = ["S", "PT011", "PT018"]
|
||
"migrations/**" = ["E402"]
|
||
|
||
[tool.pyright]
|
||
include = ["src"]
|
||
pythonVersion = "3.12"
|
||
venvPath = ".."
|
||
venv = ".venv"
|
||
typeCheckingMode = "strict"
|
||
reportMissingTypeStubs = false
|
||
reportUnknownMemberType = false
|
||
reportUnknownVariableType = false
|
||
reportUnknownArgumentType = false
|
||
|
||
[tool.pytest.ini_options]
|
||
asyncio_mode = "auto"
|
||
asyncio_default_fixture_loop_scope = "session"
|
||
asyncio_default_test_loop_scope = "session"
|
||
testpaths = ["tests"]
|
||
pythonpath = ["."]
|
||
|
||
[tool.importlinter]
|
||
root_package = "bid_doctor"
|
||
|
||
[[tool.importlinter.contracts]]
|
||
name = "core 不依赖业务模块"
|
||
type = "forbidden"
|
||
source_modules = ["bid_doctor.core"]
|
||
forbidden_modules = ["bid_doctor.identity", "bid_doctor.billing", "bid_doctor.project", "bid_doctor.document",
|
||
"bid_doctor.checklist", "bid_doctor.check", "bid_doctor.ai", "bid_doctor.audit",
|
||
"bid_doctor.notification", "bid_doctor.ops", "bid_doctor.qualification"]
|
||
|
||
[[tool.importlinter.contracts]]
|
||
name = "业务模块不依赖 api 层的组合模块"
|
||
type = "forbidden"
|
||
source_modules = ["bid_doctor.document", "bid_doctor.checklist", "bid_doctor.check", "bid_doctor.billing",
|
||
"bid_doctor.identity.service", "bid_doctor.ops", "bid_doctor.qualification"]
|
||
forbidden_modules = ["bid_doctor.project.workbench", "bid_doctor.app"]
|