# Onboarding App Shell（技术计划）

## 1. 计划目标

基于 `spec.md` 的确认项，落地客户端的“首次进入体验 + 主应用壳 + 关键入口”：

- Onboarding：**3–5 页**，每页都有问题但**全部可跳过**
- Push 设置页：**需要**，且**可跳过**；选择“立即开启”会触发系统权限申请
- 进入主 App：内容卡片支持 **点赞/讨厌**
  - Like：**加入收藏**
  - Dislike：**仅本地记录**（不做“永不出现/降权”）
- 收藏夹入口：需要；**不支持取消收藏/清空**
- 通用设置入口：需要；仅展示 **version**；iOS 小组件入口仅展示一段**美观说明文案**
- 当前阶段：**仅做客户端**（不接后端）

## 2. 默认技术决策与约束

- **路由框架**：使用现有 `expo-router`
- **导航结构**：**不使用 Tabs**
  - 使用 Stack + 顶部 Header 入口（从 Home 进入 Favorites/Settings）
- **持久化**：使用 `@react-native-async-storage/async-storage`
- **多语言**：沿用现有 i18n 基座（后续在页面文案中逐步补 key）

## 3. 路由与页面结构（不使用 Tabs）

### 3.1 路由分组（建议）

- `app/(onboarding)/...`：Onboarding 多页 + PushPrompt
- `app/(app)/...`：Home/Favorites/Settings
- `app/index.tsx`：启动路由分发（根据 onboarding 状态跳转）

### 3.2 页面清单（目标态）

- `Onboarding`（3–5 页）
  - 每页：问题展示 + “下一步” + “跳过”
  - 进度指示：`x / total`
- `PushPrompt`
  - 按钮：立即开启 / 稍后
- `Home`
  - 内容卡片（本地 mock）
  - Like / Dislike
  - Header 入口：收藏夹、设置
- `Favorites`
  - 仅展示收藏列表（不提供取消/清空）
- `Settings`
  - version 展示
  - iOS 小组件说明卡片（美观文案）
  - 可选：通知状态展示（不影响验收）

## 4. 数据模型与本地存储设计

### 4.1 Key 约定（AsyncStorage）

- `onboarding.completed`: `true | false`
- `push.promptState`: `enabled | skipped | unknown`
- `content.reactions`: `{ [contentId: string]: 'like' | 'dislike' }`
- `favorites.items`: `string[]`（收藏内容 ID 列表）

### 4.2 内容模型（本地 mock）

最小字段：

- `id: string`
- `text: string`（情绪文字/正念短句）

可选字段（非必需）：

- `bgColor/bgGradient/image`（用于后续小组件与卡片美化）

## 5. 核心交互逻辑

### 5.1 Onboarding 跳过策略

- **每页可跳过**：点击跳过直接进入下一页（或直接结束 Onboarding，二选一；默认“跳到下一页”，最后一页结束）
- **整体跳过**：在任意页可“一键跳过整个 Onboarding”
- **不允许重进**：设置页不提供重新进入 Onboarding 的入口
- Onboarding 结束后写入 `onboarding.completed=true`

### 5.2 PushPrompt

- 立即开启：触发权限申请
  - 成功/失败都可继续进入主 App
  - 写入 `push.promptState=enabled`（或按结果细分，当前阶段不强制）
- 稍后：写入 `push.promptState=skipped`
- 页面可跳过，不阻塞进入主 App

### 5.3 Like / Dislike / 收藏

- Like：
  - 写入 `content.reactions[contentId]='like'`
  - 将 `contentId` 追加到 `favorites.items`（去重）
- Dislike：
  - 写入 `content.reactions[contentId]='dislike'`
  - 不影响收藏，不改变内容排序策略（仅记录）

## 6. UI 设计要点（高层）

- Onboarding：
  - 温柔、轻量、可跳过
  - 进度清晰（例如 2/4）
- Home：
  - 卡片居中，按钮明显（Like/Dislike）
  - Header 右侧放“收藏/设置”入口（避免 Tab）
- Settings：
  - version 用“信息行”展示
  - iOS 小组件用卡片样式展示一段美观文案（可多语言）

## 7. 实施步骤（落地顺序）

1. **路由重构**：从 Tabs 模板迁移为 Stack + Header 入口（不使用 Tabs）
2. **实现启动分发**：`app/index.tsx` 根据 `onboarding.completed` 跳转
3. **实现 Onboarding 3–5 页**：支持逐页跳过与整体跳过，持久化完成状态
4. **实现 PushPrompt**：可跳过，立即开启触发权限申请并记录状态
5. **实现 Home**：本地 mock 内容 + Like/Dislike + Header 入口
6. **实现 Favorites**：展示收藏列表（不提供取消/清空）
7. **实现 Settings**：version + iOS 小组件说明文案卡片
8. **补齐 i18n key**：把新增文案接入五语资源（先覆盖 zh-CN/en，其他语言可逐步补齐）

## 8. 验收与自测清单

- 首次启动：
  - Onboarding 3–5 页可正常前进，且每页都可跳过
  - 可“一键跳过整个 Onboarding”
  - PushPrompt 可跳过；立即开启会触发权限申请；无论选择都能进入主 App
- 非首次启动：
  - 不再出现 Onboarding，直接进入主 App
- 主功能：
  - Home 可 Like/Dislike 并写入本地记录
  - Like 会进入收藏夹列表
  - 收藏夹可进入且能看到收藏内容（不提供取消/清空）
  - Settings 可进入并显示 version 与小组件说明文案

## 9. 风险与处理

- Expo/模拟器环境差异：确保在 iOS 模拟器与真机（Expo Go）都能走通流程
- 通知权限弹窗：若用户拒绝，不影响进入主功能，状态按“已提示”记录即可

