## 问题 `main` 上没有任何地方能创建项目。首页「工作流画布」卡片的两条动作都落在 `/projects`,`pages/home/index.tsx:88` 的注释写明这是占位;项目中心的「+ 新建项目」从加入那天起就是 disabled,`title` 写着「新建项目流程不在本模块中」。用户看得到项目列表,建不出项目。 \#99 把列表、创建、详情放在一起,其中列表与详情已由 #118 落地,本 issue 只补创建这一段。 ## 目标 用一页表单创建真实项目,首页与项目中心两个入口共用同一页。 ## 范围 包含: - `/projects/new` 页面与路由,挂在 AppShell 下,保留全局顶栏 - 表单字段严格按 `entities/project` 的 `CreateProjectInput` - 写入只经 `projectApis.create` - 首页「创建新项目」与项目中心「+ 新建项目」改指该页 - 校验、业务错误与传输错误的区分 - 组件测试 不包含: - 「继续已有项目」入口的落点调整(等 #100 与 PR #105 的 History 页面) - 参考图上传(另立 PR) - 创建后进入 Workflow Editor(需要 WorkflowRun 与 Controller,见 #102、#120) - 后端 `/projects` 端点 - 当前用户体系与登录 ## 产品规则 - 字段:项目名称、游戏视角、方向数量、精灵宽高、画风约束。 - 名称限 20 字(后端 `String(20)`);同一用户下不可重名,重名由后端判定。 - 视角与朝向各三档,取值经 entity 适配器映射为后端枚举,页面不自己拼数字。 - 精灵宽高各自 32–2048,给常用档位快选并允许自定义。 - 提交中禁用按钮,连续点击只发一次请求。 - 失败保留已填内容:业务错误原样显示后端 message,传输错误显示统一文案。 - 成功后进入 `/projects/:projectId`。 ## 架构边界 允许:经 `@/entities` 的 `projectApis` 写入;保存表单临时 UI 状态。 禁止:页面直接 `fetch`;新增 Store 或 localStorage;引入 `features`、Workflow、Generation;把 `ownerId` 写成常量假 ID 让创建看起来能用。 ## 验收标准 - `/projects/new` 可直达与刷新,首页和项目中心两个入口都到这里。 - 名称超长、必填缺失在提交前拦下。 - 重名时显示后端返回的具体原因,表单内容不丢。 - 连续点击创建只发一次请求。 - 成功后跳 `/projects/:projectId`。 - `ownerId` 无来源时创建入口禁用并说明原因,不使用假 ID。 - 页面中不出现 `fetch`、Store、localStorage。 - `format:check`、`lint`、`typecheck`、`test`、`build` 全部通过。 ## 依赖 后端 `POST /projects` 在 PR #75、#126,未进 main;两者 `project_name` 限长不一致(20 与 64),本页按更严的 20 实现。`ownerId` 需要当前用户来源,`/auth` 同在 PR #75,接入前创建入口禁用。 ## 备注 参考图字段 `sprite_sample_url` 后端已有,前端缺文件上传能力(PR #111),本 PR 之后单独立 PR 解决。
Activity