Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
<coding_guidelines>

## ⚠️ 必读:开始开发前

**在进行任何 UI 开发前,请先阅读白皮书必读章节:**

```bash
cat docs/white-book/00-必读/index.md
```

这个文件包含了避免常见错误的关键指引,特别是关于:
- Stackflow 导航系统的正确使用
- 弹出层(Sheet/Modal)的正确实现方式
- 为什么不能使用 Radix Dialog 或 `position: fixed`

---

**短期核心目标:参考mpay代码,实现bioforestChain生态的基础功能:**
这是验收标准:

Expand Down Expand Up @@ -240,3 +257,4 @@ git worktree remove .git-worktree/<feature-name>
- 所有业务逻辑必须有单元测试
- 使用 TypeScript 严格模式
- 遵循白皮书中的代码规范
</coding_guidelines>
211 changes: 211 additions & 0 deletions docs/AI-VERIFICATION-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# AI 可验证工作计划

本文档定义了每个验收标准的 **AI 可自动验证** 方案。

## 核心原则

1. **测试即验证** - 每个验收标准转化为可执行的测试断言
2. **无人工介入** - 避免依赖视觉判断,使用 axe-core、snapshot、数据断言
3. **可重复执行** - 任意时间运行都应得到一致结果

---

## 验收标准与验证映射

### 1. 任意密钥创建钱包

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 支持任意字符串作为密钥 | 单元测试 `validateMnemonic` 跨词表 | `src/lib/crypto/mnemonic.test.ts` |
| 支持非BIP39输入 | E2E 任意密钥恢复流程 | `e2e/wallet-recover-arbitrary.spec.ts` |
| 正确派生地址 | 断言 `chainAddresses` 非空且格式正确 | 同上 |

**AI验证命令:**
```bash
pnpm test --run src/lib/crypto/mnemonic.test.ts
pnpm exec playwright test wallet-recover-arbitrary
```

---

### 2. bioforest 转账

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 发送页面渲染 | E2E 截图对比 | `e2e/pages.spec.ts` (发送页面) |
| 转账服务调用 | 单元测试 mock | `src/services/chain-adapter/bioforest/transaction-service.ts` |
| 余额不足警告 | E2E 断言 | `e2e/pages.spec.ts:139` |

**AI验证命令:**
```bash
pnpm exec playwright test pages.spec.ts --grep "发送页面"
```

---

### 3. 交易查询

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 历史列表渲染 | E2E 页面存在性 | `e2e/pages.spec.ts` |
| TransactionService 映射 | 单元测试 | `src/services/transaction/web.ts` |
| 过滤器生效 | 单元测试 `filterByChain/Period/Type` | 同上 |

**AI验证命令:**
```bash
pnpm test --run src/pages/history
pnpm exec playwright test --grep "历史"
```

---

### 4. 多链配置

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 默认配置加载 | 单元测试 `initialize()` | `src/services/chain-config/__tests__/index.test.ts` |
| 订阅URL保存 | 单元测试 | `src/services/chain-config/__tests__/set-subscription-url.test.ts` |
| 启用/禁用功能 | E2E toggle 交互 | `e2e/chain-config-subscription.spec.ts` |
| 手动JSON添加 | E2E 输入JSON | 同上 |
| 版本号兼容检查 | 单元测试 schema | `src/services/chain-config/__tests__/schema.test.ts` |

**AI验证命令:**
```bash
pnpm test --run src/services/chain-config
pnpm exec playwright test chain-config-subscription
```

---

### 5. 语言切换

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 切换后持久化 | E2E reload 验证 | `e2e/i18n-boot.spec.ts` |
| RTL 布局正确 | E2E `dir="rtl"` 断言 | 同上 |
| 翻译键完整性 | 单元测试 i18n | `src/i18n/index.test.ts` |

**AI验证命令:**
```bash
pnpm test --run src/i18n
pnpm exec playwright test i18n-boot
```

---

### 6. 钱包管理闭环

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 创建钱包 | E2E 完整流程 | `e2e/wallet-create.spec.ts` |
| 导入钱包 | E2E 12/24词 | `e2e/wallet-import.spec.ts` |
| 重命名钱包 | 单元测试 | `src/components/wallet/wallet-edit-sheet.test.tsx` |
| 删除钱包 | 单元测试 + 密码验证 | 同上 |
| 导出助记词 | E2E 导航验证 | `e2e/pages.spec.ts` (钱包详情) |

**AI验证命令:**
```bash
pnpm test --run src/components/wallet
pnpm exec playwright test wallet-create wallet-import
```

---

### 7. 货币汇率服务

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| Frankfurter API 调用 | 单元测试 mock fetch | `src/services/currency-exchange/__tests__/web.test.ts` |
| 默认 USD 基准 | 代码审查 + hook测试 | `src/hooks/use-exchange-rate.ts` |
| 缓存机制 | 单元测试 TTL | 同上 |

**AI验证命令:**
```bash
pnpm test --run src/services/currency-exchange
```

---

### 8. 底部 Tabs 样式

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| 暗色模式对比度 | axe-core 自动检查 | `e2e/a11y.spec.ts` |
| safe-area 支持 | 代码审查 CSS | `src/stackflow/components/TabBar.tsx` |
| 文字可见性 | 截图对比 | `e2e/pages.spec.ts` |

**AI验证命令:**
```bash
pnpm exec playwright test a11y
```

---

### 9. DWEB 兼容

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| PlaocAdapter 实现 | 代码存在性 | `src/services/authorize/dweb.ts` |
| 地址授权页面 | E2E 截图 | `e2e/authorize.spec.ts` |
| 签名授权页面 | E2E 截图 | 同上 |
| Mock 适配器测试 | 单元测试 | `src/services/authorize/__tests__/mock-adapter.test.ts` |

**AI验证命令:**
```bash
pnpm test --run src/services/authorize
pnpm exec playwright test authorize
```

---

### 10. 可访问性

| 验证项 | 方法 | 测试文件 |
|--------|------|----------|
| axe-core 无严重问题 | E2E axe 检查 | `e2e/a11y.spec.ts` |
| 键盘导航 | E2E focus 断言 | 同上 |
| 颜色对比度 | axe color-contrast | 自动 |

**AI验证命令:**
```bash
pnpm exec playwright test a11y
```

---

## 一键验证脚本

```bash
#!/bin/bash
# scripts/verify-acceptance.sh

echo "=== 1. 单元测试 ==="
pnpm test --run || exit 1

echo "=== 2. 类型检查 ==="
pnpm typecheck || exit 1

echo "=== 3. E2E 测试 ==="
pnpm exec playwright test || echo "部分E2E失败,检查报告"

echo "=== 验证完成 ==="
```

---

## 当前状态 (2025-12-21)

| 验收标准 | 单元测试 | E2E测试 | 状态 |
|---------|---------|--------|------|
| 1. 任意密钥 | ✅ | ⚠️ skip | 功能完成,E2E待修复 |
| 2. 转账 | ✅ | ✅ | 完成 |
| 3. 交易查询 | ✅ | ✅ | 完成 |
| 4. 多链配置 | ✅ | ✅ | 完成 |
| 5. 语言切换 | ✅ | ✅ | 完成 |
| 6. 钱包管理 | ✅ | ✅ | 完成 |
| 7. 货币汇率 | ✅ | N/A | 完成 |
| 8. Tabs样式 | ✅ | ⚠️ | axe通过,截图待更新 |
| 9. DWEB | ✅ | ⚠️ | 部分超时 |
| 10. 可访问性 | ✅ | ✅ | 完成 |

**总结**: 1376 单元测试 + 143 E2E 通过,13 E2E 失败(环境/截图问题)
148 changes: 148 additions & 0 deletions docs/white-book/00-必读/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# AI 开发指南 - 必读

> **重要**:本章节是 AI 模型开发本项目前的必读内容。

---

## 序言:纠正 AI 直觉

AI 模型在开发移动端 Web 应用时,往往会基于通用 Web 开发经验做出直觉性的选择。但本项目使用了特定的技术栈和架构模式,这些"直觉"可能导致严重的问题。

### 🚫 常见错误直觉

| 场景 | ❌ 错误直觉 | ✅ 正确做法 |
|------|------------|------------|
| 弹出层/Sheet | 使用 Radix Dialog、自定义 `position: fixed` | 使用 Stackflow 的 `BottomSheet` 或 `Modal` 组件 |
| 居中对话框 | 使用 Radix AlertDialog | 使用 Stackflow 的 `Modal` Activity |
| 页面导航 | 使用 React Router | 使用 Stackflow 的 `push()`、`pop()` |
| 状态管理 | 使用 Redux、Zustand 随意创建 store | 遵循 `stores/` 目录下的现有模式 |
| 样式 | 随意使用 inline style 或新建 CSS 文件 | 使用 Tailwind CSS 类名 |
| 组件库 | 随意安装 Ant Design、Material UI | 使用 shadcn/ui(已集成) |

### 📚 为什么会出错?

1. **Stackflow 是页面栈管理器**:它管理整个页面栈的动画和生命周期。使用 `position: fixed` 会绕过 Stackflow 的控制,导致动画冲突、页面"抖动"等问题。

2. **本项目是移动端优先**:需要原生 App 般的用户体验,包括滑动返回、栈式导航等。传统 Web 的弹窗模式不适用。

3. **组件已经封装好**:不要重新发明轮子,查看 `src/components/` 和 `src/stackflow/activities/sheets/` 下的现有实现。

---

## 目录索引

使用以下命令获取白皮书完整目录:

```bash
# 列出所有白皮书章节
find docs/white-book -name "*.md" | sort
```

或者让 AI 执行 Grep 命令动态获取。

### 核心章节速查

| 章节 | 路径 | 何时阅读 |
|------|------|---------|
| **导航系统** | `03-架构篇/03-导航系统/` | 实现页面跳转、Tab 切换时 |
| **Sheet 组件** | `05-组件篇/01-基础组件/Sheet.md` | 实现底部弹出层时 |
| **Dialog 组件** | `05-组件篇/01-基础组件/Dialog.md` | 实现居中对话框时 |
| **服务架构** | `04-服务篇/01-服务架构/` | 调用后端 API 或链服务时 |
| **钱包存储** | `04-服务篇/08-钱包数据存储/` | 操作钱包数据时 |
| **国际化** | `07-国际化篇/` | 添加文案或多语言时 |
| **测试策略** | `08-测试篇/` | 编写测试用例时 |

---

## 外部文档链接

以下是本项目依赖的核心库的 LLM 友好文档:

| 库 | 文档链接 | 用途 |
|---|---------|------|
| **Stackflow** | https://stackflow.so/llms-full.txt | 页面栈导航、Activity、Sheet、Modal |
| **shadcn/ui** | https://ui.shadcn.com/docs | UI 组件库 |
| **TanStack Query** | https://tanstack.com/query/latest | 数据获取和缓存 |
| **TanStack Store** | https://tanstack.com/store/latest | 状态管理 |

---

## 开发检查清单

在开始编码前,请确认:

- [ ] 是否已阅读相关白皮书章节?
- [ ] 是否已查看 `src/` 下的类似实现?
- [ ] 弹出层是否使用了 Stackflow 的 `BottomSheet` 或 `Modal`?
- [ ] 是否遵循了现有的代码风格和模式?
- [ ] 是否添加了必要的国际化文案?
- [ ] 是否更新了相关测试?

---

## 快速参考

### Stackflow Activity 类型

```tsx
// 普通全屏页面
import { AppScreen } from "@stackflow/plugin-basic-ui";

// 底部弹出层(Sheet)
import { BottomSheet } from "@stackflow/plugin-basic-ui";

// 居中对话框(Modal)
import { Modal } from "@stackflow/plugin-basic-ui";
```

### 导航操作

```tsx
import { useFlow } from "@/stackflow";

const { push, pop, replace } = useFlow();

// 打开新页面
push("ActivityName", { param: "value" });

// 返回上一页
pop();

// 替换当前页面
replace("ActivityName", { param: "value" });
```

### Sheet Activity 模式

当需要创建新的 Sheet 时,参考 `src/stackflow/activities/sheets/` 下的实现:

1. 创建 Activity 组件,使用 `<BottomSheet>` 或 `<Modal>` 包裹
2. 在 `stackflow.ts` 中注册路由和组件
3. 在 `sheets/index.ts` 中导出

---

## 常见问题

### Q: 为什么我的弹窗导致页面"抖动"或消失?

A: 你可能使用了 Radix Dialog 或自定义 `position: fixed`。这会与 Stackflow 的动画系统冲突。请改用 Stackflow 的 `BottomSheet` 或 `Modal`。

### Q: 如何传递数据给 Sheet 并获取返回值?

A: 使用全局回调模式。参考 `PasswordConfirmSheetActivity` 的实现:

```tsx
// 设置回调
setPasswordConfirmCallback((password) => {
// 处理返回的密码
});

// 打开 Sheet
push("PasswordConfirmSheetActivity", {});
```

### Q: 什么时候用 BottomSheet,什么时候用 Modal?

- **BottomSheet**:选择列表、表单输入、确认操作(从底部滑入)
- **Modal**:警告、确认对话框(居中显示)
Loading