data-retention-policies について
EC チーム向けに、ストアのデータ保持、アーカイブ、削除の計画を支援するスキルです。GDPR の請求対応、財務記録に含まれる個人情報の匿名化、複数システムにまたがる削除の追跡を扱います。
主な機能
- 01データ保持スケジュールの作成
- 02Shopify、WooCommerce、BigCommerce の設定案内
- 03注文に含まれる個人情報の匿名化
- 04複数サービスの削除と監査ログの追跡
- 05バッチによる定期クリーンアップの計画
活用シーン
- 01データ保護監査や SOC 2 評価の準備
- 02GDPR のデータ開示・削除請求への対応
- 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詳細
データ保持ポリシー
概要
データ保持ポリシーでは、各カテゴリのデータをどのくらいの期間保持するか、いつアーカイブするか、いつ消去するかを定めます。EC ストアでは、法的義務(税務記録は通常 5~7 年間の保持が必要)とプライバシー規制(GDPR のデータ最小化の原則では、不要になったデータの削除が求められます)のバランスを取る必要があります。適切な方法はプラットフォームによって異なります。Shopify では一部の保持処理が自動で行われますが、WooCommerce/カスタムストアでは明示的な実装が必要です。
このスキルを使用する場面
- 新規または既存の EC プラットフォームに GDPR のデータ最小化要件を実装するとき
- 法務チームまたはコンプライアンスチームから、文書化されたデータ保持ポリシーを求められたとき
- データ保護監査または SOC 2 Type II 評価に備えるとき
- データが無制限に蓄積され、ストレージコストが増加しているとき
- 顧客からデータ主体アクセス請求が提出され、顧客のデータがどこに保存されているかを正確に把握する必要があるとき
基本手順
ステップ 1:まず保持スケジュールを文書化する
ツールを設定する前に、保持スケジュールを文書化してください。実装前に、法務、コンプライアンス、エンジニアリングの各チームが合意する必要があります。この処理活動記録(RoPA)は、大規模なデータ処理者には GDPR 第 30 条に基づき義務付けられており、すべての組織に推奨されています。
| データカテゴリ | 保持期間 | 期間経過後の対応 | 法的根拠 |
|---|---|---|---|
| 注文(財務記録) | 7 年 | 個人を特定できる情報を匿名化し、財務データは保持 | 税法(米国 IRS、EU VAT) |
| 請求書 | 7 年 | コールドストレージにアーカイブ | 税務コンプライアンス |
| 顧客アカウント | 最終利用から 3 年 | 削除 | 正当な利益 |
| セッション/ログインログ | 90 日 | 削除 | 正当な利益 |
| マーケティングメールへの同意 | 配信停止まで | 配信停止時に削除 | GDPR に基づく同意 |
| 放棄されたカートのデータ | 30 日 | 削除 | 正当な利益 |
| 不正利用/セキュリティログ | 90 日 | 匿名化 | 正当な利益 |
| 分析イベント | 13 か月 | 集計後に削除 | 正当な利益 |
重要な原則:法律で保持が義務付けられているデータは決して削除しないでください。注文については、財務記録(金額、税額、決済手段のブランド名/下 4 桁)を保持したまま、顧客の個人を特定できる情報(氏名、メールアドレス、住所)を匿名化します。
ステップ 2:プラットフォームごとの保持設定
Shopify
Shopify ストアでは、デフォルトで注文データが無期限に保持され、インフラストラクチャコンポーネントのプラットフォームレベルのデータ保持は Shopify が処理します。
顧客データのエクスポートと削除(GDPR 準拠): Shopify には GDPR 用の Webhook が組み込まれています。
- 設定 → 顧客 → 顧客のプライバシーに移動します
- 顧客が自身のデータまたは削除を請求すると、Shopify はインストール済みのアプリに
customers/data_requestおよびcustomers/redactWebhook を自動送信します - 独自のアプリまたはカスタムコードでは、これらのイベント用の Webhook ハンドラーを登録します
顧客データの手動匿名化:
- 顧客レコードを開き、その他の操作 → この顧客を匿名化を選択します
- Shopify は注文記録を保持したまま、個人を特定できる情報を匿名化されたプレースホルダーに置き換えます
- この操作は取り消せません。実行前に確認してください
メールリストの自動整理: Klaviyo(または利用中のメールプロバイダー)を使用して、12 か月以上メールを開封していない連絡先を自動的に配信停止または削除します。ほとんどのメールプロバイダーには「サンセット」自動化機能が組み込まれています。
アーカイブ用のデータエクスポート:
- 顧客 → エクスポートに移動し、顧客データを CSV としてダウンロードしてアーカイブします
- 注文については、注文 → エクスポートを選択します
- エクスポートデータは、暗号化されたコールドストレージ(例:Glacier ライフサイクルポリシーを設定した AWS S3)に保存します
WooCommerce
WooCommerce はデータ保持を自動的に適用しません。プラグインとスケジュールタスクを使って設定する必要があります。
WooCommerce に組み込まれているクリーンアップ:
- WooCommerce → Status → Tools に移動します
- Clean up WooCommerce sessions を使って期限切れのセッションデータを削除します
- WooCommerce tracker cleanup を使ってトラッキングデータを消去します
GDPR/データ保持プラグイン: WP GDPR Compliance または GDPR Cookie Consent(WebToffee 製)をインストールします。
- WP GDPR Compliance → Settings → Data Retention に移動します
- データの種類ごとに保持期間を設定します
- プラグインによって、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 を匿名化します。注文に「Anonymize」アクションを追加する WooCommerce GDPR(WebToffee 製)をインストールします。
BigCommerce
BigCommerce では、管理パネルで顧客データ管理ツールを利用できます。
顧客データのエクスポート:
- Customers → Export → All Customers(CSV)に移動します
- 顧客アカウントを削除する前のアーカイブに使用します
顧客の削除:
- Customers → 顧客を検索 → Delete に移動します
- 顧客アカウントを削除しても、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によるバッチ処理を使い、ライブトラフィックに影響するテーブルロックを避けます - サービスをまたいだ削除はチェックリストとして管理する — 複数のサービス(データベース、メールプラットフォーム、分析など)にまたがるパージでは、障害に強い処理が必要です。システムごとに完了を記録します
- GDPR の削除リクエストには 30 日以内に対応する — リマインダーとエスカレーションを備えた自動ワークフローを構築します。期限を設定して、すべてのリクエストを追跡します
よくある落とし穴
| 問題 | 解決策 |
|---|---|
| 保持ジョブによって本番テーブルがロックされる | バッチサイズを小さく(500~5000 行)し、すべての DELETE/UPDATE に LIMIT を追加して、トラフィックの少ない時間帯に実行します |
| 保留中の異議申し立てや注文がある顧客をパージしてしまう | パージの前に、保留中のチャージバック、未完了の注文、アクティブなサブスクリプションがないか確認します。リーガルホールドの仕組みを実装します |
| 検索インデックスや分析ウェアハウスを忘れてしまう | 個人データを保存するすべてのシステムの一覧を管理し、削除ワークフローの対象にそれぞれ含めます |
| GDPR の削除リクエストが 30 日以内に完了しない | 30 日の期限を追跡する自動ワークフローを構築します。期限の 5 日前になっても完了していない場合は、人にエスカレーションします |
| バックアップシステムに保持期間を過ぎたデータが含まれている | パージした顧客 ID にフラグを付け、災害復旧のためにバックアップを復元した場合は、該当レコードをただちに再パージします |
関連スキル
- @gdpr-ecommerce
- @account-security
- @financial-audit-trail
- @financial-compliance-sox