name: gdpr-compliance description: 此技能为在Empathy Ledger中实施和审查符合GDPR的功能提供全面指导。
GDPR合规技能
此技能为在Empathy Ledger中实施和审查符合GDPR的功能提供全面指导。
GDPR权利参考
第15条 - 访问权
要求:用户可以请求其个人数据的副本
实现:
// GET /api/user/export
const data = await gdprService.exportUserData(userId)
// 返回:故事、媒体、个人资料、同意记录、活动日志
第16条 - 更正权
要求:用户可以更正不准确的个人数据
实现:
- 通过个人资料设置编辑个人资料
- 通过故事编辑器编辑故事
- 所有更改记录在审计跟踪中
第17条 - 删除权(被遗忘权)
要求:用户可以请求删除其数据
实现:
// POST /api/user/deletion-request
// 启动30天删除工作流
// POST /api/stories/[id]/anonymize
// 立即匿名化特定故事
匿名化流程:
- 从故事内容中移除个人身份信息
- 将作者姓名替换为“匿名故事讲述者”
- 与个人资料解除关联(设置storyteller_id = null)
- 撤销所有活跃的分发
- 匿名化相关媒体
- 保留匿名化的审计跟踪
第20条 - 数据可携权
要求:用户可以以机器可读的格式导出数据
实现:
- JSON导出格式
- 包含所有用户生成的内容
- 可通过保管库仪表板下载
同意管理
同意捕获
interface ConsentRecord {
has_consent: boolean // 已给予初始同意
consent_verified: boolean // 同意验证已完成
consent_method?: string // '书面' | '口头' | '数字'
consent_date?: Date
consent_witness_id?: string // 用于口头同意
}
同意撤回
// POST /api/stories/[id]/consent/withdraw
// 触发:
// 1. 设置consent_withdrawn_at时间戳
// 2. 撤销所有嵌入令牌
// 3. 将所有分发标记为已撤销
// 4. 发送Webhook通知
// 5. 排队外部下架请求
// 6. 创建审计日志条目
数据处理的法律依据
对于Empathy Ledger,我们依赖:
- 同意(第6(1)(a)条) - 故事分享的主要依据
- 合法利益(第6(1)(f)条) - 平台运营、安全
数据最小化
仅收集所需内容
- 基本个人资料数据:姓名、电子邮件、组织
- 故事内容:由用户提供
- 技术数据:用于安全的最小日志记录
保留限制
- 活跃数据:账户活跃期间保留
- 已删除数据:30天内完全移除
- 匿名化数据:仅保留用于汇总统计
- 审计日志:账户删除后匿名化
实施检查清单
用户数据导出
□ 导出包含所有用户故事
□ 导出包含媒体文件
□ 导出包含个人资料数据
□ 导出包含同意记录
□ 导出包含活动日志
□ 格式为JSON(机器可读)
□ 下载安全(经过身份验证)
数据删除
□ 删除请求创建工单
□ 用户收到确认电子邮件
□ 30天处理窗口
□ 所有故事匿名化或删除
□ 所有媒体文件移除
□ 个人资料数据擦除
□ 审计跟踪匿名化
□ 通知第三方分发
同意跟踪
□ 分发前捕获同意
□ 记录同意方法
□ 同意可以撤回
□ 撤回自动级联
□ 同意变更的审计跟踪
□ 新用途需要重新同意
API端点
数据权利
GET /api/user/export- 导出所有用户数据POST /api/user/deletion-request- 请求账户删除GET /api/user/deletion-request- 检查删除状态
故事级GDPR
POST /api/stories/[id]/anonymize- 匿名化特定故事POST /api/stories/[id]/consent/withdraw- 撤回同意
审计访问
GET /api/stories/[id]/audit- 查看故事审计跟踪POST /api/stories/[id]/audit/export- 导出审计报告
数据库模式
deletion_requests
CREATE TABLE deletion_requests (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
tenant_id UUID NOT NULL,
request_type TEXT NOT NULL, -- 'anonymize_story', 'delete_account'
status TEXT DEFAULT 'pending', -- 'pending', 'processing', 'completed'
requested_at TIMESTAMPTZ,
processed_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ
);
故事匿名化字段
-- 在stories表上
anonymization_status TEXT, -- null, 'partial', 'full'
anonymized_fields JSONB, -- 跟踪哪些字段被匿名化
consent_withdrawn_at TIMESTAMPTZ -- 同意被撤回的时间
服务
GDPRService
class GDPRService {
exportUserData(userId: string): Promise<DataExport>
anonymizeStory(storyId: string): Promise<AnonymizeResult>
anonymizeUserData(userId: string): Promise<AnonymizeResult>
createDeletionRequest(userId: string, type: string): Promise<Request>
processDeletionRequest(requestId: string): Promise<void>
scrubPII(content: string): string
}
GDPR代码审查
审查代码时,验证:
- 数据收集:此数据是否必要?
- 同意:处理前是否捕获了同意?
- 访问:用户可以访问其数据吗?
- 更正:用户可以更正其数据吗?
- 删除:用户可以删除其数据吗?
- 可携性:用户可以导出其数据吗?
- 审计:操作是否被记录?
- 安全:数据是否得到适当保护?