Files
chinese-family-tree-2/MEMBER_API_HISTORY_INTEGRATION.md
T
freedakgmail 3d075c6076 0.0.8.5
2025-11-24 14:02:34 +08:00

6.4 KiB
Raw Blame History

成员 API 历史记录功能集成

概述

已成功将历史记录功能集成到成员 API 中,实现了创建和更新成员时的自动历史记录。

修改的文件

1. /app/api/trees/[treeId]/members/route.ts

修改内容:

  • 导入 recordMemberHistory 函数
  • POST 方法(创建成员)中添加历史记录调用
// 记录成员历史版本
await recordMemberHistory({
  memberId: member.id,
  treeId,
  changedBy: session.user.id,
  changeType: 'CREATE',
  newData: member
})

2. /app/api/trees/[treeId]/members/[memberId]/route.ts

修改内容:

  • 导入 recordMemberHistory 函数
  • PATCH 方法(更新成员)中添加历史记录调用
// 记录成员历史版本
await recordMemberHistory({
  memberId: member.id,
  treeId,
  changedBy: session.user.id,
  changeType: 'UPDATE',
  oldData: existingMember,
  newData: member
})

功能特性

创建成员时记录历史

  • 自动创建版本 1 的历史记录
  • 记录完整的成员数据快照
  • 记录操作人和操作时间

更新成员时记录历史

  • 自动递增版本号
  • 只记录实际变更的字段
  • 保存变更前后的值对比
  • 如果没有实际变更,不创建历史记录

历史记录内容

每条历史记录包含:

  • 版本号:自动递增(1, 2, 3...
  • 快照:成员的完整数据
  • 变更类型CREATE / UPDATE / DELETE
  • 变更人:操作用户的 ID
  • 变更时间:自动记录
  • 变更详情:具体变更的字段及新旧值对比

测试结果

测试 1:基础功能测试

文件: scripts/test-member-history.ts

测试场景:

  1. 创建成员时记录历史
  2. 更新成员时记录历史(多字段)
  3. 部分字段更新
  4. 版本号正确递增
  5. 历史记录完整可追溯

测试输出示例:

✅ 历史记录数量: 3
✅ 最新版本号: 3
✅ 变更字段:
   - fullName: "测试成员" → "测试成员(已更新)"
   - birthDate: "1990-01-01" → "1990-01-02"
   - phone: "13800138000" → "13900139000"
   - bio: "null" → "这是一段个人简介"

测试 2API 集成测试

文件: scripts/test-member-api-history.ts

测试场景:

  1. POST API 创建成员时正确记录历史
  2. PATCH API 更新成员时正确记录历史
  3. 只记录实际变更的字段
  4. 无变更时不创建历史记录
  5. 版本号正确递增
  6. 历史记录包含完整的变更信息

测试输出示例:

📋 完整历史记录:
────────────────────────────────────────────────────────────────────────────────
版本 1 | CREATE | 2025/11/24 13:05:42
变更人: cmicfteui0000db5zlmi0ni3q
────────────────────────────────────────────────────────────────────────────────
版本 2 | UPDATE | 2025/11/24 13:05:42
变更人: cmicfteui0000db5zlmi0ni3q
变更内容:
  • bio: "null" → "API 测试用户简介"
  • email: "null" → "api-test@example.com"
  • phone: "null" → "13812345678"
  • fullName: "API测试" → "API测试(已修改)"
────────────────────────────────────────────────────────────────────────────────

运行测试

基础功能测试

npx tsx scripts/test-member-history.ts

API 集成测试

npx tsx scripts/test-member-api-history.ts

数据库结构

MemberHistory 表

model MemberHistory {
  id          String   @id @default(cuid())
  memberId    String
  treeId      String
  version     Int      // 版本号
  
  // 保存成员的完整快照
  snapshot    Json     // 成员的所有字段
  
  // 变更信息
  changedBy   String   // 修改者ID
  changedAt   DateTime @default(now())
  changeType  Action   // CREATE, UPDATE, DELETE
  changes     Json?    // 具体变更的字段 { field: { old: ..., new: ... } }
  
  @@index([memberId])
  @@index([treeId])
  @@index([changedAt])
  @@unique([memberId, version])
}

使用示例

查询成员历史

import { getMemberHistory } from '@/lib/member-history'

// 获取成员的所有历史版本
const history = await getMemberHistory(memberId)

// 最新版本
const latestVersion = history[0]

// 遍历所有版本
for (const record of history) {
  console.log(`版本 ${record.version}`)
  console.log(`操作: ${record.changeType}`)
  console.log(`时间: ${record.changedAt}`)
  
  if (record.changes) {
    // 显示变更详情
    for (const [field, change] of Object.entries(record.changes)) {
      console.log(`${field}: ${change.old}${change.new}`)
    }
  }
}

比较两个版本

import { compareVersions } from '@/lib/member-history'

const history = await getMemberHistory(memberId)
const changes = compareVersions(history[1], history[0])

// changes 格式:{ field: { old: ..., new: ... } }

优势

  1. 完整记录:保存每次修改的完整快照,可以恢复到任意历史版本
  2. 精确对比:只显示实际变更的字段,避免噪音
  3. 可追溯:可以查看任意时间点的成员信息
  4. 审计友好:满足数据审计需求,记录操作人和操作时间
  5. 智能优化:无实际变更时不创建历史记录,节省存储空间

注意事项

  1. 存储空间:每次修改都保存完整快照,会占用一定存储空间
  2. 性能影响:每次更新需要额外写入历史表,但影响很小
  3. 数据清理:未来可能需要定期清理过旧的历史版本

下一步计划

  1. 设计数据库表结构
  2. 创建辅助函数
  3. 运行数据库迁移
  4. 修改 API 集成历史记录
  5. 测试功能
  6. 更新前端显示(在活动日志中显示详细变更)
  7. 🔮 实现版本历史页面(未来)
  8. 🔮 实现版本回滚功能(未来)

总结

成员 API 已成功集成历史记录功能,所有测试通过。现在每次创建或更新成员时,系统都会自动记录历史版本,为未来的版本回溯和数据审计提供了坚实的基础。