本模板用于在当前仓库内快速新增或重构一个标准后端模块,目标结构统一为:
backend/app/modules/<domain>/
├── router.py
├── deps.py
├── helpers.py
├── serializers.py
├── routes/
│ └── <domain>_routes.py
├── services/
│ ├── errors.py
│ ├── <domain>_query_service.py
│ └── <domain>_command_service.py
└── repositories/
└── <domain>_repo.py
如果当前任务还包括前端 CRUD 页面、前端路由菜单、后端菜单注册,优先使用根目录的一键全栈脚手架:
./backend/.venv/bin/python scripts/scaffold_fullstack_module.py quality_report \
--tag "质检报告" \
--api-base-path /manage/api/qualityReport \
--table-name quality_report_records \
--function-code SRS-FUNC-QUALITY-REPORT \
--with-store当前文档对应的是“仅后端侧生成或重构模块”场景。完整流程见 docs/fullstack-module-template.md。
router.py- 只负责
APIRouter创建、依赖装配、调用register_*_routes(...) - 对外暴露
create_*_router(...),尽量保持原函数签名不变
- 只负责
deps.py- 用
dataclass收口路由依赖 - 所有
ok_func/fail_func/get_conn_func/now_str_func/...都在这里定义
- 用
helpers.py- 放纯函数型解析逻辑,如分页参数标准化、payload 解析、字段映射
- 不直接做 SQL
serializers.py- 负责数据库行到接口返回结构的映射
- 负责分页返回结构构造
routes/*.py- 只做 HTTP 入参读取、调用 service、
ok/fail包装 - 不直接写 SQL
- 只做 HTTP 入参读取、调用 service、
services/*_query_service.py- 负责查询型业务编排
- 严格控制多条 SQL 的调用顺序,避免破坏现有测试
services/*_command_service.py- 负责写入型业务、校验、事务提交、异常转译
services/errors.py- 定义模块级业务异常,例如
<Domain>ServiceError(message, code)
- 定义模块级业务异常,例如
repositories/*_repo.py- 只收口 SQL,不做业务判断
- 先保留原
create_*_router(...)的对外签名。 - 提取
deps.py,让顶层 router 变成薄装配。 - 把原路由函数迁到
routes/*_routes.py。 - 把纯解析逻辑迁到
helpers.py。 - 把响应组装迁到
serializers.py。 - 把查询逻辑迁到
*_query_service.py。 - 把写逻辑、校验、事务迁到
*_command_service.py。 - 把 SQL 全部收口到
repositories/*_repo.py。 - 补定向单测,再跑全量回归。
当前仓库已提供可执行脚手架:
./backend/.venv/bin/python backend/scripts/scaffold_backend_module.py quality_report \
--tag "质检报告" \
--resource-path /manage/api/qualityReport \
--table-name quality_report_records常用参数:
module_name- 目标模块名,必须是
snake_case
- 目标模块名,必须是
--tag- 生成到
APIRouter(tags=[...])的标签名
- 生成到
--resource-path- 生成默认接口路径,例如
/manage/api/qualityReport
- 生成默认接口路径,例如
--table-name- 生成仓储层默认 SQL 表名
--output-root- 可选,默认输出到
backend/app/modules/
- 可选,默认输出到
脚手架会自动生成:
router.pydeps.pyhelpers.pyserializers.pyroutes/<module_name>_routes.pyservices/errors.pyservices/<module_name>_query_service.pyservices/<module_name>_command_service.pyrepositories/<module_name>_repo.py
生成模块后,如该模块需要出现在导航菜单中,还应同步:
- 在
backend/app/bootstrap/scaffold_router_registry.py注册新 router - 在
backend/app/modules/system_admin/scaffold_menu_registry.py注册后端菜单项 - 与前端
meta.functionCode使用同一套permission编码
# router.py
from fastapi import APIRouter
from app.modules.example.deps import ExampleRouterDeps
from app.modules.example.routes.example_routes import register_example_routes
def create_example_router(ok_func, fail_func, get_conn_func):
router = APIRouter(tags=['示例模块'])
deps = ExampleRouterDeps(
ok_func=ok_func,
fail_func=fail_func,
get_conn_func=get_conn_func,
)
register_example_routes(router, deps)
return router# routes/example_routes.py
from fastapi import APIRouter, Request
from app.modules.example.services.example_query_service import query_example_page
from app.modules.example.services.errors import ExampleServiceError
def register_example_routes(router: APIRouter, deps) -> None:
@router.get('/example/page')
def page(current: int = 1, size: int = 10):
try:
return deps.ok_func(query_example_page(deps, current=current, size=size), 'success')
except ExampleServiceError as error:
return deps.fail_func(error.message, error.code)- 不改接口路径。
- 不改成功/失败返回结构。
- 不改关键错误文案。
- 不改测试依赖的 SQL 调用顺序。
- 不改外部 import 入口和
create_*_router(...)名称。
system:认证 + 配置 + 健康检查的薄装配样板system_admin:菜单/部门/角色/用户的多路由拆分样板process:纯查询模块的最轻量样板quotation、contracts、work_order:复杂业务模块样板
./backend/.venv/bin/python -m py_compile $(rg --files backend/app/modules/<domain> | sort)
./backend/.venv/bin/python -m unittest backend.tests.test_modular_routes.ModularRoutesTestCase.<target_test> -v
./backend/.venv/bin/python -m unittest discover -s backend/tests -p 'test_*.py' -v