chore: 基线提交(重构前代码快照)
- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等) - 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb) - 含后端全部代码:application / extensions / utils / config / migrations - 含前端 ui/(后续整体迁走) - 不含根 .env(含密钥,本地保留) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+400
@@ -0,0 +1,400 @@
|
||||
# DjangoAdmin Flask+EleVue 重构方案 v2(补齐版)
|
||||
|
||||
> 本文档为《重构设计.txt》的企业级补齐版,是后续执行的唯一依据。
|
||||
> 适用范围:后端全部代码,**不含 `ui/`**(前端后续整体迁走)。
|
||||
> 依赖分析基于 2026-08-07 代码库快照:152 个 Python 文件、约 33K 行、528 处内部 import。
|
||||
|
||||
---
|
||||
|
||||
## 0. 决策记录
|
||||
|
||||
| # | 决策点 | 结论 | 影响 |
|
||||
|---|---|---|---|
|
||||
| D1 | core→modules 依赖倒置 | **依赖注入**:`core/permission.py` 定义权限校验接口,应用工厂启动时注入 `menu` 服务 | 见 §2.1 |
|
||||
| D2 | 验证层 | **仅用 WTForms**,`schema.py` 只是表单文件改名,不引入 Marshmallow | 24 个表单文件零重写 |
|
||||
| D3 | 执行策略 | **增量迁移·绞杀者模式**:`application/` 留薄转发层,模块逐一搬迁 | 见 §2.5,全程可运行可回滚 |
|
||||
| D4 | API 版本化 | **引入 `/api/v1` 前缀**,所有蓝图挂在 v1 下 | 见 §2.3,需联动前端与白名单 |
|
||||
| D5 | 服务层改造 | **做**:服务函数改为「入参数据、出参数据」,router 负责取 request/包 R | 见 §2.4,本次最大工作量 |
|
||||
| D6 | tenant 模块 | **本轮不做**,从方案删除,后续作为新功能单独立项 | 见 §3 映射表 |
|
||||
|
||||
**前置硬约束(P0)**:动手前必须先 `git init` + 基线提交。当前**不是 git 仓库**,无任何回滚兜底。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标架构总览
|
||||
|
||||
### 1.1 目录树(更新版)
|
||||
|
||||
```
|
||||
DjangoAdmin_Flask_EleVue/
|
||||
├── .env / .env.example / .gitignore / .editorconfig
|
||||
├── .flake8 / .pre-commit-config.yaml
|
||||
├── pyproject.toml # 项目管理 + tool 配置(pytest/black/isort/mypy 并入,不另设 pytest.ini)
|
||||
├── requirements.txt # 生产依赖(保持)
|
||||
├── requirements-dev.txt # 开发依赖
|
||||
├── Makefile
|
||||
├── README.md / README.en.md / CHANGELOG.md / CONTRIBUTING.md
|
||||
├── CLAUDE.md / USAGE.md / LICENSE
|
||||
├── gunicorn.conf.py / gunicorn_dev.conf.py
|
||||
├── Dockerfile # ★ 从 docker/ 提到根目录(修复 compose build 上下文)
|
||||
├── docker-compose.yml # ★ 从 docker/ 提到根目录
|
||||
├── .dockerignore
|
||||
│
|
||||
├── src/ # ★ 核心源码(原 application/)
|
||||
│ ├── __init__.py
|
||||
│ ├── app.py # 应用工厂(原 application/__init__.py)
|
||||
│ ├── wsgi.py # 生产 WSGI 入口
|
||||
│ ├── extensions.py # register_extends:扩展编排(原 extensions/__init__.py)
|
||||
│ ├── models_registry.py # ★ 模型聚合器(Flask-Migrate 依赖,见 §2.2)
|
||||
│ │
|
||||
│ ├── core/ # 基础设施层(不依赖 modules)
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── database.py # db 实例(原 extensions/sqlalchemy.py)
|
||||
│ │ ├── redis_client.py # redis 实例(原 extensions/redis.py)
|
||||
│ │ ├── scheduler.py # APScheduler 扩展实例(原 extensions/scheduler.py)
|
||||
│ │ ├── mail.py # Flask-Mail 实例(原 extensions/mail.py)
|
||||
│ │ ├── jwt.py # 原 utils/jwt.py
|
||||
│ │ ├── password.py # 原 utils/password.py
|
||||
│ │ ├── security.py # get_user_id / get_username(原 utils/security.py)
|
||||
│ │ ├── response.py # R(原 utils/response.py)
|
||||
│ │ ├── exceptions.py # BizError / AuthError 等 + 全局异常处理器
|
||||
│ │ ├── middleware.py # check_login / check_demo / transaction / op_log(op_log 接口化)
|
||||
│ │ ├── permission.py # ★ PermissionProvider 协议 + check_permission 装饰器(见 §2.1)
|
||||
│ │ ├── logger.py # 结构化日志初始化(配置在 config/logging.py)
|
||||
│ │ └── context.py # 请求上下文管理
|
||||
│ │
|
||||
│ ├── common/ # 共享层(依赖 core)
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── constants/
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── common.py
|
||||
│ │ │ ├── dictionary_constants.py # ★ 原 constants/dict.py(改名避内建遮蔽)
|
||||
│ │ │ └── error_code.py # 新增:错误码定义
|
||||
│ │ ├── enums.py
|
||||
│ │ ├── pagination.py # 分页统一封装
|
||||
│ │ ├── base_model.py # 原 models/base_model.py
|
||||
│ │ ├── base_db.py # ★ 原 models/base_db.py(原方案漏列)
|
||||
│ │ ├── base_repository.py # 新增
|
||||
│ │ ├── base_service.py # 新增
|
||||
│ │ ├── forms/ # ★ 原 application/forms/ 拆出
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── base_form.py
|
||||
│ │ │ └── fields.py # ★ 原 forms/fields.py(ArrayField,原方案漏列)
|
||||
│ │ ├── decorators.py
|
||||
│ │ ├── validators.py
|
||||
│ │ └── utils/
|
||||
│ │ ├── __init__.py # ★ 保留 `from common.utils import R, regular, password` 兼容
|
||||
│ │ ├── request.py / model_utils.py / case_converter.py / regular.py
|
||||
│ │ ├── captcha.py / file.py / rich_text.py / ip.py / user_agent.py
|
||||
│ │ ├── formatter.py / json.py
|
||||
│ │ ├── dict_utils.py # ★ 原 utils/dict.py(改名)
|
||||
│ │ └── ip2region/ # 原 utils/ip2region.py + .xdb(10MB 二进制)
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── ip2region.xdb
|
||||
│ │
|
||||
│ ├── modules/ # 业务层(依赖 core/common;允许跨模块调用业务服务)
|
||||
│ │ ├── __init__.py # ★ 导入全部模块(含各模块 models),供模型聚合
|
||||
│ │ ├── auth/ # router(login/captcha/logout + index 自服务) / schema / service / repository
|
||||
│ │ ├── system/ # user / role / menu / dept / position / level
|
||||
│ │ ├── association/ # user_role / role_menu
|
||||
│ │ ├── dictionary/ # dict + dict_item 合并(router 保留 /dict 与 /dict/item 两个前缀)
|
||||
│ │ ├── configuration/ # config + config_item 合并(/config 与 /config/item)
|
||||
│ │ ├── cms/ # article / category / link
|
||||
│ │ ├── notice/ param/ city/ file_template/ upload/
|
||||
│ │ ├── job/ # router / schema / service / models / executor
|
||||
│ │ │ # + scheduler_service.py(★ 原 services/scheduler.py)
|
||||
│ │ │ # + mail_service.py(★ 原 services/mail_svc.py)
|
||||
│ │ │ # + sms_service.py(★ 原 services/sms_svc.py)
|
||||
│ │ ├── log/ # login_log + operation_log 合并
|
||||
│ │ └── monitor/ # ★ 新增:/health 健康检查
|
||||
│ │
|
||||
│ ├── routes/
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── v1.py # v1 = Blueprint('/api/v1'),注册全部业务蓝图
|
||||
│ │
|
||||
│ └── templates/ # ★ 从方案移除(当前异常全走 JSON,无模板渲染需求,见 §3 说明)
|
||||
│
|
||||
├── config/ # 保持并新增 logging.py
|
||||
├── migrations/ # 保持(env.py 不变,模型聚合依赖 src/models_registry.py)
|
||||
├── tests/
|
||||
│ ├── conftest.py # 测试 App 构建 + 测试库/Redis fixture
|
||||
│ ├── unit/ # core / common / modules 服务单测
|
||||
│ └── integration/ # API 集成测试 + test_database.py
|
||||
├── scripts/ # init_db / seed_data / migrate_structure / backup_db / health_check
|
||||
├── static/ uploads/ logs/ instance/
|
||||
├── docker/ # ★ 保留目录,仅放 nginx/ + entrypoint.sh(Dockerfile/compose 已上提根目录)
|
||||
└── document/
|
||||
```
|
||||
|
||||
### 1.2 分层依赖规则(硬性约束)
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ modules(业务层,可互调) │
|
||||
└──────────────┬──────────────┘
|
||||
│
|
||||
┌──────────────▼──────────────┐
|
||||
│ common(共享层) │
|
||||
└──────────────┬──────────────┘
|
||||
│
|
||||
┌──────────────▼──────────────┐
|
||||
│ core(基础设施层) │
|
||||
└─────────────────────────────┘
|
||||
|
||||
约束:
|
||||
1. core 不得 import modules(依赖倒置由 DI 解决,见 §2.1)
|
||||
2. modules 之间允许跨模块 import 业务服务(如 auth→log、user→association)
|
||||
3. 全局异常由 core/exceptions.py 统一处理
|
||||
4. 所有模型必须经 src/models_registry.py 在启动时导入一次
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 关键设计
|
||||
|
||||
### 2.1 权限校验依赖注入(D1,P0-1)
|
||||
|
||||
**问题**:现 `application/middleware/check_permission.py:49` 直接 `from application.services import menu`。迁入 `core/` 后违反依赖规则。
|
||||
|
||||
**设计**:
|
||||
|
||||
```python
|
||||
# src/core/permission.py
|
||||
from typing import Protocol, List
|
||||
|
||||
class PermissionProvider(Protocol):
|
||||
"""权限数据提供方接口:core 只认接口,不认实现。"""
|
||||
def get_user_permissions(self, user_id: int) -> List[str]: ...
|
||||
|
||||
# check_permission 装饰器内部:
|
||||
provider = current_app.extensions.get('permission_provider')
|
||||
if provider is None:
|
||||
# 未注入(如 PERMISSION_ENABLED=False)→ 放行或报错,由配置决定
|
||||
...
|
||||
permissions = provider.get_user_permissions(user_id)
|
||||
```
|
||||
|
||||
```python
|
||||
# src/app.py 应用工厂,注册完蓝图后注入:
|
||||
from modules.system.menu.service import get_user_permissions
|
||||
from modules.system.menu.repository import MenuRepository
|
||||
app.extensions['permission_provider'] = MenuPermissionProvider(get_user_permissions)
|
||||
```
|
||||
|
||||
**同一模式覆盖 op_log**:`op_log.py` 直接引用 `OperationLog` 模型(`application/middleware/op_log.py:21`)。同样在 `core/middleware.py` 定义 `OperationLogWriter` 回调协议,由 `modules/log/` 在启动时注册写入实现。
|
||||
|
||||
**校验项**:`check_permission` 与 `op_log` 迁移到 core 后,`grep -r "from application" src/core/` 结果必须为空。
|
||||
|
||||
### 2.2 模型聚合与 Flask-Migrate(P1-3)
|
||||
|
||||
`migrations/env.py:26` 依赖 `current_app.extensions['migrate'].db.metadata` 全量收集表。模型打散到各模块后,**必须保证每个模型模块在启动时被 import 一次**。
|
||||
|
||||
```python
|
||||
# src/models_registry.py —— 唯一权威清单(等价原 application/models/__init__.py)
|
||||
from modules.auth import models as _auth_models # auth 无独立表则不导入
|
||||
from modules.system.user import models as _user_models
|
||||
from modules.system.role import models as _role_models
|
||||
# ... 全量列出
|
||||
```
|
||||
|
||||
- `src/app.py` 在 `register_extends` 之前 `import src.models_registry`。
|
||||
- **绞杀者过渡期**:已迁移模型进 registry,未迁移的仍由 `application/models/__init__.py` 导入,二者共同填满 `db.metadata`;每次迁移一批后跑一次 `flask db migrate` 验证 autogenerate 仍全量识别。
|
||||
- **校验项**:`flask db migrate` 生成的空迁移中 `upgrade_ops.is_empty()` 必须为 False(即所有表仍被识别)。
|
||||
|
||||
### 2.3 API v1 版本化(D4)
|
||||
|
||||
```python
|
||||
# src/routes/v1.py
|
||||
v1 = Blueprint('v1', __name__, url_prefix='/api/v1')
|
||||
v1.register_blueprint(user_blue) # 模块内蓝图保持 url_prefix='/user'
|
||||
v1.register_blueprint(menu_blue)
|
||||
# ...
|
||||
app.register_blueprint(v1)
|
||||
```
|
||||
|
||||
**联动清单**(缺一不可):
|
||||
1. `config/auth.py` 的 `LOGIN_WHITELIST_*` 增加 `/api/v1/login`、`/api/v1/captcha` 白名单。
|
||||
2. 前端 `ui/` 所有 API 调用前缀改为 `/api/v1/...`(`VITE_PROXY` 仍为 `/api` → 8021,无需改 proxy)。
|
||||
3. 后端内部 HTTP 调用(`modules/job/scheduler_service.py` 用 `requests` 调内部接口,携带 `X-Scheduler-Key`)URL 追加 `/api/v1`。
|
||||
4. **验收点**:当前 `ui/` 与后端将短暂不同步,需排一个前端 API 前缀同步改动(可在 ui/ 迁走前一次性改)。
|
||||
|
||||
### 2.4 服务层测试化改造(D5)
|
||||
|
||||
**现状**:`user.get_user_page()` 内部直接读 `request`、返回 `R` 对象 → 无法单测。
|
||||
|
||||
**目标形态**:
|
||||
|
||||
```python
|
||||
# router.py
|
||||
@user_blue.route('/page', methods=['GET'])
|
||||
@check_permission('sys:user:page')
|
||||
def page():
|
||||
params, err = parse_query_params() # router 层取参
|
||||
if err: return err
|
||||
return R.ok(data=user_service.get_user_page(params)) # router 层包 R
|
||||
|
||||
# service.py(纯函数化,可单测)
|
||||
def get_user_page(params: dict) -> dict:
|
||||
query = repository.build_query(params)
|
||||
items, total = repository.paginate(query, params.get('page', 1), PAGE_SIZE)
|
||||
return {'records': convert(items), 'total': total}
|
||||
|
||||
# 业务错误
|
||||
def reset_user_password(params: dict) -> None:
|
||||
user = repository.get_by_id(params['id'])
|
||||
if not user:
|
||||
raise BizError('用户不存在', code=1) # 由 core/exceptions.py 统一转 R.failed
|
||||
```
|
||||
|
||||
- 业务错误一律 **raise BizError**,不再 `return R.failed`(core/exceptions.py 提供 `register_error_handlers` 捕获转换)。
|
||||
- `base_service.py` / `base_repository.py` 提供泛型 CRUD 骨架,各模块 `repository.py` 承载查询。
|
||||
- **工作量提示**:这是本次对业务代码最深的一刀,26 个服务文件全部涉及,独立成 Phase 4(见 §4)。
|
||||
|
||||
### 2.5 绞杀者迁移模式(D3)
|
||||
|
||||
**目标**:全程 `app.py`(`app:app`)可启动、接口可访问,每步可回滚。
|
||||
|
||||
```
|
||||
原则:自底向上、按依赖序迁移;迁完一个旧文件立即换成薄转发层。
|
||||
|
||||
旧文件 shim 示例:
|
||||
# application/services/user.py → shim
|
||||
from src.modules.system.user.service import * # 保持 `from application.services import user` 可用
|
||||
|
||||
# application/models/user.py → shim
|
||||
from src.modules.system.user.models import *
|
||||
# (注意 models shim 必须同时导出模型类 User 与 BaseDB/BaseModel 组合,保证 application/models/__init__.py 汇总正常)
|
||||
|
||||
# extensions/sqlalchemy.py → shim
|
||||
from src.core.database import db # 统一 db 单例
|
||||
```
|
||||
|
||||
**迁移顺序**(严格依赖序):
|
||||
1. `src/core/`(db/redis/R/exceptions/logger)→ 打 shim 于 `extensions/`、`utils/`
|
||||
2. `src/common/`(base_model/base_db/base_form/utils)→ 打 shim 于 `application/models/`、`application/forms/`、`utils/`
|
||||
3. 各模块 models → forms → services → views,逐组迁移、逐组验证
|
||||
4. `core/permission.py` + 应用工厂注入
|
||||
5. `src/routes/v1.py` + `/api/v1` 切换
|
||||
6. `src/app.py` 全量接管,删除 `application/` `extensions/` `utils/`,WSGI 切 `src.wsgi:app`
|
||||
|
||||
**回滚**:任一阶段失败,回滚到上一阶段 shim(git commit 粒度)。
|
||||
|
||||
### 2.6 验证层(D2)
|
||||
|
||||
- 24 个表单文件**零逻辑重写**,仅随模块搬移并改名 `schema.py`(文件名 `forms/login.py` → `modules/auth/schema.py`)。
|
||||
- `BaseForm` + `ArrayField` 迁至 `common/forms/`。
|
||||
- **不引入 Marshmallow**,`requirements.txt` 不加新依赖。
|
||||
|
||||
### 2.7 健康检查与 Docker 修复
|
||||
|
||||
- `src/modules/monitor/router.py`:`GET /api/v1/health`(返回 `{code:0, data:{status:'ok', version:...}}`),并加入登录白名单。
|
||||
- Docker 修复清单:
|
||||
1. `Dockerfile`/`docker-compose.yml` 上提根目录,`build: context: ./`、`dockerfile: Dockerfile`(修复现有 build 上下文错误);
|
||||
2. 去掉 `privileged: true`、`user: root`、`network_mode: host` → `cap_add` + 非特权用户 + bridge 网络;
|
||||
3. `HEALTHCHECK` 改为探测 `/api/v1/health`;
|
||||
4. CMD 改为 `gunicorn -c gunicorn.conf.py src.wsgi:app`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 完整文件映射清单(含原方案遗漏项修正)
|
||||
|
||||
### 3.1 原方案遗漏文件(★ = 补齐项)
|
||||
|
||||
| 原文件 | 去向 | 说明 |
|
||||
|---|---|---|
|
||||
| `services/scheduler.py`(19KB) | `modules/job/scheduler_service.py` | 业务调度器,被 `extensions/scheduler.py` 6 处引用 |
|
||||
| `services/mail_svc.py` / `sms_svc.py` | `modules/job/mail_service.py` / `sms_service.py` | 被 job_executor / job 引用 |
|
||||
| `forms/fields.py` | `common/forms/fields.py` | `ArrayField`,被 base_form 与 user 表单引用 |
|
||||
| `views/index.py` | `modules/auth/router.py` | 自服务接口(getMenu/getUser/userInfo/updatePwd),依赖 menu/user 服务 |
|
||||
| `models/base_db.py` | `common/base_db.py` | 原方案只列了 base_model.py |
|
||||
| `models/login_log.py` | `modules/log/models.py` | ★ 原方案 auth/models.py 与 log/models.py 冲突,定案入 log |
|
||||
| `models/operation_log.py` | `modules/log/models.py` | 随 log 合并 |
|
||||
| `constant/`(空目录) | 删除 | 仅 __pycache__ |
|
||||
| `src/templates/` | **从方案移除** | 根目录无 templates,异常全走 JSON;如确需 HTML 错误页再单独立项 |
|
||||
| `system/tenant/` | **从方案删除** | 当前代码不存在(D6) |
|
||||
| Dockerfile / docker-compose.yml | 上提根目录 | 见 §2.7 |
|
||||
| `src/extensions.py` | 保留 | 与 `core/*.py` 分工:core 持有实例,extensions.py 只做 init_app 编排 |
|
||||
|
||||
### 3.2 模块映射汇总
|
||||
|
||||
| 新模块 | 蓝图中路由前缀(保持不变) | 来源 |
|
||||
|---|---|---|
|
||||
| auth | `/login` `/captcha` `/logout` `/index/*` | views/login.py + index.py |
|
||||
| system/user | `/user` | views/user.py |
|
||||
| system/role | `/role` | views/role.py |
|
||||
| system/menu | `/menu` | views/menu.py |
|
||||
| system/dept | `/dept` | views/dept.py |
|
||||
| system/position | `/position` | views/position.py |
|
||||
| system/level | `/level` | views/level.py |
|
||||
| association/user_role | `/user/role` | views/user_role.py |
|
||||
| association/role_menu | `/role/menu` | views/role_menu.py |
|
||||
| dictionary | `/dict` + `/dict/item` | views/dict.py + dict_item.py |
|
||||
| configuration | `/config` + `/config/item` | views/config.py + config_item.py |
|
||||
| cms/article | `/article` | views/article.py |
|
||||
| cms/category | `/category` | views/category.py |
|
||||
| cms/link | `/link` | views/link.py |
|
||||
| notice | `/notice` | views/notice.py |
|
||||
| param | `/param` | views/param.py |
|
||||
| city | `/city` | views/city.py |
|
||||
| job | `/job` | views/job.py + services/scheduler.py + job_executor.py + mail_svc.py + sms_svc.py |
|
||||
| log | `/login/log` + `/oper/log` | views/login_log.py + operation_log.py |
|
||||
| file_template | `/file/template` | views/file_template.py |
|
||||
| upload | `/upload` | views/upload.py |
|
||||
| monitor | `/health` | 新增 |
|
||||
|
||||
> Blueprint 名称(`config_item`、`login_log` 等)在 op_log 记录 `request.endpoint` 时使用。合并后 endpoint 名变化只影响日志展示字段,不破坏功能;如需稳定可保留原 blueprint name。
|
||||
|
||||
---
|
||||
|
||||
## 4. 分阶段执行计划(每阶段含验收标准)
|
||||
|
||||
| 阶段 | 内容 | 验收标准 | 风险 |
|
||||
|---|---|---|---|
|
||||
| **P0 基线** | `git init`;`.gitignore` 补 `logs/ instance/ *.pyc`;基线提交 | git 仓库可用,可 `git reset --hard` 回滚 | 无 |
|
||||
| **P1 工具链** | pyproject.toml / requirements-dev.txt / .flake8 / .pre-commit / Makefile / pytest 骨架 | 现有代码 `flake8` 通过(或登记存量告警);`pytest` 空跑通过 | 低 |
|
||||
| **P2 core+common** | 建 `src/core/` `src/common/`;extensions/utils 打 shim;模型聚合器建 `src/models_registry.py` | `python app.py` 启动;`flask db migrate` 仍全量识别表;全接口冒烟 | 高(依赖面最大) |
|
||||
| **P3 模块搬迁** | 按 §2.5 顺序逐组迁移 23 个模块(models→forms→services→views),每批打 shim + 验证 | 每批后 `python app.py` 启动 + 该模块接口回归通过 | 中 |
|
||||
| **P4 服务层改造** | 26 个服务文件改「入参数据/出参数据」;router 取参包 R;引入 base_service/base_repository + BizError | 核心服务(auth/user/role/menu)单测可写可跑;接口回归全绿 | 高(最大工作量) |
|
||||
| **P5 DI 注入** | core/permission.py + op_log 接口化;app 工厂注入 menu 服务 | `grep -r "from application" src/core/` 为空;权限/日志行为与现状一致 | 中 |
|
||||
| **P6 API v1** | routes/v1.py + `/api/v1`;白名单/内部调用/前端前缀同步 | 全部接口路径 `curl /api/v1/...` 通过;`/login` 白名单放行 | 中 |
|
||||
| **P7 切尾** | 删除 application/extensions/utils;`src/wsgi.py`;gunicorn.conf 指向 src.wsgi;更新 CLAUDE.md | `gunicorn -c gunicorn.conf.py src.wsgi:app` 启动;全量回归 | 高 |
|
||||
| **P8 测试+文档** | tests/ 全量落地;CHANGELOG / CONTRIBUTING / API 文档 | `pytest` 通过;覆盖率报告 | 低 |
|
||||
| **P9 运维** | Docker 修复(§2.7)+ CI/CD(lint→type-check→pytest→build) | `docker-compose up -d` 健康检查通过 | 低 |
|
||||
|
||||
**执行纪律**:
|
||||
- 每阶段独立 commit,提交信息带阶段前缀(`P2: ...`)。
|
||||
- 每个 P3 迁移批次后跑一遍全接口冒烟(可先用 Postman collection)。
|
||||
- P4 与 P5 可并行准备,但**P3 未全部收口前不得开始 P4**(服务层改造需在稳定结构上进行)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 风险登记
|
||||
|
||||
| 风险 | 等级 | 缓解 |
|
||||
|---|---|---|
|
||||
| 无版本控制 | 高 | P0 先行 git init |
|
||||
| core→modules 依赖(permission/op_log) | 高 | DI 协议 + 启动注入(§2.1) |
|
||||
| Flask-Migrate 表丢失 | 高 | models_registry + 每批迁移后 `flask db migrate` 空迁移校验(§2.2) |
|
||||
| `/api/v1` 切换导致前端/内部调用不同步 | 中 | P6 联动清单一次性核对(§2.3) |
|
||||
| 服务层改造回归 | 高 | P4 单独阶段 + 接口回归为硬门槛 |
|
||||
| utils R 的 `import utils.response as R` 别名模式 | 中 | `common/utils/__init__.py` 保留同形兼容导出 |
|
||||
| 10MB `ip2region.xdb` 路径解析 | 低 | 迁移时同步改 `ip2region/__init__.py` 内路径定位逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 遗留命名权衡(已知,接受)
|
||||
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| 根 `config/` 与 `modules/configuration/` | 两个「config」含义不同(应用配置 vs 业务配置),import 路径不冲突,予以保留 |
|
||||
| `modules/dictionary/` 与 `common/` 内字典文件 | 已通过 `dictionary_constants.py` / `dict_utils.py` 改名消解,不再遮蔽内建 `dict` |
|
||||
| repository 层为新增代码 | 23 个模块各加 repository.py,属结构性增量,工作量已计入 P3/P4 |
|
||||
|
||||
---
|
||||
|
||||
## 附:与《重构设计.txt》的主要差异
|
||||
|
||||
1. 补全 9 处遗漏文件映射、修正 2 处矛盾(auth 与 log 争 login_log、templates 不存在)
|
||||
2. 新增 5 项关键设计(DI、模型聚合、/api/v1、服务层改造、绞杀者)
|
||||
3. 新增分层依赖规则与分层校验项
|
||||
4. 新增分阶段验收标准、风险登记、执行纪律
|
||||
Reference in New Issue
Block a user