Files
hunjing/frontend/CLAUDE.md
T
2026-08-21 16:00:13 +08:00

11 KiB
Raw Blame History

前端开发规范

技术栈

Next.js + TypeScript + React + Tailwind CSS + Zustand/Jotai + pnpm

核心依赖

  • 实时通信: SSE / WebSocket
  • 可视化: Mermaid + 图谱可视化库
  • 测试: Vitest + Testing Library
  • 代码质量: ESLint (flat config) + Prettier + Husky + lint-staged

开发命令

pnpm install                    # 安装依赖
pnpm add <pkg>                  # 添加依赖
pnpm remove <pkg>               # 移除依赖

pnpm dev                        # 启动开发服务器 (默认端口 3000)
pnpm build                      # 构建生产版本
pnpm start                      # 启动生产服务器

pnpm lint                       # 运行 ESLint 检查
pnpm type-check                 # TypeScript 类型检查

# 代码格式化(Prettier)
pnpm format                     # 格式化全部文件
pnpm format:check               # 检查格式是否合规(CI / 提交钩子使用)

# 测试(Vitest)
pnpm test                       # 运行全部测试(单次)
pnpm test:watch                 # 监听模式
pnpm test:coverage              # 运行测试并生成覆盖率报告

目录结构

frontend/
├── src/
│   ├── app/                    # Next.js App Router
│   │   ├── admin/              # 司命台管理控制台(增强 UI,开关驱动)
│   │   ├── archive/            # 归档(记忆时间河)
│   │   ├── characters/         # 人物
│   │   ├── chat/               # 对话
│   │   ├── memory/             # 记忆管理
│   │   ├── personality/        # 人格
│   │   ├── runs/[runId]/       # 运行轨迹
│   │   ├── tools/              # 工具调用
│   │   ├── error.tsx           # 全局错误边界(Client,reset)
│   │   ├── global-error.tsx    # 根级错误兜底(自带 html/body)
│   │   ├── layout.tsx          # 根布局
│   │   ├── loading.tsx         # 路由加载态
│   │   ├── not-found.tsx       # 404
│   │   ├── page.tsx            # 首页(重定向 /chat)
│   │   └── template.tsx        # 页面过渡动画
│   ├── components/             # React 组件(按功能域组织)
│   │   ├── admin/              # 司命台签名组件(StarMap/VermilionAction…)
│   │   ├── archive/ characters/ chat/ memory/ personality/ runs/ tools/
│   │   ├── layout/             # 应用壳层 / 侧栏 / 主题初始化
│   │   ├── shared/             # 共享状态视图(Empty/Error/Loading)
│   │   └── ui/                 # 通用 UI(Button/Card/BronzeMirror/Badge…)
│   ├── lib/
│   │   ├── api/                # API 客户端(client.ts 统一出口 + 按域分模块)
│   │   ├── constants/          # 枚举标签常量
│   │   ├── hooks/              # 自定义 Hooks
│   │   ├── mock/               # Mock 数据层(无后端时驱动全页面)
│   │   ├── stores/             # Zustand/Jotai stores
│   │   └── utils/              # 工具函数(cn/format/error)
│   ├── test/                   # Vitest 全局 setup
│   ├── types/                  # TypeScript 类型定义
│   └── styles/                 # 全局样式(琉璃镜 token)
├── .husky/                     # Git hooks(pre-commit)
├── public/                     # 静态资源
├── .env.local                  # 环境变量 (本地)
├── .lintstagedrc.json          # lint-staged 配置
├── eslint.config.mjs           # ESLint flat config
├── vitest.config.ts            # Vitest 配置
└── next.config.ts              # Next.js 配置(rewrites 代理 /api/v1 → 后端)

组织约定:采用 src/ 根 + components 按功能域分子目录 + stores 置于 lib 下的方式,不设独立 features/ 顶层目录。浏览器请求经 next.config.ts 的 rewrites 同源代理到后端(规避跨域,含 SSE);认证与鉴权统一走 BFF:token 仅存于 httpOnly cookie,由 App Router 内的 /api/auth/*(认证)、/api/proxy/*(业务 REST 代理)、/api/sse/*(SSE 流式代理)在服务端读取并注入 Authorization,客户端 JS 不接触 token。

代码规范

页面设计

图标:统一使用 Lucide 图标,界面全程禁止使用表情符号。 设计标准:对标 Awwwards 顶级网站水准,达到 Awwwards、FWA、CSS Design Awards 每日最佳网站同等设计品质。 创意自由度:将浏览器视作交互式艺术画布,跳出传统布局框架,追求先锋视觉风格、实验性排版、流畅物理动效、极具冲击力的文字版式。 沉浸式体验:融合代码、高级渲染逻辑、图片素材,打造统一完整的精品页面,做出突破常规 UI 认知、令人惊艳的数字交互体验。

通用规范

  • 遵循 ESLint + Prettier 配置,提交前必须通过 lint 与格式检查
  • 使用 TypeScript 严格模式 (strict: true),禁止使用 any 类型
  • 组件使用函数式组件 + Hooks,优先使用 Server Components,必要时使用 'use client'
  • 文件命名: 组件使用 PascalCase (UserProfile.tsx),工具函数使用 camelCase (formatDate.ts)
  • 使用 path 别名 (@/*) 导入模块,避免相对路径层级过深
  • 状态管理: 全局状态使用 Zustand/Jotai,局部状态使用 React useState/useReducer

CSS 变量引用

CSS 变量引用遵循 三层递进规则,优先级由上至下。

规则

Tailwind 映射类            → 优先使用
Tailwind 任意值 [var(--)]  → 仅当变量不在 @theme 映射表中时使用
内联 style                → 仅限复合值 / 动态运行时值

具体对照

globals.css 的 @theme inline {} 块已映射的部分,直接用 Tailwind 类:

// ✅ 正确:变量在 @theme inline {} 中有 --color-X 映射 → 用 Tailwind 类
<div className="bg-patina text-fg-dim border-rule" />
<span className="text-cinnabar" />
<div className="bg-night-bronze text-fg" />
<div className="bg-surface" />
<button className="border-gilt text-gilt" />
<div className="bg-btn-primary-bg" />   {/* Layer 2 组件 token 同理 */}

// ✅ 正确:变量未映射到 @theme inline {} → 用 Tailwind 任意值
<div className="bg-[var(--patina-wash)]" />
<span className="text-[var(--fg-faint)]" />
<div className="border-[var(--gilt-dim)]" />
<div className="bg-[var(--cinnabar-wash)]" />

bg-[var(--x)] 是 Tailwind v4 的合法任意值语法(非 hack),属于 Tailwind 体系内,不是 style 违规。--patina-wash、--patina-dim、--gilt-faint、--gilt-dim、--cinnabar-wash、--cinnabar-dim 当前均未直接映射,使用任意值是正确做法。

// ❌ 禁止:变量已在 @theme inline {} 中有映射,却用任意值
// 不要用 bg-[var(--patina)]  —— 应写 bg-patina(已映射)
// 不要用 text-[var(--cinnabar)] —— 应写 text-cinnabar(已映射)
// 不要用 border-[var(--rule)]  —— 应写 border-rule(已映射)
// 不要用 text-[var(--fg-dim)]  —— 应写 text-fg-dim(已映射)

// ❌ 禁止:用内联 style 表达单值 CSS 变量
// 不要写 style={{ color: "var(--patina)" }}
// 不要写 style={{ background: "var(--surface)" }}

// ✅ 正确:渐变色/复合 CSS 用内联 style(Tailwind 无法表达)
<div style={{
  background: "linear-gradient(180deg, var(--patina-wash), var(--surface))",
  boxShadow: "inset 0 1px 0 var(--face-in-top), var(--shadow)",
}} />

// ✅ 正确:动态运行时值用内联 style
<div style={{ color: health === "ok" ? "var(--patina)" : "var(--cinnabar)" }} />

// ✅ 正确:SVG 属性用内联 style 或 className
<circle style={{ fill: "var(--patina)", stroke: "var(--gilt)" }} />

映射速查

当前 @theme inline {} 中已映射的 铜镜鉴心 变量(查阅 globals.css 确认完整列表):

CSS 变量 Tailwind 类前缀 示例
--patina patina bg-patina text-patina border-patina
--patina-bright patina-bright bg-patina-bright
--gilt gilt bg-gilt text-gilt
--cinnabar cinnabar bg-cinnabar text-cinnabar
--ink ink bg-ink
--night-bronze night-bronze bg-night-bronze
--fg fg text-fg
--fg-dim fg-dim text-fg-dim
--fg-faint fg-faint text-fg-faint
--rule rule border-rule bg-rule
--surface surface bg-surface
--surface-hi surface-hi bg-surface-hi
--patina-wash patina-wash bg-patina-wash
--patina-dim patina-dim border-patina-dim bg-patina-dim
--gilt-dim gilt-dim border-gilt-dim text-gilt-dim bg-gilt-dim
--gilt-faint gilt-faint bg-gilt-faint
--cinnabar-wash cinnabar-wash bg-cinnabar-wash
--cinnabar-dim cinnabar-dim border-cinnabar-dim
--glass glass bg-glass
--glass-border glass-border border-glass-border
--overlay-hover overlay-hover bg-overlay-hover

未映射(用 bg-[var(--x)]):--face-sheen --sweep-gradient --face-in-top --face-in-bot --shadow --aurora-* --code-* 以及 SVG 特有的 --raw-*

例外清单

以下变量是复合 CSS 值或动画属性,必须用内联 style,不能抽象为 Tailwind 类:

  • 渐变/光照效果:--face-sheen --sweep-gradient --face-in-top --face-in-bot
  • 阴影:--shadow
  • 背景光晕:--aurora-*
  • 动态 color-mix() 表达式

规则生效日:此约定写入后,新代码必须遵守。存量代码暂不回溯,待 P0/P1 功能补齐后再做 codemod 迁移。

  • 统一通过 lib/api(client.ts 出口)调用后端,禁止在组件内散落 fetch
  • SSE 连接封装在 lib/sse-client.ts,不在组件内直接实例化 EventSource
  • 所有 API 调用必须有 TypeScript 类型定义和错误处理(ApiError 统一承载 code/trace_id)

可视化规范

  • 图谱可视化使用专用图谱库,Mermaid 用于流程图/时序图等
  • 可视化组件必须支持响应式和主题切换 (暗色/亮色)

代码审查

pnpm lint          # ESLint 检查
pnpm type-check    # TypeScript 类型检查
pnpm format:check  # Prettier 格式检查
pnpm test          # Vitest 测试
  • 必须同时通过 lint、type-check 与格式检查才能提交
  • Husky + lint-staged 已配置 pre-commit 钩子:对暂存文件自动跑 ESLint --fix + Prettier,再整体 type-check;不通过则阻止提交(临时跳过用 git commit --no-verify)
  • 注:本仓库 git 根在父目录(monorepo),prepare 脚本以 cd .. && husky frontend/.husky 安装钩子,core.hooksPath 指向 frontend/.husky/_

绝对禁止事项

  • 直接修改 package.json 或 pnpm-lock.yaml(依赖必须用 pnpm add/remove;scripts 字段可用 pnpm pkg set,注意带冒号的键需用方括号语法 scripts["name"])
  • 在客户端代码中硬编码敏感信息 (密钥、Token等)
  • 使用 any 类型 (除非经过团队评审)
  • 忽略 TypeScript 或 ESLint 错误强制提交
  • 在 Server Component 中直接使用 useState、useEffect 等客户端 Hooks
  • 使用 CSS-in-JS 方案 (统一使用 Tailwind CSS)
  • 在 Client Component 中直接调用数据库
  • 在 useEffect 中做页面初始数据请求
  • 创建 Class 组件