# 故事017.001: rencai mini ui包基础框架搭建

## 元信息
- **史诗**: 017 - 人才小程序功能实现
- **优先级**: P1 - 核心基础设施
- **状态**: Approved
- **创建日期**: 2025-12-25
- **负责人**: 开发团队

## 故事描述

**作为** 人才小程序开发者,
**我想要** 搭建rencai系列mini ui包的基础框架,
**以便** 为人才小程序的6个核心页面提供可复用的UI组件和API客户端集成,建立完整的技术基础。

### 背景

**现有系统状态:**
- 史诗015已完成3/8核心故事（38%）,核心API就绪
- 人才用户认证API和个人信息查询API已实现
- mini-talent项目已从mini项目复制基础框架
- mini-ui-packages目录下已有yongren系列UI包作为参考

**原型设计参考:**
- `docs/小程序原型/rencai.html` 提供了完整的6个页面原型设计
- 原型包含: 登录页、首页/个人主页、考勤记录页、个人信息页、就业信息页、设置页

**技术集成模式:**
- 参照史诗011(用人方小程序)的成功模式和架构
- 每个UI包内部管理自己的API客户端和RPC类型
- API调用逻辑封装在页面组件内部
- mini-talent只需导入页面组件使用,无需关心API实现

**需要创建的7个UI包:**
1. `@d8d/rencai-dashboard-ui` - 首页/个人主页UI包
2. `@d8d/rencai-auth-ui` - 登录认证UI包
3. `@d8d/rencai-personal-info-ui` - 个人信息UI包
4. `@d8d/rencai-attendance-ui` - 考勤记录UI包
5. `@d8d/rencai-employment-ui` - 就业信息UI包
6. `@d8d/rencai-settings-ui` - 设置页UI包
7. `@d8d/rencai-shared-ui` - 共享UI组件包

## 验收标准

### UI包基础结构
- [ ] rencai系列7个UI包基础目录结构创建完成
- [ ] 每个UI包包含必需的子目录: `src/api/`, `src/pages/`, `src/components/`, `src/types/`, `src/utils/`, `tests/`

### API客户端集成
- [ ] 每个UI包包含自己的API客户端文件 (`src/api/index.ts`)
- [ ] API客户端基于史诗015提供的RPC路由定义
- [ ] 使用Hono RPC的`hc`客户端实现类型安全的API调用
- [ ] API客户端封装在页面组件内部,mini-talent无需关心实现细节

### package.json配置
- [ ] 每个UI包的package.json配置了完整的exports字段
- [ ] exports字段包含页面组件的导出路径(如`"./pages/LoginPage/LoginPage"`)
- [ ] 参照yongren-dashboard-ui的package.json格式
- [ ] 正确配置workspace依赖关系
- [ ] 每个UI包包含dev脚本: `"dev": "tsc --watch"` 用于TypeScript编译监视

### 项目集成
- [ ] mini-talent项目的路由结构配置完成,支持页面导航
- [ ] 页面组件使用exports配置的完整路径导入: `import LoginPage from '@d8d/rencai-auth-ui/pages/LoginPage/LoginPage'`
- [ ] 基础布局组件(状态栏、底部导航、页面容器)可用并符合移动端设计
- [ ] 人才用户认证框架就绪,支持后续登录页面集成
- [ ] 根目录package.json配置了rencai系列UI包的开发脚本
- [ ] `dev:mini-ui-packages`脚本包含所有rencai UI包的并行编译监视
- [ ] `pnpm run dev`命令能够正常启动所有服务,包括rencai UI包的编译监视

### 兼容性验证
- [ ] 现有mini-talent项目功能不受影响
- [ ] rencai系列UI包遵循yongren系列UI包的API客户端模式
- [ ] 保持路由结构的统一性,新增路由不影响现有功能
- [ ] rencai系列UI包遵循现有的mini-ui-packages包结构规范

### 测试验证
- [ ] 编写基础测试验证UI包结构正确性
- [ ] 测试验证现有功能保持完整
- [ ] 类型检查通过 (`pnpm typecheck`)

## 任务列表

### 任务1: 分析史诗015已完成的API模块 (AC: UI包基础结构, API客户端集成)
- [ ] 1.1 查阅史诗015的PRD文档,确认已完成的API列表
- [ ] 1.2 确认每个UI包需要集成的RPC客户端和路由
- [ ] 1.3 分析API路径约定 (`api/v1/rencai` 前缀)
- [ ] 1.4 确认史诗015已实现的API:
  - 人才用户认证API (登录)
  - 个人信息查询API (基本信息、银行卡、证件照片)

### 任务2: 创建rencai系列UI包基础结构 (AC: UI包基础结构)
- [ ] 2.1 在`mini-ui-packages`下创建7个UI包目录:
  - `rencai-dashboard-ui/`
  - `rencai-auth-ui/`
  - `rencai-personal-info-ui/`
  - `rencai-attendance-ui/`
  - `rencai-employment-ui/`
  - `rencai-settings-ui/`
  - `rencai-shared-ui/`
- [ ] 2.2 为每个UI包创建标准子目录结构:
  - `src/api/` - API客户端
  - `src/pages/` - 页面组件
  - `src/components/` - UI组件
  - `src/types/` - TypeScript类型定义
  - `src/utils/` - 工具函数
  - `src/index.ts` - 包主入口 (保持为空,仅包含注释)
  - `tests/` - 测试文件
- [ ] 2.3 创建`src/index.ts`文件,内容为:
  ```typescript
  // 采用细粒度路径导出方式
  // 不再导出任何内容，所有工具和组件通过具体路径导入
  ```

### 任务3: 配置每个UI包的package.json、Jest配置和开发脚本 (AC: package.json配置)
- [ ] 3.1 参照`yongren-dashboard-ui/package.json`创建每个UI包的package.json
- [ ] 3.2 配置包名称为`@d8d/rencai-<name>-ui`
- [ ] 3.3 配置exports字段,支持以下导出路径:
  - `"."` - 主入口
  - `"./api"` - API客户端
  - `"./pages/<PageName>/<PageName>"` - 页面组件导出路径
- [ ] 3.4 配置workspace依赖:
  - `@d8d/mini-shared-ui-components`
  - `@d8d/rencai-shared-ui` (共享UI组件)
  - 对应的后端模块包 (如`@d8d/allin-company-module`)
- [ ] 3.5 配置Taro相关依赖:
  - `@tarojs/components`: "4.1.4"
  - `@tarojs/plugin-platform-weapp`: "4.1.4"
  - `@tarojs/react`: "4.1.4"
  - `@tarojs/taro`: "4.1.4"
- [ ] 3.6 配置scripts脚本 (必须包含以下脚本):
  ```json
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "typecheck": "tsc --noEmit",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  }
  ```
  **重要**: `dev`脚本使用`tsc --watch`,用于开发时监视TypeScript文件变化并自动编译
- [ ] 3.7 配置测试相关依赖:
  - devDependencies中添加: `"@d8d/mini-testing-utils": "workspace:*"`
  - 其他测试依赖: `jest`, `ts-jest`, `@testing-library/react`, 等
- [ ] 3.8 创建`jest.config.cjs`配置文件,参照`yongren-dashboard-ui/jest.config.cjs`:
  ```javascript
  module.exports = {
    preset: 'ts-jest',
    testEnvironment: 'jsdom',
    setupFilesAfterEnv: ['@d8d/mini-testing-utils/setup'],
    moduleNameMapper: {
      '^@/(.*)$': '<rootDir>/src/$1',
      '^~/(.*)$': '<rootDir>/tests/$1',
      '^@tarojs/taro$': '@d8d/mini-testing-utils/testing/taro-api-mock.ts',
      '\\.(css|less|scss|sass)$': '@d8d/mini-testing-utils/testing/style-mock.js',
      '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
        '@d8d/mini-testing-utils/testing/file-mock.js'
    },
    testMatch: [
      '<rootDir>/tests/**/*.spec.{ts,tsx}',
      '<rootDir>/tests/**/*.test.{ts,tsx}'
    ],
    // ... 其他配置
  }
  ```

### 任务4: 创建API客户端 (AC: API客户端集成)
- [ ] 4.1 为每个UI包创建`src/api/<rencai>Client.ts`
- [ ] 4.2 使用简单的RPC客户端导出模式,参照`yongren-statistics-ui/src/api/enterpriseStatisticsClient.ts`:
  ```typescript
  // src/api/<rencai>Client.ts
  import type { <rencaiRoutes> } from '@d8d/<rencai>-module'
  import { rpcClient } from '@d8d/mini-shared-ui-components/utils/rpc/rpc-client'

  // 人才小程序API路径前缀: /api/v1/rencai
  export const <rencai>Client = rpcClient<typeof <rencaiRoutes>>('/api/v1/rencai')
  ```
- [ ] 4.3 创建`src/api/index.ts`导出API客户端
- [ ] 4.4 集成史诗015提供的RPC路由定义
- [ ] 4.5 确保API路径使用`/api/v1/rencai`前缀

### 任务5: 创建基础布局组件 (AC: 项目集成, 基础布局组件)
- [ ] 5.1 在`@d8d/rencai-shared-ui`中创建基础布局组件:
  - `StatusBar` - 状态栏组件
  - `TabBarLayout` - 底部导航布局组件 (参照`yongren-shared-ui/src/components/YongrenTabBarLayout.tsx`)
  - `PageContainer` - 页面容器组件
  - `Navbar` - 导航栏组件 (支持带/不带返回按钮)
- [ ] 5.2 TabBarLayout组件应包含:
  - TabBarItems配置: 首页、考勤、我的、更多 (4个标签)
  - 图标使用heroicons图标库
  - 导航路由映射到rencai页面路径
  - 使用`@d8d/mini-shared-ui-components/components/tab-bar`作为基础
- [ ] 5.3 参照原型设计`docs/小程序原型/rencai.html`的UI样式
- [ ] 5.4 使用Tailwind CSS实现移动端友好的设计
- [ ] 5.5 确保组件符合小程序的尺寸规范 (375px宽度参考)

### 任务6: 建立人才用户认证框架 (AC: 人才用户认证框架)
- [ ] 6.1 在`@d8d/rencai-auth-ui`中创建认证基础框架
- [ ] 6.2 集成史诗015提供的人才用户认证API
- [ ] 6.3 创建认证上下文 (AuthContext) 管理登录状态
- [ ] 6.4 实现token存储和验证逻辑
- [ ] 6.5 创建登录页面基础结构 (页面组件占位)
- [ ] 6.6 支持身份证号/残疾证号密码登录模式

### 任务7: 配置mini-talent项目的路由结构 (AC: 项目集成)
- [ ] 7.1 **删除旧的yongren页面**: 删除`mini-talent/src/pages/yongren/`目录及其所有子目录
  ```bash
  rm -rf mini-talent/src/pages/yongren
  ```
- [ ] 7.2 **更新app.config.ts配置**:
  - 删除所有yongren相关的页面路由
  - 删除yongren相关的TabBar配置
  - 更新窗口标题为"人才小程序"
  - 添加rencai系列页面路由和TabBar配置
- [ ] 7.3 创建rencai系列页面目录结构:
  ```bash
  mkdir -p mini-talent/src/pages/login
  mkdir -p mini-talent/src/pages/index
  mkdir -p mini-talent/src/pages/attendance
  mkdir -p mini-talent/src/pages/personal-info
  mkdir -p mini-talent/src/pages/employment
  mkdir -p mini-talent/src/pages/settings
  ```
- [ ] 7.4 配置底部TabBar导航 (首页、考勤、我的、更多)
- [ ] 7.5 使用`TabBarLayout`组件包装TabBar页面
- [ ] 7.6 确保路由配置与原型设计一致

### 任务8: 编写基础测试 (AC: 测试验证)
- [ ] 8.1 为每个UI包编写基础测试,验证包结构正确性
- [ ] 8.2 测试API客户端的导入和导出
- [ ] 8.3 测试页面组件的导入路径
- [ ] 8.4 验证mini-talent项目现有功能不受影响
- [ ] 8.5 运行`pnpm typecheck`确保类型检查通过

### 任务9: 配置开发服务器并行启动 (AC: 项目集成)
- [ ] 9.1 在根目录`package.json`的`scripts`中添加rencai系列UI包的开发脚本:
  ```json
  "dev:rencai-dashboard-ui": "pnpm --filter \"@d8d/rencai-dashboard-ui\" run dev",
  "dev:rencai-auth-ui": "pnpm --filter \"@d8d/rencai-auth-ui\" run dev",
  "dev:rencai-personal-info-ui": "pnpm --filter \"@d8d/rencai-personal-info-ui\" run dev",
  "dev:rencai-attendance-ui": "pnpm --filter \"@d8d/rencai-attendance-ui\" run dev",
  "dev:rencai-employment-ui": "pnpm --filter \"@d8d/rencai-employment-ui\" run dev",
  "dev:rencai-settings-ui": "pnpm --filter \"@d8d/rencai-settings-ui\" run dev",
  "dev:rencai-shared-ui": "pnpm --filter \"@d8d/rencai-shared-ui\" run dev"
  ```
- [ ] 9.2 更新`dev:mini-ui-packages`脚本,将rencai系列UI包添加到concurrently命令中:
  ```json
  "dev:mini-ui-packages": "concurrently \
    \"pnpm run dev:dev:allin-enums\" \
    \"pnpm run dev:mini-enterprise-auth-ui\" \
    \"pnpm run dev:mini-shared-ui-components\" \
    \"pnpm run dev:yongren-shared-ui\" \
    \"pnpm run dev:yongren-dashboard-ui\" \
    \"pnpm run dev:yongren-order-management-ui\" \
    \"pnpm run dev:yongren-settings-ui\" \
    \"pnpm run dev:yongren-statistics-ui\" \
    \"pnpm run dev:yongren-talent-management-ui\" \
    \"pnpm run dev:mini-charts\" \
    \"pnpm run dev:rencai-shared-ui\" \
    \"pnpm run dev:rencai-dashboard-ui\" \
    \"pnpm run dev:rencai-auth-ui\" \
    \"pnpm run dev:rencai-personal-info-ui\" \
    \"pnpm run dev:rencai-attendance-ui\" \
    \"pnpm run dev:rencai-employment-ui\" \
    \"pnpm run dev:rencai-settings-ui\""
  ```
- [ ] 9.3 验证`pnpm run dev`命令能够正常启动所有服务,包括rencai系列UI包的编译监视
- [ ] 9.4 确认rencai系列UI包的TypeScript编译输出正确,无编译错误

## 开发者笔记

### 前置故事见解

**史诗016完成状态:**
- ✅ mini-charts图表组件包已完成 (故事016.001-016.013)
- ✅ 提供了可复用的UI组件开发经验

**史诗015完成状态 (2025-12-25):**
- ✅ 人才用户认证API已完成 (故事015-02)
- ✅ 个人信息查询API已完成 (故事015-03)
- ⚠️ 就业信息API进行中 (故事015-05)
- ⚠️ 帮助与支持API进行中 (故事015-06)
- ⚠️ 通知与消息API进行中 (故事015-07)
- 🚀 **启动建议**: 史诗017可以立即开始,与史诗015并行开发

### 技术栈要求

**来源**: [architecture/tech-stack.md](../architecture/tech-stack.md)

**运行时和框架:**
- **Node.js**: 20.18.3
- **Hono**: 4.8.5 (RPC客户端)
- **React**: 19.1.0 (UI组件)
- **Taro**: 4.1.4 (小程序框架)
- **Tailwind CSS**: 4.1.11 (样式)

**测试框架:**
- **Jest**: 30.2.0 (mini项目使用Jest,不是Vitest!)
- **ts-jest**: 29.4.5 (TypeScript预处理器)
- **@testing-library/react**: 16.3.0 (React组件测试)
- **@d8d/mini-testing-utils**: workspace包 (Taro小程序测试工具,提供统一的mock配置)

**包管理:**
- **pnpm**: workspace管理

### UI包开发规范

**来源**: [architecture/ui-package-standards.md](../architecture/ui-package-standards.md)

**关键规范要求:**

#### 1. 包结构规范
```
mini-ui-packages/<package-name>/
├── package.json              # 包配置 (必须包含exports字段)
├── tsconfig.json             # TypeScript配置
├── jest.config.cjs           # Jest测试配置
├── src/
│   ├── index.ts              # 主入口文件 (保持为空,采用细粒度导出)
│   ├── api/                  # API客户端
│   │   └── index.ts          # API导出
│   ├── pages/                # 页面组件
│   │   └── <PageName>/
│   │       ├── <PageName>.tsx
│   │       └── index.ts
│   ├── components/           # UI组件
│   ├── types/                # TypeScript类型定义
│   └── utils/                # 工具函数
└── tests/                    # 测试文件
```

**src/index.ts规范** (参照`yongren-statistics-ui/src/index.ts`):
```typescript
// 采用细粒度路径导出方式
// 不再导出任何内容，所有工具和组件通过具体路径导入
```

**重要**: 主入口文件`src/index.ts`保持为空(仅包含注释),所有导出通过package.json的exports字段配置的具体路径进行。

#### 2. UI包内部导入规范

**重要**: UI包内部导入必须使用相对路径,不要使用别名。

**正确示例** (参照`yongren-dashboard-ui/src/pages/Dashboard/Dashboard.tsx`):
```typescript
// ✅ 正确: 使用相对路径导入同一包内的模块
import { enterpriseCompanyClient } from '../../api'
import { SomeComponent } from '../components/SomeComponent'
import { utilFunction } from '../../utils/helper'
```

**错误示例**:
```typescript
// ❌ 错误: 不要使用别名导入UI包内部的模块
import { enterpriseCompanyClient } from '@/api'
import { SomeComponent } from '@/pages/Dashboard/components'
```

**说明**:
- UI包内部导入(同一包内的文件)必须使用相对路径
- `@/`和`~/`别名仅在Jest配置中用于测试路径映射,不在源代码中使用
- 只有跨包导入才使用workspace包名(如`@d8d/mini-shared-ui-components`)

#### 3. package.json exports配置规范
```json
{
  "exports": {
    ".": {
      "types": "./dist/src/index.d.ts",
      "import": "./dist/src/index.js",
      "require": "./dist/src/index.js"
    },
    "./api": {
      "types": "./src/api/index.ts",
      "import": "./src/api/index.ts",
      "require": "./src/api/index.ts"
    },
    "./pages/<PageName>/<PageName>": {
      "types": "./dist/src/pages/<PageName>/<PageName>.d.ts",
      "import": "./dist/src/pages/<PageName>/<PageName>.js",
      "require": "./dist/src/pages/<PageName>/<PageName>.js"
    }
  }
}
```

**重要**: 页面组件的导出路径必须与实际文件路径匹配,便于mini-talent导入:
```typescript
// mini-talent中的导入方式
import LoginPage from '@d8d/rencai-auth-ui/pages/LoginPage/LoginPage'
```

#### 4. Jest配置规范
每个UI包必须创建`jest.config.cjs`配置文件,参照`yongren-dashboard-ui/jest.config.cjs`:

```javascript
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['@d8d/mini-testing-utils/setup'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '^~/(.*)$': '<rootDir>/tests/$1',
    '^@tarojs/taro$': '@d8d/mini-testing-utils/testing/taro-api-mock.ts',
    '\\.(css|less|scss|sass)$': '@d8d/mini-testing-utils/testing/style-mock.js',
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '@d8d/mini-testing-utils/testing/file-mock.js'
  },
  testMatch: [
    '<rootDir>/tests/**/*.spec.{ts,tsx}',
    '<rootDir>/tests/**/*.test.{ts,tsx}'
  ],
  collectCoverageFrom: [
    'src/**/*.{ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/index.{ts,tsx}',
    '!src/**/*.stories.{ts,tsx}'
  ],
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov', 'html'],
  testPathIgnorePatterns: [
    '/node_modules/',
    '/dist/',
    '/coverage/'
  ],
  transform: {
    '^.+\\.(ts|tsx)$': 'ts-jest',
    '^.+\\.(js|jsx)$': 'babel-jest'
  },
  transformIgnorePatterns: [
    '/node_modules/(?!(swiper|@tarojs)/)'
  ],
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json']
}
```

**关键配置说明**:
- `setupFilesAfterEnv`: 使用`@d8d/mini-testing-utils/setup`进行测试环境初始化
- `moduleNameMapper`:
  - `^@/(.*)$` 和 `^~/(.*)$`: 仅用于测试文件的路径映射,不在源代码中使用
  - `^@tarojs/taro$`: 映射Taro API到mock
  - 样式和文件映射: 将样式文件和静态文件映射到mock
- **重要**: 源代码中不使用`@/`或`~/`别名,只使用相对路径
- `testMatch`: 支持`.spec.{ts,tsx}`和`.test.{ts,tsx}`两种测试文件格式

#### 5. RPC客户端实现规范
每个UI包使用简单的RPC客户端导出模式 (参照`yongren-statistics-ui/src/api/enterpriseStatisticsClient.ts`):

```typescript
// src/api/<rencai>Client.ts
import type { <rencaiRoutes> } from '@d8d/<rencai>-module'
import { rpcClient } from '@d8d/mini-shared-ui-components/utils/rpc/rpc-client'

// 人才小程序API路径前缀: /api/v1/rencai
export const <rencai>Client = rpcClient<typeof <rencaiRoutes>>('/api/v1/rencai')
```

**src/api/index.ts导出**:
```typescript
export { <rencai>Client } from './<rencai>Client'
```

#### 6. 类型定义规范
**必须使用RPC推断类型**，避免直接导入schema类型:

```typescript
// ✅ 正确：使用RPC推断类型 + 相对路径导入
import type { InferResponseType } from 'hono'
import { <rencai>Client } from '../api/<rencai>Client'

export type <Rencai>InfoResponse = InferResponseType<typeof <rencai>Client.personal.info.$get, 200>

// ❌ 错误：直接导入schema类型 (可能导致Date/string不匹配)
import type { <Rencai> } from '@d8d/<rencai>-module/schemas'

// ❌ 错误：使用别名导入UI包内部模块
import { <rencai>Client } from '@/api/<rencai>Client'
```

### 项目结构指南

**来源**: [architecture/source-tree.md](../architecture/source-tree.md)

**mini-talent项目结构:**
```
mini-talent/                   # 人才小程序项目
├── src/
│   ├── app.tsx                # 小程序入口
│   ├── app.config.ts          # 小程序配置 (需替换为rencai页面路由)
│   ├── app.css                # 全局样式
│   ├── index.html             # HTML模板
│   └── pages/                 # 页面目录
│       ├── login/             # 登录页 (从UI包导入)
│       │   └── index.tsx
│       ├── index/             # 首页/个人主页 (从UI包导入)
│       │   └── index.tsx
│       ├── attendance/        # 考勤记录 (从UI包导入)
│       │   └── index.tsx
│       ├── personal-info/     # 个人信息 (从UI包导入)
│       │   └── index.tsx
│       ├── employment/        # 就业信息 (从UI包导入)
│       │   └── index.tsx
│       └── settings/          # 设置页 (从UI包导入)
│           └── index.tsx
├── config/                    # 配置文件
├── package.json
├── jest.config.js             # Jest配置
└── tsconfig.json
```

**说明**:
- mini-talent项目结构简洁,主要包含页面路由配置
- API客户端、布局组件(如TabBarLayout)由UI包管理
- TabBarLayout参考: `mini-ui-packages/yongren-shared-ui/src/components/YongrenTabBarLayout.tsx`
- 页面组件从rencai系列UI包导入,作为薄包装层

**mini-talent/src/app.config.ts配置 (新):**

完全替换现有的yongren配置为rencai配置:
```typescript
export default defineAppConfig({
  pages: [
    'pages/login/index',           // 登录页
    'pages/index/index',           // 首页/个人主页
    'pages/attendance/index',      // 考勤记录
    'pages/personal-info/index',   // 个人信息
    'pages/employment/index',      // 就业信息
    'pages/settings/index',        // 设置页
  ],
  window: {
    backgroundTextStyle: 'light',
    navigationBarBackgroundColor: '#3b82f6',
    navigationBarTitleText: '人才小程序',
    navigationBarTextStyle: 'white',
    navigationStyle: 'custom'
  },
  tabBar: {
    custom: true,
    color: "#6b7280",
    selectedColor: "#3b82f6",
    backgroundColor: "#ffffff",
    list: [
      {
        pagePath: 'pages/index/index',
        text: '首页'
      },
      {
        pagePath: 'pages/attendance/index',
        text: '考勤'
      },
      {
        pagePath: 'pages/personal-info/index',
        text: '我的'
      },
      {
        pagePath: 'pages/settings/index',
        text: '更多'
      }
    ]
  },
  usingComponents: {}
})
```

**重要变更**:
- ✅ 删除所有yongren相关页面路由
- ✅ 更新导航栏标题为"人才小程序"
- ✅ TabBar配置: 首页、考勤、我的、更多 (4个标签)
- ✅ 页面组件从rencai系列UI包导入

**mini-ui-packages目录结构:**
```
mini-ui-packages/
├── yongren-dashboard-ui/      # 参考实现 (用人方仪表板)
├── yongren-auth-ui/           # 参考实现 (用人方认证)
├── yongren-shared-ui/         # 参考实现 (用人方共享组件)
├── mini-shared-ui-components/ # 通用小程序UI组件
├── rencai-dashboard-ui/       # [待创建] 人才仪表板
├── rencai-auth-ui/            # [待创建] 人才认证
├── rencai-personal-info-ui/   # [待创建] 人才个人信息
├── rencai-attendance-ui/      # [待创建] 人才考勤记录
├── rencai-employment-ui/      # [待创建] 人才就业信息
├── rencai-settings-ui/        # [待创建] 人才设置
└── rencai-shared-ui/          # [待创建] 人才共享组件
```

**根目录package.json脚本配置:**

开发服务器启动使用concurrently并行运行所有服务的编译监视:
```json
{
  "scripts": {
    "dev": "concurrently \
      \"pnpm run dev:mini\" \
      \"pnpm run dev:mini-talent\" \
      \"pnpm run dev:web\" \
      \"pnpm run dev:weapp\" \
      \"pnpm run dev:weapp-talent\" \
      \"pnpm run dev:mini-ui-packages\" ",

    "dev:mini-ui-packages": "concurrently \
      [... existing yongren packages ...] \
      \"pnpm run dev:rencai-shared-ui\" \
      \"pnpm run dev:rencai-dashboard-ui\" \
      \"pnpm run dev:rencai-auth-ui\" \
      \"pnpm run dev:rencai-personal-info-ui\" \
      \"pnpm run dev:rencai-attendance-ui\" \
      \"pnpm run dev:rencai-employment-ui\" \
      \"pnpm run dev:rencai-settings-ui\"",

    "dev:rencai-dashboard-ui": "pnpm --filter \"@d8d/rencai-dashboard-ui\" run dev",
    "dev:rencai-auth-ui": "pnpm --filter \"@d8d/rencai-auth-ui\" run dev",
    // ... 其他rencai UI包
  }
}
```

**重要**: 每个UI包的`dev`脚本使用`tsc --watch`,在开发时监视TypeScript文件变化并自动编译到`dist/`目录。

### 原型设计参考

**来源**: [docs/小程序原型/rencai.html](../小程序原型/rencai.html)

**原型包含6个完整页面:**

1. **登录页** (原型行115-158)
   - 身份证号/残疾证号输入框
   - 密码输入框
   - 登录按钮
   - 忘记密码链接
   - 注册入口

2. **首页/个人主页** (原型行160-301)
   - 顶部个人信息卡片 (姓名、残疾类型、出勤统计、本月薪资)
   - 打卡模块 (打卡状态、上班/下班打卡时间、远程打卡按钮)
   - 功能入口网格 (个人信息、考勤记录、薪资查询、企业信息)
   - 最新通知列表

3. **考勤记录页** (原型行303-481)
   - 月份选择器
   - 考勤统计卡片 (出勤率、正常出勤天数、迟到/早退/缺勤次数)
   - 考勤日历视图 (标记已打卡日期)
   - 打卡明细列表 (按日期倒序)

4. **个人信息页** (原型行483-628)
   - 顶部个人信息摘要
   - 基本信息列表 (姓名、性别、年龄、身份证号、残疾证号、残疾类型、联系电话、联系地址)
   - 银行卡信息列表 (银行名称、卡号脱敏、卡类型、是否默认)
   - 证件照片网格 (身份证、残疾证、体检报告、征信报告)

5. **就业信息页** (原型行630-768)
   - 当前就业状态卡片 (企业名称、岗位名称、入职日期、工作状态、订单编号、薪资水平)
   - 薪资记录列表 (按月份查询)
   - 就业历史时间线 (按时间倒序)

6. **设置页** (原型行770-906)
   - 个人信息摘要 (姓名、残疾类型、出勤统计、本月薪资)
   - 功能入口列表 (修改个人信息、账号与安全、消息通知设置)
   - 帮助与支持入口 (帮助中心、用户协议、隐私政策)
   - 退出登录按钮

**移动端设计规范:**
- 宽度参考: 375px
- 状态栏高度: 44px
- 底部导航高度: 60px
- 圆角规范: 12px (卡片)、40px (移动框架)
- 颜色主题: 蓝色渐变 (#3b82f6 → #1e40af)
- 字体规范: 标题18-24px, 正文14px, 小字12px

### 史诗015 API集成要点

**来源**: [docs/prd/epic-015-talent-mini-program-api-support.md](../prd/epic-015-talent-mini-program-api-support.md)

**API路径约定:**
所有人才小程序API使用 `api/v1/rencai` 前缀:
- 人才用户登录: `POST /api/v1/rencai/auth/login`
- 人才个人信息: `GET /api/v1/rencai/personal/info`
- 银行卡信息查询: `GET /api/v1/rencai/personal/bank-cards`
- 证件照片查询: `GET /api/v1/rencai/personal/photos`
- 考勤记录查询: `GET /api/v1/rencai/attendance/records` (P2延期,前端模拟)
- 就业信息查询: `GET /api/v1/rencai/employment/info`
- 薪资记录查询: `GET /api/v1/rencai/salary/records`
- 就业历史查询: `GET /api/v1/rencai/employment/history`

**已完成的API (可直接集成):**
- ✅ 人才用户认证API (故事015-02)
- ✅ 个人信息查询API (故事015-03)

**进行中的API (后续集成):**
- ⚠️ 就业信息API (故事015-05)
- ⚠️ 帮助与支持API (故事015-06)
- ⚠️ 通知与消息API (故事015-07)

**只读设计原则:**
遵循与用人方小程序相同的设计原则,人才小程序API以查询功能为主。所有数据修改操作由管理员在管理后台统一处理。人才用户仅有的写入操作包括: 登录认证、通知标记已读。

### 测试策略

**来源**: [architecture/testing-strategy.md](../architecture/testing-strategy.md)

**测试框架选择:**
- **mini项目使用Jest** (不是Vitest!)
- 测试命令: `pnpm test` (在mini目录下运行)
- 测试配置: `jest.config.js`

**测试文件位置:**
```
mini-ui-packages/<package-name>/
└── tests/
    ├── unit/              # 单元测试
    │   └── *.test.tsx
    └── integration/       # 集成测试
        └── *.test.tsx
```

**测试要求:**
1. 为每个UI包编写基础测试,验证包结构正确性
2. 测试API客户端的导入和导出
3. 测试页面组件的导入路径
4. 验证mini-talent项目现有功能不受影响
5. 运行`pnpm typecheck`确保类型检查通过

**Mock响应工具函数 (参考):**
```typescript
const createMockResponse = (status: number, data?: any) => ({
  status,
  ok: status >= 200 && status < 300,
  body: null,
  bodyUsed: false,
  statusText: status === 200 ? 'OK' : 'Error',
  headers: new Headers(),
  url: '',
  redirected: false,
  type: 'basic' as ResponseType,
  json: async () => data || {},
  text: async () => '',
  blob: async () => new Blob(),
  arrayBuffer: async () => new ArrayBuffer(0),
  formData: async () => new FormData(),
  clone: function() { return this; }
})
```

### 编码标准

**来源**: [architecture/coding-standards.md](../architecture/coding-standards.md)

**关键编码规范:**

#### 1. 必须遵循UI包开发规范
开发UI包时,**必须**参考并遵循[UI包开发规范](../architecture/ui-package-standards.md),该规范基于史诗008(AllIn UI模块移植)的经验总结。

#### 2. 关键检查点 (基于史诗008经验)
- **API路径映射验证**: 开发前必须验证故事中的API路径映射与实际后端路由定义的一致性
- **类型推断最佳实践**: 必须使用RPC推断类型,而不是直接导入schema类型
- **测试选择器优化**: 必须为关键交互元素添加`data-testid`属性
- **表单组件模式**: 必须使用条件渲染两个独立的Form组件
- **API调用一致性**: 必须根据实际路由名称修正API调用

#### 3. 常见错误避免
- ❌ 不要直接导入schema类型 (可能导致Date/string类型不匹配)
- ❌ 不要使用`getByText()`查找可能重复的文本元素
- ❌ 不要在单个Form组件上动态切换props
- ❌ 不要使用故事中描述但实际不存在的路由名称
- ❌ **不要在UI包内部导入中使用别名** (`@/`, `~/`等),必须使用相对路径

**路径使用示例**:
```typescript
// ✅ 正确: UI包内部使用相对路径
import { apiClient } from '../../api'
import { MyComponent } from '../components'

// ✅ 正确: 跨包导入使用workspace包名
import { SharedComponent } from '@d8d/mini-shared-ui-components'

// ❌ 错误: UI包内部使用别名
import { apiClient } from '@/api'
import { MyComponent } from '~/pages/Dashboard/components'
```

#### 4. 参考实现
- **用人方统计UI包**: `mini-ui-packages/yongren-statistics-ui`
  - API客户端: `src/api/enterpriseStatisticsClient.ts` (简单RPC客户端导出模式)
  - 主入口文件: `src/index.ts` (保持为空,采用细粒度导出)
  - 参照此文件实现rencai UI包的API客户端和导出方式

- **用人方仪表板UI包**: `mini-ui-packages/yongren-dashboard-ui`
  - 组件: `src/pages/Dashboard/Dashboard.tsx`
  - package.json exports配置
  - 目录结构参考
  - Jest配置: `jest.config.cjs`

### 数据模型参考

**来源**: [architecture/data-model-schema-changes.md](../architecture/data-model-schema-changes.md)

**相关数据表 (基于allin数据库):**
- `users2` - 用户表 (已扩展支持talent用户类型)
- `disabled_person` - 残疾人信息表
- `disabled_bank_card` - 银行卡信息表
- `disabled_person_photo` - 证件照片表
- `employment_order` - 就业订单表
- `order_person` - 订单人员关联表

**数据库schema扩展 (故事015-01已完成):**
- `users2`表新增`talent`用户类型
- `users2`表新增`person_id`字段 (外键引用`disabled_person.person_id`)

### 技术约束

1. **向后兼容**: 不影响现有mini-talent项目功能
2. **类型安全**: 使用TypeScript严格模式,所有API调用必须有类型定义
3. **模块独立性**: 每个UI包独立管理自己的API客户端和类型定义
4. **测试覆盖**: 所有新增代码必须有测试覆盖
5. **代码规范**: 遵循项目编码标准和UI包开发规范

### 风险和缓解措施

**主要风险:**
1. **API集成风险**: 史诗015的API可能尚未全部完成,需要并行开发
2. **UI组件复用风险**: rencai系列UI包可能与现有yongren系列UI包存在差异
3. **兼容性风险**: 不同小程序平台可能存在兼容性问题

**缓解措施:**
1. **分阶段集成**: 先集成已完成的API (人才用户认证、个人信息查询)
2. **UI组件规范统一**: 参照yongren系列UI包的结构和命名规范
3. **类型安全**: 使用RPC推断类型,避免类型不匹配问题
4. **测试驱动**: 编写完整的测试,确保功能正确性

## 变更日志

| 日期 | 版本 | 描述 | 作者 |
|------|------|------|------|
| 2025-12-25 | 1.0 | 创建故事文档 | Bob (Scrum Master) |

## 开发者记录

*此部分由开发代理在实施过程中填写*

### 使用的代理模型

Claude Sonnet 4 (claude-sonnet-4-20250514)

### 调试日志引用

无

### 完成说明列表

1. **API客户端导入修正**: 初始实现时错误地从`@d8d/server`导入路由类型,已修正为从相应的后端模块包导入:
   - `rencaiAuthRoutes` 从 `@d8d/core-module/auth-module`
   - `talentPersonalInfoRoutes` 从 `@d8d/allin-disability-module`
   - `talentEmploymentRoutes` 从 `@d8d/allin-order-module`

2. **mini-talent页面简化**: 页面文件采用"薄包装层"设计,仅从UI包导入并导出组件,不做额外包装

3. **复用现有共享组件**: StatusBar、PageContainer、Navbar等通用组件使用`@d8d/mini-shared-ui-components`中的实现,避免重复创建

4. **简化导出结构**: 页面组件不需要额外的index.ts文件,直接通过package.json的exports字段导出

5. **待实现功能**: 以下功能已创建基础框架,待后续故事实现:
   - 各UI包的具体页面组件实现
   - API客户端集成真实API调用(当前为占位实现)
   - 完整的测试覆盖

### 文件列表

**新增/修改的UI包配置文件 (21个)**:
- `mini-ui-packages/rencai-dashboard-ui/package.json`
- `mini-ui-packages/rencai-dashboard-ui/jest.config.cjs`
- `mini-ui-packages/rencai-dashboard-ui/tsconfig.json`
- `mini-ui-packages/rencai-dashboard-ui/src/index.ts`
- `mini-ui-packages/rencai-auth-ui/package.json`
- `mini-ui-packages/rencai-auth-ui/jest.config.cjs`
- `mini-ui-packages/rencai-auth-ui/tsconfig.json`
- `mini-ui-packages/rencai-auth-ui/src/index.ts`
- `mini-ui-packages/rencai-personal-info-ui/package.json`
- `mini-ui-packages/rencai-personal-info-ui/jest.config.cjs`
- `mini-ui-packages/rencai-personal-info-ui/tsconfig.json`
- `mini-ui-packages/rencai-personal-info-ui/src/index.ts`
- `mini-ui-packages/rencai-attendance-ui/package.json`
- `mini-ui-packages/rencai-attendance-ui/jest.config.cjs`
- `mini-ui-packages/rencai-attendance-ui/tsconfig.json`
- `mini-ui-packages/rencai-attendance-ui/src/index.ts`
- `mini-ui-packages/rencai-employment-ui/package.json`
- `mini-ui-packages/rencai-employment-ui/jest.config.cjs`
- `mini-ui-packages/rencai-employment-ui/tsconfig.json`
- `mini-ui-packages/rencai-employment-ui/src/index.ts`
- `mini-ui-packages/rencai-settings-ui/package.json`
- `mini-ui-packages/rencai-settings-ui/jest.config.cjs`
- `mini-ui-packages/rencai-settings-ui/tsconfig.json`
- `mini-ui-packages/rencai-settings-ui/src/index.ts`
- `mini-ui-packages/rencai-shared-ui/package.json`
- `mini-ui-packages/rencai-shared-ui/jest.config.cjs`
- `mini-ui-packages/rencai-shared-ui/tsconfig.json`
- `mini-ui-packages/rencai-shared-ui/src/index.ts`

**API客户端文件 (13个)**:
- `mini-ui-packages/rencai-auth-ui/src/api/talentAuthClient.ts`
- `mini-ui-packages/rencai-auth-ui/src/api/index.ts`
- `mini-ui-packages/rencai-dashboard-ui/src/api/talentDashboardClient.ts`
- `mini-ui-packages/rencai-dashboard-ui/src/api/index.ts`
- `mini-ui-packages/rencai-personal-info-ui/src/api/talentPersonalInfoClient.ts`
- `mini-ui-packages/rencai-personal-info-ui/src/api/index.ts`
- `mini-ui-packages/rencai-employment-ui/src/api/talentEmploymentClient.ts`
- `mini-ui-packages/rencai-employment-ui/src/api/index.ts`
- `mini-ui-packages/rencai-attendance-ui/src/api/talentAttendanceClient.ts`
- `mini-ui-packages/rencai-attendance-ui/src/api/index.ts`
- `mini-ui-packages/rencai-settings-ui/src/api/talentSettingsClient.ts`
- `mini-ui-packages/rencai-settings-ui/src/api/index.ts`

**基础布局组件 (1个)**:
- `mini-ui-packages/rencai-shared-ui/src/components/RencaiTabBarLayout.tsx`
  - 注: StatusBar、PageContainer、Navbar等通用组件使用`@d8d/mini-shared-ui-components`中的实现

**认证框架 (2个)**:
- `mini-ui-packages/rencai-auth-ui/src/utils/AuthContext.tsx`
- `mini-ui-packages/rencai-auth-ui/src/pages/LoginPage/LoginPage.tsx`
  - 注: 不需要index.ts,直接通过package.json的exports导出

**mini-talent页面文件 (7个)**:
- `mini-talent/src/app.config.ts` (更新)
- `mini-talent/src/pages/login/index.tsx` (更新)
- `mini-talent/src/pages/index/index.tsx` (新建)
- `mini-talent/src/pages/attendance/index.tsx` (新建)
- `mini-talent/src/pages/personal-info/index.tsx` (新建)
- `mini-talent/src/pages/employment/index.tsx` (新建)
- `mini-talent/src/pages/settings/index.tsx` (新建)

**根目录配置 (1个)**:
- `package.json` (更新,添加rencai UI包开发脚本)

**总计**: 45个文件

## 故事草稿检查清单结果

**执行日期**: 2025-12-25
**执行者**: Bob (Scrum Master)

### 验证结果

| 类别 | 状态 | 问题 |
|------|------|------|
| 1. 目标与上下文清晰度 | PASS | - |
| 2. 技术实现指导 | PASS | - |
| 3. 参考文档有效性 | PASS | - |
| 4. 自包含性评估 | PASS | - |
| 5. 测试指导 | PASS | - |

### 详细检查结果

#### 1. 目标与上下文清晰度 ✅ PASS
- ✅ 故事目标/目的清晰陈述: 搭建rencai系列mini ui包的基础框架
- ✅ 与史诗目标的关系明确: 史诗017人才小程序功能实现的基础故事
- ✅ 在整体系统流程中的位置已解释: 参照史诗011成功模式,建立技术基础
- ✅ 对前置故事的依赖已识别: 依赖史诗015已完成的API模块
- ✅ 业务上下文和价值清晰: 为残疾人用户提供完整的人才小程序功能

#### 2. 技术实现指导 ✅ PASS
- ✅ 关键文件已识别:
  - 7个UI包的目录结构
  - package.json配置文件
  - API客户端文件 (src/api/<rencai>Client.ts)
  - 页面组件文件结构
- ✅ 所需技术已明确指定:
  - TypeScript, React, Taro, Hono RPC, Tailwind CSS
  - Jest测试框架 (mini项目使用Jest,不是Vitest)
- ✅ 关键API和接口已充分描述:
  - API路径约定 (`/api/v1/rencai` 前缀)
  - RPC客户端实现模式 (简单导出模式,参照yongren-statistics-ui)
  - package.json exports配置规范 (包含完整示例)
- ✅ 必要的数据模型或结构已引用:
  - 史诗015的API模块
  - 原型设计文档
  - 数据库表结构
- ✅ 环境变量已列出 (不适用,使用默认配置)
- ✅ 标准编码模式的例外已注明:
  - mini项目使用Jest而非Vitest
  - 页面组件导出路径的完整格式
  - 类型推断必须使用RPC推断类型
  - RPC客户端使用简单导出模式而非管理器模式

#### 3. 参考文档有效性 ✅ PASS
- ✅ 外部文档引用指向特定相关部分:
  - [architecture/tech-stack.md](../architecture/tech-stack.md)
  - [architecture/ui-package-standards.md](../architecture/ui-package-standards.md)
  - [architecture/source-tree.md](../architecture/source-tree.md)
  - [architecture/testing-strategy.md](../architecture/testing-strategy.md)
  - [architecture/coding-standards.md](../architecture/coding-standards.md)
  - [architecture/data-model-schema-changes.md](../architecture/data-model-schema-changes.md)
  - [docs/prd/epic-015-talent-mini-program-api-support.md](../prd/epic-015-talent-mini-program-api-support.md)
  - [docs/小程序原型/rencai.html](../小程序原型/rencai.html)
- ✅ 前置故事的关键信息已总结:
  - 史诗015完成状态 (38%,3/8核心故事完成)
  - 史诗016完成状态 (mini-charts图表组件包完成)
  - 史诗011成功模式参考 (用人方小程序)
- ✅ 提供了参考文档相关性的上下文:
  - 每个引用都说明了来源和用途
  - 原型设计包含完整的6个页面详细描述
- ✅ 引用格式一致: 使用统一的Markdown链接格式

#### 4. 自包含性评估 ✅ PASS
- ✅ 核心信息包含在故事中:
  - 完整的UI包结构规范
  - 详细的package.json配置示例
  - 完整的RPC客户端实现代码
  - 原型设计的详细描述 (包含行号引用)
  - 史诗015 API集成要点总结
- ✅ 隐含假设已明确:
  - 史诗015的API可能尚未全部完成,需要并行开发
  - 考勤记录API为P2延期功能,当前为前端模拟实现
- ✅ 领域特定术语已解释:
  - RPC客户端模式
  - API客户端管理器
  - 页面组件导出路径
  - 类型推断最佳实践
- ✅ 边界情况或错误场景已处理:
  - 风险和缓解措施章节
  - 史诗015 API延期情况的处理策略

#### 5. 测试指导 ✅ PASS
- ✅ 测试方法已概述:
  - 单元测试 (Jest)
  - 集成测试
  - 类型检查 (pnpm typecheck)
- ✅ 关键测试场景已识别:
  - UI包结构正确性验证
  - API客户端导入导出测试
  - 页面组件导入路径测试
  - 现有功能回归测试
- ✅ 成功标准已定义:
  - 7个UI包基础结构创建完成
  - package.json exports配置正确
  - API客户端集成完成
  - 路由结构配置完成
  - 基础布局组件可用
  - 认证框架就绪
  - 现有功能不受影响
  - 类型检查通过
- ✅ 特殊测试考虑已注明:
  - mini项目使用Jest而非Vitest
  - Mock响应工具函数示例
  - 测试文件位置规范

### 最终评估

**故事准备状态**: ✅ **READY**

**清晰度评分**: **9/10**

**主要优点**:
1. **上下文完整**: 提供了史诗015完成状态、原型设计、技术规范的完整上下文
2. **技术指导详细**: 包含完整的代码示例 (package.json配置、RPC客户端实现、类型推断示例)
3. **参考文档精确**: 所有引用都指向具体的文档章节,并提供了详细的行号引用
4. **风险缓解充分**: 明确识别了API集成风险,并提供了分阶段集成策略
5. **测试指导清晰**: 明确了测试框架选择 (Jest),并提供了具体的测试场景

**建议改进**:
1. 考虑在任务2中明确说明每个UI包具体需要创建的文件清单 (当前已足够详细,非必需)
2. 可以在任务4中添加史诗015 API路由的具体导入路径示例 (当前已有足够指导,非必需)

**开发者视角**:
- ✅ 可以根据当前故事文档实施
- ✅ 所有关键技术决策已明确 (测试框架选择、API客户端模式、类型推断方法)
- ✅ 参考实现已提供 (yongren-dashboard-ui)
- ✅ 原型设计详细描述提供了完整的UI指导
- ✅ 可能的疑问: 史诗015的具体API路由导入路径 (可通过查看史诗015文档解决,非阻塞)

**结论**: 故事提供了充分的实施上下文,开发者可以基于此文档成功实施UI包基础框架搭建工作。

## QA结果

*此部分由QA代理在审查完成后填写*
