关于 data-retention-policies
面向电商团队的数据保留政策技能,帮助制定保留期限、归档与清除规则,并按平台规划实施。重点涵盖 GDPR 请求、订单个人信息匿名化及跨系统删除审计。
主要功能
- 01制定数据保留计划
- 02Shopify、WooCommerce 与 BigCommerce 配置建议
- 03订单个人信息匿名化
- 04跨服务删除与审计日志
- 05分批安排定期清理
适用场景
- 01准备数据保护审计或 SOC 2 评估
- 02处理 GDPR 数据访问或删除请求
- 03降低无管控数据积累带来的存储成本
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill data-retention-policies安装后在 Claude Code 中输入/data-retention-policies确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonevals/gdpr-customer-purge-with-legal-hold-and-/criteria.jsontask.mdevals/order-pii-anonymization-preserving-finan/criteria.jsontask.mdevals/retention-schedule-and-automated-purge-j/criteria.jsontask.md详细介绍
数据保留政策
概述
数据保留政策规定每类数据的保存时长、归档时间和清除时间。电商商店必须在法律义务(税务记录通常必须保存 5–7 年)与隐私法规(GDPR 的数据最小化原则要求删除不再需要的数据)之间取得平衡。合适的做法取决于你的平台:Shopify 会自动处理部分数据保留,而 WooCommerce/自定义商店则需要明确实施相关措施。
何时使用此技能
- 为新的或现有的电商平台实施 GDPR 数据最小化要求时
- 法务或合规团队要求制定书面数据保留政策时
- 准备数据保护审计或 SOC 2 Type II 评估时
- 数据无序累积导致存储成本不断增长时
- 客户提交数据主体访问请求,而你需要确切了解其数据存储位置时
核心说明
步骤 1:先记录保留期限
在配置任何工具之前,先记录数据保留期限。法务、合规和工程团队必须在实施前达成一致。根据 GDPR 第 30 条,大型数据处理方必须制定此类处理活动记录(RoPA),建议所有组织都制定:
| 数据类别 | 保留期限 | 期限届满后的操作 | 法律依据 |
|---|---|---|---|
| 订单(财务记录) | 7 年 | 匿名化 PII;保留财务数据 | 税法(美国 IRS、欧盟 VAT) |
| 发票 | 7 年 | 归档至冷存储 | 税务合规 |
| 客户账户 | 最后活动后 3 年 | 删除 | 合法利益 |
| 会话/登录日志 | 90 天 | 删除 | 合法利益 |
| 营销邮件同意记录 | 直到取消订阅 | 取消订阅时删除 | GDPR 同意 |
| 弃置购物车数据 | 30 天 | 删除 | 合法利益 |
| 欺诈/安全日志 | 90 天 | 匿名化 | 合法利益 |
| 分析事件 | 13 个月 | 汇总后删除 | 合法利益 |
核心原则:法律要求保留的数据绝不可删除。对于订单,应将客户的 PII(姓名、电子邮件、地址)匿名化,同时保留财务记录(金额、税款、支付方式品牌/末 4 位)。
步骤 2:针对平台配置数据保留
Shopify
Shopify 默认会无限期保存订单数据,并负责处理基础设施组件层面的平台数据保留。
导出和删除客户数据(符合 GDPR): Shopify 提供内置的 GDPR Webhook:
- 前往 Settings → Customers → Customer privacy
- 当客户请求获取或删除其数据时,Shopify 会自动向所有已安装的应用发送
customers/data_request和customers/redactWebhook - 对于你自己的应用或自定义代码,请为这些事件注册 Webhook 处理程序
手动匿名化客户信息:
- 打开客户记录 → More actions → Anonymize this customer
- Shopify 会用匿名占位信息替换 PII,同时保留订单记录
- 此操作不可逆,继续前请确认
自动清理邮件列表: 使用 Klaviyo(或你的邮件服务提供商)自动屏蔽或删除连续 12 个月以上未打开邮件的联系人。大多数邮件服务提供商都内置了“sunset”自动化功能。
导出数据以供归档:
- 前往 Customers → Export,将客户数据下载为 CSV 以供归档
- 对于订单:前往 Orders → Export
- 将导出文件存储在加密的冷存储中(例如,采用 Glacier 生命周期策略的 AWS S3)
WooCommerce
WooCommerce 不会自动执行数据保留。你需要通过插件和计划任务进行配置。
WooCommerce 内置清理功能:
- 前往 WooCommerce → 状态 → 工具
- 使用 清理 WooCommerce 会话 删除过期的会话数据
- 使用 WooCommerce 跟踪器清理 清除跟踪数据
GDPR / 数据保留插件: 安装 WP GDPR Compliance 或 GDPR Cookie Consent(由 WebToffee 提供):
- 前往 WP GDPR Compliance → 设置 → 数据保留
- 按数据类型配置保留期限
- 插件会通过 WP-Cron 创建计划清理任务
手动计划清理(WP-Cron):
// Add to your theme's functions.php or a custom plugin
// Schedule a daily cleanup job
if (!wp_next_scheduled('wc_data_retention_cleanup')) {
wp_schedule_event(time(), 'daily', 'wc_data_retention_cleanup');
}
add_action('wc_data_retention_cleanup', 'run_data_retention');
function run_data_retention() {
// Delete WooCommerce sessions older than 90 days
global $wpdb;
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->prefix}woocommerce_sessions WHERE session_expiry < %d",
time() - (90 * DAY_IN_SECONDS)
)
);
// Log the cleanup
error_log('WC data retention: cleaned sessions older than 90 days');
}
符合税务要求的订单 PII 匿名化: 不要删除订单(税务记录要求保留订单)。应在保留财务数据的同时,将 PII 匿名化。安装 WooCommerce GDPR(WebToffee),该插件会为订单添加“匿名化”操作。
BigCommerce
BigCommerce 在管理面板中提供客户数据管理工具。
导出客户数据:
- 前往 客户 → 导出 → 所有客户(CSV)
- 删除客户账户前,用于存档
删除客户:
- 前往 客户 → 找到该客户 → 删除
- 删除客户账户后,BigCommerce 会保留关联的订单记录
自动保留: BigCommerce 没有内置的计划数据保留功能。使用 BigCommerce Customers API 和 Orders API 来:
- 查询超过 3 年未活跃的客户
- 存档其数据
- 删除或匿名化其账户
这需要自定义脚本或第三方集成(例如通过 Zapier 或自定义应用)。
自定义 / 无头架构
对于自定义店面,应实现按计划运行的自动清除和匿名化任务。
关键原则:分批少量处理、避开高峰期运行,并始终记录日志:
// Run nightly at 2 AM UTC
import { CronJob } from 'cron';
new CronJob('0 2 * * *', runRetentionJobs).start();
async function runRetentionJobs() {
const jobs = [
{ name: 'purge_sessions', fn: purgeSessions },
{ name: 'purge_abandoned_carts', fn: purgeAbandonedCarts },
{ name: 'anonymize_old_orders', fn: anonymizeOldOrders },
{ name: 'purge_inactive_customers', fn: purgeInactiveCustomers },
];
for (const job of jobs) {
try {
const result = await job.fn();
await db.retentionAuditLog.insert({ job: job.name, ...result, runAt: new Date() });
} catch (err) {
await alertOps(`Retention job failed: ${job.name}`, err);
}
}
}
// Paginated delete — avoids table locks
async function purgeSessions(): Promise<{ deleted: number }> {
const cutoff = new Date(Date.now() - 90 * 86400_000);
let deleted = 0;
while (true) {
const batch = await db.sessions.findExpired(cutoff, { limit: 1000 });
if (batch.length === 0) break;
await db.sessions.deleteBatch(batch.map(s => s.id));
deleted += batch.length;
await new Promise(r => setTimeout(r, 100)); // yield between batches
}
return { deleted };
}
// Anonymize order PII but keep financial data (7-year tax requirement)
async function anonymizeOldOrders(): Promise<{ anonymized: number }> {
const cutoff = new Date(Date.now() - 7 * 365 * 86400_000);
const orders = await db.orders.findWhere({ created_at: { lt: cutoff }, pii_anonymized_at: null }, { limit: 500 });
for (const order of orders) {
await db.orders.update(order.id, {
customer_email: `anon_${order.id}@deleted.invalid`,
customer_name: 'Anonymous Customer',
shipping_name: 'Anonymous',
shipping_street: null,
shipping_city: order.shipping_city, // Keep for tax jurisdiction
shipping_country: order.shipping_country,
billing_name: 'Anonymous',
billing_street: null,
// Financial data (total_amount, tax_amount, payment_method_last4): UNCHANGED
pii_anonymized_at: new Date(),
});
}
return { anonymized: orders.length };
}
跨服务删除客户数据: 删除客户时,应清除所有保存其数据的系统中的数据:
async function purgeCustomer(customerId: string, reason: 'gdpr_request' | 'inactivity') {
// 1. Anonymize orders (keep for tax, remove PII)
await anonymizeOrdersForCustomer(customerId);
// 2. Delete from email platform (Klaviyo, Mailchimp)
await emailPlatform.deleteContact(customerId);
// 3. Delete from search index (Algolia, Elasticsearch)
await searchIndex.deleteCustomer(customerId);
// 4. Delete analytics identifier
await analytics.deleteUser(customerId);
// 5. Delete the customer profile
await db.customers.anonymize(customerId);
// 6. Log for compliance evidence
await db.retentionAuditLog.insert({ action: 'customer_purged', customerId, reason, executedAt: new Date() });
}
最佳实践
- 实施前先做好文档记录 — 法务、合规和工程团队必须就保留计划达成一致;工程团队单方面做出的决定会造成合规漏洞
- 匿名化财务记录,绝不删除 — 订单必须保留至税务法定期限;将 PII 字段替换为匿名化占位符
- 单独保留只追加的保留审计日志 — 这是向合规审计人员提供的证据;绝不要删除此日志中的内容
- 在非高峰时段分批少量运行清除任务 — 使用
SELECT ... LIMIT n分批处理,避免锁定表并影响实时流量 - 将跨服务删除作为检查清单处理 — 涉及多个服务(数据库、电子邮件平台、分析系统)的清除操作必须可靠;分别记录每个系统的完成情况
- 在 30 天内响应 GDPR 删除请求 — 构建带提醒和升级机制的自动化工作流;跟踪所有请求及其截止日期
常见问题
| 问题 | 解决方案 |
|---|---|
| 保留任务锁定了生产表 | 使用较小的批次(500–5000 行),为每条 DELETE/UPDATE 添加 LIMIT,并在流量较低时运行 |
| 清除了存在未解决争议或待处理订单的客户数据 | 清除前检查是否存在待处理的拒付、未完成订单和有效订阅;实现法律保留机制 |
| 忘记搜索索引和分析数据仓库 | 维护所有存储个人数据的系统清单;将每个系统纳入每个删除工作流 |
| 未在 30 天内完成 GDPR 删除请求 | 构建带有 30 天截止日期跟踪器的自动化工作流;如果截止日期前 5 天仍未完成,则升级给人工处理 |
| 备份系统中保留了超出保留期限的数据 | 标记已清除客户的 ID,以便在灾难恢复时还原备份后立即重新清除这些记录 |
相关技能
- @gdpr-ecommerce
- @account-security
- @financial-audit-trail
- @financial-compliance-sox