|
|
@@ -0,0 +1,520 @@
|
|
|
+# Epic-005: Mini-Auth 通用模块 Package 化集成 - Brownfield Enhancement
|
|
|
+
|
|
|
+## Epic Goal
|
|
|
+
|
|
|
+将 mini-auth-demo 项目中开发的高度通用模块(地区、地点、小程序认证、支付、乘客管理)以独立 package 方式组织到 `/packages` 目录下,为未来继承该 starter 的项目提供按需使用的可复用基础模块,同时保持模块的独立性和向后兼容性。
|
|
|
+
|
|
|
+## Epic Description
|
|
|
+
|
|
|
+### Existing System Context
|
|
|
+
|
|
|
+**Current relevant functionality:**
|
|
|
+- 主项目目前包含基础的认证、用户管理、文件管理模块
|
|
|
+- 使用 TypeORM + PostgreSQL 作为数据访问层
|
|
|
+- 采用 Hono 框架构建 RESTful API
|
|
|
+- 前端使用 React/Taro 框架
|
|
|
+- 已有基础的 JWT 认证和用户角色管理
|
|
|
+
|
|
|
+**Technology stack:**
|
|
|
+- Backend: Node.js, TypeScript, Hono, TypeORM, PostgreSQL
|
|
|
+- Frontend: React, Taro, TanStack Query
|
|
|
+- Authentication: JWT, Redis session management
|
|
|
+- Payment: WeChat Pay v3 SDK
|
|
|
+- Database: PostgreSQL with tree structure support
|
|
|
+
|
|
|
+**Integration points:**
|
|
|
+- 现有认证系统需要扩展支持小程序登录
|
|
|
+- 数据库需要新增地区、地点、乘客等实体表
|
|
|
+- 现有用户实体需要扩展小程序相关字段
|
|
|
+- 支付模块需要与现有订单系统集成
|
|
|
+
|
|
|
+### Enhancement Details
|
|
|
+
|
|
|
+**What's being added/changed:**
|
|
|
+- 地区模块:完整的省市区三级联动数据管理和API
|
|
|
+- 地点模块:基于地理位置的POI管理和搜索功能
|
|
|
+- 小程序认证:微信小程序登录和手机号解密功能
|
|
|
+- 支付模块:微信小程序支付集成和回调处理
|
|
|
+- 乘客模块:多乘客管理和默认乘客设置
|
|
|
+
|
|
|
+**Package 架构设计:**
|
|
|
+```
|
|
|
+packages/
|
|
|
+├── server/ # 核心服务器 (现有,重构后)
|
|
|
+├── crud-core/ # CRUD核心基础设施 (新增)
|
|
|
+├── database-core/ # 数据库核心 (新增)
|
|
|
+├── auth-core/ # 认证核心 (新增)
|
|
|
+├── utils-core/ # 工具核心 (新增)
|
|
|
+├── shared-types/ # 共享类型定义 (新增)
|
|
|
+├── mini-auth/ # 小程序认证增强 (新增)
|
|
|
+├── mini-payment/ # 小程序支付 (新增)
|
|
|
+├── geo-areas/ # 地区模块 (新增)
|
|
|
+├── geo-locations/ # 地点模块 (新增)
|
|
|
+└── passenger-management/ # 乘客管理 (新增)
|
|
|
+```
|
|
|
+
|
|
|
+**How it integrates:**
|
|
|
+- 每个模块作为独立 package,支持按需安装
|
|
|
+- 遵循现有项目架构模式,使用相同的 TypeORM 实体和服务结构
|
|
|
+- 复用现有的认证中间件和权限控制
|
|
|
+- 保持 API 设计风格一致,使用 Hono 路由
|
|
|
+- 集成到现有的数据库连接和事务管理
|
|
|
+- 通过 pnpm workspace 管理依赖关系
|
|
|
+
|
|
|
+**Success criteria:**
|
|
|
+- 所有通用模块作为独立 package 可用
|
|
|
+- 现有功能不受影响,保持向后兼容
|
|
|
+- 支持按需安装,项目可选择性引入所需模块
|
|
|
+- 提供完整的 API 文档和类型定义
|
|
|
+- 所有模块通过单元测试和集成测试
|
|
|
+- package 间依赖关系清晰,版本管理独立
|
|
|
+
|
|
|
+## Stories
|
|
|
+
|
|
|
+### 阶段 0: 基础设施重构
|
|
|
+1. **Story 0.1:** 基础设施核心包 - 创建 shared-types、database-core、auth-core、utils-core package
|
|
|
+2. **Story 0.2:** CRUD基础设施包 - 创建 crud-core package,重构server依赖关系
|
|
|
+
|
|
|
+### 阶段 1: 业务模块 Package 化
|
|
|
+3. **Story 1:** 地区模块 package - 实现省市区三级联动数据管理和API
|
|
|
+4. **Story 2:** 地理位置和乘客模块 package - 实现地点模块和乘客管理模块
|
|
|
+5. **Story 3:** 小程序生态模块 package - 实现小程序认证和支付模块
|
|
|
+
|
|
|
+## Compatibility Requirements
|
|
|
+
|
|
|
+- [x] 现有 APIs 保持不变,新增模块使用独立命名空间
|
|
|
+- [x] 数据库 schema 变更向后兼容,新增表不影响现有功能
|
|
|
+- [x] UI 组件遵循现有设计模式,提供可复用的 React/Taro 组件
|
|
|
+- [x] 性能影响最小化,关键操作使用缓存和索引优化
|
|
|
+- [x] Package 依赖关系清晰,避免循环依赖
|
|
|
+- [x] 支持按需安装,项目可选择性引入所需模块
|
|
|
+
|
|
|
+## Risk Mitigation
|
|
|
+
|
|
|
+**Primary Risk:** 数据库 schema 变更可能影响现有数据
|
|
|
+**Mitigation:** 使用 TypeORM migrations 管理数据库变更,确保数据迁移安全
|
|
|
+**Rollback Plan:** 保留数据库备份,提供回滚脚本,模块化设计便于独立禁用
|
|
|
+
|
|
|
+**Primary Risk:** 小程序认证与现有认证系统冲突
|
|
|
+**Mitigation:** 扩展现有认证服务,提供多种认证方式共存
|
|
|
+**Rollback Plan:** 保持原有认证方式不变,小程序认证作为可选功能
|
|
|
+
|
|
|
+**Primary Risk:** Package 依赖关系复杂化
|
|
|
+**Mitigation:** 设计清晰的依赖层次,基础设施package作为基础依赖
|
|
|
+**Rollback Plan:** 保持核心 server package 独立,其他 package 可选择性移除
|
|
|
+
|
|
|
+**Primary Risk:** 基础设施重构影响现有功能
|
|
|
+**Mitigation:** 分阶段重构,每个阶段完成后进行回归测试
|
|
|
+**Rollback Plan:** 保留重构前的代码备份,提供快速回滚方案
|
|
|
+
|
|
|
+## Definition of Done
|
|
|
+
|
|
|
+- [ ] 所有 stories 完成且验收标准满足
|
|
|
+- [ ] 现有功能通过回归测试验证
|
|
|
+- [ ] 集成点正常工作,API 调用无冲突
|
|
|
+- [ ] 模块文档和类型定义完整
|
|
|
+- [ ] 现有功能无回归问题
|
|
|
+- [ ] 所有 package 独立构建和测试通过
|
|
|
+- [ ] Package 依赖关系清晰,无循环依赖
|
|
|
+
|
|
|
+## 架构设计详情
|
|
|
+
|
|
|
+### Package 结构设计
|
|
|
+
|
|
|
+```
|
|
|
+packages/
|
|
|
+├── server/ # 核心服务器 (现有,重构后)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── crud-core/ # CRUD核心基础设施 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── database-core/ # 数据库核心 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── auth-core/ # 认证核心 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── utils-core/ # 工具核心 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── shared-types/ # 共享类型定义 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── mini-auth/ # 小程序认证增强 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── mini-payment/ # 小程序支付 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── geo-areas/ # 地区模块 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+├── geo-locations/ # 地点模块 (新增)
|
|
|
+│ ├── src/
|
|
|
+│ ├── package.json
|
|
|
+│ └── tsconfig.json
|
|
|
+└── passenger-management/ # 乘客管理 (新增)
|
|
|
+ ├── src/
|
|
|
+ ├── package.json
|
|
|
+ └── tsconfig.json
|
|
|
+```
|
|
|
+
|
|
|
+### 依赖关系设计
|
|
|
+
|
|
|
+#### 依赖层次
|
|
|
+```
|
|
|
+shared-types (基础类型)
|
|
|
+ ↑
|
|
|
+database-core (数据库基础设施)
|
|
|
+ ↑
|
|
|
+auth-core (认证基础设施) + utils-core (工具基础设施)
|
|
|
+ ↑
|
|
|
+crud-core (CRUD基础设施)
|
|
|
+ ↑
|
|
|
+业务模块 (geo-areas, mini-auth等)
|
|
|
+ ↑
|
|
|
+server (应用入口)
|
|
|
+```
|
|
|
+
|
|
|
+#### 基础设施 Package 依赖关系
|
|
|
+
|
|
|
+**crud-core package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/crud-core",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/database-core": "workspace:*",
|
|
|
+ "typeorm": "^0.3.20",
|
|
|
+ "@hono/zod-openapi": "1.0.2",
|
|
|
+ "zod": "^4.1.12"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**database-core package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/database-core",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "typeorm": "^0.3.20",
|
|
|
+ "pg": "^8.16.3"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**auth-core package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/auth-core",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "jsonwebtoken": "^9.0.2",
|
|
|
+ "bcrypt": "^6.0.0"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**utils-core package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/utils-core",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**shared-types package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/shared-types",
|
|
|
+ "dependencies": {
|
|
|
+ "zod": "^4.1.12"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 业务模块 Package 依赖关系
|
|
|
+
|
|
|
+**geo-areas package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/geo-areas",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/crud-core": "workspace:*",
|
|
|
+ "typeorm": "^0.3.20"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**geo-locations package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/geo-locations",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/crud-core": "workspace:*",
|
|
|
+ "@d8d/geo-areas": "workspace:*",
|
|
|
+ "typeorm": "^0.3.20"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**passenger-management package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/passenger-management",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/crud-core": "workspace:*",
|
|
|
+ "typeorm": "^0.3.20"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**mini-auth package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/mini-auth",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/auth-core": "workspace:*",
|
|
|
+ "jsonwebtoken": "^9.0.2",
|
|
|
+ "axios": "^1.12.2"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**mini-payment package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/mini-payment",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "wechatpay-node-v3": "^1.0.0"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**重构后的 server package**
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "@d8d/server",
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/shared-types": "workspace:*",
|
|
|
+ "@d8d/crud-core": "workspace:*",
|
|
|
+ "@d8d/database-core": "workspace:*",
|
|
|
+ "@d8d/auth-core": "workspace:*",
|
|
|
+ "@d8d/utils-core": "workspace:*",
|
|
|
+ // 业务模块依赖
|
|
|
+ "@d8d/geo-areas": "workspace:*",
|
|
|
+ "@d8d/geo-locations": "workspace:*",
|
|
|
+ "@d8d/passenger-management": "workspace:*",
|
|
|
+ "@d8d/mini-auth": "workspace:*",
|
|
|
+ "@d8d/mini-payment": "workspace:*",
|
|
|
+ // 其他现有依赖保持不变
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Package 导出设计
|
|
|
+
|
|
|
+#### shared-types 导出
|
|
|
+```typescript
|
|
|
+// 基础类型
|
|
|
+export interface BaseEntity {
|
|
|
+ id: string;
|
|
|
+ createdAt: Date;
|
|
|
+ updatedAt: Date;
|
|
|
+}
|
|
|
+
|
|
|
+// 地区相关类型
|
|
|
+export interface Area {
|
|
|
+ id: string;
|
|
|
+ name: string;
|
|
|
+ code: string;
|
|
|
+ level: number;
|
|
|
+ parentId?: string;
|
|
|
+}
|
|
|
+
|
|
|
+// 地点相关类型
|
|
|
+export interface Location {
|
|
|
+ id: string;
|
|
|
+ name: string;
|
|
|
+ latitude: number;
|
|
|
+ longitude: number;
|
|
|
+ areaId: string;
|
|
|
+}
|
|
|
+
|
|
|
+// 小程序相关类型
|
|
|
+export interface MiniAuthUser {
|
|
|
+ openid: string;
|
|
|
+ unionid?: string;
|
|
|
+ sessionKey: string;
|
|
|
+}
|
|
|
+
|
|
|
+// Zod schemas
|
|
|
+export const areaSchema = z.object({
|
|
|
+ // ...
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+#### 模块 package 导出模式
|
|
|
+每个模块 package 遵循统一的导出模式:
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 实体
|
|
|
+export { AreaEntity } from './entities/area.entity';
|
|
|
+
|
|
|
+// 服务
|
|
|
+export { AreaService } from './services/area.service';
|
|
|
+
|
|
|
+// DTOs
|
|
|
+export { CreateAreaDto, UpdateAreaDto } from './dto/area.dto';
|
|
|
+
|
|
|
+// 控制器
|
|
|
+export { AreaController } from './controllers/area.controller';
|
|
|
+
|
|
|
+// 路由
|
|
|
+export { areaRoutes } from './routes/area.routes';
|
|
|
+
|
|
|
+// 类型
|
|
|
+export type { Area, AreaLevel } from './types/area.types';
|
|
|
+```
|
|
|
+
|
|
|
+### 使用示例
|
|
|
+
|
|
|
+#### 项目按需使用
|
|
|
+```json
|
|
|
+// package.json - 只需要地区功能
|
|
|
+{
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/server": "^1.0.0",
|
|
|
+ "@d8d/geo-areas": "^1.0.0"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// package.json - 需要完整地理位置功能
|
|
|
+{
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/server": "^1.0.0",
|
|
|
+ "@d8d/geo-areas": "^1.0.0",
|
|
|
+ "@d8d/geo-locations": "^1.0.0"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// package.json - 需要小程序生态功能
|
|
|
+{
|
|
|
+ "dependencies": {
|
|
|
+ "@d8d/server": "^1.0.0",
|
|
|
+ "@d8d/mini-auth": "^1.0.0",
|
|
|
+ "@d8d/mini-payment": "^1.0.0"
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 代码中使用
|
|
|
+```typescript
|
|
|
+// 只导入需要的模块
|
|
|
+import { AreaService } from '@d8d/geo-areas';
|
|
|
+import { LocationService } from '@d8d/geo-locations';
|
|
|
+import { MiniAuthService } from '@d8d/mini-auth';
|
|
|
+
|
|
|
+// 或者从 server 统一导入
|
|
|
+import {
|
|
|
+ AreaService,
|
|
|
+ LocationService,
|
|
|
+ MiniAuthService
|
|
|
+} from '@d8d/server';
|
|
|
+```
|
|
|
+
|
|
|
+## 模块详细说明
|
|
|
+
|
|
|
+### 地区模块 (Areas Module)
|
|
|
+- **功能**: 完整的中国行政区划管理
|
|
|
+- **核心实体**: AreaEntity (省市区三级树形结构)
|
|
|
+- **主要服务**: AreaService (树形查询、路径查询、层级查询)
|
|
|
+- **API**: /api/areas, /api/admin/areas
|
|
|
+- **前端组件**: AreaPicker (三级联动选择器)
|
|
|
+
|
|
|
+### 地点模块 (Locations Module)
|
|
|
+- **功能**: 地理位置POI管理和搜索
|
|
|
+- **核心实体**: LocationEntity (名称、坐标、类型)
|
|
|
+- **主要服务**: LocationService (搜索、筛选、距离计算)
|
|
|
+- **API**: /api/locations, /api/admin/locations
|
|
|
+
|
|
|
+### 小程序认证模块 (Mini Auth Module)
|
|
|
+- **功能**: 微信小程序登录和手机号解密
|
|
|
+- **核心服务**: MiniAuthService (code2session、用户创建、手机号解密)
|
|
|
+- **集成点**: 扩展现有 UserEntity (openid, unionid 字段)
|
|
|
+- **API**: /api/auth/mini-login, /api/auth/decrypt-phone
|
|
|
+
|
|
|
+### 支付模块 (Payment Module)
|
|
|
+- **功能**: 微信小程序支付集成
|
|
|
+- **核心服务**: PaymentService (创建支付、处理回调、查询状态)
|
|
|
+- **依赖**: wechatpay-node-v3 SDK
|
|
|
+- **API**: /api/payment/create, /api/payment/callback
|
|
|
+
|
|
|
+### 乘客模块 (Passengers Module)
|
|
|
+- **功能**: 多乘客管理和默认乘客设置
|
|
|
+- **核心实体**: PassengerEntity (姓名、证件、联系方式)
|
|
|
+- **主要服务**: PassengerService (CRUD、默认乘客管理)
|
|
|
+- **API**: /api/passengers, /api/admin/passengers
|
|
|
+
|
|
|
+## 技术实现要点
|
|
|
+
|
|
|
+### 基础设施重构
|
|
|
+1. **Package 架构**: 基础设施和业务模块分离,支持按需安装
|
|
|
+2. **依赖管理**: 清晰的依赖层次,避免循环依赖
|
|
|
+3. **类型共享**: shared-types 作为所有package的基础依赖
|
|
|
+
|
|
|
+### 业务模块实现
|
|
|
+4. **数据库设计**: 使用 TypeORM 实体和 migrations
|
|
|
+5. **服务层**: 基于 crud-core 的服务模式,依赖注入
|
|
|
+6. **API 层**: Hono 路由,统一错误处理
|
|
|
+7. **前端集成**: 提供 React/Taro 组件和类型定义
|
|
|
+8. **配置管理**: 环境变量控制模块启用状态
|
|
|
+9. **测试覆盖**: 每个 package 独立测试 + 集成测试
|
|
|
+
|
|
|
+## 向后兼容性保证
|
|
|
+
|
|
|
+### 基础设施重构
|
|
|
+- 现有API接口保持不变
|
|
|
+- 数据库schema保持不变
|
|
|
+- 认证流程保持不变
|
|
|
+- 重构分阶段进行,每个阶段验证兼容性
|
|
|
+
|
|
|
+### 业务模块集成
|
|
|
+- 现有用户表新增字段均为可选
|
|
|
+- 所有新增 API 使用独立命名空间
|
|
|
+- 数据库 migrations 确保数据安全
|
|
|
+- 提供模块禁用配置选项
|
|
|
+- 核心 server package 保持独立,其他 package 可选
|
|
|
+- Package 版本独立管理,避免强制升级
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Story Manager Handoff
|
|
|
+
|
|
|
+"请为这个brownfield epic开发详细的用户故事。关键考虑因素:
|
|
|
+
|
|
|
+- 这是一个对现有系统的增强,运行在 Node.js + TypeScript + Hono + TypeORM + PostgreSQL 技术栈上
|
|
|
+- 集成点:现有认证系统、用户实体、数据库连接、API路由结构
|
|
|
+- 需要遵循的现有模式:TypeORM实体结构、Hono路由设计、服务层依赖注入、统一错误处理
|
|
|
+- 关键兼容性要求:现有API保持不变、数据库变更向后兼容、认证流程不中断
|
|
|
+- 每个故事必须包含验证现有功能保持完整的测试
|
|
|
+
|
|
|
+该epic应该保持系统完整性,同时实现将mini-auth-demo项目中的通用模块(地区、地点、小程序认证、支付、乘客管理)标准化并集成到主项目的目标。"
|