chore(协作流程): 收口团队协作规则与主线清理机制

为新平台主链补齐团队协作模式、模块边界、任务单和提测清单。

新增本地清理脚本,移除误纳入仓库的 npm 缓存日志,并把清理后 type-check 失效的问题收回到脚本层修复。
This commit is contained in:
WuYongJie 2026-03-31 10:23:56 +08:00
parent f14df4a24b
commit 8d1f86756d
16 changed files with 1050 additions and 538 deletions

18
.gitignore vendored
View File

@ -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/

View File

@ -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
**维护者**:开发团队

View File

@ -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>
```

View File

@ -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. 交接时最容易漏掉的事
- 没说清楚这次只做什么
- 没说清楚哪些目录不能碰
- 没说清楚新平台主链和旧兼容链的边界
- 没写验证方式
- 没同步文档,导致下一个人继续靠猜

View File

@ -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`

View File

@ -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:<通过 / 未跑>
- 人工验证:<写页面和结果>
风险:
- <没有风险 / 写明确风险>
规范审查结论:
这是自审,不是独立复审;<passed / passed with warnings / rejected>
```

View File

@ -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`

View File

@ -0,0 +1,40 @@
# 规范审查清单
## 1. 审查只看三件事
### 架构有没有被破坏
- 新平台主链和旧 CAD 兼容链有没有混写
- 模块边界有没有被打穿
- 数据归属有没有乱掉
- 本次是不是顺手扩大了无关范围
### 视觉有没有跑偏
- 有没有明显偏离当前统一视觉标准
- 有没有临时拼凑感很强的新界面
- 新页面和现有页面的层级、间距、交互有没有失控
### 这次是不是根因修复
- 是不是找到了真正原因
- 还是只是加了补丁绕过去
- 会不会把问题转移到别的模块
## 2. 结论只能是这三种
- `passed`
- `passed with warnings`
- `rejected`
## 3. 必须写明是不是独立复审
- 如果是自己审自己,必须写:
- `这是自审,不是独立复审`
## 4. 直接判定 rejected 的情况
- 明显破坏模块边界
- 明显破坏统一视觉
- 明显只是补丁式修复
- 没做最小验证就宣称完成

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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
})

50
scripts/run-type-check.js Normal file
View File

@ -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
})