005.001.story.md 42 KB

Story 5.1: 基础数据管理和实体结构

Status

✅ Completed

Story

As a 系统管理员 I want 能够配置活动、路线等基础数据 so that 用户能够查询和使用出行服务

Acceptance Criteria

  1. 支持创建和管理活动类型(去程活动、返程活动)
  2. 支持配置路线信息(出发地、目的地、上车点、下车点、出发时间、车型、价格、座位数)
  3. 支持设置活动关联的路线
  4. 支持启用/禁用活动、路线
  5. 支持创建和管理地点信息(名称、省份、城市、区县、详细地址、经纬度)
  6. 支持去程/返程路线动态判断:目的地=活动地点为去程,出发地=活动地点为返程
  7. 支持省市区三级联动查询和选择
  8. 支持按省市区多维度查询地点和路线

Tasks / Subtasks

  • 创建基础数据实体 (AC: 1, 2, 3)
    • src/server/modules/routes/ 创建 route.entity.ts
    • src/server/modules/activities/ 创建 activity.entity.ts
    • src/share/ 创建相关类型定义
  • 创建省市区实体和关联关系 (AC: 5, 7, 8)
    • src/server/modules/areas/ 创建 area.entity.ts
    • src/server/modules/locations/ 创建 location.entity.ts
    • 更新ActivityEntity,添加venueLocation字段关联LocationEntity
    • 更新RouteEntity,添加startLocation和endLocation字段关联LocationEntity
    • src/share/ 创建省市区和地点相关类型定义
    • 在Route实体中添加 routeType 计算字段,根据活动地点关系自动判断类型
    • 在路线查询API中集成去程/返程筛选功能
    • 在管理后台路线列表页面显示路线类型(去程/返程)
  • 创建Zod Schema (AC: 1, 2, 3, 4)
    • src/server/modules/routes/ 创建 route.schema.ts (创建、更新、获取、列表Schema)
    • src/server/modules/activities/ 创建 activity.schema.ts (创建、更新、获取、列表Schema)
    • 验证Schema符合业务逻辑约束
  • 创建省市区Zod Schema (AC: 5)
    • src/server/modules/areas/ 创建 area.schema.ts (创建、更新、获取、列表Schema)
    • src/server/modules/locations/ 创建 location.schema.ts (创建、更新、获取、列表Schema)
    • 更新Activity和Route的Schema,支持地点关联
    • 验证省市区和地点Schema符合业务逻辑约束
  • 数据库迁移和种子数据 (AC: 1, 2, 3, 4)
    • 创建数据库迁移文件,添加活动、路线相关表结构
    • 创建种子数据,添加示例活动和路线数据
    • 验证数据库迁移和种子数据正确性
  • 省市区数据库迁移和种子数据 (AC: 5)
    • 创建数据库迁移文件,添加省市区表结构
    • 创建数据库迁移文件,添加地点表结构
    • 更新活动和路线表,添加地点关联字段
    • 使用 scripts/generate-area-sql.mjs 生成省市区种子数据
    • 创建种子数据,添加示例地点数据
    • 验证省市区和地点数据库迁移和种子数据正确性
  • 实现管理后台API (AC: 1, 2, 3, 4)
    • src/server/api/admin/activities/index.ts 使用 createCrudRoutes 创建活动管理API
    • src/server/api/admin/routes/index.ts 使用 createCrudRoutes 创建路线管理API
    • 配置搜索字段、关联关系、筛选条件
    • 实现启用/禁用功能
  • 实现省市区管理API (AC: 5, 7, 8)
    • src/server/api/admin/areas/index.ts 使用 createCrudRoutes 创建省市区管理API
    • 配置搜索字段、筛选条件(层级、父级ID)
    • 实现省市区层级查询API(省份列表、城市列表、区县列表)
    • 配置省市区树形结构查询API
    • 实现省市区三级联动查询API(根据省份获取城市,根据城市获取区县)
    • 实现省市区完整层级路径查询API(根据区县ID获取完整省市区路径)
    • 实现省市区查询端点:
    • GET /api/v1/areas/provinces - 获取省份列表
    • GET /api/v1/areas/cities?provinceId=1 - 获取城市列表
    • GET /api/v1/areas/districts?cityId=34 - 获取区县列表
  • 实现地点管理API (AC: 5, 8)
    • src/server/api/admin/locations/index.ts 使用 createCrudRoutes 创建地点管理API
    • 配置搜索字段、关联关系、筛选条件
    • 更新活动和路线API,支持地点关联查询
    • 支持按省市区筛选地点
    • 支持地点名称模糊搜索
    • 支持按省市区多维度查询地点
  • [x] 实现用户端路线查询API (AC: 6, 7, 8)

    • src/server/api/routes/index.ts 中实现路线搜索API
    • 支持按出发地、目的地、日期查询路线
    • 支持按路线类型(去程/返程)筛选
    • 支持按价格、出发时间排序
    • 返回包含关联活动信息的路线列表
    • 实现去重后的活动列表展示
  • [x] 实现省市区管理页面 (AC: 5)

    • 创建省市区管理页面 - 省市区数据配置和管理
    • 实现省市区管理页面的搜索和筛选功能
    • 实现省市区创建和编辑表单
    • 支持省市区层级展示和树形结构
    • 实现省市区三级联动选择组件
    • 更新地点表单,支持省市区三级联动选择组件
  • [x] 实现地点管理页面 (AC: 5)

    • 创建地点管理页面 - 地点信息配置和管理
    • 实现地点管理页面的搜索和筛选功能
    • 实现地点创建和编辑表单
    • 更新活动和路线表单,支持地点选择组件
    • 支持按省市区筛选地点列表
  • [x] 编写地点管理测试 (AC: 5, 6, 7, 8)

    • 管理后台API集成测试 (tests/integration/server/)
    • 地点管理API CRUD操作测试 (P0)
    • 地点搜索和筛选功能测试 (P1)
    • 地点关联关系测试 (P1)
    • 省市区三级联动API测试 (P1)
    • 去程/返程动态判断逻辑测试 (P0)
    • 省市区多维度查询测试 (P1)
    • 用户端路线查询API测试 (P0)
    • 路线活动关联查询测试 (P1)
    • 活动地点关联查询测试 (P1)
    • 活动管理页面地点筛选功能测试 (P1)
    • 管理后台页面组件测试 (tests/integration/client/)
    • LocationManagementPage组件测试 (P1)
    • LocationForm组件测试 (P1)
    • LocationSelect组件测试 (P1) - 完成8个测试用例,覆盖渲染、选择、搜索、加载状态、禁用状态
    • 省市区三级联动组件测试 (P1)
    • ActivityManagementPage地点显示和筛选测试 (P1)
    • ActivityForm地点选择组件测试 (P1) - 完成7个测试用例,覆盖表单渲染、地点选择、验证和提交
    • RouteForm地点选择组件测试 (P1) - 完成7个测试用例,覆盖出发地和目的地选择功能
    • E2E测试 (tests/e2e/specs/admin/)
    • 地点管理E2E测试 (P1)
    • 省市区三级联动E2E测试 (P1)
    • 去程/返程路线识别E2E测试 (P0)
    • 用户端路线查询E2E测试 (P0)
    • 活动管理页面地点功能E2E测试 (P1)
  • [x] 实现地点选择组件 (AC: 5)

    • 创建LocationSelect组件,支持地点搜索和选择
    • 在ActivityForm中集成LocationSelect组件,选择举办地点
    • 在RouteForm中集成LocationSelect组件,选择出发地和目的地
    • 实现地点搜索功能,支持按名称、省份、城市搜索
    • 实现地点列表展示,显示地点名称和完整地址
    • 添加地点选择验证
    • 在活动管理页面显示活动地点信息
    • 在活动列表表格中显示举办地点名称和地址
    • 支持按活动地点筛选活动列表
    • 在活动详情页面显示完整的活动地点信息
    • 在活动表单中显示已选择地点的完整信息
    • 在路线表单中显示已选择地点的完整信息
    • 添加地点选择表单验证和错误提示
  • [x] 实现管理后台页面 (AC: 1, 2, 3, 4)

    • 创建活动管理页面 - 活动类型配置和管理
    • 创建路线管理页面 - 路线信息配置和管理
    • 实现活动管理页面的搜索和筛选功能
    • 实现路线管理页面的搜索和筛选功能
    • 实现活动创建和编辑表单
    • 实现路线创建和编辑表单
    • 实现启用/禁用功能
    • 在活动列表表格中显示举办地点信息
    • 在路线列表表格中显示完整的地点信息(出发地、目的地)
    • 支持按活动地点筛选活动列表
    • 支持按出发地/目的地筛选路线列表
    • 在活动详情页面显示完整的地点信息
    • 在路线详情页面显示完整的地点信息
  • [x] 编写测试 (AC: 1, 2, 3, 4)

    • 管理后台API集成测试 (tests/integration/server/)
    • 活动管理API CRUD操作测试 (P0)
    • 路线管理API CRUD操作测试 (P0)
    • 搜索和筛选功能测试 (P1)
    • 启用/禁用功能测试 (P0)
    • 活动路线关联测试 (P1)
    • 活动地点关联查询测试 (P1)
    • 路线地点关联查询测试 (P1)
    • 管理后台页面组件测试 (tests/integration/client/)
    • ActivityManagementPage组件测试 (P1)
    • RouteManagementPage组件测试 (P1)
    • ActivityForm组件测试 (P1)
    • RouteForm组件测试 (P1)
    • ActivitySelect组件测试 (P1)
    • LocationSelect组件测试 (P1)
    • ActivityManagementPage地点显示和筛选测试 (P1)
    • RouteManagementPage地点显示和筛选测试 (P1)
    • ActivityForm地点选择功能测试 (P1)
    • RouteForm地点选择功能测试 (P1)
    • E2E测试 (tests/e2e/specs/admin/)
    • 活动管理E2E测试 (P1)
    • 路线管理E2E测试 (P1)
    • 搜索筛选E2E测试 (P2)
    • 启用禁用操作E2E测试 (P1)
    • 活动管理页面地点功能E2E测试 (P1)
    • 路线管理页面地点功能E2E测试 (P1)
  • [x] 实现活动选择组件 (AC: 3)

    • 创建ActivitySelect组件,支持活动搜索和选择
    • 在RouteForm中集成ActivitySelect组件,替换原有的数字输入框
    • 实现活动搜索功能,支持按名称搜索
    • 实现活动列表展示,显示活动名称和类型
    • 添加活动选择验证
  • [x] 修复表单时间格式问题 (AC: 1, 2, 3, 4)

    • 修复活动API响应schema中的时间字段类型
    • 修复路线API响应schema中的时间字段类型
    • 修复ActivityForm组件中的时间格式转换
    • 修复RouteForm组件中的时间格式转换
    • 更新管理后台开发规范,添加日期时间处理标准

Dev Notes

数据模型设计

基于 [docs/prd/epic-005-travel-service-core.md#后端数据模型] 和 [docs/architecture/data-model-schema-changes.md],需要实现以下实体:

Area实体 (遵循 通用CRUD实体设计规范):

  • id - 主键
  • parentId - 关联父级区域,0表示顶级(省/直辖市)
  • name - 区域名称
  • level - 层级: 1:省/直辖市, 2:市, 3:区/县
  • code - 行政区划代码
  • createdAtupdatedAt 时间戳
  • 使用TypeORM装饰器定义字段

Location实体 (遵循 通用CRUD实体设计规范):

  • name - 地点名称
  • province - 关联AreaEntity (level=1)
  • city - 关联AreaEntity (level=2)
  • district - 关联AreaEntity (level=3)
  • address - 详细地址
  • latitude - 纬度
  • longitude - 经度
  • 支持状态管理(启用/禁用)
  • 包含 createdAtupdatedAt 时间戳
  • 使用TypeORM装饰器定义字段

Activity实体 (遵循 通用CRUD实体设计规范):

  • name - 活动名称
  • description - 活动描述
  • venueLocation - 关联LocationEntity(举办地点)
  • startDate - 开始时间
  • endDate - 结束时间
  • 支持状态管理(启用/禁用)
  • 包含 createdAtupdatedAt 时间戳
  • 使用TypeORM装饰器定义字段

Route实体 (遵循 通用CRUD实体设计规范):

  • startLocation - 关联LocationEntity(出发地)
  • endLocation - 关联LocationEntity(目的地)
  • pickupPoint - 上车点
  • dropoffPoint - 下车点
  • departureTime - 出发时间
  • vehicleType - 车型
  • price - 价格
  • seatCount - 座位数
  • activity - 关联ActivityEntity
  • 支持状态管理(启用/禁用)
  • 包含 createdAtupdatedAt 时间戳
  • 使用TypeORM装饰器定义字段

数据库迁移要求

  • 创建 locations 表,包含必要的字段和索引
  • 创建 routes 表,包含必要的字段和索引
  • 创建 activities 表,包含必要的字段和索引
  • 创建关联关系表(如需要)
  • 添加适当的约束和索引优化查询性能

查询逻辑业务流程

基于优化的数据模型,查询逻辑需要相应调整:

地点查询流程:

  • 支持按省份、城市、区县多维度查询地点
  • 支持地点名称模糊搜索
  • 支持按省市区筛选地点

路线查询流程:

  • 通过地点关联查询路线
  • 路线类型动态判断:目的地=活动地点为去程,出发地=活动地点为返程
  • 支持按省市区范围查询路线

用户端路线和活动查询流程:

  • 用户输入出发地、目的地、日期时,系统:
    1. 查询匹配的出发地点和目的地点
    2. 通过地点ID查询符合条件的路线(出发地、目的地、日期)
    3. 根据路线找到关联的活动
    4. 展示去重后的活动列表,每个活动显示可用的路线信息

查询API设计:

  • GET /api/v1/routes/search?startLocationId=123&endLocationId=456&date=2025-10-15
  • 响应包含:路线列表 + 关联的活动信息
  • 支持按路线类型(去程/返程)筛选
  • 支持按价格、出发时间排序

去程/返程动态判断逻辑:

  • 去程路线: 目的地 = 活动举办地点
  • 返程路线: 出发地 = 活动举办地点
  • 简化数据模型: 每个活动只需创建一次,路线根据与活动地点的关系自动识别类型

业务逻辑实现位置:

  • src/server/modules/routes/route.service.ts 中实现 getRouteType 方法
  • 在Route实体中添加计算字段 routeType,基于活动地点关系自动判断
  • 在路线查询API中支持按路线类型筛选
  • 在管理后台路线列表页面显示路线类型

管理后台API设计

基于 [docs/prd/epic-005-travel-service-core.md#管理后台API],使用 通用CRUD规范 实现以下API端点:

地点管理API (使用 createCrudRoutes):

  • GET /api/v1/admin/locations - 地点管理列表(支持分页、搜索、筛选)
  • GET /api/v1/admin/locations/:id - 地点详情
  • POST /api/v1/admin/locations - 创建地点
  • PUT /api/v1/admin/locations/:id - 更新地点
  • DELETE /api/v1/admin/locations/:id - 删除地点

地点管理API配置:

  • 搜索字段: ['name', 'province', 'city', 'district', 'address']
  • 筛选字段: province, city, district
  • 排序字段: name, province, city
  • 中间件: [authMiddleware]
  • Zod Schema: 创建、更新、获取、列表Schema

活动管理API (使用 createCrudRoutes):

  • GET /api/v1/admin/activities - 活动管理列表(支持分页、搜索、筛选)
  • GET /api/v1/admin/activities/:id - 活动详情
  • POST /api/v1/admin/activities - 创建活动
  • PUT /api/v1/admin/activities/:id - 更新活动
  • DELETE /api/v1/admin/activities/:id - 删除活动

活动管理API配置:

  • 搜索字段: ['name', 'description']
  • 关联关系: ['routes', 'venueLocation']
  • 筛选字段: type (活动类型)
  • 中间件: [authMiddleware]
  • Zod Schema: 创建、更新、获取、列表Schema

路线管理API (使用 createCrudRoutes):

  • GET /api/v1/admin/routes - 路线管理列表(支持分页、搜索、筛选)
  • GET /api/v1/admin/routes/:id - 路线详情
  • POST /api/v1/admin/routes - 创建路线
  • PUT /api/v1/admin/routes/:id - 更新路线
  • DELETE /api/v1/admin/routes/:id - 删除路线

路线管理API配置:

  • 搜索字段: ['vehicleType']
  • 关联关系: ['activity', 'startLocation', 'endLocation']
  • 筛选字段: vehicleType, price (范围查询), routeType (去程/返程)
  • 排序字段: price, departureTime
  • 中间件: [authMiddleware]
  • Zod Schema: 创建、更新、获取、列表Schema
  • 自定义查询: 支持按路线类型(去程/返程)筛选

地点选择组件设计

基于地点实体设计方案,需要实现地点选择组件来提升用户体验:

LocationSelect组件功能要求

  • 支持地点搜索和选择,提升用户体验
  • 显示地点名称和完整地址信息(省份+城市+区县)
  • 支持按地点名称、省份、城市搜索
  • 集成到ActivityForm中,选择举办地点
  • 集成到RouteForm中,选择出发地和目的地
  • 遵循管理后台组件设计规范

组件位置

  • src/client/admin/components/LocationSelect.tsx

集成要求

  • 在ActivityForm中替换现有的venue输入字段
  • 在RouteForm中替换现有的startPoint和endPoint输入字段
  • 保持与现有表单验证的兼容性
  • 支持地点列表的异步加载和搜索

活动选择组件设计

基于用户体验改进需求,需要实现活动选择组件来替换原有的数字ID输入框:

ActivitySelect组件功能要求

  • 支持活动搜索和选择,提升用户体验
  • 显示活动名称和类型(去程/返程)
  • 支持按活动名称搜索
  • 集成到RouteForm中,替换原有的activityId数字输入框
  • 遵循管理后台组件设计规范

组件位置

  • src/client/admin/components/ActivitySelect.tsx

集成要求

  • 在RouteForm中替换现有的activityId输入字段
  • 保持与现有表单验证的兼容性
  • 支持活动列表的异步加载和搜索

管理后台页面设计

基于 [docs/prd/epic-005-travel-service-core.md#管理后台页面任务],需要实现以下页面:

地点管理页面:

前端RPC实现规范

严格遵循 RPC Client 使用规范

客户端导入和类型定义

// 从统一的API模块导入客户端
import { activityClient, routeClient } from '@/client/api';
import type { InferRequestType, InferResponseType } from 'hono/client';

// 类型提取规范
type ActivityResponse = InferResponseType<typeof activityClient.$get, 200>['data'][0];
type RouteResponse = InferResponseType<typeof routeClient.$get, 200>['data'][0];
type CreateActivityRequest = InferRequestType<typeof activityClient.$post>['json'];
type UpdateActivityRequest = InferRequestType<typeof activityClient[':id']['$put']>['json'];

数据获取规范

// 使用React Query进行数据获取
const { data, isLoading, refetch } = useQuery({
  queryKey: ['activities', searchParams],
  queryFn: async () => {
    const res = await activityClient.$get({
      query: {
        page: searchParams.page,
        pageSize: searchParams.limit,
        keyword: searchParams.keyword
      }
    });
    if (res.status !== 200) throw new Error('获取数据失败');
    return await res.json();
  },
  staleTime: 5 * 60 * 1000,  // 5分钟缓存
  cacheTime: 10 * 60 * 1000, // 10分钟缓存
});

统一错误处理

// 统一操作处理函数
const handleOperation = async (operation: () => Promise<any>) => {
  try {
    await operation();
    toast.success('操作成功');
  } catch (error) {
    console.error('操作失败:', error);
    toast.error('操作失败,请重试');
  }
};

// 创建活动示例
const handleCreateActivity = async (data: CreateActivityRequest) => {
  await handleOperation(async () => {
    const res = await activityClient.$post({ json: data });
    if (res.status !== 201) throw new Error('创建失败');
  });
};

防抖搜索实现

// 防抖搜索函数
const debounce = (func: Function, delay: number) => {
  let timeoutId: NodeJS.Timeout;
  return (...args: any[]) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
};

const debouncedSearch = useCallback(
  debounce((keyword: string) => {
    setSearchParams(prev => ({ ...prev, keyword, page: 1 }));
  }, 300),
  []
);

活动管理页面:

路线管理页面:

种子数据要求

  • 创建示例活动数据:至少包含去程活动和返程活动各3个
  • 创建示例路线数据:关联到相应的活动
  • 确保数据符合业务逻辑约束

文件位置

  • 后端实体:
    • src/server/modules/locations/location.entity.ts
    • src/server/modules/routes/route.entity.ts
    • src/server/modules/activities/activity.entity.ts
  • Zod Schema (遵循 Schema设计规范):
    • src/server/modules/locations/location.schema.ts
    • src/server/modules/routes/route.schema.ts
    • src/server/modules/activities/activity.schema.ts
  • 共享类型:
    • src/share/location.types.ts
    • src/share/route.types.ts
    • src/share/activity.types.ts
  • 管理后台API (使用 createCrudRoutes):
    • src/server/api/admin/locations/index.ts
    • src/server/api/admin/activities/index.ts
    • src/server/api/admin/routes/index.ts
  • 管理后台页面 (遵循 文件组织规范):
    • mini/src/pages/admin/locations/LocationManagementPage.tsx
    • mini/src/pages/admin/activities/ActivityManagementPage.tsx
    • mini/src/pages/admin/routes/RouteManagementPage.tsx
  • 选择组件:
    • src/client/admin/components/LocationSelect.tsx
    • src/client/admin/components/ActivitySelect.tsx
  • 数据库迁移: src/server/migrations/ 目录
  • 种子数据: src/server/seeds/ 目录

技术栈要求

  • 后端框架: Hono + TypeORM
  • 数据库: PostgreSQL 17
  • 迁移工具: TypeORM Migration
  • 管理后台前端: 遵循 管理后台开发规范

开发规范要求

  • 实体定义: 遵循TypeORM实体规范
  • 类型定义: 使用TypeScript严格类型
  • 数据库约束: 添加适当的数据库级约束
  • 索引优化: 为常用查询字段添加索引
  • 管理后台开发: 严格遵循 管理后台开发规范
  • API开发: 严格遵循 通用CRUD规范

测试要求

  • 实体测试: 验证实体字段定义和关联关系
  • 数据库测试: 验证迁移和种子数据正确性
  • 约束测试: 验证数据库约束有效性
  • API测试 (遵循 通用CRUD测试要求):
    • 验证CRUD操作的正确性
    • 测试搜索、筛选、排序功能
    • 验证关联关系查询
  • 管理后台页面测试 (遵循 测试规范):
    • 组件测试:验证页面渲染和交互
    • E2E测试:验证完整的管理流程

测试实施指导

基于测试设计分析 (docs/qa/assessments/005.001-test-design-20251016.md),测试实施应遵循以下优先级:

P0 优先实施 (核心功能):

  • 活动类型枚举验证
  • 路线字段格式验证
  • 数据库CRUD操作测试
  • 启用/禁用状态切换测试
  • 去程/返程动态判断逻辑测试
  • 省市区三级联动API测试
  • 用户端路线查询API测试

P1 其次实施 (重要功能):

  • 搜索和筛选功能测试
  • 活动路线关联测试
  • 管理后台页面组件测试
  • 关键E2E用户旅程测试
  • 省市区多维度查询测试
  • 地点关联关系测试
  • 路线活动关联查询测试

P2 最后实施 (辅助功能):

  • 高级搜索筛选E2E测试
  • 管理后台页面导航测试
  • 省市区三级联动E2E测试
  • 用户端路线查询E2E测试

测试文件位置参考:

  • 集成测试: tests/integration/server/admin/
  • 组件测试: tests/integration/client/admin/
  • E2E测试: tests/e2e/specs/admin/

Change Log

Date Version Description Author
2025-10-18 6.0 ✅ 完成地点管理功能测试覆盖:添加LocationSelect、ActivityForm、RouteForm完整测试套件,修复测试环境问题 James (Dev Agent)
2025-10-18 5.0 补充活动管理页中活动地点的相关任务,完善地点显示、筛选和测试覆盖 John (PM)
2025-10-17 4.0 添加省市区实体设计方案,支持省市区三级联动数据管理,完善地点管理任务 James (Dev Agent)
2025-10-17 3.0 添加地点实体设计方案,支持省市区结构化地址管理,优化活动实体设计 John (PM)
2025-10-16 2.0 修复TypeScript类型错误,提升代码质量:修复Schema定义、枚举类型、filters参数格式,移除所有any类型使用 James (Dev Agent)
2025-10-16 1.9 完成活动管理和路线管理E2E测试,实现完整的测试覆盖 James (Dev Agent)
2025-10-16 1.8 修复表单时间格式问题,补充日期时间处理规范 Winston (Architect)
2025-10-16 1.7 补充活动选择组件任务,提升用户体验 Bob (Scrum Master)
2025-10-16 1.6 完成管理后台页面所有功能:搜索筛选、创建编辑、启用/禁用 James (Dev Agent)
2025-10-16 1.5 添加前端RPC实现规范,确保符合管理后台RPC Client使用规范 Bob (Scrum Master)
2025-10-16 1.4 添加通用CRUD规范引用,完善API实现细节 Bob (Scrum Master)
2025-10-16 1.3 添加管理后台开发规范引用,确保符合标准 Bob (Scrum Master)
2025-10-16 1.2 修正故事,移除班次实体,与epic005和数据模型保持一致 Bob (Scrum Master)
2025-10-16 1.1 修正故事,添加管理后台功能,完全满足epic005 US005-01需求 Bob (Scrum Master)
2025-10-16 1.0 初始故事创建,从005.002迁移基础数据实体任务 Bob (Scrum Master)

Dev Agent Record

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

Agent Model Used

Claude Sonnet 4.5 (2025-09-29)

Debug Log References

  • 检查并验证了基础数据实体的实现
  • 检查并验证了Zod Schema的实现
  • 检查并验证了管理后台API的实现
  • 检查并验证了管理后台页面的实现
  • 修复TypeScript类型错误:Schema定义、枚举类型、filters参数格式、any类型使用
  • 分析活动实体设计问题,识别缺少举办地点字段和去程/返程逻辑冗余
  • 设计地点实体方案,支持省市区结构化地址管理
  • 优化活动实体设计,添加venueLocation字段关联LocationEntity
  • 优化路线实体设计,添加startLocation和endLocation字段关联LocationEntity
  • 设计去程/返程动态判断逻辑:目的地=活动地点为去程,出发地=活动地点为返程
  • 发现省市区数据文件(scripts/省市区.csv),确认需要省市区实体(AreaEntity)
  • 设计省市区实体方案,支持省市区三级联动数据管理
  • 更新PRD文档,添加完整的省市区实体设计方案
  • 更新故事5.1,添加完整的省市区管理任务结构
  • 设计省市区API,支持三级联动查询和完整层级路径查询

Completion Notes List

已完成的任务:

  • 基础数据实体已创建并符合规范
  • Zod Schema已创建并包含完整验证逻辑
  • 管理后台API已使用createCrudRoutes实现
  • 管理后台页面已创建并集成到路由系统
  • 活动管理页面已实现完整的搜索、筛选、创建、编辑、启用/禁用功能
  • 路线管理页面已实现完整的搜索、筛选、创建、编辑、启用/禁用功能
  • 所有代码遵循项目编码标准和RPC客户端使用规范
  • 使用React Hook Form + Zod实现表单验证
  • 使用React Query进行数据管理
  • 实现防抖搜索优化用户体验
  • 修复筛选参数实现(使用通用CRUD的filters参数)
  • 创建ActivitySelect组件,提升用户体验
  • 在RouteForm中集成ActivitySelect组件,替换原有的数字输入框
  • 实现活动搜索功能,支持按名称搜索
  • 实现活动列表展示,显示活动名称和类型
  • 添加活动选择验证
  • 完成管理后台API集成测试(活动管理和路线管理)
  • 完成管理后台页面组件测试(ActivitiesPage和RoutesPage)
  • 扩展TestDataFactory支持活动和路线测试数据
  • 扩展IntegrationTestAssertions支持活动和路线断言
  • 完成活动管理E2E测试,覆盖完整的CRUD操作流程
  • 完成路线管理E2E测试,覆盖完整的CRUD操作流程
  • 完成启用/禁用操作E2E测试,验证状态切换功能
  • 在活动管理和路线管理页面添加data-testid属性,提升测试可靠性
  • 创建活动管理和路线管理页面对象类,遵循Page Object Model模式
  • 更新测试设置文件,集成新的页面对象
  • 创建完整的省市区实体结构,支持省市区三级联动
  • 创建地点实体结构,支持结构化地址管理
  • 创建省市区和地点的Zod Schema验证
  • 实现去程/返程动态判断逻辑,通过计算属性routeType实现
  • 创建SQL生成脚本,生成完整的省市区种子数据
  • 执行数据库种子脚本,成功导入3280条省市区数据
  • 验证数据完整性:34个省级区域、943个市级区域、2303个区县级区域
  • 更新故事任务状态,标记省市区数据库迁移和种子数据任务为已完成
  • 验证所有省市区相关实体、Schema、类型定义文件已正确创建
  • 实现省市区管理API:使用createCrudRoutes创建完整的省市区CRUD API,支持层级查询和三级联动
  • 实现地点管理API:使用createCrudRoutes创建完整的地点CRUD API,支持按省市区筛选和搜索
  • 实现用户端路线查询API:创建用户路线搜索API,支持出发地、目的地、日期查询和路线类型筛选
  • 实现省市区管理页面:创建完整的省市区管理页面,支持搜索、筛选、创建、编辑功能
  • 实现地点管理页面:创建完整的地点管理页面,支持搜索、筛选、创建、编辑功能
  • 实现地点选择组件:创建LocationSelect组件,支持地点搜索和选择,集成到活动和路线表单中
  • 更新导航菜单:在管理后台添加"基础数据管理"菜单组,包含区域管理和地点管理
  • 修复TypeScript类型错误:解决构建过程中的类型错误,确保项目构建成功
  • 完善活动管理页面地点功能:在活动列表表格中显示举办地点信息,支持按地点筛选活动,在活动详情页面显示完整的地点信息
  • 完善路线管理页面地点功能:在路线列表表格中显示完整的地点信息(出发地、目的地),支持按出发地/目的地筛选路线,在路线详情页面显示完整的地点信息
  • 完善表单中地点功能:在活动表单和路线表单中显示已选择地点的完整信息,添加地点选择表单验证和错误提示
  • 完成地点管理功能测试覆盖
    • 添加LocationSelect组件完整测试套件,覆盖渲染、选择、搜索、加载状态、禁用状态
    • 完善ActivityForm地点选择功能测试,验证表单渲染、地点选择、验证和提交
    • 完善RouteForm出发地和目的地选择测试,验证地点选择功能和表单交互
    • 修复测试环境中的QueryClient问题,创建TestWrapper组件
    • 优化LocationSelect组件支持data-testid属性,提升测试可靠性
    • 所有地点相关测试通过验证,确保地点管理功能质量

技术实现细节:

  • 严格遵循RPC客户端使用规范
  • 使用TypeScript确保类型安全
    • 修复Schema定义不完整问题,确保API返回完整对象
    • 使用枚举类型替代字符串字面量,提升类型安全性
    • 移除所有any类型使用,遵循TypeScript最佳实践
    • 确保测试代码具有完整的类型推断
  • 实现组件化表单设计
  • 支持活动类型筛选(去程/返程)
  • 支持车型筛选(大巴/中巴/小车)
  • 实现状态切换确认对话框
  • 所有单元测试通过验证
  • 创建Combobox组件,基于Command和Popover组件
  • 实现ActivitySelect组件,支持活动搜索和选择
  • 集成React Query进行异步数据获取
  • 实现防抖搜索优化性能
  • 显示活动名称和类型信息
  • 修复活动API响应schema中的时间字段类型问题
  • 修复路线API响应schema中的时间字段类型问题
  • 在ActivityForm和RouteForm中添加时间格式转换函数
  • 使用date-fns库进行时间格式化
  • 更新管理后台开发规范,添加日期时间处理标准
  • 扩展测试基础设施支持活动和路线实体
  • 实现全面的API集成测试覆盖CRUD、搜索、筛选、状态切换
  • 实现组件集成测试覆盖页面渲染、表单交互、错误处理
  • 修复测试数据字段映射问题(status vs isDisabled, seats vs seatCount)
  • 实现完整的E2E测试覆盖活动管理和路线管理功能
  • 使用data-testid属性提升测试可靠性,避免基于文本的定位器
  • 遵循Page Object Model设计模式,创建专业的页面对象类
  • 使用Playwright进行E2E测试,确保端到端流程正确性
  • 实现活动CRUD操作E2E测试:创建、编辑、删除、启用/禁用
  • 实现路线CRUD操作E2E测试:创建、编辑、删除、启用/禁用
  • 验证状态切换功能在E2E测试中的正确性
  • 修复TypeScript类型错误,提升代码质量
    • 修复Schema定义不完整问题:扩展活动获取Schema和路线获取Schema为完整对象定义
    • 修复枚举类型使用错误:使用ActivityType枚举值替代字符串字面量
    • 修复filters参数格式错误:使用JSON.stringify传递筛选条件
    • 移除测试代码中的所有any类型使用,提升类型安全性

File List

已创建/修改的文件:

地点管理功能测试相关文件:

省市区实体设计相关文件:

QA Results

测试设计审查 (2025-10-16)

审查人: Quinn (Test Architect)

测试策略:

  • 总测试场景: 24个
  • 单元测试: 8个 (33%)
  • 集成测试: 10个 (42%)
  • E2E测试: 6个 (25%)
  • 优先级分布: P0: 10个, P1: 8个, P2: 6个

质量门控状态: ✅ 测试设计通过

  • 每个验收标准都有适当的测试覆盖
  • 测试级别分配合理
  • 优先级与业务风险对齐
  • 无重复覆盖问题

实施建议: 开发团队应按P0→P1→P2优先级顺序实施测试