Files
chinese-family-tree-2/PERMISSION_IMPLEMENTATION_PLAN.md
T
freedakgmail e44dd0bd95 0.0.8.0
2025-11-23 18:03:04 +08:00

5.4 KiB

🔐 权限控制实施计划

已完成

1. 权限工具函数 (lib/permissions.ts)

  • 创建 permissions 对象,包含所有权限检查函数
  • 添加辅助函数:getRoleDisplayNamegetRoleDescriptiongetRolePermissions
  • 修复类型冲突问题
  • 添加完整的中文注释

2. 首页 (app/page.tsx)

  • 导入 permissions
  • 更新"添加成员"按钮权限控制

🚧 进行中

3. 成员列表页 (app/members/page.tsx)

需要更新的按钮:

  • 筛选按钮(所有人可见)
  • 新增成员按钮 → permissions.canCreate(role)
  • 在族谱图中定位按钮(所有人可见)

4. 成员详情页 (app/members/[id]/page.tsx)

需要更新的按钮:

  • 添加父亲 → permissions.canCreate(role)
  • 添加母亲 → permissions.canCreate(role)
  • 添加子女 → permissions.canCreate(role)
  • 添加配偶 → permissions.canCreate(role)
  • 编辑 → permissions.canUpdate(role)
  • 删除 → permissions.canDeleteMember(role)
  • 打印(所有人可见)
  • 分享(所有人可见)

5. 新增成员页 (app/members/new/page.tsx)

需要检查:

  • 整个页面需要 permissions.canCreate(role) 权限
  • 无权限时重定向

6. 族谱图页 (app/tree/page.tsx)

需要更新的按钮:

  • 关系查询(所有人可见)
  • 视图模式(所有人可见)
  • 放大/缩小/重置(所有人可见)
  • 导出图片 → permissions.canExport(role)

7. 关系计算页 (app/relationship/page.tsx)

需要检查:

  • 所有按钮都是查询功能,所有人可见

8. 系统设置页 (app/settings/page.tsx)

需要更新的按钮:

  • 导出数据 → permissions.canExport(role)
  • 导入数据 → permissions.canImport(role)
  • 导出GEDCOM → permissions.canExport(role)
  • 导入GEDCOM → permissions.canImport(role)
  • 清空数据 → permissions.canClearData(role)
  • 清空日志 → permissions.canClearData(role)
  • 修改密码(所有人可见)

9. 全局导航 (components/site-header.tsx)

需要更新的按钮:

  • 删除家族树 → permissions.canDeleteTree(role)
  • 创建新家族树 → permissions.canCreateTree(role)
  • 搜索(所有人可见)
  • 通知(所有人可见)
  • 设置(所有人可见)

📝 待办事项

API 层面权限验证

  • /api/trees/[treeId]/members POST → 检查 EDITOR 权限
  • /api/trees/[treeId]/members/[memberId] PATCH → 检查 EDITOR 权限
  • /api/trees/[treeId]/members/[memberId] DELETE → 检查 EDITOR 权限
  • /api/trees/[treeId] DELETE → 检查 OWNER 权限
  • /api/trees/[treeId]/invite POST → 检查 OWNER 权限
  • /api/trees/[treeId]/collaborators/[collaboratorId] DELETE → 检查 OWNER 权限
  • /api/trees/[treeId]/import POST → 检查 EDITOR 权限

组件层面

  • components/members/member-form.tsx → 检查编辑权限
  • components/tree/collaborator-dialog.tsx → 检查 OWNER 权限
  • components/settings/activity-log-viewer.tsx → 清空日志需要 OWNER 权限

测试

  • 测试 OWNER 权限
  • 测试 EDITOR 权限
  • 测试 VIEWER 权限
  • 测试权限边界情况

文档

  • 更新用户手册
  • 更新 API 文档
  • 添加权限错误处理说明

🎯 实施优先级

P0 - 立即实施(本次)

  1. 创建权限工具函数
  2. 更新首页
  3. 🚧 更新成员列表页
  4. 🚧 更新成员详情页
  5. 🚧 更新系统设置页

P1 - 短期实施(今天)

  1. 更新全局导航
  2. 更新新增成员页
  3. 更新族谱图页

P2 - 中期实施(本周)

  1. API 层面权限验证
  2. 组件层面权限控制
  3. 错误处理和提示

P3 - 长期实施(下周)

  1. 完整测试
  2. 文档更新
  3. 性能优化

📋 代码模板

前端按钮权限控制

// 导入权限函数
import { permissions } from "@/lib/permissions"

// 获取当前角色
const { currentTree } = useFamily()
const role = currentTree?.currentUserRole

// 条件渲染(推荐)
{permissions.canCreate(role) && (
  <Button onClick={handleAdd}>添加成员</Button>
)}

// 禁用状态
<Button 
  disabled={!permissions.canUpdate(role)}
  onClick={handleEdit}
>
  编辑
</Button>

API 权限验证

// API 路由中
import { checkPermission } from "@/lib/permissions"
import { Role } from "@prisma/client"

export async function POST(request: Request) {
  const session = await getServerSession(authOptions)
  if (!session?.user?.id) {
    return NextResponse.json({ error: "未授权" }, { status: 401 })
  }

  // 检查权限
  const { hasPermission, role } = await checkPermission(
    session.user.id,
    treeId,
    Role.EDITOR // 需要的最低权限
  )

  if (!hasPermission) {
    return NextResponse.json({ error: "权限不足" }, { status: 403 })
  }

  // 执行操作...
}

🔍 检查清单

每个页面完成后检查

  • 所有按钮都添加了权限控制
  • 导入了 permissions
  • 获取了 role
  • 使用了正确的权限检查函数
  • 测试了三种角色的显示效果

每个 API 完成后检查

  • 添加了权限验证
  • 返回了正确的错误码
  • 添加了错误信息
  • 测试了权限边界

当前进度: 2/9 页面完成 (22%)
预计完成时间: 今天晚上
负责人: System