データの削除、移行、バックアップと復元
対象読者:プロジェクト開発者とローカル運用者。
現在の 0.4 Alpha は G4 の現行データをそのまま更新します。旧 Alpha reset を再実行しないでください。旧アカウント、旧 JWT、SDK v1/v2 キューは復元しません。archived は引き続きフィードバックの処理状態です。
開発者の操作
プロジェクトの有効な owner/admin はフィードバックの削除とプロジェクト閉鎖ができます。組織と所属プロジェクト全体の閉鎖は組織 owner のみです。Console の詳細、プロジェクト概要/設定、組織設定で操作を選び、表示された対象 ID を正確に入力します。サーバーが現在のアカウント、session、membership を検証します。Project Key に管理用の読取/削除/移行権限はなく、system_admin にもテナント認可の例外はありません。
確認後は新しい閲覧、アップロード、署名 URL 発行を停止します。閉鎖時は対象 Key と membership も無効になります。他の組織/プロジェクトと G4 の匿名履歴参照は保持します。受領記録の pending、failed、completed はアクセス停止と物理削除を区別し、元の要求アカウントだけが閲覧できます。Console リンクを保管し、保守後に更新してください。タイムアウトは未確認です。同じ対象で再試行します。オブジェクト削除を確認してからメタデータを消去します。取得済みコピーは回収できず、旧 signed URL は元の期限か物理削除まで使える場合があります。
現在のプロジェクトメンバーは「プロジェクトデータをエクスポート」を利用できます。完全な ZIP は閲覧可能なフィードバック、コメント、実際の添付、サイズと SHA-256 を記載した manifest.json を含みます。Viewer の連絡先はサーバーで除外します。アカウント記録、パスワード/hash、token、Project Key、招待、signed URL は含めません。上限は 1000 件と未圧縮 128 MiB。超過や不完全な場合は全体を失敗させます。コピーは私密に保管し、一覧を検証し、不要になったら削除してください。
保持期限と保守
フィードバック、コメント、添付は報告の received_at から正確に 90 日で期限切れになります。追加や再試行で延長しません。完全なバックアップは 7 日、機微情報を除いた監査と完了済み受領記録の要求者関連付けは 180 日です。SDK ローカルは別の 7 日規則を維持します。保守実行前でも期限切れの閲覧を拒否します。
Infra で scripts/data-maintenance.sh --action inspect からデプロイ ID を取得し、同じ ID を明示します。--apply がない場合はプレビューです。
最小例
./scripts/data-maintenance.sh --action cleanup --deployment-id "$deployment_id" --batch 50
./scripts/data-maintenance.sh --action cleanup --deployment-id "$deployment_id" --batch 50 --apply
./scripts/data-maintenance.sh --action reconcile --deployment-id "$deployment_id"
1 回のオブジェクト/報告予算は 1–100 で、期限切れ・補助記録は別の有限バッチで処理し、pending が残れば繰り返します。失敗時は非ゼロ終了とし参照を保持します。未確定アップロードの意図は 1 時間の待機後に清掃します。補償で既に消えたオブジェクト参照も対象です。不明なオブジェクトは摘要だけ報告し、似たプレフィックスでは削除しません。bucket は私有かつ非バージョン化で、固有ストレージマーカーが DB と一致する必要があります。遅延再送を拒否する最小 UUID/クライアント ID 摘要はデプロイ存続中保持しますが、本文や連絡先は保持しません。session/code の期限と発行予算も守ります。
運用者のバックアップと隔離復元
通常の dev-apps-up.sh は migration 後に独立した recovery-journal と recovery-witness volume を初期化/確認します。確認済み制限操作は独立して永続化されています。両 authority を DB/オブジェクトのバックアップに入れないでください。欠損、古い記録、破損、未完了は両 API を閉じたままにします。中断した操作を --action reconcile-recovery --deployment-id "$deployment_id" --apply で照合できるのは元の権威 DB だけです。
Infra から私有ルートで実行します。
python3 scripts/backup-local.py --root "$PWD/.backups"
python3 scripts/backup-local.py --root "$PWD/.backups" --apply
export DATA_BACKUP_ROOT="$PWD/.backups"
./scripts/data-maintenance.sh --action prune-backups --deployment-id "$deployment_id" --output /backup-data --batch 20
./scripts/data-maintenance.sh --action prune-backups --deployment-id "$deployment_id" --output /backup-data --batch 20 --apply
ソースを停止し、実際の pg_dump と登録済みオブジェクトを取得し、全 checksum と独立 catalog への manifest 登録を確認してからソースを再開します。最近の未確定アップロード、不明オブジェクト、受領済み添付の欠損は完了を妨げます。部分ディレクトリはバックアップではありません。機微な DB/オブジェクトを含むためディレクトリ 0700、ファイル 0600 を維持し、返されたパスと manifest hash を記録します。
完全で期限内の backup_name を選び、現在のソース project/environment のまま検証し、ソースを凍結した最新 cutover seal を取得します。
./scripts/data-maintenance.sh --action verify-backup --deployment-id "$deployment_id" --output "/backup-data/$backup_name"
umask 077
mkdir -p .restore-control
export DATA_CONTROL_ROOT="$PWD/.restore-control"
./scripts/data-maintenance.sh --action begin-cutover --deployment-id "$deployment_id" --apply > "$DATA_CONTROL_ROOT/cutover.json"
別の空のローカル Compose project、私有 bucket、環境ファイル、競合しないポートと資格情報を用意します。復元前に対象の migration、seed、API を動かしません。ソースや既存業務 DB を上書きしないでください。変数はこの空の対象を示し、source_project は凍結中の元ソースです。
docker compose --file docker-compose.yml --env-file "$restore_env" --project-name "$restore_project" up -d postgres minio
docker compose --file docker-compose.yml --env-file "$restore_env" --project-name "$restore_project" run --rm --no-deps minio-init
export RECOVERY_AUTHORITY_PROJECT="$source_project"
python3 scripts/restore-local.py --backup "$DATA_BACKUP_ROOT/$backup_name" --seal "$DATA_CONTROL_ROOT/cutover.json" --target-project "$restore_project" --target-env "$restore_env" --authority-project "$source_project"
python3 scripts/restore-local.py --backup "$DATA_BACKUP_ROOT/$backup_name" --seal "$DATA_CONTROL_ROOT/cutover.json" --target-project "$restore_project" --target-env "$restore_env" --authority-project "$source_project" --apply
空の対象に検証済み bytes を戻し、最新の削除/アカウント/Key/member/SDK gate の事実を適用し、削除済み・期限切れオブジェクトを物理清掃してから開放します。失敗時は隔離を維持し、同じバックアップと seal で再試行します。completed 後だけ対象 API を起動し、RECOVERY_AUTHORITY_PROJECT を保持して dev-apps-up.sh が外部 authority override を利用するようにします。元ソースに down -v を実行すると引き継いだ authority を消してしまいます。元ソースは停止を維持し、旧データ廃止や authority 移設は運用者が範囲を確認して行います。
復元した session、code、pending 招待は無効で、存続アカウントは既存のメール再設定フローで新しいパスワードを設定してからログインします。削除/無効化されたアカウントは拒否し、個人削除に巻き込んで共有 Key を失効させません。失効 Key と閉鎖スコープは復活しません。復元点後の内容・受領メタデータは失われ得ます。独立保持は明示した校正事実だけです。不足する owner 身元を作らず、十分新しいバックアップを使います。
python3 scripts/check-g5-data.py --recovery は合成データによる実際の PG/MinIO 往復と失敗門禁です。本番 RPO/RTO、災害耐久性、SLA の証明ではありません。実際の独立保存先、周期、監視、資格情報、メール配送と復旧目標は G6 で決めます。
dump の書き込み前に独立 catalog が未完了バックアップを登録します。prune-backups はこれも元の 7 日期限で削除し、再試行で延長しません。ソース再開後、正確な deployment ID と --action discard-backup --output "/backup-data/$backup_name" --apply で指定した未完了コピーを削除できます。承認済みバックアップや未知ファイルは拒否します。プロセス終了後は recovery-status を確認し、正確なソース nonce だけで resume-source --fence-id "$fence_id" --apply を実行します。帰属を確認できなければ停止を維持します。
復元スクリプトは pg_restore 前に独立承認と全ファイルを検証し、稼働中の対象 API と対応するチェックポイントのない非空 DB を拒否します。seal ディレクトリに私密チェックポイントを保存し、中断したインポートは同じ最初は空だった DB と不変の backup/seal/環境だけで再実行します。校正開始後は古い dump を再インポートしません。環境・制御ファイルは 0600、制御ディレクトリは 0700 にします。成功後も API は停止したままで、運用者が外部 authority を指定して起動します。
よくある間違い
PostgreSQL dump だけでは完全なバックアップではありません。旧ログと旧 DB の組合せは最新 authority の証拠ではありません。S3 失敗を完了と扱わず、ソース bucket を復元先に使わず、復元の門禁を手動で解除しません。
次のステップ
アカウント復旧を確認し、隔離検証を先に実行してください。本番運用の約束は G6 の範囲です。