Commit Graph

333 Commits

Author SHA1 Message Date
cjw 3615902e8d fix(deploy): .env 显式写 BACKEND_PORT=(空值),backend 不再随机分配宿主机端口 2026-09-26 21:14:19 +08:00
cjw f0110df164 🔧 build(deploy): .env / .env.example 补 FRONTEND_PORT=10003 + 端口段重写
部署机实测:docker compose up -d --build 报
WARN[0000] The "FRONTEND_PORT" variable is not set. Defaulting to a blank string.
根因:之前所有 compose 端口相关 commit 只改 .env.example,未同步 .env;
服务器 .env 缺失 FRONTEND_PORT 与 BACKEND_PORT,前端容器端口因此暴露到
docker 自动分配的 32769,backend 暴露到 32770。

修复:
- .env 端口段补全:FRONTEND_PORT=10003 + BACKEND_PORT(注释留空)
- .env.example 端口段重写:与 .env 对齐,强化 DEPLOYMENT.md §1.2 选择 A
  约定(前端独占宿主端口、backend 不暴露)
- 移除冗余的 HOST/PORT(uvicorn compose 命令硬编码 8000/8001,
  直跑场景由 --host/--port 控制;env 注入未读取,删除减少心智负担)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 21:11:03 +08:00
cjw d7f92f1816 📝 docs(deploy): DEPLOYMENT §1.2 写入端口约定——选择 A 为默认
约定:unified 模式下前端独占宿主端口,backend 不暴露宿主端口,
浏览器始终只面对一个源,由前端 Nginx 同域反代到 backend,彻底
消除 CORS。BACKEND_PORT 留空 = 不暴露,仅 docker 网络内可达。

§1.2 补全:.env 最小集(FRONTEND_PORT=10003)、端口链路示意、
何时选 B(临时调试 / 压测 / k8s 健康检查,不建议常规生产用,会
引入 CORS 与攻击面问题)、缺配置 fail-fast 的硬约束说明,
并指向 .env.example 与 PORT_CONFIG.md 详细配置。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 21:03:49 +08:00
cjw a889671bb5 🔧 build(deploy): 取消宿主端口映射的默认值——.env 必须显式配置
三个 compose 文件的 ports 映射去掉 ${VAR:-默认值} 兜底:

- docker-compose.yml: frontend ${FRONTEND_PORT:-10003} → ${FRONTEND_PORT}
- docker-compose.moldinsight.yml: moldinsight ${MOLDINSIGHT_PORT:-10003} → ${MOLDINSIGHT_PORT}
- docker-compose.inventory.yml: inventory ${INVENTORY_PORT:-10004} → ${INVENTORY_PORT}

端口必须由 .env 显式配置,否则 compose 启动期 fail-fast(避免悄悄用了
某个端口导致宿主端口冲突或调试时困惑)。

注:DB_PORT:5432 / REDIS_PORT:6379 等应用行为默认值保留(与"宿主机
端口"不同,属基础设施默认端口,不影响端口暴露策略)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 21:00:59 +08:00
cjw aaf887507f 🐛 fix(deploy): backend 宿主机端口受 .env BACKEND_PORT 控制
上一版 backend 写死 expose: ["8000"](不暴露宿主),但这违背"全局服
务的最终映射到宿主机只能受 .env 中的端口配置决定"的原则——调试场景下
.env 没办法把 backend 暴露到宿主。

修正:backend ports 改为 "${BACKEND_PORT:-}:8000",由 .env 决定:
- BACKEND_PORT 留空/未设 = 不暴露宿主端口(仅经前端 /api 反代)
- BACKEND_PORT=10003 = 暴露宿主 10003(调试 / 压测用)

.env.example 同步加注释说明。

验证:模拟 .env 两种场景下,端口映射完全由 BACKEND_PORT 决定。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:58:10 +08:00
cjw b934b737e8 🐛 fix(deploy): 修 unified backend 与 frontend 抢占宿主 10003 冲突
上一版把 frontend 与 backend 都映射 10003:8000,会触发 docker 启动时
"bind: address already in use"。修正:

- docker-compose.yml backend ports 改为 expose: ["8000"]——不映射宿主机,
  仅在 docker 网络 gemold_network 内被 frontend 经 backend:8000 反代访问
- .env.example 删除 BACKEND_PORT 字段(不再需要)
- PORT_CONFIG / DEPLOY_PORT 端口映射表/示例同步:unified backend 不暴露
  宿主机端口,统一经前端 /api 反代

验证:yaml 渲染后无任何 service 对抢宿主端口(unified 仅 frontend 暴露
$FRONTEND_PORT=10003;moldinsight-only 仅 moldinsight 暴露 10003;
inventory-only 仅 inventory 暴露 10004)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:56:20 +08:00
cjw cf465d28e2 🔧 build(deploy): frontend 容器内端口 80→8000——避免占用宿主 80
- deploy/Dockerfile.frontend EXPOSE 80 → 8000
- deploy/nginx/frontend.conf listen 80 → 8000
- docker-compose.yml frontend ports "${FRONTEND_PORT:-10003}:80" → ":8000"

容器内端口统一 8000 系列(backend=8000、inventory=8001、frontend=8000),
frontend 不再抢占 80(留给外层 nginx/监控);1024+ 无需 root 权限。
宿主机端口(10003)保持不变。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:53:21 +08:00
cjw e65dcc2d39 🔧 build(deploy): 端口默认值统一 10003/10004——前端入口固定 10003
约定"容器内部端口无所谓,重要的是宿主机端口;前端 = 10003"。

- .env.example 端口段重写:移除冗余 HOST/PORT(uvicorn 命令硬编码,
  无人读 env)+ 移除误导注释;FRONTEND_PORT/BACKEND_PORT/MOLDINSIGHT_PORT
  默认 10003,INVENTORY_PORT 默认 10004
- docker-compose.yml frontend 默认 80→10003、backend 8000→10003,删除
  backend service 内冗余 HOST/PORT env
- docker-compose.moldinsight.yml / docker-compose.inventory.yml 默认
  端口同步
- DEPLOY_PORT §3 / PORT_CONFIG §1 §2 端口映射示例同步
- STATUS 补录

验证:yaml 渲染端口映射 unified frontend 10003→80、backend 10003→8000,
moldinsight 10003→8000,inventory 10004→8001。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:45:38 +08:00
cjw 0dfb3c63b1 📝 docs(status): 补 2026-09-26 批次——3 个部署机收尾修复
- --workdir 误用修复(celery 5.x 已移除):compose command 改为
  cd /app/src && exec celery -A celery_app worker
- 裸 up 不重建已有镜像澄清(DEPLOYMENT/README/OPERATIONS/LINUX_SETUP)
- build.sh 三步描述统一(celery 复用 backend 镜像)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:01:28 +08:00
cjw 8f8a7ea00a 🐛 fix(deploy): celery worker 启动命令移除 --workdir(celery 5.x 已移除)
部署机实测:celery worker --workdir=/app/src 报
"No such option '--workdir'"(旧 Dockerfile.celery 用的参数,
celery 4.x 兼容,5.x 已删除;项目锁的是新版本)。

修复:compose 的 moldinsight-celery command 改为
  cd /app/src && exec celery -A celery_app worker ...
直接切到 src/ 目录启动 worker(celery_app.py 内 include=
["celery_tasks"] 是裸模块名,需在 src/ 下才能解析),不依赖
celery 版本是否支持 --workdir。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-26 20:01:05 +08:00
cjw b03431b511 📝 docs(deploy): 明确裸 up 不重建已有镜像 + 修正 build.sh 三步描述
- DEPLOYMENT §1.2 / LINUX_SETUP §11 / README / OPERATIONS 补充:
  docker compose up -d 对本地已有同名镜像不会自动重建,更新代码后
  需 up -d --build 或先 build(部署机实测复用旧镜像后澄清)
- build.sh 描述由四步修正为 base → backend → frontend 三步(celery
  复用 backend 镜像,随 Dockerfile.celery 移除的文档收尾)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 17:05:01 +08:00
cjw 7717c9fa14 🔧 build(deploy): 镜像 base 由 miniconda 切换 Miniforge
Dockerfile.moldinsight FROM continuumio/miniconda3:24.7.1-0 →
condaforge/miniforge3:24.7.1-2:

- conda-forge 默认且唯一渠道,无 defaults 渠道与 Anaconda ToS 顾虑
- 与 CI 已用的 Miniforge 安装(.gitea/workflows/ci.yml 清华镜像)及
  开发机 Miniforge 环境同源
- tag 经 Docker Hub 社区用例确认存在;conda create 步骤与
  python=3.12 / pythonocc-core=7.9.0 锁定不变
- TECH_DEBT D13 锁定记录同步;STATUS 补录

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 16:33:40 +08:00
cjw 2fd1b3da21 🐛 fix(deploy): 修干净机器首次构建两处必挂——.dockerignore 排除 deploy/ + celery 并行构建依赖
部署机首次 docker compose up -d 实测暴露:

- .dockerignore 自"重写独立dockerfile"起排除整个 deploy/,而
  Dockerfile.frontend COPY deploy/nginx/frontend.conf、Dockerfile.moldinsight
  COPY deploy/requirements-*.txt → COPY not found。历史一直有旧镜像兜底未暴露;
  BuildKit 不支持重包含被排除目录的子文件,直接移除该行
- Dockerfile.celery FROM gemold-backend:latest 在 compose 并行构建下引用
  尚不存在的本地镜像必挂 → 删除 Dockerfile.celery,moldinsight-celery 改为
  与 API 服务同一 build 声明 + 同一 gemold-backend:latest tag(compose 去重
  只构建一次),celery 仅以 command: 覆盖启动 worker,参数语义不变
- build.sh/.bat 移除 gemold-celery 构建步骤;OPERATIONS / OCC_THROUGHPUT /
  TECH_DEBT / .env.example 的 Dockerfile.celery 指向同步改写;STATUS 补录

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 16:18:44 +08:00
cjw 4373fafd55 🐛 fix(deploy): 移除服务 profiles——裸 up / 裸 -f 恢复一键可用
compose 规则:声明了 profiles 的服务在不带 --profile 时永远不会被选中。
拆分首版保留 profiles(双保险设计)导致部署机实测 docker compose up -d
与 -f <file> up -d 均报 "no service selected",与"一键部署、换文件名换
模式"的核心诉求互斥,故彻底移除:

- 三个 compose 文件的全部 services 去掉 profiles 块,模式切换唯一入口 = -f 文件名
- 历史 --profile full/moldinsight/inventory 写法随之失效(目标服务本就已
  移出默认文件,兼容无意义);文档/构建脚本提示/STATUS 日志同步改为失效声明
- frontend/README 移除"仅起前端"用法(前端反代依赖 unified backend,推荐整栈)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 16:09:26 +08:00
cjw a548623ea5 📦 build(deploy): Compose 按部署模式拆分三文件——换文件名即换模式一键部署
- docker-compose.yml(unified 默认入口)/ docker-compose.moldinsight.yml / docker-compose.inventory.yml 三文件一一对应三种部署模式,profiles 字段保留(--profile 旧命令双保险可用)
- 修复两个既有部署隐患:moldinsight-only 场景 celery depends_on 悬空;moldinsight service image 统一为 gemold-backend:latest 与 Dockerfile.celery FROM 对齐(废弃 gemold-moldinsight tag)
- gemold_network / uploads_data / html_data 固定 name 命名;inventory-only 不声明卷避免空卷;每文件内 x-base-env anchor 收敛重复 environment(SECRET_KEY/ADMIN_PASSWORD fail-fast 保留)
- 文档同步 11 处:DEPLOYMENT §1.1 一键部署总表 + §2 三模式命令、LINUX_SETUP §6/§11、README、OPERATIONS §4、build.sh/.bat 提示、PORT_CONFIG / DEPLOY_PORT / STORAGE_SETUP / frontend/README
- STATUS.md 补 2026-09-24 批次日志

验证:三文件 YAML 结构静态校验通过;5 个 service environment 键与拆分前逐一比对零丢失(39/39、34/34、39/39、34/34、20/20)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 15:28:13 +08:00
cjw 6baa6b0d0a docs:ARCHITECTURE / ROADMAP 同步 D17 Human-in-Loop 完成
更新两个权威文档与 D17 端到端闭环对齐:

- docs/ROADMAP.md §2.2 主线二"moldinsight 工程化增强"重点方向
  加一条 D17 已完成条目(2026-09-23~24,3 个 commit:数据 + 权限 +
  写入 API / 算法接缝 + OCC payload / 前端按钮 + Dialog + 经验角标;
  详见 TECH_DEBT.md D17),与既有 ~~XXX~~(YYYY-MM-DD 完成)格式一致

- docs/ARCHITECTURE.md 新增 §6.4 D17 Human-in-Loop 老师傅经验反馈闭环
  —— 已完成段:用 ASCII 数据流图展示老师傅点反馈按钮 → 路由层
  → service 写入 → 续期衰减 → 上传新 STP 触发 resolve_for_process_params
  → OCC payload 透传 → planner 算法加成 → ResultView 渲染的端到端链路

  段内列出"硬规则遵守"(跨模块 FK 守 §5.1、OCC payload 守
  occ_worker.py:7-8、D9 边界不破、init_db.py 幂等修复已落)和
  "重量级约束"(weight 仅正向、sample_count<2 时 ×0.5、graceful 退化、
  角色门控),最后给测试基线指针

  放在 §6.3"文档与结构尚未完全同步"之后作为"已完成端到端闭环"
  对照示例,便于新成员理解 D17 在系统中的位置

文档侧仅变更,无代码改动;按 AGENTS.md §4.1 映射表,模块边界
(ARCHITECTURE.md)/ 演进路线(ROADMAP.md)相关变更同步。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 10:15:36 +08:00
cjw 483f158424 D17 批 3:前端按钮 + Dialog + 经验角标——闭环可视
让老师傅能用起来:ResultView 加按钮组 + HumanFeedbackDialog 组件 +
经验角标渲染 + 接口变更三件套随批完成,admin / process_engineer 可在
分析结果页标记采纳 / 建议调整 / 拒绝,下次同指纹产品分析自动消费。

变更内容:
- frontend/src/modules/moldinsight/components/HumanFeedbackDialog.vue(new)
  新组件:t-dialog + t-form + t-radio-group 三选一(采纳 / 建议调整 /
  拒绝)+ t-textarea 原因 + t-textarea 调整建议(仅 adjust 模式显隐);
  走 moldinsightApi.submitExperienceFeedback,提交成功后 emit 'submitted'
  让父组件重新拉 hints 刷新角标;表单打开时 watch 重置;loading 态 /
  error 通知复用 shared/notification
- frontend/src/modules/moldinsight/ResultView.vue
  - import moldinsightApi 与 HumanFeedbackDialog
  - state 增加 feedbackDialogVisible / hintsFingerprint / hints
  - Scheme interface 扩展 axis / confidence_score / method 顶层字段
    (前端 TS 类型与后端 Pydantic 字段对齐)
  - computed taskId / hintsByAxis / currentAxisHint(避免 undefined index
    TS 报错)/ canGiveFeedback(is_superuser || roles 含 process_engineer)
  - function loadExperienceHints(onMounted + 提交后各调一次;失败静默
    退化,按钮仍可点)/ openFeedbackDialog / onFeedbackSubmitted
  - 模板:
    * 推荐方案卡片 summary-header 加 t-tag theme="success" variant="light"
      经验角标("📚 历史经验 N 条",title 提示采纳/拒绝计数)
    * export-buttons-bar 加 👍 老师傅反馈 按钮(v-if="canGiveFeedback"
      角色门控;theme="default" size="small" 与既有 6 个 t-button 视觉一致)
    * </t-loading> 之后挂 HumanFeedbackDialog(v-model:visible + 11 个 props
      透传 scheme_id / axis / fingerprint / score_at_submit / 等)
- frontend/src/shared/api-client.ts moldinsightApi 加两个方法:
  getExperienceHints(taskId) / submitExperienceFeedback(taskId, data)
  (返回类型由 openapi-typescript 自动生成,无需手维护)

接口变更三件套随批完成:
- openapi.json 重导出(unified app,含 ExperienceFeedbackCreate /
  ExperienceFeedbackResponse / ExperienceHintItem / ExperienceHintsResponse
  四个新 schema,2 个新 path 出现)
- npm run gen:api 再生 frontend/src/types/api.ts(生成物,禁止手改)
- npm run build 通过(vue-tsc + vite,ResultView 包 37.18 kB / 11.91 kB
  gzip)

- docs/STATUS.md 顶部加 2026-09-24 批 3 日志条目
- docs/TECH_DEBT.md D17 追加批 3 已完成描述 + 缩减剩余工作(仅剩批 4
  按需排期)

设计要点:
- canGiveFeedback 借 (appStore.user as any).roles 临时绕过 AppUser
  类型不含 roles 的限制(前端硬规则:"不要硬编码 'admin' 字符串"——
  按 role.code === 'process_engineer' 匹配)
- currentAxisHint 解决 selectedScheme.axis 可能 undefined 的索引报错
- onFeedbackSubmitted 提交后立即 loadExperienceHints 触发角标刷新,
  实现"写入即消费"前端可见

后端基线:192 passed, 13 skipped(批 3 纯前端,不动后端)。
D17 闭环端到端可用:admin / process_engineer 在 ResultView 点反馈
按钮 → Dialog 提交 → 角标即时刷新 + 下次同指纹产品分析算法加成。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 10:03:09 +08:00
cjw 505f3591ab D17 批 2:算法接缝(OCC payload 通道 + hints 透传到分模评分)—— 闭环通
让批 1 沉淀的老师傅经验 hints 真接入分模方案生成:
processing_service 拉同指纹 hints 装进 OCC worker payload,
planner 透传到 candidate_generator(axis 优先级加成)和
scheme_scorer(score_breakdown 新字段 + total_score 加成),
写入即消费闭环通。

变更内容:
- src/moldinsight/core/parting_candidate_generator.py
  generate_candidates(..., hints=None):_build_axis_metrics 末尾按 hints
  加成(priority_score += weight × 20 上限;sample_count ≥ 2 + weight ≥ 0.5
  → method 标签升级 "human_experience_primary")
- src/moldinsight/core/parting_scheme_scorer.py
  score_schemes(schemes, *, hints=None) keyword-only:_score_scheme 新增
  human_hint_bonus 字段(weight × 12 上限;sample_count < 2 时 ×0.5 折半
  防信号不足过度影响);_compute_human_hint_bonus 静态方法解析 axis
  (parting.axis → axis → Z);bonus 纳入 total_score
- src/moldinsight/core/multi_scheme_planner.py
  generate_plan(..., hints=None):透传 hints 到 candidate_generator 与
  scheme_scorer;global_summary.applied_hints 注入返回供前端 ResultView
  渲染经验角标
- src/moldinsight/services/processing_service.py
  _step_generate_cavity 加 db_session 形参;调用
  experience_feedback_service.resolve_for_process_params 拿同指纹 hints,
  装进 run_occ payload 顶层 experience_hints;解析失败回退空 list
  不阻塞主流程(旧任务不因 receives 闭包退化)
- src/moldinsight/core/occ_worker.py
  _op_generate_cavity:payload.get("experience_hints") or {} 透传给
  planner.generate_plan(..., hints=...);普通 dict 跨进程 pickle 安全
  (满足 occ_worker.py:7-8 硬规则)
- tests/test_experience_feedback_algorithm.py(new)11 例:
  - candidate_generator 3 例(无 hints 默认 / hints 加成 / sample_count < 2 不升级)
  - scheme_scorer 4 例(无 hints 无 bonus / bonus 加成 / sample_count 折半 /
    weight=0 不加成)
  - multi_scheme_planner 2 例 OCC-gated(透传 / applied_hints 默认空)
  - processing_service 2 例 OCC-gated(payload 含 experience_hints /
    解析失败回退空 list)

设计取舍:
- keyword-only hints:避免与位置参数混淆
- weight 仅正向上有效:max(0, (adopted-rejected)/total),老师傅拒绝
  的不扣分老算法,只让采纳的加分
- signal-noise 控制:sample_count < 2 时 bonus ×0.5,但 priority_score
  仍加成(候选方向仍偏向,避免完全无信号)
- graceful degradation:hints 解析失败回退空 list,主流程继续

- docs/STATUS.md 顶部加 2026-09-23 批 2 日志条目
- docs/TECH_DEBT.md D17 追加批 2 已完成描述 + 缩减剩余工作(仅剩批 3 / 4)

测试基线:192 passed, 13 skipped(净增 7 通过 + 4 OCC-gated skip)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:21:33 +08:00
cjw 2c9ba9d6b3 D17 批 1:Human-in-Loop 老师傅经验反馈(数据 + 权限 + 写入 API)
新增 experience_feedback 表(32 表迁移,alembic head b7d1f4a92c3e),
老师傅对系统推荐方案给出"采纳 / 调整 / 拒绝"反馈,按"产品指纹 +
工艺参数"为键跨任务匹配,下次同指纹产品分析自动消费。

变更内容:
- src/moldinsight/models/experience_feedback.py(new)ORM:Base 单点来源、
  跨模块裸 FK(user_id / processing_task_id / stp_file_id)、不建 ORM
  relationship;fingerprint JSON 列存跨任务匹配键
- src/moldinsight/models/__init__.py 导出 ExperienceFeedback
- migrations/versions/b7d1f4a92c3e_add_experience_feedback.py(new)32 表
  迁移;fingerprint 列 PG 下加 GIN 索引(jsonb_path_query 支持)
- src/shared/database/init_db.py 加 3 个权限码(view_experience_feedback /
  feedback_experience_hint / manage_experience_feedback)+ 新角色
  process_engineer;admin 角色 permissions 同步补齐;init_permissions /
  init_roles 改为按 code 比对(新增保留已有 id,避免 FK 引用失效)——
  修复既有 DB 启动期漏掉新权限的幂等 bug
- src/moldinsight/services/experience_feedback_service.py(new)service:
  compute_fingerprint 分桶(bbox_aspect / volume_bucket / face_bucket /
  undercut_class / material_family / is_foam)/ record_feedback(D9 边界:
  service.flush + 路由 commit;D17 衰减:同 stp_file_id 整体续期 90 天 TTL,
  无 celery beat 依赖)/ list_hints_for_task / resolve_for_process_params
- src/moldinsight/api/experience_feedback_router.py(new)路由:Pydantic
  模型写在路由文件内(项目硬规则);POST /api/tasks/{task_id}/experience-feedback
  + GET /api/tasks/{task_id}/experience-hints;归属 TaskQueryService.ensure_task_access
  + User.has_permission 全仓首次调用点
- src/moldinsight/api/__init__.py ROUTE_MODULES 注册新路由
- tests/test_model_ownership.py EXPECTED_TABLES 加 experience_feedback
  (31→32)
- tests/test_experience_feedback_fingerprint.py(new)分桶参数化覆盖
  bbox / volume / face / undercut / material / is_foam 各边界值
- tests/test_experience_feedback_router.py(new)API 契约 9 例
  (401/403/422/200 路径 + 衰减续期 + 任务归属校验 + ORM 注册收口)
- docs/STATUS.md 顶部加 2026-09-23 批 1 日志条目
- docs/TECH_DEBT.md D17 加批 1 已完成描述 + 剩余工作清单
- docs/API_CONTRACT.md §3.2 加 D17 端点表格

测试基线:185 passed, 9 skipped(净增 59 测试)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 16:11:17 +08:00
cjw 79441a8a87 批次6:D4文档治理收口 + D13锁文件流程固化
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>
2026-09-23 09:59:02 +08:00
cjw 64dc85bd14 批次5:inventory服务下沉收口 + Pydantic v2 / datetime弃用清零
- inventory业务层下沉(薄路由+service orchestration模式):
  - customer/supplier/warehouse -> master_data_service
  - material_routes(价格历史/趋势/供应商关联)-> material_service
  - product_routes(CRUD/BOM/from-task跨模块桥接)-> product_service
  - dashboard_routes(首页统计/低库存预警)-> dashboard_service
- inventory侧新增service回归覆盖(dashboard 2 / master_data 10 /
  material 10 / product 14),含跨模块桥接测试种子
- Pydantic v2弃用清零:全仓14处 class Config 全部迁移到
  model_config = ConfigDict(from_attributes=True)(含 shared auth)
- datetime.utcnow() 弃用清零:auth_service 3处统一改 datetime.now(timezone.utc)
- 同步文档:STATUS / ROADMAP / TECH_DEBT(D12清偿)/ AGENTS 代码地图

测试基线:126 passed, 4 skipped(无deprecation warning)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-22 16:13:45 +08:00
cjw c51e6b793a x 2026-09-18 18:21:01 +08:00
cjw e728dcd226 批次4后续专项完成:D11清偿 + OCC方案B实施 + 部署参数 + D2诚实标注 + CI门禁
① D11 HTML 报告 RustFS 单源化(TECH_DEBT P2 清偿):可视化产物写任务临时目录后
   裸传报告键 html/reports/{filename}(文件名寻址),/html StaticFiles 挂载删除,
   新增 html_report_router 根路径代理(报告键→遗留 JSON 包装→本地卷兜底→404,
   防穿越);URL 形状 /html/{filename} 不变,持久化引用零迁移;celery 摘除
   html_data 卷,镜像不再烤入陈旧报告;顺带删除 get_stp_file_with_data 死数据块
② OCC 方案 B(D10 清偿):run_occ(op_name, payload) 契约 + 常驻工作进程池
   (occ_process_pool + occ_worker 操作注册表),超时/崩溃 terminate 换新补位、
   任务级超时 recover 整体重建,残留线程泄漏根治;TopoDS 不跨进程(generate_cavity
   分模 + 方案 STEP 持久化全在子进程内,返回 export_manifest);删除内存形状缓存链、
   CADExporter.export_mold_results、shape_loader(→ stp_materializer)
③ OCC 方案 A 部署参数:CELERY_CONCURRENCY / CELERY_MAX_TASKS_PER_CHILD 进
   Dockerfile.celery + compose + .env.example
④ D2 诚实标注:铝价响应带 source: "simulated",前端按来源渲染标注(原硬编码
   "上海期货交易所"属虚假声明),死代码 getAluminumPrice 删除
⑤ CI 门禁:.gitea/workflows/ci.yml 三 job(pytest / 前端构建含 vue-tsc /
   openapi 漂移检测)

接口变更三件套随批完成(openapi 76→77 paths + gen:api + 前端构建通过;方案 B
接口面零变化)。测试基线 143 passed, 0 skipped(新增 16 项)。文档六处同步。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-18 17:22:01 +08:00
cjw 0e6b3b1811 后端设计治理:批次 0-4 全部完成(安全/部署/一致性/结构/架构)
按 ROADMAP §3.1 治理批次推进的后端设计审查整改:

- 批次 0(安全):/api/status/{task_id} 补 JWT 鉴权与任务归属校验;
  pythonocc_available 真实探测;bcrypt 超 72 字节显式拒绝;
  SECRET_KEY/RUSTFS_* 惰性校验,代码侧弱默认移除
- 批次 1(部署正确性):主处理链路改走 RustFS(分派入参 stp_file_id 化,
  worker 按 object_key 下载);AUTO_MIGRATE 开关 + 迁移目录 alembic/→migrations/
  修复包遮蔽(自动迁移此前从未真正生效);OCC 镜像改 conda 原生执行 +
  基础镜像 tag 锁定;compose 关键项改 ${VAR:?} 强制显式配置
- 批次 2(任务一致性):删除 Redis 进程内存回退,PG 为任务状态单一事实源;
  批量元数据入库(processing_tasks.batch_id,迁移 a3f8c2d91e47);
  型腔失败任务标 failed 不再静默 completed;事务边界收口
  (数据本体写 flush-only、失败先回滚再置 failed、进度更新保留即时 commit)
- 批次 3(API 与代码结构):592 行 advanced_router 拆为 design/cost/machining/
  export 四子路由,请求体全量 Pydantic 化;ROUTE_MODULES + route_registry
  (/api/health 呈现 degraded,DEBUG fail fast);纯计算端点统一 to_thread;
  StorageIntegrationService 按职责三拆;MAX_FILE_SIZE 接线生效、
  celery 复用 Settings.redis_url;管理员重置密码改 JSON body(端到端断裂修复);
  openapi.json 重导出(76 paths)+ 前端 gen:api
- 批次 4(架构演进):共享 ORM 按模块拆分(shared/models/base.py + identity.py、
  moldinsight/models/、inventory/models/,删除三条无使用方的跨模块
  relationship,跨模块桥接收敛为裸 FK 硬规则,无兼容 facade);
  OCC executor 重建补 cancel_futures=True(消除旧队列被慢恢复线程
  并行消化的数据竞争);OCC 吞吐方案设计先行
  (docs/topics/performance/OCC_THROUGHPUT.md);顺手清偿 D15
  (vite.config.ts 未用参数致 npm run build 失败)

测试基线:125 passed, 2 skipped(pytest + sqlite+aiosqlite;归属边界、
路由契约、配置治理、鉴权回归等随批新增)
文档同步:STATUS / TECH_DEBT / ROADMAP / ARCHITECTURE / API_CONTRACT /
OPERATIONS / AGENTS

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-17 16:15:49 +08:00
cjw 4537faf2c4 优化 2026-09-16 17:55:04 +08:00
cjw 3f120417d1 文档 2026-09-15 18:07:33 +08:00
cjw 6464e89942 文档 2026-09-15 18:02:25 +08:00
cjw 4fbff0761a x 2026-09-02 18:18:42 +08:00
cjw 5e531ffe1e 文档目录结构简洁化 2026-09-01 18:05:18 +08:00
cjw bee439cf34 x 2026-08-31 18:01:34 +08:00
cjw 3ea59551db 模块拆分 init 2026-08-27 14:53:22 +08:00
cjw e6ddea33a2 fix(frontend): 移除 openapi-typescript 依赖,解决 TS6 peer 冲突导致服务器 npm install 失败
- openapi-typescript 仅用于本地 gen:api 生成类型,不参与构建,服务器不需要
- gen:api 改用 npx --yes openapi-typescript@7.13.0 按需拉取
- 服务器 npm install 不再需要 --legacy-peer-deps
2026-08-04 10:13:08 +08:00
cjw 3b5f70f1f3 chore(deploy): 移除仓库内 deploy.sh,避免与服务器钩子脚本同名冲突 2026-08-03 17:08:45 +08:00
cjw eab4137c0a fix(frontend)+chore(deploy): 修复明细表格渲染 + static/ 改服务器构建
- SalesOrdersTab/PurchaseOrdersTab/MaterialsTab/ProductsTab: t-table 明细行不渲染(push/splice 改新数组引用)+ Decimal 算术类型错误(Number() 包裹)
- static/ 不再进 git(.gitignore),改为 deploy.sh 在服务器 npm run build
- 新增 deploy.sh:拉取 + 构建前端 + 重启后端
2026-08-03 16:12:34 +08:00
cjw 4ec6f98f10 x 2026-07-31 16:55:52 +08:00
cjw 2f811b986c fix(deploy): 恢复跟踪 .env,修复服务器 git pull 后无 .env 导致服务无法启动 2026-07-31 16:07:44 +08:00
cjw 5016458e44 x 2026-07-31 15:57:13 +08:00
cjw a330757946 xx 2026-07-30 11:01:00 +08:00
cjw 853c478657 xxx 2026-07-30 10:30:50 +08:00
cjw cf6d708566 xxx 2026-07-27 15:54:25 +08:00
cjw a8c0e1af3d docs: 更新演进路线图(P1-2 注册表 + P1-4 Alembic 进度)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 11:05:03 +08:00
cjw 00ca81287e feat(db): 引入 Alembic 取代裸 DDL 迁移
- alembic init + env.py 接 settings/models metadata(asyncpg->psycopg2 同步 URL)
- 补 3 个 CheckConstraint 到 models(原只在裸 DDL)
- 离线生成初始迁移(31 表+约束+95 索引,全 sa.* 通用类型)
- init_db 用 _run_alembic_migrations(自动基线+upgrade head)替换 create_tables+ensure_schema_updates(删 92 行裸 DDL)
- 删破坏性 migrate_db.py(drop_all)
- 既有 DB 首次启动自动 stamp 基线,无需手动

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 11:04:23 +08:00
cjw 66ba6e00f5 refactor(moldinsight): 引入可插拔注册表(MoldGenerator + FeatureDetector)
- 新增 MoldGeneratorRegistry:multi_scheme_planner 消除 if-else,按 mold_type 选生成器
- 新增 FeatureDetectorRegistry:geometry_analyzer._detect_features 消除 6 个检测器硬编码
- 新增模具类型/特征检测器只需 register 一行
- 移除 OCC ThreadPoolExecutor(注册表本身串行执行)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 11:03:16 +08:00
cjw f3d2951dc3 x 2026-07-20 10:16:27 +08:00
cjw 8493f0df03 init 2026-07-13 17:44:50 +08:00
cjw 975fa1ffac init 2026-07-13 17:44:37 +08:00
cjw 6b3188e693 x 2026-06-23 09:38:31 +08:00
cjw f6d8829071 x 2026-06-16 11:15:03 +08:00
cjw f71a48d3b8 x 2026-06-12 13:55:38 +08:00
cjw c4616cbbee x 2026-06-11 15:08:42 +08:00