79441a8a87
D4 文档/规划/历史混放收口:
- docs/TECH_DEBT.md §2 由'按批次回顾'精简为'按主题摘要',
与§3重复内容(批次0-4详细展开)整体迁入
docs/archive/2026-09_governance_batches.md
- docs/STATUS.md 顶部 2026-09-17 之前条目迁入
docs/archive/2026-09_status_history.md,仅保留指针
- D2 历史口径补齐为 2026-09-18 批次4后续专项清偿
- D4 标已清偿
- AGENTS.md / docs/archive/README.md 同步导航
D13 锁文件流程固化(镜像引入主体已清偿,仅剩锁文件落盘):
- 新增 deploy/generate_lockfiles.{sh,bat}:在 moldinsight conda
环境(仅项目依赖)执行 pip freeze --exclude pythonocc-core,
产出 deploy/requirements-{base,moldinsight}.lock.txt
- deploy/Dockerfile.moldinsight 注释改为指向生成脚本
- docs/OPERATIONS.md §2.1 增加完整流程说明
- tests/test_lockfile_generation.py 加锁文件存在性+体积契约;
tests/conftest.py 注册 --run-lockfile-check 选项,
默认 skip(仓库单测不阻塞),CI 镜像构建 job 显式启用 fail-fast
遗留:锁文件本身尚未落盘(本机Miniforge跨项目开发栈混装,
污染严重不能直接 pip freeze);待 CI / 生产首次构建时按流程落锁。
测试基线:126 passed, 9 skipped(默认4原有skip + D13新增5skip;
启用 --run-lockfile-check 时严格断言2项锁文件契约)
Co-Authored-By: Claude Code <noreply@anthropic.com>
8.3 KiB
8.3 KiB
2026-09 后端设计治理批次实施流水账(归档)
文档定位:2026-09 设计审查产出的批次 0–4 与后续专项的完整实施流水账。 主骨架权威文档见:
- ../STATUS.md(每批次完成的时间点与产物)
- ../TECH_DEBT.md(活跃债务 / 已清偿项的当前位置)
- ../ROADMAP.md(批次计划与执行顺序)
- ../ARCHITECTURE.md(平台 / 模块边界当前定稿)
批次 0(2026-09-16,安全与诚实)
/api/status/{task_id}补 JWT 鉴权 + 任务归属校验(无 token 401 / 他人或无主任务 403 / 不存在 404)- 归属校验收敛为
TaskQueryService.ensure_task_access供 task_router 与 advanced_router 共用(原 D5) - 上传预检
pythonocc_available从硬编码 true 改为惰性真实探测 - bcrypt 口令治理:创建侧超 72 字节显式拒绝、验证侧截断比较
SECRET_KEY未配置 /RUSTFS_*缺失时惰性校验抛明确错误- 完成态任务未持久化
analysis_metrics时/api/status组装视图 500 修复 - 测试基线:96 passed
- 回归测试:
tests/test_status_endpoint_auth.py8 项 - 接口行为变化已同步 ../API_CONTRACT.md §3.2
批次 1(2026-09-16,部署正确性)
- 主处理链路改走 RustFS:分派入参
file_path→stp_file_id(原 D6) - 处理方按 PG 元数据从 RustFS 下载源文件到任务专属临时目录(保留原始文件名,下游产物命名不变),任务结束即清理
- RustFS 不可用时回退
STPFile.file_path节点本地路径;compose 为 backend / celery 增加共享卷uploads_data/html_data作过渡兜底 AUTO_MIGRATE开关(settings / .env.example / compose 透传),默认true保持单机开发行为(原 D12)- 迁移目录
alembic/→migrations/(修复import alembic命中本地目录遮蔽真实包的命名冲突)+ Docker 镜像补COPY migrations/+COPY alembic.ini - Dockerfile.moldinsight 改为 conda 运行时原生执行,基础镜像 tag 锁定(原 D13 主体)
- compose 关键项去弱默认:
SECRET_KEY/ADMIN_PASSWORD改${VAR:?}强制显式配置;create_admin_user对空口令显式报错 - 测试基线:98 passed, 1 skipped
- 回归测试:
tests/test_deployment_config.py
批次 2(2026-09-16,任务一致性模型)
- Redis 进程内存回退彻底删除(写 no-op / 读 None,Redis 仅热缓存),PG 为任务状态单一事实源(原 D7)
- 批量元数据入库:
processing_tasks新增batch_id列(迁移a3f8c2d91e47),GET /api/batch/{batch_id}改为 PG 聚合查询 +STPFile.user_id归属校验 - 删除 Redis batch key 与进程内 dict 双通道
TaskQueryServicePG 视图与 batch 聚合响应补progress/current_step- 型腔分模失败不再吞异常 → 任务 failed(原 D8)
- 持久化事务边界收口:数据本体写方法只 flush,编排层分阶段原子收口(阶段 A 几何+网格、阶段 B 型腔+HTML+特征+指标+验证),失败先 rollback 再置 failed(原 D9)
- 进度/状态更新保留即时 commit(长任务进度可见性)
- 测试基线:105 passed, 1 skipped
- 回归测试:
tests/test_batch_status_pg.py4 项 +tests/test_redis_no_fallback.py3 项
批次 3(2026-09-17,API 与代码结构)
advanced_router按职责拆为 design / cost / machining / export 四个子路由,端点路径不变(原 D1)- 全部请求体改 Pydantic 模型(
request.json()手动解析退役),校验失败统一 422 _get_cached_import上提为core_modules.py共用- 路由装载失败显式化:
ROUTE_MODULES清单 +route_registry,失败经/api/health呈现 degraded(pythonocc真实探测),DEBUG 下 fail fast - 纯 Python 重计算端点统一
asyncio.to_thread投放线程池,不再阻塞事件循环 StorageIntegrationService(867 行)按职责拆为 TaskStorage / AnalysisStorage / FileHistory 三服务(原 D14 部分)MAX_FILE_SIZE接线生效、celery_app 复用Settings.redis_url(原 D14 收尾)- 连带修复:管理员重置密码改 JSON body(原裸 str 参数被解析为 query param,前端发 body 必 422);Dockerfile.celery 的 FROM tag 与实际构建 tag 对齐
- 接口变更三件套随批完成:openapi.json 重导出(76 paths)+ 前端
gen:api - 测试基线:122 passed, 2 skipped
- 回归测试:4 个测试文件共 17 项(
test_advanced_split_contract/test_route_load_status/test_config_governance/test_auth_password_reset)
批次 4(2026-09-17,架构演进)
- 共享 ORM 按模块拆分(原 D3 主体):891 行
shared/models/database.py(31 模型类三类同居)拆为shared/models/base.py(唯一 Base + 归属约定)/shared/models/identity.py(7 表)/moldinsight/models/(9 表)/inventory/models/(catalog/warehouse/trading/finance 15 表) - 三条跨模块 ORM relationship(
User.stp_files/STPFile.user/STPFile.product)经全仓核实均无使用方,直接删除;跨模块桥接收敛为裸 FK 硬规则(../ARCHITECTURE.md §5.1) - 约 45 处 import 全量改写,无兼容 facade
- 全量注册点收敛为 migrations/env.py 与 tests/conftest.py
- 零调用方的死方法
db_manager.create_tables一并删除 _reset_occ_executor补cancel_futures=True(旧实现下"慢恢复"的旧线程会继续消化旧队列,与新 executor 并发操作非线程安全的 OCC,属数据竞争而非单纯泄漏,原 D10 短期治理)- 吞吐路线定稿于
topics/performance/OCC_THROUGHPUT.md(短期 A:celery prefork 伸缩 + max-tasks-per-child 兜底;中期 B:run_occ 接口进程化 + kill-on-timeout 根治) - 顺手清偿 D15:
vite.config.ts删除未用的mode参数,vue-tsc -b恢复通过 - 回归测试:
tests/test_model_ownership.py(31 表全量注册 / 单模块独立 mapper 配置 / 旧模块无 facade) - 测试基线:125 passed, 2 skipped
- 接口面零变化(无 openapi 重导出)
批次 4 后续专项(2026-09-18)
- D11 清偿:可视化报告 RustFS 单源化
- 写侧 HTMLGenerator 每任务写临时目录,
.html/_summary.json/_data.json三件统一裸传 RustFS 报告键html/reports/{filename} - 读侧
/htmlStaticFiles 本地挂载删除,新增代理路由html_report_router.py(报告键直取 → 遗留html/{hash}.jsonJSON 包装解析 → 本地卷存量兜底 → 404) - 防路径穿越(单段文件名校验),URL 形状
/html/{filename}不变 - 部署:celery 服务摘除
html_data卷;Dockerfile.moldinsight 删除COPY html_output/ - 已知约束:报告路由不做认证(iframe 无法携带 Authorization 头)
- 删除
get_stp_file_with_data的死数据块
- 写侧 HTMLGenerator 每任务写临时目录,
- OCC 方案 A 部署参数落地:
CELERY_CONCURRENCY/CELERY_MAX_TASKS_PER_CHILD进 Dockerfile.celery + compose + .env.example - D2 清偿:铝价响应带
source: "simulated";前端按来源渲染"模拟数据 · 参考走势"标注;死代码getAluminumPrice删除 - D10 方案 B 实施:
run_occ(fn, *args)→run_occ(op_name, payload);常驻 OCC 进程池 + kill-on-timeout 根治残留线程泄漏 - CI 门禁:
.gitea/workflows/ci.yml三 job(pytest / 前端构建 / openapi 漂移检测) - 接口变更三件套随批完成:openapi.json 重导出(76→77 paths,新增
/html/{filename})+ 前端gen:api再生 - 测试基线:143 passed, 0 skipped
后续小步治理(2026-09-21 ~ 2026-09-22)
- 2026-09-21 inventory 业务层继续沉淀批次(4 批):
customer / supplier / warehouse→master_data_servicematerial_routes(价格历史 / 趋势 / 供应商关联)→material_serviceproduct_routes(CRUD / BOM / from-task 跨模块桥接)→product_servicedashboard_routes(首页统计 / 低库存预警)→dashboard_service
- 2026-09-22 schema / datetime 现代化弃用清零(D12):
- 全仓 14 处
class Config:+ auth_routes 三处全部迁移到model_config = ConfigDict(from_attributes=True) auth_service.py中datetime.utcnow()改用datetime.now(timezone.utc)
- 全仓 14 处
- 测试基线最终落点:126 passed, 4 skipped,零 deprecation warning