Files
scaffold/template/.claude/rules/frontend.md
T
baozaotumao df48c36422 refactor: 规则中性化——剥离 PPT 业务,统一为订单示范域
把规则从原 ppt-gen 项目泛化为通用脚手架,覆盖 19 个文件:
- ddd/architecture/design-discipline/error-codes/communication-* 等:
  领域术语、错误码、消息示例、扩展点、状态流统一为「订单」示范域
- agent-dag/agent.md/agent-concurrency/agent-llm-*:DAG 节点、配置、并发、
  LLM 适配从「对话→预览→生成→截图→合成」改为「intake→process→validate→finalize」
- backend-db:Session 实体/状态机/ORM/仓储/checkpoint 对齐新流水线
- 移除幻灯片专属依赖与产物:agent 去 playwright/python-pptx,
  Dockerfile 去 Chromium 系统库,.gitignore 去 *.pptx
- 保留合法通用项:ANSI(PTY 处理)、Playwright(E2E 测试工具)、Gemini CLI(真实 provider)

验证:gemini-cli/openai-api 两变体生成退出 0,生成项目零 PPT 残留,
backend/agent 骨架均可 import 运行。
2026-06-01 23:15:05 -07:00

4.9 KiB
Raw Blame History

paths
paths
frontend/**

frontend

React + Vite + TypeScript + Tailwind 前端的技术栈、目录、各层职责边界、TS 规范与测试规范。

下文以「订单」交互为示范,仅占位;组件/状态命名替换为你的业务,分层与边界规则不变。实时交互界面经 WebSocket 展示服务端推送的状态变化。

技术栈

用途
React 18 + Vite 构建工具 + UI 框架
TypeScriptstrict mode 类型安全
Tailwind CSS v3 样式(禁止自定义 CSS,全用 utility class
Zustand 全局状态管理
TanStack Query v5 服务端状态(REST 请求)
Zod 运行时 WebSocket 消息验证
sonner Toast 通知(错误/成功提示)
Vitest + Testing Library 单元测试

包管理(pnpm

pnpm add zustand @tanstack/react-query zod sonner
pnpm dev          # 开发服务器 http://localhost:5173
pnpm build        # 构建
pnpm test         # vitestwatch 模式)
pnpm test:run     # 单次运行(CI 用)
pnpm typecheck    # tsc --noEmit

关键文件:package.jsonpnpm-lock.yaml(锁文件,必须提交 git)、vite.config.tstsconfig.json

环境配置(.env

配置项见 .env.example(提交 git);真实配置放 .envgitignore)。

  • 只有 VITE_ 前缀的变量才会被注入浏览器端代码,通过 import.meta.env.VITE_XXX 读取
  • 前端变量对用户完全可见,严禁放任何密钥(图片源 API Key 走 localStorage,不进 .env
const wsUrl = import.meta.env.VITE_BACKEND_WS_URL   // ws://localhost:8000

目录结构

frontend/
├── src/
│   ├── components/              # 纯 UI 组件(无业务逻辑,无直接 store 读写)
│   │   ├── OrderForm.tsx        # 录入/编辑表单(示范)
│   │   ├── OrderList.tsx        # 列表展示
│   │   ├── StatusBadge.tsx      # 状态标识
│   │   ├── ProgressBar.tsx      # 处理进度条
│   │   ├── ErrorBoundary.tsx    # React 错误边界(组件级异常)
│   │   └── Toast.tsx            # 全局 Toast 容器(sonner Toaster
│   ├── pages/                   # 页面级组件(组合 components,接入 hooks
│   │   └── OrderPage.tsx
│   ├── hooks/                   # 自定义 Hook(业务逻辑与副作用)
│   │   ├── useWebSocket.ts      # WebSocket 生命周期管理
│   │   └── useOrder.ts          # 会话状态机(dispatch + 状态衍生)
│   ├── services/                # 外部通信封装(纯函数,无 React 依赖)
│   │   └── wsClient.ts          # WebSocket send/receive,消息序列化
│   ├── store/                   # Zustand store
│   │   └── orderStore.ts        # session、messages、orders、status
│   ├── types/                   # TypeScript 类型(只定义,不实现)
│   │   └── messages.ts          # WsMessage、OrderDTO、SessionStatus 等
│   ├── schemas/                 # Zod schema(运行时验证,与 types 一一对应)
│   │   └── messages.ts          # wsMessageSchema、createOrderSchema 等
│   ├── utils/                   # 纯函数工具(无副作用)
│   │   └── format.ts            # 纯函数格式化(金额/日期等)
│   └── main.tsx                 # 入口:挂载 ErrorBoundary + Toaster
└── tests/
    ├── components/
    ├── hooks/
    └── schemas/

各层职责边界

可以做 不可以做
components/ 渲染 propsemit 回调 直接读 store、发 WebSocket
pages/ 组合 components,调用 hooks 包含复杂业务逻辑
hooks/ 读写 store,调用 services 返回 JSX
services/ 网络通信、序列化 读 store,使用 React API
store/ 持有状态,提供 actions 包含副作用

TypeScript 规范

  • 开启 strict: true
  • 命名:camelCase 变量/函数、PascalCase 组件/类型
  • 禁止 any(用 unknown + 类型守卫)
  • 所有 Zustand action 必须有明确返回类型
  • Zod schema 与 TypeScript 类型通过 z.infer<> 保持同源,禁止手写重复类型
  • types/messages.ts 由后端 Pydantic 契约生成pnpm gen:types),禁止手改;改协议从后端改起(见根 CLAUDE.md「契约管理」)
  • 线上 JSON 契约字段为 snake_case,故生成类型的 DTO 字段为 snake_case;前端自身内部标识符仍用 camelCase

测试规范

  • 组件测试:Testing Library,测行为不测实现(不 query class/id,用 role/label
  • Hook 测试:renderHook + mock wsClient
  • Schema 测试:Zod parse 合法/非法用例各覆盖
  • ErrorBoundary 测试:注入 throw 的子组件,验证 fallback 渲染
  • 覆盖率目标:hooks 和 schemas 100%,组件 > 70%