| 版本 | 日期 | 描述 | 作者 |
|---|---|---|---|
| 3.1 | 2025-10-15 | 更新乘客信息支持多种证件类型 | Winston |
| 3.0 | 2025-10-15 | 更新为出行服务项目架构 | Winston |
| 2.4 | 2025-09-20 | 完善BMAD全栈架构规范,添加高层架构图、API规范、安全架构 | Winston |
| 2.3 | 2025-09-20 | 根据实际项目结构更新测试架构和共享目录 | Winston |
| 2.2 | 2025-09-19 | 更新测试策略文档引用 | Winston |
| 2.1 | 2025-09-19 | 添加数据库定时备份策略 | Winston |
| 2.0 | 2025-09-14 | 增强架构文档 | Winston |
本文档定义了出行服务项目的整体架构方案,基于对mini-demo页面迁移项目的深度分析。主要目标是将演示原型转化为功能完整的出行服务平台,同时保持技术架构的现代化和可扩展性。
注意: 本项目的详细架构文档已拆分为多个子文档,位于 docs/architecture/ 目录中。如需查看完整的架构文档结构,请参阅 架构文档索引。
基于mini项目迁移需求,新增以下规范文档:
全面定义出行服务项目的架构方案、技术栈选择、数据模型设计和集成策略
| 日期 | 版本 | 描述 | 作者 |
|---|---|---|---|
| 2025-10-15 | 3.1 | 更新乘客信息支持多种证件类型(身份证、港澳通行证、台湾通行证、护照等) | Winston |
| 2025-10-15 | 3.0 | 更新为出行服务项目架构 | Winston |
| 2025-09-20 | 2.4 | 完善BMAD全栈架构规范,添加高层架构图、API规范、安全架构 | Winston |
| 2025-09-20 | 2.3 | 根据实际项目结构更新测试架构和共享目录 | Winston |
| 2025-09-19 | 2.2 | 更新测试策略文档引用 | Winston |
| 2025-09-19 | 2.1 | 添加数据库定时备份策略 | Winston |
| 2025-09-14 | 2.0 | 增强架构文档 | Winston |
| 2024-09-14 | 1.0 | 初始现有系统分析 | Winston |
✅ 技术文档完整:
✅ 已补充:
any类型需要修复平台: 多八多云端开发容器环境 核心服务: PostgreSQL 17, Redis 7, MinIO对象存储 部署主机: Node.js 20.19.2运行时,开放8080端口外网访问 区域: 本地开发环境,生产环境参数相同 目标平台: 微信小程序为主要发布平台
graph TD
subgraph "前端应用层"
A[Taro + React 小程序] --> B[微信小程序API]
A --> C[React Query 状态管理]
A --> D[shadcn/ui 组件库]
E[React 管理后台] --> F[React Router v7]
end
subgraph "API网关层"
G[Hono 4.8.5 API路由] --> H[Zod Schema验证]
G --> I[JWT认证中间件]
G --> J[OpenAPI文档生成]
end
subgraph "业务服务层"
K[出行服务模块] --> L[活动管理服务]
K --> M[路线管理服务]
K --> N[订单管理服务]
K --> O[乘客管理服务]
K --> P[支付集成服务]
Q[通用CRUD服务] --> R[TypeORM实体管理]
Q --> S[数据库备份工具]
end
subgraph "数据存储层"
T[PostgreSQL 17] --> U[用户数据]
T --> V[活动数据]
T --> W[路线数据]
T --> X[订单数据]
T --> Y[乘客数据]
Z[Redis 7 缓存] --> AA[会话缓存]
AB[MinIO 对象存储] --> AC[文件存储]
end
subgraph "第三方服务"
AD[微信支付] --> AE[支付处理]
AF[地图服务] --> AG[位置服务]
end
subgraph "基础设施层"
AH[多八多云端容器] --> AI[Node.js 20.19.2]
AJ[开放8080端口] --> AK[外网访问]
end
A --> G
E --> G
G --> K
G --> Q
K --> T
Q --> T
G --> Z
G --> AB
K --> AD
K --> AF
J --> AL[Swagger UI /ui]
style A fill:#e1f5fe
style E fill:#f3e5f5
style G fill:#fff3e0
style K fill:#e8f5e8
style O fill:#fff0f5
style R fill:#e8f5e8
style W fill:#ffebee
style Y fill:#f3e5f5
style AA fill:#fff3e0
style AC fill:#e1f5fe
| 类别 | 当前技术 | 版本 | 在项目中的用途 | 备注 |
|---|---|---|---|---|
| 运行时 | Node.js | 20.19.2 | 服务器运行时环境 | ES模块支持 |
| 框架 | Hono | 4.8.5 | Web框架和API路由 | RPC类型安全 |
| 前端框架 | Taro + React | 最新 | 小程序用户界面构建 | 多端支持 |
| 构建工具 | Vite | 7.0.0 | 开发服务器和构建 | 热重载支持 |
| 数据库 | PostgreSQL | 17 | 数据持久化存储 | 通过TypeORM |
| ORM | TypeORM | 0.3.25 | 数据库操作抽象 | 实体管理 |
| 样式 | Tailwind CSS | 4.1.11 | 原子化CSS框架 | 设计一致性 |
| 状态管理 | React Query | 5.83.0 | 服务端状态管理 | 数据同步 |
| 认证 | JWT | 9.0.2 | 用户认证和安全 | Bearer Token |
| 技术 | 版本 | 用途 | Rationale | 集成方法 |
|---|---|---|---|---|
| Vitest | 2.x | 单元测试框架 | 填补测试空白,确保代码质量,更好的TypeORM支持 | 集成到现有构建流程 |
| Testing Library | 13.x | React组件测试 | 提供组件级测试能力 | 与React项目集成 |
| hono/testing | 内置 | API端点测试 | 验证API功能和集成 | Hono官方测试工具,更好的类型安全 |
| node-cron | latest | 定时任务调度 | Node.js定时任务调度库 | 集成到应用启动流程 |
| MinIO | latest | 对象存储服务 | 提供可扩展的文件存储解决方案,支持大文件上传和分段上传 | 通过MinIO客户端SDK集成 |
| MinIO客户端SDK | latest | MinIO API集成 | 提供与MinIO服务的完整交互能力 | 后端服务集成 |
| Taro | 最新 | 多端小程序框架 | 支持微信小程序发布,更好的开发体验 | 替换mini-demo原生开发 | | 微信支付SDK | 最新 | 支付集成 | 支持出行服务支付需求 | 后端API集成 | | 地图服务SDK | 最新 | 位置服务 | 支持路线规划和位置跟踪 | 前后端集成 | | 活动-路线管理 | 自定义 | 活动路线关系 | 支持1个活动关联多条路线 | 业务逻辑层实现 | | 多乘客管理 | 自定义 | 乘客信息管理 | 支持下单时选择N个乘车人 | 业务逻辑层实现 |
用户模型:
id: number - 主键标识符username: string - 唯一用户名(主要登录标识)email: string | null - 可选邮箱地址password: string - 加密密码(bcrypt哈希)roles: Role[] - 用户角色多对多关系文件管理模型:
id: number - 主键标识符name: string - 文件名path: string - MinIO存储路径size: number - 文件大小(字节)type: string - 文件类型uploadUserId: number - 上传用户IDuploadTime: Date - 上传时间活动模型:
id: number - 主键标识符name: string - 活动名称type: ActivityType - 活动类型(去程活动/返程活动)startDate: Date - 活动开始日期endDate: Date - 活动结束日期status: ActivityStatus - 活动状态路线模型:
id: number - 主键标识符activityId: number - 关联的活动IDstartPoint: string - 上车点endPoint: string - 下车点departureTime: Date - 出发时间vehicleType: string - 车型maxPassengers: number - 最大乘客数price: number - 价格driverPlate: string - 司机车牌driverPhone: string - 司机电话订单模型:
id: number - 主键标识符userId: number - 用户IDrouteId: number - 路线IDactivityId: number - 活动IDpassengerCount: number - 乘客数量totalAmount: number - 订单总金额status: string - 订单状态(待出发、行程中、已完成、已取消)paymentStatus: string - 支付状态passengerSnapshots: JSON - 乘客信息快照数组(下单时的多个乘客信息)routeSnapshot: JSON - 路线信息快照(下单时的路线信息)createdAt: Date - 创建时间乘客模型:
id: number - 主键标识符userId: number - 用户IDname: string - 乘客姓名idType: IdType - 证件类型(身份证、回乡证、护照等)idNumber: string - 证件号码phone: string - 手机号isDefault: boolean - 是否默认乘客积分模型:
id: number - 主键标识符userId: number - 用户IDpoints: number - 积分余额earnedPoints: number - 累计获得积分usedPoints: number - 累计使用积分// 用户实体接口
export interface User {
id: number;
username: string;
email: string | null;
password: string;
roles: Role[];
createdAt: Date;
updatedAt: Date;
}
// 角色实体接口
export interface Role {
id: number;
name: string;
permissions: string[];
users: User[];
createdAt: Date;
updatedAt: Date;
}
// 活动实体接口
export interface Activity {
id: number;
name: string;
type: ActivityType;
startDate: Date;
endDate: Date;
status: ActivityStatus;
routes: Route[];
createdAt: Date;
updatedAt: Date;
}
// 路线实体接口
export interface Route {
id: number;
activityId: number;
activity: Activity;
startPoint: string;
endPoint: string;
departureTime: Date;
vehicleType: VehicleType;
maxPassengers: number;
price: number;
driverPlate: string;
driverPhone: string;
availableSeats: number;
orders: Order[];
createdAt: Date;
updatedAt: Date;
}
// 订单实体接口
export interface Order {
id: number;
userId: number;
user: User;
routeId: number;
route: Route;
activityId: number;
activity: Activity;
passengerCount: number;
totalAmount: number;
status: OrderStatus;
paymentStatus: PaymentStatus;
passengerSnapshots: PassengerSnapshot[];
routeSnapshot: RouteSnapshot;
passengers: Passenger[];
createdAt: Date;
updatedAt: Date;
}
// 乘客实体接口
export interface Passenger {
id: number;
userId: number;
user: User;
name: string;
idType: IdType; // 证件类型
idNumber: string; // 证件号码
phone: string;
isDefault: boolean;
orders: Order[];
createdAt: Date;
updatedAt: Date;
}
// 乘客信息快照接口
export interface PassengerSnapshot {
name: string;
idType: IdType; // 证件类型
idNumber: string; // 证件号码
phone: string;
isDefault: boolean;
}
// 路线信息快照接口
export interface RouteSnapshot {
startPoint: string;
endPoint: string;
departureTime: Date;
vehicleType: VehicleType;
maxPassengers: number;
price: number;
driverPlate: string;
driverPhone: string;
}
// 积分实体接口
export interface Points {
id: number;
userId: number;
user: User;
points: number;
earnedPoints: number;
usedPoints: number;
lastUpdated: Date;
}
// 枚举定义
export enum OrderStatus {
WAITING_DEPARTURE = '待出发',
IN_PROGRESS = '行程中',
COMPLETED = '已完成',
CANCELLED = '已取消'
}
export enum PaymentStatus {
PENDING = '待支付',
PAID = '已支付',
FAILED = '支付失败',
REFUNDED = '已退款'
}
export enum VehicleType {
CARPOOL = '拼车',
BUSINESS = '商务车',
CHARTER = '包车'
}
export enum ActivityType {
OUTBOUND = '去程活动',
INBOUND = '返程活动'
}
export enum ActivityStatus {
ACTIVE = '进行中',
ENDED = '已结束',
CANCELLED = '已取消'
}
export enum IdType {
ID_CARD = '身份证',
HONG_KONG_MACAO_PASS = '港澳通行证',
TAIWAN_PASS = '台湾通行证',
PASSPORT = '护照',
OTHER = '其他证件'
}
// 分页响应接口
export interface PaginatedResponse<T> {
data: T[];
pagination: {
total: number;
current: number;
pageSize: number;
totalPages: number;
};
}
快照设计说明:
实际项目组件组织:
src/client/
├── admin/ # 管理后台应用
│ ├── components/ # 管理后台专用组件
│ │ ├── ProtectedRoute.tsx # 路由保护组件
│ │ ├── ErrorPage.tsx # 错误页面
│ │ └── NotFoundPage.tsx # 404页面
│ ├── hooks/ # 管理后台Hooks
│ │ └── AuthProvider.tsx # 认证状态管理
│ ├── layouts/ # 布局组件
│ │ └── MainLayout.tsx # 主布局
│ ├── pages/ # 页面组件
│ │ ├── Dashboard.tsx # 仪表板
│ │ ├── Login.tsx # 登录页面
│ │ ├── Users.tsx # 用户管理
│ │ └── Files.tsx # 文件管理页面
│ ├── routes.tsx # 路由配置
│ └── index.tsx # 管理后台入口
├── home/ # 用户前台应用
├── components/ # 共享UI组件
│ └── ui/ # shadcn/ui组件库(50+组件)
│ ├── button.tsx # 按钮组件
│ ├── input.tsx # 输入框组件
│ ├── table.tsx # 表格组件
│ └── ... # 其他组件
├── hooks/ # 共享Hooks
├── lib/ # 工具库
├── utils/ # 工具函数
│ └── minio.ts # MinIO上传工具
└── api.ts # API客户端配置
技术栈配置:
实际后端项目结构:
src/server/
├── api/ # API路由层
│ ├── auth/ # 认证相关路由
│ │ ├── login.ts # 登录路由
│ │ ├── logout.ts # 登出路由
│ │ └── register.ts # 注册路由
│ ├── users/ # 用户管理路由
│ │ ├── index.ts # 用户列表路由
│ │ ├── [id].ts # 用户详情路由
│ │ └── __tests__/ # 路由测试
│ ├── roles/ # 角色管理路由
│ ├── files/ # 文件管理路由
│ │ ├── multipart-policy/ # 多部分上传策略
│ │ ├── multipart-complete/ # 完成多部分上传
│ │ ├── [id]/ # 文件操作路由
│ │ └── upload-policy/ # 上传策略路由
│ └── __integration_tests__/ # 集成测试
├── modules/ # 业务模块层
│ ├── auth/ # 认证业务模块
│ │ ├── auth.service.ts # 认证服务
│ │ └── __tests__/ # 认证测试
│ ├── users/ # 用户业务模块
│ │ ├── user.entity.ts # 用户实体
│ │ ├── user.service.ts # 用户服务
│ │ └── __tests__/ # 用户测试
│ ├── files/ # 文件业务模块
│ │ ├── file.entity.ts # 文件实体
│ │ ├── file.service.ts # 文件服务
│ │ ├── minio.service.ts # MinIO服务
│ │ ├── file.schema.ts # 文件验证Schema
│ │ └── __tests__/ # 文件测试
├── utils/ # 工具层
│ ├── generic-crud.service.ts # 通用CRUD服务
│ ├── generic-crud.routes.ts # 通用CRUD路由
│ ├── errorHandler.ts # 错误处理
│ ├── backup.ts # 数据库备份工具
│ ├── restore.ts # 数据库恢复工具
│ ├── logger.ts # 日志工具
│ └── __tests__/ # 工具测试
├── middleware/ # 中间件层
│ ├── auth.middleware.ts # 认证中间件
│ └── permission.middleware.ts # 权限中间件
├── types/ # 类型定义
├── data-source.ts # 数据库连接配置
└── index.ts # 服务器入口
后端技术栈配置:
src/server/utils/generic-crud.service.tssrc/server/utils/generic-crud.routes.ts文件管理服务:
/ui 端点graph TD
A[前端React组件] --> B[Hono API路由]
B --> C[通用CRUD服务]
C --> D[TypeORM实体]
C --> E[Zod验证]
B --> F[OpenAPI文档生成]
F --> G[Swagger UI]
B --> H[文件管理服务]
H --> I[MinIO对象存储]
H --> J[文件实体管理]
subgraph "文件上传流程"
K[前端上传组件] --> L[获取上传策略]
L --> M[直接上传到MinIO]
M --> N[更新文件记录]
end
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#fff3e0
style D fill:#e8f5e8
style H fill:#fff0f5
style I fill:#f0fff0
/api/v1/),保持向后兼容openapi: 3.0.0
info:
title: D8D Starter API
version: 1.0.0
description: D8D Starter项目RESTful API文档
servers:
- url: http://localhost:3000/api/v1
description: 本地开发环境
- url: https://api.example.com/api/v1
description: 生产环境
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
username:
type: string
email:
type: string
nullable: true
roles:
type: array
items:
$ref: '#/components/schemas/Role'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
Role:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
permissions:
type: array
items:
type: string
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
PaginatedUsers:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
Pagination:
type: object
properties:
total:
type: integer
current:
type: integer
pageSize:
type: integer
totalPages:
type: integer
security:
- BearerAuth: []
用户管理端点:
/api/v1/users文件管理端点:
/api/v1/files/upload-policy请求示例:
{
"page": 1,
"pageSize": 10,
"keyword": "搜索词",
"sortBy": "createdAt",
"sortOrder": "DESC"
}
响应示例:
{
"data": [
{
"id": 1,
"email": "user@example.com",
"roles": [{"id": 1, "name": "admin"}]
}
],
"pagination": {
"total": 100,
"current": 1,
"pageSize": 10
}
}
d8d-starter/
├── src/
│ ├── client/ # React前端应用
│ │ ├── admin/ # 管理后台应用
│ │ │ ├── components/ # 管理后台组件
│ │ │ ├── hooks/ # 管理后台Hooks
│ │ │ ├── layouts/ # 布局组件
│ │ │ ├── pages/ # 页面组件
│ │ │ ├── routes.tsx # 路由配置
│ │ │ └── index.tsx # 入口文件
│ │ ├── home/ # 用户前台应用(待开发)
│ │ ├── components/ # 共享UI组件
│ │ │ └── ui/ # shadcn/ui组件库
│ │ ├── hooks/ # 共享Hooks
│ │ ├── lib/ # 工具库
│ │ ├── utils/ # 工具函数
│ │ ├── api.ts # API客户端
│ │ └── index.tsx # 前端入口
│ ├── server/ # Hono后端应用
│ │ ├── api/ # API路由
│ │ ├── modules/ # 业务模块
│ │ ├── middleware/ # 中间件
│ │ └── index.ts # 服务器入口
│ └── share/ # 前后端共享代码
│ └── types.ts # TypeScript类型定义
├── tests/
│ └── e2e/ # E2E测试 (Playwright)
└── package.json
实际开发命令:
# 安装依赖
pnpm install
# 启动完整开发环境(前后端同时运行)
pnpm dev
# 运行测试
pnpm test # 运行API测试 (Vitest)
pnpm test:api # 运行API测试
pnpm test:components # 运行组件测试
pnpm test:integration # 运行集成测试 (同test:components)
pnpm test:e2e # 运行E2E测试
pnpm test:e2e:chromium # 运行Chrome E2E测试
pnpm test:e2e:ui # 运行E2E测试UI模式
pnpm test:e2e:debug # 运行E2E调试模式
# 代码质量检查
pnpm lint # ESLint检查
pnpm typecheck # TypeScript类型检查
pnpm test:coverage # 生成测试覆盖率报告
# 数据库相关
pnpm db:backup # 数据库备份
pnpm db:restore # 数据库恢复
pnpm db:backup:list # 列出备份文件
pnpm db:backup:latest # 获取最新备份
pnpm db:backup:cleanup # 清理旧备份
pnpm db:migrate # 数据库迁移
pnpm db:seed # 数据库种子数据
pnpm db:reset # 重置数据库
环境配置:
# 前端环境变量 (Vite)
VITE_API_BASE_URL=http://localhost:3000/api
# 后端环境变量
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
JWT_SECRET=your-jwt-secret-key
NODE_ENV=development
tests/ 目录中,按类型分层组织mini/tests/ 目录详细的测试策略、标准、执行流程和最佳实践请参考 测试策略文档。
实际测试结构:
tests/
├── e2e/ # E2E测试 (Playwright)
│ ├── fixtures/ # 测试夹具数据
│ │ ├── test-users.json # 测试用户数据
│ │ ├── roles.json # 角色数据
│ │ └── test-data.ts # TypeScript测试数据
│ ├── pages/ # 页面对象模型
│ │ └── admin/ # 管理后台页面对象
│ │ ├── login.page.ts # 登录页面对象
│ │ ├── dashboard.page.ts # 仪表板页面对象
│ │ └── user-management.page.ts # 用户管理页面对象
│ ├── specs/ # 测试规范
│ │ └── admin/ # 管理后台E2E测试
│ │ ├── dashboard.spec.ts # 仪表板测试
│ │ ├── login.spec.ts # 登录测试
│ │ ├── settings.spec.ts # 设置测试
│ │ └── users.spec.ts # 用户管理测试
│ ├── utils/ # 测试工具
│ │ └── test-setup.ts # 测试设置工具
│ ├── global-setup.ts # 全局设置
│ ├── global-teardown.ts # 全局清理
│ └── playwright.config.ts # Playwright配置
├── integration/ # 集成测试
│ ├── client/ # 前端集成测试
│ │ └── admin/ # 管理后台集成测试
│ │ ├── dashboard.test.tsx # 仪表板集成测试
│ │ ├── login.test.tsx # 登录集成测试
│ │ └── users.test.tsx # 用户管理集成测试
│ └── server/ # 后端集成测试
│ ├── auth.integration.test.ts # 认证集成测试
│ ├── backup.integration.test.ts # 备份集成测试
│ ├── files/ # 文件服务集成测试
│ │ ├── files.integration.test.ts
│ │ └── minio.integration.test.ts
│ └── users.integration.test.ts # 用户集成测试
├── unit/ # 单元测试
│ ├── basic.test.ts # 基础单元测试
│ ├── client/ # 前端单元测试
│ │ └── pages/ # 页面单元测试
│ │ ├── Users.test.tsx # 用户页面单元测试
│ │ └── debug.test.tsx # 调试页面单元测试
│ └── server/ # 后端单元测试
│ ├── modules/ # 业务模块单元测试
│ │ └── files/ # 文件服务单元测试
│ │ ├── file.service.test.ts
│ │ └── minio.service.test.ts
│ ├── modules/user.service.test.ts # 用户服务单元测试
│ └── utils/ # 工具单元测试
│ ├── backup.test.ts # 备份工具测试
│ └── restore.test.ts # 恢复工具测试
└── utils/ # 测试工具
├── client/ # 前端测试工具
│ ├── test-query.tsx # 测试查询工具
│ ├── test-render.tsx # 测试渲染工具
│ └── test-router.tsx # 测试路由工具
├── server/ # 后端测试工具
│ ├── integration-test-db.ts # 集成测试数据库
│ ├── integration-test-utils.ts # 集成测试工具
│ ├── service-mocks.ts # 服务模拟
│ ├── service-stubs.ts # 服务桩
│ ├── test-auth.ts # 测试认证
│ └── test-db.ts # 测试数据库
└── setup.ts # 通用测试设置
测试框架配置:
tests/ 目录中,按类型分层组织前端安全:
default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'后端安全:
认证授权:
数据安全:
基础设施安全:
✅ 技术栈验证: Node.js + Hono + React + TypeORM 验证通过 ✅ 架构模式: 分层架构、模块化设计验证通过 ✅ 代码质量: 类型安全、错误处理需要增强 ✅ 安全性: 基础安全措施存在,需要加强 ✅ 测试覆盖: 完整的测试基础设施已建立(Vitest + Testing Library + Playwright) ✅ 部署策略: Docker部署成熟稳定 ✅ 备份策略: 数据库定时备份方案已设计
基于此架构文档,开始实现以下故事:
开始实现时注意:
前端监控:
后端监控:
interface ApiError {
error: {
code: string; // 错误代码,如: 'VALIDATION_ERROR'
message: string; // 用户友好的错误信息
details?: Record<string, any>; // 详细错误信息
timestamp: string; // ISO时间戳
requestId: string; // 请求追踪ID
};
}
docs/architecture.md (本文件)docs/architecture/ (包含组件架构、API设计、技术栈等子文档)docs/prd.mddocs/architecture/testing-strategy.md/ui 端点访问文档状态: 正式版 下次评审: 2025-10-14