Files

145 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 啡跃 Endoleap
本地 Next.js App Router + TypeScript + Tailwind CSS + shadcn/ui 项目。首页采用留白、黑色主按钮、衬线标题与线稿画布预览;账户页保留原有布局。工作台使用合并后的单侧栏。
项目目录:`/Users/zzyang/endoleap`。
## 启动
```sh
npm ci
npm run dev
```
默认仅监听本机 localhost:17321。生产模式:`npm run build && npm start`。
- 首页:/(未登录显示 landing page;有效登录会话跳转 /dashboard)
- 登录、注册:/login
- 登录回调:/auth/callback
- 真实工作台:/dashboard
- 本地演示:/dashboard?demo=1
- 无限图谱:/dashboard/{workspace}/{board}
## 路由结构
- `src/app/layout.tsx`:根布局、中文语言标记、全局样式与页面元信息。
- `src/app/page.tsx`:首页。
- `src/app/login/page.tsx`、`src/app/auth/callback/page.tsx`:账户页与登录回调。
- `src/app/dashboard/layout.tsx`:共享单侧栏;`page.tsx` 保留空白工作区。
- `src/app/dashboard/dashboard.tsx`:侧栏收起/展开、页面搜索、新建图谱与底部账户弹出框。
- `src/app/dashboard/[workspace]/[board]/page.tsx`:按 workspace 和图谱 ID 打开页面,重新读取后端资料。
- `src/components/ui/icon-button.tsx`:Lucide 图标按钮,图标为 16×16px,上下 4px、左右 6px 内边距,总尺寸为 28×24px。
- `src/app/api/**/route.ts`:Foundry 代理与 OAuth 跳转,使用 App Router Route Handlers。
## 配置
复制 .env.example 为 .env.local,按实际部署填写:
- FOUNDRY_API_ORIGIN:仅供 Next 服务端请求后端,默认 https://api.foundry.entroia.com。
- NEXT_PUBLIC_FOUNDRY_PROJECT:项目标识,默认 endoleap。
Slack Client Secret、Signing Secret、Verification Token、用户令牌与 app token 均不需要放入此前端。浏览器调用同源 Next API,由服务端转发到 Foundry。Foundry 会话保存在 HttpOnly / SameSite=Lax Cookie,生产 HTTPS 反向代理需传 X-Forwarded-Proto=https。不要将原始会话写入客户端存储。
Google / Slack 的提供方回调仍是 Foundry 后端地址;后端的项目回调映射必须指向本前端 /auth/callback。协议、主机名、端口必须与启动第三方登录时一致,否则 sessionStorage 中的 verifier 无法恢复。正式账号授权、邮件验证与 OAuth 全流程尚未完成真人验收;HTTP 302 跳转成功不能代表登录成功。
## 当前功能与范围
- 响应式首页、锚点导航与 FAQ。
- 邮箱注册 / 登录 / 邮件验证兑换,Google 和 Slack 的 PKCE 登录入口及回调处理。
- 真实用户资料、空间列表与创建、画布列表与创建。资料和空间并行读取;首次创建画布时自动建立个人空间。
- 单侧栏第一行提供完全收起/恢复与新建页面,第二行为当前空间页面列表搜索。画布列表包含可展开的父子画布目录,搜索保留祖先路径,直接打开子图时自动展开所在目录。侧栏使用 Motion for React 14.9.1 实现 240ms 开关动画,尊重系统减少动态效果偏好,收起后保留左上角快捷浮框。
- 账户菜单分为工作空间概览、账户设置、用户资料与空间切换、新建工作空间、退出登录;账户设置和新建空间均接入 Foundry。菜单文字和行距参考 Notion 收紧,工作空间分组标题保留浅灰色。
- 底部按钮、账户菜单和设置面板使用 Foundry `profile.avatar_url` 提供的 Google 头像;无头像或图片加载失败时显示姓名首字。
- 新建页面使用 Foundry Core 的 `POST /workspaces/{workspace}/materials`,提交 `kind: board`、默认名称“未命名图谱”和内容版本;由后端生成 ID。没有空间时先创建“个人空间”,成功后跳转到图谱的独立地址。
- 本地演示提供示例图谱、搜索、新建和浏览器保存,支持图谱独立地址与刷新。
- 图谱页面使用 React Flow 12.12.1,支持空白处平移、节点拖动、连线、多选、缩放和文本编辑。文字、脚本、图片节点和创作模板可从底部悬浮工具栏插入。
- 右上角悬浮框提供撤销、重做、缩放、恢复 100%、适应画布和 JSON 导出;底部支持 JSON 导入及操作帮助。
- 真实图谱先读取 Core Canvas 快照,再开放编辑;节点、样式、连线与视图以独立版本串行自动保存。旧本地草稿需用户明确选择恢复;版本冲突停止覆盖并保留恢复记录。演示模式仅本地保存。支持 Core Canvas V1/V2;V2 分区是真实子画布,内部内容按所属画布独立保存。
- 分享、Agent、收藏、自由绘图及多人协同尚未接入。画布覆盖整个视口,侧栏和快捷浮框覆盖其上;演示数据不写入线上。
- 收起侧栏后,左上角浮框显示 Logo 和用户头像;头像与展开侧栏底部的账户按钮打开同一个菜单。
- 本地演示仅用于查看界面,不提供后端认证与权限。
Figma 原始 Logo、人物插画与图标已下载到 public/assets,不依赖临时 Figma URL。品牌保持啡跃 Endoleap;shadcn Button / Dialog 使用官方 registry 源码。依赖版本固定,package-lock.json 可用于 npm ci。
## 验证
```sh
npm run build
node tests/api-smoke.mjs
```
API 测试使用本机临时后端和独立前端进程,检查会话 Cookie、令牌不泄漏、同源校验和路径白名单,不访问线上账号。构建需先完成。冒烟测试还覆盖所有页面地址、元信息、OAuth 跳转、请求体限制及退出会话。此前的浏览器验收覆盖登录/注册切换、演示画布创建、搜索空状态、笔记保存、桌面与 390px 手机布局;本次迁移的验证结果见 VALIDATION.md。
若执行环境限制 Turbopack 的 CSS 工作进程绑定本地端口,可使用官方 Webpack 模式:`npm run build -- --webpack`。
项目已同步至 `ssh://git@gitea.entroia.com:22222/Zayden-Jung/Endoleap.git`;尚未部署。
性能分析、实测耗时和修复说明见 [PERFORMANCE.md](PERFORMANCE.md)。
流程回归可在支持 TypeScript 类型擦除的 Node 版本执行:`node --experimental-strip-types --test tests/workspace.test.mjs`。
## 品牌资源
`public/brand/` 原样复用旧 PROMPT 仓库 `Zayden-Jung/probably-rendering-one-more-pixel-tonight` 的 `packages/brand/assets/`,来源提交 `47467874841ea7f7b4b362d4ec0e66f236c6a7d6`。
共 88 个原始资源:6 套 PNG(logo/icon/mono 的 light 与 dark 版本,每套 16、24、32、48、64、128、180、192、256、512、1024、2048px),8 个 SVG,以及 8 个应用图标文件(含 3 种 ICO、Apple Touch 和 PWA PNG)。所有文件与来源 Git blob 哈希一致。
收起侧栏后的浮框使用 Logo 返回 `/`;展开侧栏后仍保留新建页面按钮。首页与账户页品牌组件使用原始 SVG,根布局声明 ICO、深浅色 PNG favicon 和 Apple Touch 图标。
## 画布操作
- 单击选择,双击编辑文本或卡片名称。纯文本与图片可整块拖动;选中时四侧连接点可拖线。
- 触控板滚动平移,Ctrl / ⌘ 加滚动或捏合缩放。V 选择,H 抓手,空格临时平移,Shift 框选。
- 上方编辑栏提供文字样式、旋转和八向拉伸模式。旋转时 Shift 吸附 15°;八向拉伸时 Shift 固定比例,Esc 退出。图标保留等比缩放预设。
- 连线可单独选择:颜色、粗细、透明度、实/虚/点线、箭头与箭尾形状/大小/填充均可设置。双击线或点击添加按钮插入曲线点,拖动锚点和控制柄制作多段贝塞尔链;支持平滑、镜像和独立控制柄。
- 连线动画可关闭、始终播放或仅执行时播放,包含沿完整曲线的流光、流动虚线和脉冲;方向、颜色和时长可设。执行动画由真实任务边事件驱动。
- 底部 AI 模式可保持开启;选择文本/图片/卡片后,上方为编辑栏,下方为固定屏幕尺寸的 AI 面板。模型从后端目录读取,支持原地生成、取消及可选下游传播;冲突结果保留供明确应用。
- 新选框通过服务端事务创建并关联真实子画布。标签用三个图标切换隐藏/固定字号/随缩放,悬停查看解释。选框可收起、展开及调整概览比例,子图真实内容尺寸不变。
- 展开内容使用子画布投影,编辑保存到实际 owner;不会在父图复制一份。拖入/移出使用多画布事务;新跨图连线按后端能力通过 connections 命令创建端口链。删除选框解散并保留内容。
- 原地生成与用户拖动可合并;内容冲突保留本地草稿。网络结果不确定时暂停编辑,用相同幂等请求重试或重新读取。每个画布有独立版本与串行保存器。
- 图标面板支持 2313 个 Lucide 和 24 个 Tabler 图标试用、分类/搜索、虚拟列表及本地图形分片加载。未打开面板不加载目录。
- 有子图时导出完整 owner 文档集合;关系型子图备份不直接覆盖导入到其他画布。历史 V1/关系不兼容草稿可导出,不能覆盖 V2 子图关系。
## Canvas V2 接口与检查
后端基线由用户交付的部署 `b4e537b`、CI #912/#913 与指定测试画布迁移摘要确认。跨图 connections 扩展以线上 `capabilities.subgraphs.connections` 为准;客户端先检查能力,再发事务。前端未重复运行迁移或调用线上付费模型。
同源代理转发 V2 Accept、If-Match、Idempotency-Key 和事件分页查询,保留 ETag/schema/Retry-After;受管图片通过带会话的二进制代理读取。快照上限 5 MiB,图片上传支持受限 multipart;服务令牌不会发给浏览器。
验证命令:
```sh
npm run typecheck
node --experimental-strip-types --test tests/*.test.mjs
CANVAS_UI_TOOLS=/path/to/isolated-tools node tests/canvas-ui-check.mjs
```
DOM 工具仅需在临时目录安装 esbuild/jsdom,见测试文件开头;不启动浏览器。生产构建与 `tests/api-smoke.mjs` 使用隔离副本和临时本地服务,避免影响现有开发服务器。实际结果及限制见 VALIDATION.md。
Headless Canvas API 的完整方案保留在本地忽略的 `docs/HEADLESS_CANVAS_API_DRAFT.md`。当前工作分支已接入纯 core/runtime、ledger/queue、IndexedDB 恢复、渐进导入/深复制、canonical Foundry 协议和私有 ESM 包预览;使用方式见 `headless/README.md`,尚未发布 npm registry,也不代表完整产品验收或后端部署完成。
Workspace AssetDepot 支持重新授权后的跨项目采用、持久绑定与共享字节。浏览器数据库 v4 将已确认上传的项目文件转换为共享字节指针,保留原 File MIME 和逻辑读取接口;绑定使用恢复格式13。共享回收要求所有项目的持久引用清单完整且与 Root 同步;关闭项目仍受保护。源文件转换、字节、引用清单和 Root 在同一个事务中保存,未确认上传继续保留原 Blob。
应用提示使用 Sonner,图标说明使用 Radix Tooltip;根布局统一安装 provider。画布通用操作错误与归属完成使用固定 ID 通知,保存冲突、失败上传和重试操作仍保留在相关内容处。消息和浮层依赖仅属于应用 UI,不作为未来 headless core 的依赖。
## 会话期限
会话为可撤销的随机令牌。30 天闲置续期、90 天绝对期限由 Core 控制,代理按剩余期限更新 HttpOnly Cookie;既有过期会话不恢复。详细本地说明为 `docs/SESSION_LIFETIME.md`。
## 图片附件与加载
真实画布新上传的图片存入 Foundry 附件 API,快照只保存原始附件引用,避免 Base64 随每次打开和保存传输。原图保留;画布按需读取单一最长边 1024px 的预览,放大后可读取原图。预览权限与原图一致,Core 的配套预览功能已随 PR #15 合并并部署(b2ae48e);小图或 GIF 可能直接返回原始文件。
指定测试画布已完成一次性旧图迁移,原图、节点与连线的哈希核对一致;临时迁移入口及执行逻辑已移除。打开页面不会自动迁移或 PATCH。只改变视角保存在本机;真实内容修改才自动保存到服务器。
## 跨分区拖放同步
拖放后元素保持落位,旁边显示局部同步状态;其他元素仍可编辑和拖动。移动中的节点及分区几何暂时受保护,归属事务排队使用最新版本。期间的本地编辑在响应到达后合并,再自动保存。响应丢失时重试复用同一请求和幂等键;明确版本冲突则先重读版本,避免重复移动或覆盖其他编辑。
Core `subgraphs.member_positions` 能力启用时,最终落点(源画布局部坐标)与归属通过一次 members POST 原子保存,单纯拖放不再先 PATCH 坐标。旧后端仍使用先保存坐标再迁移的兼容流程,但不显示整屏等待遮罩。Core 配套 PR #16 已合并并部署为 2207c85;刷新页面后会重新检测并启用新接口能力。
上传图片时立即在画布显示本地预览,并在后台上传原始文件;上传成功才把稳定附件引用加入快照。服务端预览加载完成前继续显示本地图片,避免网络等待期间空白。失败保留文件供重试/取消,重试沿用同一幂等键;本地 blob URL 不保存到服务端。
上传中的图片也是正常本地节点,可立即选中、拖动、缩放、改名、删除和撤销;上传完成只补齐附件引用,不重置节点。上传前改变分区归属会先在本地完成,文件准备好后保存到当时的实际所属画布。临时上传标记和 blob 地址由传输层排除,不发送给 Core;文件仍未可用时,依赖服务端文件的 AI 生成需等待上传完成。