From 8d1f86756d9af4ac7ff04598966078299ae3111d Mon Sep 17 00:00:00 2001 From: WuYongJie Date: Tue, 31 Mar 2026 10:23:56 +0800 Subject: [PATCH] =?UTF-8?q?chore(=E5=8D=8F=E4=BD=9C=E6=B5=81=E7=A8=8B):=20?= =?UTF-8?q?=E6=94=B6=E5=8F=A3=E5=9B=A2=E9=98=9F=E5=8D=8F=E4=BD=9C=E8=A7=84?= =?UTF-8?q?=E5=88=99=E4=B8=8E=E4=B8=BB=E7=BA=BF=E6=B8=85=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为新平台主链补齐团队协作模式、模块边界、任务单和提测清单。 新增本地清理脚本,移除误纳入仓库的 npm 缓存日志,并把清理后 type-check 失效的问题收回到脚本层修复。 --- .gitignore | 18 + docs/README.md | 30 +- docs/workflow/任务单模板.md | 149 ++++++++ docs/workflow/同事交接模板.md | 92 +++++ docs/workflow/团队协作模式.md | 225 ++++++++++++ docs/workflow/提测与验收清单.md | 108 ++++++ docs/workflow/模块边界说明.md | 228 ++++++++++++ docs/workflow/规范审查清单.md | 40 +++ docs/项目总览.md | 55 ++- .../2025-12-11T08_22_48_825Z-debug-0.log | 334 ------------------ ...25-12-11T08_22_48_825Z-eresolve-report.txt | 148 -------- .../2025-12-11T08_22_50_432Z-debug-0.log | 18 - .../2025-12-11T08_24_49_960Z-debug-0.log | 12 - package.json | 3 +- scripts/cleanup-local-artifacts.js | 78 ++++ scripts/run-type-check.js | 50 +++ 16 files changed, 1050 insertions(+), 538 deletions(-) create mode 100644 docs/workflow/任务单模板.md create mode 100644 docs/workflow/同事交接模板.md create mode 100644 docs/workflow/团队协作模式.md create mode 100644 docs/workflow/提测与验收清单.md create mode 100644 docs/workflow/模块边界说明.md create mode 100644 docs/workflow/规范审查清单.md delete mode 100644 local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-debug-0.log delete mode 100644 local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-eresolve-report.txt delete mode 100644 local-packages/npm-cache/cache/_logs/2025-12-11T08_22_50_432Z-debug-0.log delete mode 100644 local-packages/npm-cache/cache/_logs/2025-12-11T08_24_49_960Z-debug-0.log create mode 100644 scripts/cleanup-local-artifacts.js create mode 100644 scripts/run-type-check.js diff --git a/.gitignore b/.gitignore index f390d121..8870a99e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,21 @@ yarn-error.log* next-env.d.ts /src/generated/prisma + +# local workspace artifacts +.codex-logs/ +_logs/ +output/ +temp/ +public/uploads/ +*.vsix +nul +%OUT% +.dev-*.log +.qa-*.log +.start-*.log +.next-start-*.log +dev-server.log +trace-deprecation-build.log +typecheck-latest.log +local-packages/npm-cache/cache/_logs/ diff --git a/docs/README.md b/docs/README.md index 3c23e6d4..c79f68d4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ -# 3D 家具安装展示系统 - 文档导航 +# 家具开品平台 - 文档导航 -> **最后更新**:2026-03-13 -> **项目状态**:生产基础能力已具备,当前进入结构化数据与装配体验持续收口阶段 +> **最后更新**:2026-03-31 +> **项目状态**:新平台一期骨架已落地,旧 `CAD -> 装配步骤` 链继续作为兼容链保留 --- @@ -25,6 +25,13 @@ - **[快速测试指南](./开发指南/快速测试指南.md)** - 测试相关指南 - **[项目上下文](./agent-memory/project-context.md)** - 当前高频回归点、默认工作流、项目目标 +### 🤝 团队协作 +- **[团队协作模式](./workflow/团队协作模式.md)** - 当前推荐分工、分支规则、提交流程 +- **[模块边界说明](./workflow/模块边界说明.md)** - 新平台主链、包装协作、旧 CAD 兼容链的边界 +- **[任务单模板](./workflow/任务单模板.md)** - 给人和 Codex 共用的任务模板 +- **[提测与验收清单](./workflow/提测与验收清单.md)** - 提交前必须过的最小检查 +- **[同事交接模板](./workflow/同事交接模板.md)** - 给非程序员同事和 Codex 的交接模板 + ### 🧠 长期记忆与问题收口 - **[长期记忆导航](./agent-memory/README.md)** - 当前长期记录入口 - **[长期决策日志](./agent-memory/decision-log.md)** - 近期关键决策 @@ -79,6 +86,13 @@ docs/ ├── README.md # 📖 本文档(导航入口) ├── 项目总览.md # 🎯 项目整体情况 ├── PHASES_8_9_SUMMARY.md # 📊 最新阶段总结 +├── workflow/ # 🤝 团队协作规则 +│ ├── 团队协作模式.md +│ ├── 模块边界说明.md +│ ├── 任务单模板.md +│ ├── 提测与验收清单.md +│ ├── 同事交接模板.md +│ └── 规范审查清单.md │ ├── 架构设计/ # 🏗️ 架构相关文档 │ ├── auth-system-design.md # 认证系统设计 @@ -128,9 +142,9 @@ docs/ ### 当前重点 -- `CAD 导入 -> SKU 级结构数据 -> 装配编辑 -> 3D 回放 -> 分享` 是当前主线 -- 生产脚本、健康检查、部署配置已经到位,重心已转到数据准确性和体验稳定性 -- 当前还在持续收口:板材点选、孔位高亮、折角线、爆炸视图、镜头调度、安装顺序生成 +- 新主线已切到:`资产中心 -> 自动组合 -> 草稿组 -> 包装方案 -> 正式入库 -> 轻仓库` +- 旧 `CAD 导入 -> SKU 级结构数据 -> 装配编辑 -> 3D 回放` 继续保留为兼容链 +- 当前重点不是继续堆页面,而是先把资产精度、模块边界和团队协作规则立住 ### 当前建议查看顺序 @@ -156,6 +170,6 @@ docs/ --- -**文档版本**:v2.1 -**最后更新**:2026-03-13 +**文档版本**:v2.2 +**最后更新**:2026-03-31 **维护者**:开发团队 diff --git a/docs/workflow/任务单模板.md b/docs/workflow/任务单模板.md new file mode 100644 index 00000000..77ec9026 --- /dev/null +++ b/docs/workflow/任务单模板.md @@ -0,0 +1,149 @@ +# 任务单模板 + +这个模板既给人看,也给 Codex 看。 +原则:不要只写“帮我改一下”,要把边界、目标和验收写明白。 + +--- + +## 1. 任务基本信息 + +- 任务名称: +- 所属模块: +- 负责人: +- 所在分支: +- 计划开始时间: + +--- + +## 2. 这次要解决什么问题 + +用人话写: + +- 当前现象: +- 希望变成什么样: +- 为什么现在必须做: + +--- + +## 3. 本次只做什么 + +列 3 到 5 条最核心内容: + +- +- +- + +--- + +## 4. 本次明确不做什么 + +这个部分一定要写,不然 AI 和人都容易顺手扩范围: + +- +- +- + +--- + +## 5. 影响范围 + +### 页面 / 入口 + +- + +### API + +- + +### 服务 / 仓库 / 数据表 + +- + +### 文档 + +- + +--- + +## 6. 验收标准 + +至少写到“看见什么算完成”: + +- [ ] +- [ ] +- [ ] + +--- + +## 7. 验证方式 + +把能跑的命令和要人工点的页面都写出来: + +- 命令: + - `npm run type-check` + - `npm test -- --runTestsByPath <按需补>` + - `npm run build` +- 人工验证: + - + - + +--- + +## 8. 禁止改动区 + +把这次不应该碰的目录直接写死: + +- +- +- + +--- + +## 9. 风险和依赖 + +- 风险: +- 依赖谁继续接: +- 是否需要后续补文档: + +--- + +## 10. 直接发给 Codex 的提示词模板 + +```text +请在当前仓库处理下面这个任务。 + +任务名称:<任务名称> +所属模块:<模块名> +目标:<一句话说清楚> + +本次只做: +1. <事项 1> +2. <事项 2> +3. <事项 3> + +本次不做: +1. <事项 1> +2. <事项 2> + +关键目录: +- <目录 1> +- <目录 2> + +禁止改动: +- <目录或文件 1> +- <目录或文件 2> + +验收标准: +1. <标准 1> +2. <标准 2> +3. <标准 3> + +验证要求: +- 至少跑 `npm run type-check` +- 按需跑相关测试 +- 能跑就跑 `npm run build` + +需要同步更新的文档: +- <文档路径 1> +- <文档路径 2> +``` diff --git a/docs/workflow/同事交接模板.md b/docs/workflow/同事交接模板.md new file mode 100644 index 00000000..c551e205 --- /dev/null +++ b/docs/workflow/同事交接模板.md @@ -0,0 +1,92 @@ +# 同事交接模板 + +适用对象:不一定是程序员,但会用 Codex 协作的人。 +目标:让接手的人不用先读完整仓库,也能知道从哪里开始、哪里不能乱改。 + +--- + +## 1. 先把这 5 句话说清楚 + +- 这次要做的模块是什么 +- 现在做到哪一步了 +- 你接下来只需要做什么 +- 哪些目录不能碰 +- 做完后怎么验证 + +--- + +## 2. 交接卡片模板 + +```text +任务名称:<名称> +当前状态:<已完成到哪里> +你接手的部分:<只写这次要做的内容> + +先看这几个文件: +- <文件 1> +- <文件 2> +- <文件 3> + +不要改这些地方: +- <目录或文件 1> +- <目录或文件 2> + +验收标准: +1. <标准 1> +2. <标准 2> +3. <标准 3> + +验证方式: +- `npm run type-check` +- `npm test -- --runTestsByPath <补具体文件>` +- `npm run build` +- 人工打开:<页面路径> +``` + +--- + +## 3. 直接发给 Codex 的交接提示词 + +```text +请接手这个仓库里的一个局部任务,不要扩范围。 + +任务名称:<任务名称> +你现在只负责:<一句话> + +当前背景: +<用 3 到 5 行说清楚现在已经做到哪一步> + +先看这些文件: +- <文件 1> +- <文件 2> +- <文件 3> + +禁止改动: +- <目录或文件 1> +- <目录或文件 2> + +本次验收标准: +1. <标准 1> +2. <标准 2> +3. <标准 3> + +验证要求: +- 至少跑 `npm run type-check` +- 按需跑相关测试 +- 能跑就跑 `npm run build` + +完成后请按下面格式回报: +1. 现在你要做什么 +2. 是否完成 +3. 还有没有风险 +``` + +--- + +## 4. 交接时最容易漏掉的事 + +- 没说清楚这次只做什么 +- 没说清楚哪些目录不能碰 +- 没说清楚新平台主链和旧兼容链的边界 +- 没写验证方式 +- 没同步文档,导致下一个人继续靠猜 diff --git a/docs/workflow/团队协作模式.md b/docs/workflow/团队协作模式.md new file mode 100644 index 00000000..2eadf9c4 --- /dev/null +++ b/docs/workflow/团队协作模式.md @@ -0,0 +1,225 @@ +# 团队协作模式 + +适用范围:`furniture-3d-system` 仓库。 +目标:把当前项目从“单人连续开发”切换成“多人并行协作,但主链不打架”的模式。 + +--- + +## 1. 先记住一句话 + +这个仓库现在默认按下面这条主链协作: + +`资产中心 -> 自动组合 -> 草稿组 -> 包装方案 -> 成品展示 -> 正式入库 -> 轻仓库` + +旧的 `CAD -> 装配步骤` 链继续保留,但它是**历史兼容链**,不是新开品主链。 + +--- + +## 2. 当前推荐分工 + +### 平台主线负责人 + +负责新平台一期主链: + +- 资产中心 +- 自动组合 +- 草稿组 +- 正式入库 +- 轻仓库 +- 新平台公共导航与页面骨架 + +默认涉及目录: + +- `src/app/asset-center` +- `src/app/auto-combinations` +- `src/app/draft-groups` +- `src/app/intake` +- `src/app/warehouse` +- `src/app/api/asset-center` +- `src/app/api/auto-combinations` +- `src/app/api/draft-groups` +- `src/app/api/intake` +- `src/app/api/warehouse` +- `src/components/platform` +- `src/lib/open-product` +- `src/lib/planning` +- `src/server/services/asset-center.service.ts` +- `src/server/services/combination.service.ts` +- `src/server/services/draft-group.service.ts` +- `src/server/services/intake.service.ts` +- `src/server/services/planning.service.ts` +- `src/server/services/warehouse.service.ts` + +### 包装负责人 + +负责包装方案增强,以及未来对接新平台的包装结果。 + +默认涉及目录: + +- `src/app/api/pre-skus/[id]/packaging` +- `src/app/api/products/[id]/packaging` +- `src/server/services/packaging.service.ts` +- `src/server/services/draft-group.service.ts` +- `src/server/repositories/packaging.repository.ts` +- `src/server/repositories/draft-group.repository.ts` +- `docs/开发指南/包装方案增强` + +默认边界: + +- 可以增强包装对象、包装结果、包装展示。 +- 不直接改自动组合规则。 +- 不直接改正式入库规则。 +- 不把包装流程做成独立顶层系统入口。 + +### 兼容链负责人 + +负责旧产品详情、旧装配编辑器、CAD 导入链、板件/孔位/五金/装配步骤兼容维护。 + +默认涉及目录: + +- `src/app/products/[id]` +- `src/app/products/[id]/assembly` +- `src/app/products/[id]/skus/[skuId]` +- `src/app/products/[id]/skus/[skuId]/assembly` +- `src/app/api/products/[id]/assembly` +- `src/app/api/products/[id]/panels` +- `src/app/api/products/[id]/holes` +- `src/app/api/products/[id]/import-hardware` +- `src/app/api/holes` +- `src/app/api/hardware` +- `src/components/assembly` +- `src/components/3d` +- `src/lib/assembly-generator.ts` +- `src/lib/panel-assembly-semantic.ts` +- `src/lib/sku-cad-data.ts` +- `src/server/services/assembly.service.ts` +- `src/server/services/panel.service.ts` +- `src/server/services/sku-cad-import.helper.ts` + +默认边界: + +- 只做兼容维护、语义接入、步骤生成和旧链体验修正。 +- 不把旧产品详情页重新拉回成新平台主入口。 +- 不在旧链里偷偷新增新平台业务真相。 + +--- + +## 3. 分支规则 + +### 主分支 + +- `main` 只允许合并,不允许日常直接开发。 +- 如果远端开启保护分支,就继续保持。 + +### 开发分支 + +统一使用: + +- `codex/<负责人>-<模块>` + +示例: + +- `codex/wuyongjie-open-platform` +- `codex/xuxiake-packaging` +- `codex/team-cad-compat` + +### 合并方式 + +- 默认先推自己的功能分支。 +- 通过 compare / PR 再进入 `main`。 +- 没有过验收清单,不合并。 + +--- + +## 4. 每个任务都按这个流程走 + +1. 先建一张任务单。 +2. 写清楚本次只做什么、不做什么、验收标准是什么。 +3. 明确归属模块,不跨模块顺手乱改。 +4. 开发前先读对应模块边界说明。 +5. 改完后同步必要文档。 +6. 跑最小验证。 +7. 做一次规范自审,再推分支。 + +--- + +## 5. 人和 AI 都要遵守的几条硬规则 + +### 先修根因,不打补丁 + +- 影响 3D 拼装、命名、包装、BOM、安装步骤的数据,优先在数据源修。 +- 不允许只在页面上压报错、绕校验。 + +### 不跨层 + +- Page / Route 不直接写 Prisma 业务逻辑。 +- Route 负责收参、鉴权、返回。 +- Service 负责业务规则。 +- Repository 负责数据访问。 + +### 不混主链和兼容链 + +- 新平台主链的数据真相在 `AssetFamily / AssetVariant / DraftGroup / PreSku`。 +- 旧 `Product / SKU / Panel / Hole / ProductHardware` 继续服务兼容链。 +- 包装本期要能挂接 `PreSku`,但不直接跳过草稿组去造正式产品。 + +### 不破坏统一视觉 + +- 新平台页面优先复用 `src/components/platform`。 +- 旧装配编辑器继续走现有视觉体系,不另起一套杂样式。 + +--- + +## 6. 本地目录管理规则 + +### 需要长期保留的 + +- 源码 +- 迁移 +- 测试 +- 正式文档 +- 确认要进仓库的设计稿或说明 + +### 默认视为本地产物的 + +- `.dev-*.log` +- `.qa-*.log` +- `.start-*.log` +- `.next-start-*.log` +- `dev-server.log` +- `.codex-logs/` +- `_logs/` +- `output/` +- `temp/` +- `public/uploads/` + +### 推荐习惯 + +- 提交前先运行:`npm run clean:local` +- 然后再看:`git status --short` + +--- + +## 7. 提交前最少要交代什么 + +- 这次改的是哪个模块 +- 本次只做了什么 +- 哪些地方明确没做 +- 跑了哪些验证 +- 有没有风险或依赖别人继续接 + +详细清单见:`docs/workflow/提测与验收清单.md` + +--- + +## 8. 给 Codex 的一句话协作口径 + +如果要把任务转给 AI,建议在任务里直接写明: + +- 当前目标 +- 所属模块 +- 禁止改动的目录 +- 验收标准 +- 需要同步更新的文档 + +模板见:`docs/workflow/任务单模板.md` 和 `docs/workflow/同事交接模板.md` diff --git a/docs/workflow/提测与验收清单.md b/docs/workflow/提测与验收清单.md new file mode 100644 index 00000000..06b8e741 --- /dev/null +++ b/docs/workflow/提测与验收清单.md @@ -0,0 +1,108 @@ +# 提测与验收清单 + +目标:让“做完了”变成有证据,不靠感觉。 + +--- + +## 1. 提测前先过这 6 项 + +- [ ] 任务范围没有失控,没有顺手改无关模块 +- [ ] 关键文档已同步 +- [ ] 先跑过 `npm run clean:local` +- [ ] `git status --short` 里没有不该提交的日志、缓存、临时文件 +- [ ] 改动文件和任务单一致 +- [ ] 自己能用一句话说清根因和修复方式 + +--- + +## 2. 最小验证命令 + +### 默认必跑 + +```bash +npm run type-check +``` + +### 按需补跑 + +```bash +npm test -- --runTestsByPath <相关测试文件> +``` + +### 能跑就跑 + +```bash +npm run build +``` + +--- + +## 3. 页面 / 接口人工确认 + +至少确认与任务直接相关的入口: + +- [ ] 对应页面能打开 +- [ ] 关键按钮/表单/保存动作能走通 +- [ ] 关键接口返回正常 +- [ ] 没有把别的入口改坏 + +--- + +## 4. 文档确认 + +下面这些情况要同步文档: + +- 改了模块边界 +- 改了页面入口 +- 改了 API 入参或返回 +- 改了数据模型 +- 改了交接方式 + +最少同步到: + +- `docs/workflow/团队协作模式.md` +- `docs/workflow/模块边界说明.md` +- 对应模块的专项说明文档 + +--- + +## 5. 规范自审 + +这是自审,不是独立复审。 +结论只能写: + +- `passed` +- `passed with warnings` +- `rejected` + +自审固定只看 3 件事: + +- 架构有没有被破坏 +- 视觉有没有跑偏 +- 这次是不是根因修复 + +如果不通过,就不要推 `main` 合并链路。 + +--- + +## 6. 提测说明模板 + +```text +现在要做什么: +<一句话说明这次改动解决了什么问题> + +是否完成: +<已完成 / 部分完成> + +验证结果: +- type-check:<通过 / 未跑> +- test:<通过 / 未跑> +- build:<通过 / 未跑> +- 人工验证:<写页面和结果> + +风险: +- <没有风险 / 写明确风险> + +规范审查结论: +这是自审,不是独立复审; +``` diff --git a/docs/workflow/模块边界说明.md b/docs/workflow/模块边界说明.md new file mode 100644 index 00000000..9c2d9a90 --- /dev/null +++ b/docs/workflow/模块边界说明.md @@ -0,0 +1,228 @@ +# 模块边界说明 + +目标:让人和 AI 在开工前先知道“哪里是新平台主链,哪里是旧兼容链,哪里不能乱碰”。 + +--- + +## 1. 页面与入口边界 + +### 新平台主链入口 + +- `/`:新平台首页导航 +- `/asset-center`:资产中心 +- `/auto-combinations`:自动组合 +- `/draft-groups`:草稿组列表 +- `/draft-groups/[id]`:草稿组详情 +- `/intake`:正式入库 +- `/warehouse`:轻仓库 + +### 旧兼容链入口 + +- `/products` +- `/products/[id]` +- `/products/[id]/assembly` +- `/products/[id]/skus/[skuId]` +- `/products/[id]/skus/[skuId]/assembly` + +### 不要混的原则 + +- 新平台入口负责“规划、预览、入库前整理”。 +- 旧兼容链负责“历史产品、CAD 导入、板件/孔位/五金/装配步骤”。 +- 不要把旧产品详情页重新改成新平台首页。 + +--- + +## 2. 新平台主链边界 + +### 前端目录 + +- `src/app/page.tsx` +- `src/app/asset-center` +- `src/app/auto-combinations` +- `src/app/draft-groups` +- `src/app/intake` +- `src/app/warehouse` +- `src/components/platform` + +### API 目录 + +- `src/app/api/asset-center` +- `src/app/api/auto-combinations` +- `src/app/api/draft-groups` +- `src/app/api/intake` +- `src/app/api/planning` +- `src/app/api/pre-skus` +- `src/app/api/series-templates` +- `src/app/api/warehouse` + +### 服务与仓库 + +- `src/server/services/asset-center.service.ts` +- `src/server/services/combination.service.ts` +- `src/server/services/draft-group.service.ts` +- `src/server/services/intake.service.ts` +- `src/server/services/planning.service.ts` +- `src/server/services/series-template.service.ts` +- `src/server/services/warehouse.service.ts` +- `src/server/repositories/asset-center.repository.ts` +- `src/server/repositories/draft-group.repository.ts` +- `src/server/repositories/planning.repository.ts` +- `src/server/repositories/series-template.repository.ts` +- `src/server/repositories/warehouse.repository.ts` + +### 纯规则与类型 + +- `src/lib/open-product` +- `src/lib/planning` + +### 这里的业务真相是什么 + +- 资产族:`AssetFamily` +- 规格款:`AssetVariant` +- 草稿组:`DraftGroup` +- 准 SKU:`PreSku` +- 入库结果:正式 `Product / SKU` + +### 不要做的事 + +- 不直接从自动组合跳过草稿组生成正式产品。 +- 不把旧 `Product / SKU` 当作新平台组合阶段的数据真相。 +- 不把包装做成绕过草稿组的独立系统。 + +--- + +## 3. 包装协作边界 + +### 当前包装入口分两条 + +- 新平台承接口:`src/app/api/pre-skus/[id]/packaging/route.ts` +- 旧正式产品口:`src/app/api/products/[id]/packaging` + +### 主要服务 + +- `src/server/services/packaging.service.ts` +- `src/server/services/draft-group.service.ts` +- `src/server/repositories/packaging.repository.ts` +- `src/server/repositories/draft-group.repository.ts` + +### 当前约定 + +- 包装结果最终按单个 `PreSku` 保存。 +- 正式产品包装链保留,作为兼容与发布后使用。 +- 工艺图组合本期只预留接口,不在主线里单独展开。 + +### 包装负责人不要乱碰的地方 + +- 自动组合生成规则 +- 草稿组转正式 SKU 的规则 +- 旧 CAD 的板件/孔位/五金推导链 + +--- + +## 4. 旧 CAD 兼容链边界 + +### 页面目录 + +- `src/app/products/[id]` +- `src/app/products/[id]/assembly` +- `src/app/products/[id]/skus/[skuId]` +- `src/app/products/[id]/skus/[skuId]/assembly` +- `src/components/assembly` +- `src/components/3d` + +### API 目录 + +- `src/app/api/products/[id]/assembly` +- `src/app/api/products/[id]/panels` +- `src/app/api/products/[id]/holes` +- `src/app/api/products/[id]/import-hardware` +- `src/app/api/holes` +- `src/app/api/hardware` +- `src/app/api/product-hardware` + +### 服务与库 + +- `src/server/services/assembly.service.ts` +- `src/server/services/panel.service.ts` +- `src/server/services/hole.service.ts` +- `src/server/services/hardware.service.ts` +- `src/server/services/sku-cad-import.helper.ts` +- `src/server/repositories/panel.repository.ts` +- `src/server/repositories/hole.repository.ts` +- `src/server/repositories/hardware.repository.ts` +- `src/server/repositories/product-hardware.repository.ts` + +### 纯规则与共享链路 + +- `src/lib/assembly-generator.ts` +- `src/lib/panel-assembly-semantic.ts` +- `src/lib/sku-cad-data.ts` +- `src/lib/3d/engine.ts` + +### 当前约定 + +- 装配语义是旧链增强能力,不是新平台主数据源。 +- 旧链可以继续生成安装步骤和预览,但不要反向主导新平台资产模型。 + +--- + +## 5. 共享层边界 + +### 所有人都可能会碰到,但不要随手改 + +- `prisma/schema.prisma` +- `prisma/migrations` +- `src/server/services/index.ts` +- `src/server/repositories/index.ts` +- `src/app/layout.tsx` +- `src/app/api/platform/schemas.ts` + +### 共享层规则 + +- 任何 Prisma 模型调整,都必须带迁移。 +- 任何新接口,都要有明确输入输出 DTO。 +- 任何跨模块字段变更,都要先同步文档,再改代码。 + +--- + +## 6. 看到这些情况要先停一下 + +- 一个任务同时改新平台主链和旧兼容链,但任务单里没写原因。 +- Route 里开始直接写 Prisma 查询。 +- 包装开始自己造一套 `Product / SKU`。 +- 页面样式开始绕开 `src/components/platform` 和既有视觉标准。 +- 改动影响命名、BOM、包装、安装步骤,但没说明数据来源。 + +--- + +## 7. 开工前最少要看什么 + +### 做新平台主链 + +先看: + +- `docs/workflow/团队协作模式.md` +- `src/components/platform/platform-navigation.ts` +- `src/lib/open-product/types.ts` +- `src/server/services/planning.service.ts` +- `src/server/services/draft-group.service.ts` + +### 做包装 + +先看: + +- `docs/workflow/团队协作模式.md` +- `docs/开发指南/包装方案增强/包装方案增强-同事交接说明.md` +- `src/app/api/pre-skus/[id]/packaging/route.ts` +- `src/server/services/packaging.service.ts` +- `src/server/services/draft-group.service.ts` + +### 做旧 CAD 兼容链 + +先看: + +- `docs/solutions/workflow-issues/CAD插件装配语义导出改造说明-20260325.md` +- `src/app/products/[id]/assembly/AssemblyEditorWorkspace.tsx` +- `src/components/assembly/AssemblyEditorClient.tsx` +- `src/server/services/assembly.service.ts` +- `src/lib/assembly-generator.ts` diff --git a/docs/workflow/规范审查清单.md b/docs/workflow/规范审查清单.md new file mode 100644 index 00000000..7a42f10c --- /dev/null +++ b/docs/workflow/规范审查清单.md @@ -0,0 +1,40 @@ +# 规范审查清单 + +## 1. 审查只看三件事 + +### 架构有没有被破坏 + +- 新平台主链和旧 CAD 兼容链有没有混写 +- 模块边界有没有被打穿 +- 数据归属有没有乱掉 +- 本次是不是顺手扩大了无关范围 + +### 视觉有没有跑偏 + +- 有没有明显偏离当前统一视觉标准 +- 有没有临时拼凑感很强的新界面 +- 新页面和现有页面的层级、间距、交互有没有失控 + +### 这次是不是根因修复 + +- 是不是找到了真正原因 +- 还是只是加了补丁绕过去 +- 会不会把问题转移到别的模块 + +## 2. 结论只能是这三种 + +- `passed` +- `passed with warnings` +- `rejected` + +## 3. 必须写明是不是独立复审 + +- 如果是自己审自己,必须写: + - `这是自审,不是独立复审` + +## 4. 直接判定 rejected 的情况 + +- 明显破坏模块边界 +- 明显破坏统一视觉 +- 明显只是补丁式修复 +- 没做最小验证就宣称完成 diff --git a/docs/项目总览.md b/docs/项目总览.md index 2b4018fc..e250777e 100644 --- a/docs/项目总览.md +++ b/docs/项目总览.md @@ -1,7 +1,7 @@ -# 3D 家具安装展示系统 - 项目总览 +# 家具开品平台 - 项目总览 -> **最后更新**:2026-03-13 -> **项目状态**:生产基础能力已具备,当前进入结构化数据与装配体验持续收口阶段 +> **最后更新**:2026-03-31 +> **项目状态**:新平台一期骨架已落地,当前进入团队协作收口与业务主链稳定阶段 --- @@ -12,38 +12,47 @@ | Phase 1-8 | ✅ 已完成 | 认证、权限、组织架构、产品/SKU、反馈、日志、报表等核心业务闭环 | | Phase 9 | ✅ 已完成 | 性能优化与安全测试用例已配置 | | Phase 10 | ✅ 已完成 | 备份/恢复、健康检查、部署脚本与配置校验 | -| 当前迭代 | 🚧 持续收口 | SKU 级结构数据、CAD 导入链路、装配编辑器与 3D 回放体验持续修正 | +| 当前迭代 | 🚧 新平台一期 | 资产中心、自动组合、草稿组、正式入库、轻仓库骨架已进入主线 | -> 当前代码已经具备上线运行所需的基础能力,但产品主线仍在围绕“CAD 数据准确性 + 装配体验稳定性”做持续收口。 +> 当前项目已经从“CAD 导入生成安装步骤工具”升级为“组件资产 -> 组合规划 -> 3D 展示 -> 入库管理”的开品平台。旧 CAD 链继续保留,但不再是新主链。 --- ## ✅ 已实现功能(基于代码) -### 1) 业务与协作 +### 1) 新平台一期主链 + +- 资产中心:板材、组件、五金、包装材料统一入口 +- 自动组合:按资产族生成候选组合 +- 草稿组:承接多个准 SKU 的预览、包装和展示 +- 正式入库:从草稿组转正式产品 / SKU +- 轻仓库:查看正式 SKU、包装成品、库存和库位 + +### 2) 业务与协作 - JWT 登录、首次登录流程、RBAC 6 角色 - 部门/小组/成员管理 - 产品(SPU)与 SKU 管理、协作者与可见性 - 回收站与恢复 - 分享链接与访问统计 -### 2) 3D/装配与工艺 +### 3) 3D/装配与工艺 - 装配步骤管理、装配版本与恢复 - 安装顺序保存并直接生成步骤(`generate-from-order`) - 装配 PDF 生成 - 板件管理、孔位检测 - 五金件库、自动匹配/映射记忆、导入与同步 - SKU 详情页与装配编辑器共享 3D 板件 / 孔位 / 爆炸 / 回放主链路 +- 装配语义保存、预览与步骤生成优先级已接入旧链 -### 3) 材质与主题 +### 4) 材质与主题 - 材质库与材质分类 - 主题配置与激活(管理员) -### 4) 包装与报表 +### 5) 包装与报表 - 包装方案与箱体明细 - 操作日志与审计报表(用户活动、产品变更、SKU 交接、反馈统计) -### 5) 运维与生产就绪 +### 6) 运维与生产就绪 - 备份与恢复脚本(数据库/文件/全量) - 健康检查 API 与系统健康页面 - 配置校验、部署脚本、Docker 生产配置 @@ -52,9 +61,19 @@ ## 🧭 主要页面与入口 -- `/`:首页(产品列表) +- `/`:新平台首页导航 +- `/asset-center` +- `/auto-combinations` +- `/draft-groups` +- `/intake` +- `/warehouse` +- `/products` +- `/products/[id]` +- `/products/[id]/assembly` +- `/products/[id]/skus/[skuId]` +- `/products/[id]/skus/[skuId]/assembly` - `/login`、`/first-login` -- `/products`、`/products/[id]`、`/products/new` +- `/products/new` - `/users` - `/admin/categories`、`/admin/materials`、`/admin/themes` - `/system-health` @@ -96,16 +115,18 @@ ## 🔎 需要关注/可迭代点 -- **真实 SKU 终验**:板材点选、孔位高亮、折角线、爆炸与镜头调度仍需持续人工回归 -- **装配回放体验**:镜头计划已开始收口到共享模型,但仍需更多真实样例验证 -- **导入与绑定精度**:继续围绕 CAD 导出数据、孔位 / 五金件绑定做准确性收口 -- **端到端测试**:目前主要为 Jest 单测/集成测试,E2E 仍未系统配置 +- **资产精度**:新平台后续成败取决于 `AssetVariant` 的拼装数据是否准确 +- **包装对接**:包装结果需要稳定挂到 `PreSku`,不能重新依附旧产品详情页逻辑 +- **兼容链稳定**:旧 CAD 链仍需持续回归,避免影响历史产品使用 +- **团队协作**:后续必须按模块边界协作,不能继续多人直接混改同一条主链 --- ## 📖 相关文档 - `docs/README.md`:文档导航 +- `docs/workflow/团队协作模式.md`:当前协作规则 +- `docs/workflow/模块边界说明.md`:模块边界 - `docs/部署指南.md`:部署说明 - `docs/运维指南.md`:备份/恢复/监控 - `docs/Phase10完成报告.md`:生产就绪落地说明 @@ -113,4 +134,4 @@ --- **维护者**:开发团队 -**文档版本**:v2.1 +**文档版本**:v2.2 diff --git a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-debug-0.log b/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-debug-0.log deleted file mode 100644 index 97faa031..00000000 --- a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-debug-0.log +++ /dev/null @@ -1,334 +0,0 @@ -0 verbose cli C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -1 info using npm@11.6.1 -2 info using node@v24.11.0 -3 silly config load:file:C:\Program Files\nodejs\node_modules\npm\npmrc -4 silly config load:file:D:\3danzhuang\furniture-3d-system\.npmrc -5 silly config load:file:C:\Users\Mr_Wu01\.npmrc -6 silly config load:file:C:\Users\Mr_Wu01\AppData\Roaming\npm\etc\npmrc -7 verbose title npm ci -8 verbose argv "ci" "--prefer-offline" "--no-audit" -9 verbose logfile logs-max:10 dir:D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_48_825Z- -10 verbose logfile D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_48_825Z-debug-0.log -11 silly logfile done cleaning log files -12 silly packumentCache heap:4496293888 maxSize:1124073472 maxEntrySize:562036736 -13 silly idealTree buildDeps -14 silly fetch manifest react@^16.8.0 || ^17.0.0 || ^18.0.0 -15 silly packumentCache full:https://registry.npmmirror.com/react cache-miss -16 http fetch GET 200 https://registry.npmmirror.com/npm 317ms -17 http fetch GET 200 https://registry.npmmirror.com/react 504ms (cache miss) -18 silly packumentCache full:https://registry.npmmirror.com/react set size:1154769 disposed:false -19 warn ERESOLVE overriding peer dependency { -19 warn ERESOLVE code: 'ERESOLVE', -19 warn ERESOLVE edge: { -19 warn ERESOLVE type: 'peer', -19 warn ERESOLVE name: 'react', -19 warn ERESOLVE spec: '^16.8.0 || ^17.0.0 || ^18.0.0', -19 warn ERESOLVE error: 'INVALID', -19 warn ERESOLVE from: { -19 warn ERESOLVE name: '@react-spring/animated', -19 warn ERESOLVE version: '9.7.5', -19 warn ERESOLVE location: 'node_modules/@react-spring/animated', -19 warn ERESOLVE isWorkspace: false, -19 warn ERESOLVE dependents: [Array] -19 warn ERESOLVE } -19 warn ERESOLVE }, -19 warn ERESOLVE dep: { -19 warn ERESOLVE name: 'react', -19 warn ERESOLVE version: '18.3.1', -19 warn ERESOLVE whileInstalling: { -19 warn ERESOLVE name: '@react-spring/animated', -19 warn ERESOLVE version: '9.7.5', -19 warn ERESOLVE path: 'D:\\3danzhuang\\furniture-3d-system\\node_modules\\@react-spring\\animated' -19 warn ERESOLVE }, -19 warn ERESOLVE location: 'node_modules/react', -19 warn ERESOLVE isWorkspace: false, -19 warn ERESOLVE dependents: [ [Object] ] -19 warn ERESOLVE }, -19 warn ERESOLVE force: false, -19 warn ERESOLVE isMine: false, -19 warn ERESOLVE strictPeerDeps: false, -19 warn ERESOLVE current: { -19 warn ERESOLVE name: 'react', -19 warn ERESOLVE version: '19.2.1', -19 warn ERESOLVE location: 'node_modules/react', -19 warn ERESOLVE isWorkspace: false, -19 warn ERESOLVE dependents: [ -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object], -19 warn ERESOLVE [Object], [Object] -19 warn ERESOLVE ] -19 warn ERESOLVE }, -19 warn ERESOLVE peerConflict: { -19 warn ERESOLVE current: { -19 warn ERESOLVE name: 'react', -19 warn ERESOLVE version: '19.2.1', -19 warn ERESOLVE location: 'node_modules/react', -19 warn ERESOLVE isWorkspace: false, -19 warn ERESOLVE dependents: [Array] -19 warn ERESOLVE }, -19 warn ERESOLVE peer: { -19 warn ERESOLVE name: 'react', -19 warn ERESOLVE version: '18.3.1', -19 warn ERESOLVE whileInstalling: [Object], -19 warn ERESOLVE location: 'node_modules/react', -19 warn ERESOLVE isWorkspace: false, -19 warn ERESOLVE dependents: [Array] -19 warn ERESOLVE } -19 warn ERESOLVE } -19 warn ERESOLVE } -20 warn ERESOLVE overriding peer dependency { -20 warn ERESOLVE code: 'ERESOLVE', -20 warn ERESOLVE edge: { -20 warn ERESOLVE type: 'peer', -20 warn ERESOLVE name: 'react', -20 warn ERESOLVE spec: '^16.8.0 || ^17.0.0 || ^18.0.0', -20 warn ERESOLVE error: 'INVALID', -20 warn ERESOLVE from: { -20 warn ERESOLVE name: '@react-spring/core', -20 warn ERESOLVE version: '9.7.5', -20 warn ERESOLVE location: 'node_modules/@react-spring/core', -20 warn ERESOLVE isWorkspace: false, -20 warn ERESOLVE dependents: [Array] -20 warn ERESOLVE } -20 warn ERESOLVE }, -20 warn ERESOLVE dep: { -20 warn ERESOLVE name: 'react', -20 warn ERESOLVE version: '18.3.1', -20 warn ERESOLVE whileInstalling: { -20 warn ERESOLVE name: '@react-spring/core', -20 warn ERESOLVE version: '9.7.5', -20 warn ERESOLVE path: 'D:\\3danzhuang\\furniture-3d-system\\node_modules\\@react-spring\\core' -20 warn ERESOLVE }, -20 warn ERESOLVE location: 'node_modules/react', -20 warn ERESOLVE isWorkspace: false, -20 warn ERESOLVE dependents: [ [Object] ] -20 warn ERESOLVE }, -20 warn ERESOLVE force: false, -20 warn ERESOLVE isMine: false, -20 warn ERESOLVE strictPeerDeps: false, -20 warn ERESOLVE current: { -20 warn ERESOLVE name: 'react', -20 warn ERESOLVE version: '19.2.1', -20 warn ERESOLVE location: 'node_modules/react', -20 warn ERESOLVE isWorkspace: false, -20 warn ERESOLVE dependents: [ -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object], -20 warn ERESOLVE [Object], [Object] -20 warn ERESOLVE ] -20 warn ERESOLVE }, -20 warn ERESOLVE peerConflict: { -20 warn ERESOLVE current: { -20 warn ERESOLVE name: 'react', -20 warn ERESOLVE version: '19.2.1', -20 warn ERESOLVE location: 'node_modules/react', -20 warn ERESOLVE isWorkspace: false, -20 warn ERESOLVE dependents: [Array] -20 warn ERESOLVE }, -20 warn ERESOLVE peer: { -20 warn ERESOLVE name: 'react', -20 warn ERESOLVE version: '18.3.1', -20 warn ERESOLVE whileInstalling: [Object], -20 warn ERESOLVE location: 'node_modules/react', -20 warn ERESOLVE isWorkspace: false, -20 warn ERESOLVE dependents: [Array] -20 warn ERESOLVE } -20 warn ERESOLVE } -20 warn ERESOLVE } -21 warn ERESOLVE overriding peer dependency { -21 warn ERESOLVE code: 'ERESOLVE', -21 warn ERESOLVE edge: { -21 warn ERESOLVE type: 'peer', -21 warn ERESOLVE name: 'react', -21 warn ERESOLVE spec: '^16.8.0 || ^17.0.0 || ^18.0.0', -21 warn ERESOLVE error: 'INVALID', -21 warn ERESOLVE from: { -21 warn ERESOLVE name: '@react-spring/shared', -21 warn ERESOLVE version: '9.7.5', -21 warn ERESOLVE location: 'node_modules/@react-spring/shared', -21 warn ERESOLVE isWorkspace: false, -21 warn ERESOLVE dependents: [Array] -21 warn ERESOLVE } -21 warn ERESOLVE }, -21 warn ERESOLVE dep: { -21 warn ERESOLVE name: 'react', -21 warn ERESOLVE version: '18.3.1', -21 warn ERESOLVE whileInstalling: { -21 warn ERESOLVE name: '@react-spring/shared', -21 warn ERESOLVE version: '9.7.5', -21 warn ERESOLVE path: 'D:\\3danzhuang\\furniture-3d-system\\node_modules\\@react-spring\\shared' -21 warn ERESOLVE }, -21 warn ERESOLVE location: 'node_modules/react', -21 warn ERESOLVE isWorkspace: false, -21 warn ERESOLVE dependents: [ [Object] ] -21 warn ERESOLVE }, -21 warn ERESOLVE force: false, -21 warn ERESOLVE isMine: false, -21 warn ERESOLVE strictPeerDeps: false, -21 warn ERESOLVE current: { -21 warn ERESOLVE name: 'react', -21 warn ERESOLVE version: '19.2.1', -21 warn ERESOLVE location: 'node_modules/react', -21 warn ERESOLVE isWorkspace: false, -21 warn ERESOLVE dependents: [ -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object], -21 warn ERESOLVE [Object], [Object] -21 warn ERESOLVE ] -21 warn ERESOLVE }, -21 warn ERESOLVE peerConflict: { -21 warn ERESOLVE current: { -21 warn ERESOLVE name: 'react', -21 warn ERESOLVE version: '19.2.1', -21 warn ERESOLVE location: 'node_modules/react', -21 warn ERESOLVE isWorkspace: false, -21 warn ERESOLVE dependents: [Array] -21 warn ERESOLVE }, -21 warn ERESOLVE peer: { -21 warn ERESOLVE name: 'react', -21 warn ERESOLVE version: '18.3.1', -21 warn ERESOLVE whileInstalling: [Object], -21 warn ERESOLVE location: 'node_modules/react', -21 warn ERESOLVE isWorkspace: false, -21 warn ERESOLVE dependents: [Array] -21 warn ERESOLVE } -21 warn ERESOLVE } -21 warn ERESOLVE } -22 warn ERESOLVE overriding peer dependency { -22 warn ERESOLVE code: 'ERESOLVE', -22 warn ERESOLVE edge: { -22 warn ERESOLVE type: 'peer', -22 warn ERESOLVE name: 'react', -22 warn ERESOLVE spec: '^16.8.0 || ^17.0.0 || ^18.0.0', -22 warn ERESOLVE error: 'INVALID', -22 warn ERESOLVE from: { -22 warn ERESOLVE name: '@react-spring/three', -22 warn ERESOLVE version: '9.7.5', -22 warn ERESOLVE location: 'node_modules/@react-spring/three', -22 warn ERESOLVE isWorkspace: false, -22 warn ERESOLVE dependents: [Array] -22 warn ERESOLVE } -22 warn ERESOLVE }, -22 warn ERESOLVE dep: { -22 warn ERESOLVE name: 'react', -22 warn ERESOLVE version: '18.3.1', -22 warn ERESOLVE whileInstalling: { -22 warn ERESOLVE name: '@react-spring/three', -22 warn ERESOLVE version: '9.7.5', -22 warn ERESOLVE path: 'D:\\3danzhuang\\furniture-3d-system\\node_modules\\@react-spring\\three' -22 warn ERESOLVE }, -22 warn ERESOLVE location: 'node_modules/react', -22 warn ERESOLVE isWorkspace: false, -22 warn ERESOLVE dependents: [ [Object] ] -22 warn ERESOLVE }, -22 warn ERESOLVE force: false, -22 warn ERESOLVE isMine: false, -22 warn ERESOLVE strictPeerDeps: false, -22 warn ERESOLVE current: { -22 warn ERESOLVE name: 'react', -22 warn ERESOLVE version: '19.2.1', -22 warn ERESOLVE location: 'node_modules/react', -22 warn ERESOLVE isWorkspace: false, -22 warn ERESOLVE dependents: [ -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object], -22 warn ERESOLVE [Object], [Object] -22 warn ERESOLVE ] -22 warn ERESOLVE }, -22 warn ERESOLVE peerConflict: { -22 warn ERESOLVE current: { -22 warn ERESOLVE name: 'react', -22 warn ERESOLVE version: '19.2.1', -22 warn ERESOLVE location: 'node_modules/react', -22 warn ERESOLVE isWorkspace: false, -22 warn ERESOLVE dependents: [Array] -22 warn ERESOLVE }, -22 warn ERESOLVE peer: { -22 warn ERESOLVE name: 'react', -22 warn ERESOLVE version: '18.3.1', -22 warn ERESOLVE whileInstalling: [Object], -22 warn ERESOLVE location: 'node_modules/react', -22 warn ERESOLVE isWorkspace: false, -22 warn ERESOLVE dependents: [Array] -22 warn ERESOLVE } -22 warn ERESOLVE } -22 warn ERESOLVE } -23 silly fetch manifest react@^18 -24 silly packumentCache full:https://registry.npmmirror.com/react cache-miss -25 http cache https://registry.npmmirror.com/react 17ms (cache hit) -26 silly packumentCache full:https://registry.npmmirror.com/react set size:6035119 disposed:false -27 silly fetch manifest react-dom@^18 -28 silly packumentCache full:https://registry.npmmirror.com/react-dom cache-miss -29 http fetch GET 200 https://registry.npmmirror.com/react-dom 290ms (cache miss) -30 silly packumentCache full:https://registry.npmmirror.com/react-dom set size:1304099 disposed:false -31 verbose stack Error: could not resolve -31 verbose stack at PlaceDep.failPeerConflict (C:\Program Files\nodejs\node_modules\npm\node_modules\@npmcli\arborist\lib\place-dep.js:503:25) -31 verbose stack at new PlaceDep (C:\Program Files\nodejs\node_modules\npm\node_modules\@npmcli\arborist\lib\place-dep.js:157:21) -31 verbose stack at #buildDepStep (C:\Program Files\nodejs\node_modules\npm\node_modules\@npmcli\arborist\lib\arborist\build-ideal-tree.js:932:18) -31 verbose stack at async Arborist.buildIdealTree (C:\Program Files\nodejs\node_modules\npm\node_modules\@npmcli\arborist\lib\arborist\build-ideal-tree.js:182:7) -31 verbose stack at async CI.exec (C:\Program Files\nodejs\node_modules\npm\lib\commands\ci.js:63:5) -31 verbose stack at async Npm.exec (C:\Program Files\nodejs\node_modules\npm\lib\npm.js:208:9) -31 verbose stack at async module.exports (C:\Program Files\nodejs\node_modules\npm\lib\cli\entry.js:67:5) -32 error code ERESOLVE -33 error ERESOLVE could not resolve -34 error -35 error While resolving: @react-three/drei@9.122.0 -35 error Found: react@19.2.1 -35 error node_modules/react -35 error react@"19.2.1" from the root project -35 error peerOptional react@">=16.8" from zustand@3.7.2 -35 error node_modules/@react-three/fiber/node_modules/zustand -35 error zustand@"^3.7.1" from @react-three/fiber@8.18.0 -35 error node_modules/@react-three/fiber -35 error @react-three/fiber@"^8.17.10" from the root project -35 error 2 more (@react-spring/three, @react-three/drei) -35 error 12 more (@use-gesture/react, its-fine, lucide-react, next, ...) -35 error -35 error Could not resolve dependency: -35 error peer react@"^18" from @react-three/drei@9.122.0 -35 error node_modules/@react-three/drei -35 error @react-three/drei@"^9.119.2" from the root project -35 error -35 error Conflicting peer dependency: react@18.3.1 -35 error node_modules/react -35 error peer react@"^18" from @react-three/drei@9.122.0 -35 error node_modules/@react-three/drei -35 error @react-three/drei@"^9.119.2" from the root project -35 error -35 error Fix the upstream dependency conflict, or retry -35 error this command with --force or --legacy-peer-deps -35 error to accept an incorrect (and potentially broken) dependency resolution. -36 error -36 error -36 error For a full report see: -36 error D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_48_825Z-eresolve-report.txt -37 silly unfinished npm timer idealTree:buildDeps 1765441369267 -38 silly unfinished npm timer idealTree:node_modules/@react-three/drei 1765441369832 -39 verbose cwd D:\3danzhuang\furniture-3d-system -40 verbose os Windows_NT 10.0.26100 -41 verbose node v24.11.0 -42 verbose npm v11.6.1 -43 notice -43 notice New minor version of npm available! 11.6.1 -> 11.7.0 -43 notice Changelog: https://github.com/npm/cli/releases/tag/v11.7.0 -43 notice To update run: npm install -g npm@11.7.0 -43 notice { force: true, Symbol(proc-log.meta): true } -44 verbose exit 1 -45 verbose code 1 -46 error A complete log of this run can be found in: D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_48_825Z-debug-0.log diff --git a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-eresolve-report.txt b/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-eresolve-report.txt deleted file mode 100644 index 00897410..00000000 --- a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_48_825Z-eresolve-report.txt +++ /dev/null @@ -1,148 +0,0 @@ -'Log files: -D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_48_825Z-debug-0.log - -# npm resolution error report - -While resolving: @react-three/drei@9.122.0 -Found: react@19.2.1 -node_modules/react - react@"19.2.1" from the root project - peerOptional react@">=16.8" from zustand@3.7.2 - node_modules/@react-three/fiber/node_modules/zustand - zustand@"^3.7.1" from @react-three/fiber@8.18.0 - node_modules/@react-three/fiber - @react-three/fiber@"^8.17.10" from the root project - peer @react-three/fiber@">=6.0" from @react-spring/three@9.7.5 - node_modules/@react-spring/three - @react-spring/three@"~9.7.5" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer @react-three/fiber@"^8" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@">= 16.8.0" from @use-gesture/react@10.3.1 - node_modules/@use-gesture/react - @use-gesture/react@"^10.3.1" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@">=18.0" from its-fine@1.2.5 - node_modules/its-fine - its-fine@"^1.0.6" from @react-three/fiber@8.18.0 - node_modules/@react-three/fiber - @react-three/fiber@"^8.17.10" from the root project - peer @react-three/fiber@">=6.0" from @react-spring/three@9.7.5 - node_modules/@react-spring/three - @react-spring/three@"~9.7.5" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer @react-three/fiber@"^8" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@"^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" from lucide-react@0.559.0 - node_modules/lucide-react - lucide-react@"^0.559.0" from the root project - peer react@"^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0" from next@16.0.8 - node_modules/next - next@"16.0.8" from the root project - peer react@"^19.2.1" from react-dom@19.2.1 - node_modules/react-dom - react-dom@"19.2.1" from the root project - peer react-dom@"^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0" from next@16.0.8 - node_modules/next - next@"16.0.8" from the root project - peerOptional react-dom@">=16.13" from react-use-measure@2.1.7 - node_modules/react-use-measure - react-use-measure@"^2.1.7" from @react-three/fiber@8.18.0 - node_modules/@react-three/fiber - @react-three/fiber@"^8.17.10" from the root project - peer @react-three/fiber@">=6.0" from @react-spring/three@9.7.5 - node_modules/@react-spring/three - @react-spring/three@"~9.7.5" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer @react-three/fiber@"^8" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@"^16.8.0 || ^17 || ^18 || ^19" from react-hook-form@7.68.0 - node_modules/react-hook-form - react-hook-form@"^7.54.2" from the root project - peer react-hook-form@"^7.0.0" from @hookform/resolvers@3.10.0 - node_modules/@hookform/resolvers - @hookform/resolvers@"^3.9.1" from the root project - peer react@">=16.13" from react-use-measure@2.1.7 - node_modules/react-use-measure - react-use-measure@"^2.1.7" from @react-three/fiber@8.18.0 - node_modules/@react-three/fiber - @react-three/fiber@"^8.17.10" from the root project - peer @react-three/fiber@">=6.0" from @react-spring/three@9.7.5 - node_modules/@react-spring/three - @react-spring/three@"~9.7.5" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer @react-three/fiber@"^8" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" from styled-jsx@5.1.6 - node_modules/styled-jsx - styled-jsx@"5.1.6" from next@16.0.8 - node_modules/next - next@"16.0.8" from the root project - peer react@">=17.0" from suspend-react@0.1.3 - node_modules/suspend-react - suspend-react@"^0.1.3" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - suspend-react@"^0.1.3" from @react-three/fiber@8.18.0 - node_modules/@react-three/fiber - @react-three/fiber@"^8.17.10" from the root project - peer @react-three/fiber@">=6.0" from @react-spring/three@9.7.5 - node_modules/@react-spring/three - @react-spring/three@"~9.7.5" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer @react-three/fiber@"^8" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peerOptional react@">=16.8" from zustand@4.5.7 - node_modules/tunnel-rat/node_modules/zustand - zustand@"^4.3.2" from tunnel-rat@0.1.2 - node_modules/tunnel-rat - tunnel-rat@"^0.1.2" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peer react@"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" from use-sync-external-store@1.6.0 - node_modules/use-sync-external-store - use-sync-external-store@"^1.2.2" from zustand@4.5.7 - node_modules/tunnel-rat/node_modules/zustand - zustand@"^4.3.2" from tunnel-rat@0.1.2 - node_modules/tunnel-rat - tunnel-rat@"^0.1.2" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peerOptional use-sync-external-store@">=1.2.0" from zustand@5.0.9 - node_modules/zustand - zustand@"^5.0.2" from the root project - zustand@"^5.0.1" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - peerOptional react@">=18.0.0" from zustand@5.0.9 - node_modules/zustand - zustand@"^5.0.2" from the root project - zustand@"^5.0.1" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - -Could not resolve dependency: -peer react@"^18" from @react-three/drei@9.122.0 -node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - -Conflicting peer dependency: react@18.3.1 -node_modules/react - peer react@"^18" from @react-three/drei@9.122.0 - node_modules/@react-three/drei - @react-three/drei@"^9.119.2" from the root project - -Fix the upstream dependency conflict, or retry -this command with --force or --legacy-peer-deps -to accept an incorrect (and potentially broken) dependency resolution. diff --git a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_50_432Z-debug-0.log b/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_50_432Z-debug-0.log deleted file mode 100644 index e9a4ea22..00000000 --- a/local-packages/npm-cache/cache/_logs/2025-12-11T08_22_50_432Z-debug-0.log +++ /dev/null @@ -1,18 +0,0 @@ -0 verbose cli C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -1 info using npm@11.6.1 -2 info using node@v24.11.0 -3 silly config load:file:C:\Program Files\nodejs\node_modules\npm\npmrc -4 silly config load:file:D:\3danzhuang\furniture-3d-system\.npmrc -5 silly config load:file:C:\Users\Mr_Wu01\.npmrc -6 silly config load:file:C:\Users\Mr_Wu01\AppData\Roaming\npm\etc\npmrc -7 verbose title npm exec prisma generate -8 verbose argv "exec" "--" "prisma" "generate" -9 verbose logfile logs-max:10 dir:D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_50_432Z- -10 verbose logfile D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_22_50_432Z-debug-0.log -11 silly logfile done cleaning log files -12 verbose cwd D:\3danzhuang\furniture-3d-system -13 verbose os Windows_NT 10.0.26100 -14 verbose node v24.11.0 -15 verbose npm v11.6.1 -16 verbose exit 0 -17 info ok diff --git a/local-packages/npm-cache/cache/_logs/2025-12-11T08_24_49_960Z-debug-0.log b/local-packages/npm-cache/cache/_logs/2025-12-11T08_24_49_960Z-debug-0.log deleted file mode 100644 index 40716744..00000000 --- a/local-packages/npm-cache/cache/_logs/2025-12-11T08_24_49_960Z-debug-0.log +++ /dev/null @@ -1,12 +0,0 @@ -0 verbose cli C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -1 info using npm@11.6.1 -2 info using node@v24.11.0 -3 silly config load:file:C:\Program Files\nodejs\node_modules\npm\npmrc -4 silly config load:file:D:\3danzhuang\furniture-3d-system\.npmrc -5 silly config load:file:C:\Users\Mr_Wu01\.npmrc -6 silly config load:file:C:\Users\Mr_Wu01\AppData\Roaming\npm\etc\npmrc -7 verbose title npm run prisma:studio -8 verbose argv "run" "prisma:studio" -9 verbose logfile logs-max:10 dir:D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_24_49_960Z- -10 verbose logfile D:\3danzhuang\furniture-3d-system\local-packages\npm-cache\cache\_logs\2025-12-11T08_24_49_960Z-debug-0.log -11 silly logfile done cleaning log files diff --git a/package.json b/package.json index 62a25169..053d3491 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,13 @@ "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", + "clean:local": "node scripts/cleanup-local-artifacts.js", "prisma:generate": "prisma generate", "prisma:check-client-sync": "node scripts/check-prisma-client-sync.js", "prisma:push": "prisma db push", "prisma:studio": "prisma studio", "prisma:seed": "tsx prisma/seed.ts", - "type-check": "next typegen && tsc --noEmit --incremental false", + "type-check": "node scripts/run-type-check.js", "demo:create": "node scripts/create-demo-data.js", "demo:setup": "npm run prisma:push && npm run demo:create", "demo:update": "node scripts/update-demo-models.js", diff --git a/scripts/cleanup-local-artifacts.js b/scripts/cleanup-local-artifacts.js new file mode 100644 index 00000000..a9bf9fdb --- /dev/null +++ b/scripts/cleanup-local-artifacts.js @@ -0,0 +1,78 @@ +const fs = require('fs/promises') +const path = require('path') + +const root = process.cwd() + +const directories = [ + '.codex-logs', + '_logs', + '.next', + 'coverage', + 'output', + 'temp', +] + +const files = [ + '%OUT%', + 'nul', + 'dev-server.log', + 'trace-deprecation-build.log', + 'typecheck-latest.log', + 'tsconfig.tsbuildinfo', +] + +const globPatterns = [ + /^\.dev-.*\.log$/, + /^\.qa-.*\.log$/, + /^\.start-.*\.log$/, + /^\.next-start-.*\.log$/, +] + +async function removeTarget(relativePath, removed) { + const absolutePath = path.join(root, relativePath) + + try { + await fs.rm(absolutePath, { recursive: true, force: true }) + removed.push(relativePath) + } catch (error) { + console.warn(`[skip] ${relativePath}: ${error.message}`) + } +} + +async function main() { + const removed = [] + const entries = await fs.readdir(root, { withFileTypes: true }) + + for (const directory of directories) { + await removeTarget(directory, removed) + } + + for (const file of files) { + await removeTarget(file, removed) + } + + for (const entry of entries) { + if (!entry.isFile()) { + continue + } + + if (globPatterns.some((pattern) => pattern.test(entry.name))) { + await removeTarget(entry.name, removed) + } + } + + if (removed.length === 0) { + console.log('No local artifacts removed.') + return + } + + console.log('Removed local artifacts:') + for (const item of removed) { + console.log(`- ${item}`) + } +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/run-type-check.js b/scripts/run-type-check.js new file mode 100644 index 00000000..c3208f47 --- /dev/null +++ b/scripts/run-type-check.js @@ -0,0 +1,50 @@ +const fs = require('fs/promises') +const path = require('path') +const { spawn } = require('child_process') + +const repoRoot = process.cwd() +const nextBin = path.join(repoRoot, 'node_modules', 'next', 'dist', 'bin', 'next') +const tscBin = path.join(repoRoot, 'node_modules', 'typescript', 'bin', 'tsc') + +function run(command, args) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { + cwd: repoRoot, + stdio: 'inherit', + shell: false, + }) + + child.on('exit', (code) => { + if (code === 0) { + resolve() + return + } + + reject(new Error(`${command} ${args.join(' ')} exited with code ${code}`)) + }) + }) +} + +async function ensureNextCacheLifeStub() { + const typesDir = path.join(repoRoot, '.next', 'types') + const cacheLifePath = path.join(typesDir, 'cache-life.d.ts') + + await fs.mkdir(typesDir, { recursive: true }) + + try { + await fs.access(cacheLifePath) + } catch { + await fs.writeFile(cacheLifePath, '', 'utf8') + } +} + +async function main() { + await run(process.execPath, [nextBin, 'typegen']) + await ensureNextCacheLifeStub() + await run(process.execPath, [tscBin, '--noEmit', '--incremental', 'false']) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +})