大規模なファイルアップロード:バリデーション、保存、アクセス
大規模なファイルアップロードでは、明確なバリデーション、整った保存パス、期限付きダウンロードリンク、強力な権限設定がユーザーファイルを守ります。

大規模なユーザーアップロードが難しい理由
少人数でテストするとアップロードは簡単に見えますが、実際のユーザーが本物のファイルを送ってくると難しくなります:大きな写真、スキャンしたPDF、拡張子が間違っている謎のドキュメント。そうなると、アップロードはフォームのボタンだけで済む話ではなく、安全性と運用の問題になります。
最初に表面化する問題は大抵、セキュリティ、コスト、プライバシーの三点です。攻撃者がマルウェアをアップロードしようとし、ユーザーはアプリで開けないファイルを置き、チームが誤って公開URLで機密文書をさらしてしまうことがあります。ストレージ費は増え、同じファイルが何度もダウンロードされると帯域も膨らみます。
画像とPDFは異なる問題を生みます。画像は巨大になり得るし多くのフォーマットがあり、位置情報のような隠れたメタデータを含むことがあります。サムネイルやリサイズを用意してアプリの速度を保つ必要があります。PDFは安全にプレビューするのが面倒で、埋め込みコンテンツを含むことがあり、請求書や身分証、契約書などの機密記録が含まれることが多く、広くアクセス可能にすべきではありません。
スケールでは、同時にアップロードするユーザーが増え、ファイルが大きくなり総ストレージも増え、ダウンロードや再試行が増え、チームや役割、保持ルールが複雑になります。
目標は「アップロードが動くこと」ではありません。目標は数ヶ月後でも管理が容易な安全なアップロードです:明確なルール、予測可能なストレージパス、監査に適したメタデータ、そしてビジネスが実際にファイルを共有するやり方に合ったアクセスコントロールです。
ファイル種類と誰がアクセスするかをマップする
ストレージやセキュリティを調整する前に、ユーザーが何をアップロードし、誰がそれを見られるかを明確にしてください。スケールでの多くのアップロード問題は実際にはストレージ問題ではなく、アクセス、保持、リスクに関する期待のミスマッチです。
実際のファイルカテゴリをリストアップすることから始めます。単に "ドキュメント" や "画像" とざっくり分けるのではなく、アバターは契約PDFとは全く挙動が違いますし、サポートのスクリーンショットは月次レポートとは異なります。
実務的な方法の一つは、各カテゴリをアクセスパターンに結び付けることです:
- アバターや公開プロファイル画像は多くの人が読み取り可能で、編集は所有者のみ。
- 領収書や請求書はデフォルトでプライベート、会計担当やアカウント所有者のみ共有。
- 契約書やコンプライアンス関連は厳密に制限され、監査ログや厳しい保持ルールが必要。
- レポートやエクスポートはチーム内で共有できるが、適切なワークスペースや顧客に限定する。
- チケット添付は通常チケットの参加者のみがプライベートにアクセスでき、時限的にすることもある。
次に簡単なリスクのスナップショットを取りましょう。アップロードはマルウェアを隠すことがあり、身分証や銀行情報、医療情報などの機密データを漏らす可能性がありますし、URLを推測するだけでアクセスできる壊れた権限が存在するかもしれません。だからファイルアップロードはバイト管理だけでなくアクセス制御の問題でもあるのです。
パフォーマンスも重要です。大きなPDF、高解像度画像、脆弱なモバイル回線は部分的なアップロードや再試行を引き起こします。どのアップロードを確実に成功させる必要があるか(請求書、身分証など)と、どれが任意か(プロフィールバナーなど)を事前に決めてください。
各ファイルタイプについて、後で作り直す必要がないように早期にいくつかの質問に答えておきます:
- 誰がアップロード、閲覧、置換、削除できるか?
- プライベートか、グループ内で共有か、公開か?
- アクセスは期限付きか、即時取り消し可能か?
- アップロードが中断されて再試行されたらどうするか?
- どのくらい保持し、誰がエクスポートできるか?
AppMasterのようなツールで構築する場合は、これらの答えをまずプロダクトルールとして扱い、その後データモデルとエンドポイントに実装して、Webとモバイルで権限が一貫するようにしてください。
早期に問題を防ぐファイルアップロードのバリデーションルール
大規模なファイルアップロードを安全で予測可能に保ちたいなら、バリデーションが最初の防衛線です。良いルールは悪いファイルがストレージに到達する前に止め、ユーザーに明確なフィードバックを返すことでサポートチケットを減らします。
ブロックリストではなく許可リストから始めてください。ファイル名の拡張子をチェックし、アップロードされたコンテンツから得られるMIMEタイプも検証します。拡張子だけに頼るのは簡単にすり抜けられますし、MIMEだけに頼るのもデバイス間で一貫しないことがあります。
サイズ上限はファイルタイプとプロダクトルールに合わせるべきです。画像は5〜10MBが許容されることが多く、PDFはより高い上限が必要かもしれません。動画は別のパイプラインが必要になることが多いです。有料プランがあるなら上限をプランに紐づけて、「あなたのプランはPDFを最大10MBまで許可します」と具体的に伝えられるようにします。
一部のファイルはさらに深いチェックが必要です。画像では幅と高さ(場合によってはアスペクト比)を検証してページが巨大になるのを防ぎます。PDFではページ数が問題になることがあり、ユースケースが小さい範囲を期待しているなら検証してください。
アップロード時にファイル名をリネームしてください。ユーザー名には空白、絵文字、scan.pdfのような繰り返しが含まれることが多いです。生成されたIDと安全な拡張子を使い、表示用に元の名前をメタデータとして保存します。
多くのアプリで機能するバリデーションの基本ラインは次のとおりです:
- 許可リスト(拡張子+MIME)を使い、その他は拒否する。
- タイプごとに最大サイズを設定(必要ならプランごとにも)。
- 画像の寸法を検証し、極端なサイズは拒否する。
- ユースケースに応じてPDFのページ数を検証する。
- 安全で一意なファイル名にリネームし、元の名前はメタデータで保管する。
バリデーションが失敗したときは、ユーザーが対処できる明確なメッセージを一つ表示してください(例:「PDFは20MB以下かつ50ページ以内である必要があります」)。同時に管理者向けに技術的な詳細(検出したMIME、サイズ、ユーザーID、理由)をログに残します。AppMasterでは、これらのチェックをBusiness Processに置けば、すべてのアップロードパスが同じルールに従います。
アップロードとファイルメタデータのデータモデル
良いデータモデルがあればアップロードは退屈になります。目標は、誰がファイルを所有し、何のためで、安全に使えるかを追跡することです。特定のストレージベンダーに縛られないように設計してください。
信頼できるパターンは二段階フローです。まずデータベースにアップロードレコードを作成してアップロードIDを返します。次にそのIDを使ってバイナリをストレージにアップロードします。これにより、バケットに対応する行がない謎のファイルが残るのを防ぎ、バイト移動前に権限を強制できます。
シンプルな uploads テーブル(またはコレクション)があれば十分なことが多いです。AppMasterではこれはData DesignerのPostgreSQLモデルに自然に対応し、Webとモバイルで使えます。
後でサポートや監査に必要になるものを保存してください:
- 所有者参照(
user_id)とスコープ(org_idまたはteam_id) - 用途(avatar, invoice_pdf, ticket_attachment など)
- 元のファイル名、検出されたMIMEタイプ、
size_bytes - ストレージへの参照(バケット/コンテナ、
object_key)とチェックサム(任意) - タイムスタンプ(
created_at,uploaded_at)とアップロード元のIP/デバイス(任意)
状態モデルは小さく保って読みやすくするのが良いです。多くのプロダクトで次の四つの状態で十分です:
pending: レコードはあるがアップロード未完了uploaded: バイトが保存済みverified: チェックを通過して使用可能blocked: チェック失敗またはポリシー違反
最初からクリーンアップを計画してください。ユーザーがタブを閉じたり接続を失ったりすると未完成の pending が残ります。日次ジョブで期限切れの pending 行のストレージオブジェクトを削除し、キャンセルとしてマークして報告用に残し、古い blocked 項目は保持ウィンドウ後に削除し、verified ファイルはビジネスルールに従って保持します。
このモデルによって、複雑さを増やさずに追跡性と制御が得られます。
長期的に整頓されたままのストレージの組織
ファイルアップロードが大量になると、最大のリスクはコストではなく「混乱」です。チームがファイルが何で誰のものか、最新かどうかを判断できなければバグを出し、データを漏らします。
一貫したフォルダ戦略を選んで守ってください。多くのチームはテナント(会社)→用途→日付で整理します。別のチームはテナント→ユーザー→用途にします。正確な選択よりも一貫性が重要です。日付を入れるとディレクトリが無制限に大きくなるのを防ぎ、クリーンアップジョブが簡単になります。
パスやファイル名に個人データを埋め込まないでください。メールアドレス、フルネーム、請求番号、電話番号などは避け、ランダムIDを使ってください。意味のある検索が必要なら、それはオブジェクトキーではなくデータベースのメタデータに保存してください。
オリジナルと派生物を分けて保管するとルールが明確になります。オリジナルは一度だけ保存し、サムネイルやプレビューは別プレフィックスに置いて保持と権限を分けます。プレビューはオリジナルより広く許可できる場合があります。
シンプルで堅牢な命名アプローチの例:
- テナントID(またはワークスペースID)でパーティションする
- 用途プレフィックスを追加(avatars, invoices, attachments)
- タイムバケット(YYYY/MM)を追加
- ファイル名には不透明なファイルIDを使う
- 派生物は別プレフィックス(previews, thumbnails)に保存する
バージョン管理の扱いを決めてください。ユーザーがファイルを置換できるなら、同じオブジェクトキーを上書きする(シンプルで履歴なし)か、新しいバージョンを作って古いものを非アクティブにする(監査向け)かを選びます。多くのチームはコンプライアンス文書は履歴を残し、プロフィール画像は上書きすることが多いです。
命名ルールを書き残してください。AppMasterでは共有の規約としてプロジェクトドキュメントに置き、バックエンドロジック、UIビルダー、将来の統合が同じパスを生成するようにします。
権限とアクセス制御パターン
大規模なアップロードで権限は小さな抜け穴が大きな事故になる箇所です。拒否をデフォルトにすることから始めてください:アップロードされたファイルは明確に許可されるまではプライベートです。
二つの質問を分けて考えると役立ちます:レコードを見られるのは誰か、バイトを取得できるのは誰か。これらは同じではありません。多くのアプリは、メタデータ(ファイル名、サイズ、アップロード日)を見られるがダウンロードはできない、という扱いが適切です。
よくあるアクセスパターン
ファイルタイプごとに一つの主要パターンを選び、例外は慎重に追加してください:
- 所有者のみ:アップローダー(とサービスアカウント)のみダウンロード可能。
- チームベース:ワークスペース/プロジェクトのメンバーがダウンロード可能。
- 役割ベース:FinanceやHRのような役割がチームを超えてダウンロード可能。
- リンク共有:特別なトークンでダウンロードを許可、通常は有効期限とスコープ付き。
エッジケースにはワンオフの対応ではなく明確なルールが必要です。管理者の扱い(グローバルアクセスかカテゴリ限定か)、サポートが一時アクセスをどう得るか(時間制限かつログ記録)、ユーザー削除時の振る舞い(コンプライアンスで保持するか、所有権を再割当てするか、削除するか)を決めてください。
メタデータとダウンロードを別に扱う
シンプルなパターンは二段階チェックです:(1) ユーザーはアップロードレコードを読めるか、(2) ユーザーはダウンロードレスポンスを要求できるか。二つ目のチェックで「許可されるまではプライベート」を強制し、IDを推測されてもダウンロードできないようにします。
機密文書はアクセスをログに残してください。最低でも誰がダウンロードしたか(ユーザーIDと役割)、何をダウンロードしたか(ファイルIDとタイプ)、いつか(タイムスタンプ)、なぜ許可されたか(ポリシー結果、共有トークン、管理者オーバーライド)、どこから来たか(IPやデバイス)を記録します。
AppMasterでは、これらのルールはBusiness Process Editorに置かれることが多く、メタデータ一覧用のフローと、ダウンロード用のより厳しいフローを分けて管理します。
有効期限付きダウンロードリンク:摩擦なく安全な共有
有効期限付きダウンロードリンクは「URLを持っていれば誰でも永遠にダウンロードできる」方式と「毎回ログインが必要」の中間の良い選択です。メールでドキュメントを共有したり、外部の契約者に一時アクセスを与えるのに適しています。スケールでもサポート負荷を下げる利点があります。
二つの一般的パターン:
- 署名付きURLは自動で期限切れになります。シンプルで高速ですが、リンクが配布されると取り消しが難しい。
- トークンベースのダウンロードエンドポイントはより制御が利きます。リンクには短いトークンが含まれ、アプリが各リクエストで権限をチェックしてファイルを提供またはリダイレクトします。
実用的な設定:
- 共有リンクは短い有効期限(10〜60分)を使い、必要なら更新させる。
- 信頼されたログインセッションでは長めの有効期限を許容する(例:「再ダウンロード」生成で新しいリンクを発行)。
- リンクは厳密にスコープする:一つのファイル、一人のユーザー(または受取人)、一つのアクション(表示かダウンロードか)。
- リンクの作成と使用をログに残して、流出があった場合に追跡できるようにする。
スコープは重要です。表示はインライン表示を意味し、ダウンロードはコピー保存を意味します。両方が必要ならそれぞれ別のリンクとルールにしてください。
取り消しを計画しておくことも重要です。ユーザーのアクセスが失われた場合(返金、役割変更、契約終了)、署名付きURLだけでは不十分なことがあります。トークンエンドポイントならトークンを即時無効化できます。署名付きURLを使う場合は有効期限を短くし、署名キーをローテーションすることで全体を取り消せますが、キーのローテーションは慎重に行ってください(全てのリンクが取り消されるため)。
例:顧客ポータルで会計担当者にメール送付する請求書リンクは30分で期限切れ、表示のみ許可、請求書IDと顧客アカウントに結び付けます。顧客がアカウントから削除されたら、メールが転送されてもトークンは拒否されます。
ステップバイステップ:スケーラブルなアップロードフロー
信頼できるアップロードフローは「何を許可するか」「バイトをどこに置くか」「誰が後で取得できるか」を分離します。これらが混ざると小さなエッジケースが本番事故に発展します。
画像、PDF、ほとんどのユーザー生成ファイルに対する実用的なフロー:
- 用途ベースのルールを定義する。各用途(avatar, invoice, ID document)について許可タイプ、最大サイズ、最大ページ数のような追加チェックを決める。
- バックエンドでアップロードリクエストを作成する。クライアントがアップロードの許可を求める。バックエンドはアップロード先(オブジェクトストレージキー+短命トークンなど)を返し、
pendingの新しいアップロード行を作る。 - バイトをストレージにアップロードし、完了を確認する。クライアントはストレージへアップロードし、その後バックエンドに完了を通知する。バックエンドは期待されるキーと基本プロパティを確認して行を
uploadedにする。 - 非同期で検証を実行する。バックグラウンドで実際のファイルタイプを検証(理想的にはマジックバイトも含む)、サイズを強制、寸法やページ数など安全なメタデータを抽出し、必要ならマルウェアスキャンを実行する。失敗したら
blockedにしてダウンロードを防ぐ。 - ポリシーに従ってダウンロードを提供する。ダウンロード時にユーザーがファイルの所有実体(ユーザー、組織、チケット、注文)へのアクセス権を持っているかを確認する。その後プロキシで配信するか、ストレージをプライベートに保つために有効期限付きのダウンロードリンクを返す。
クリーンアップを追加する。放置された pending は短いウィンドウ後に削除し、参照されていないファイル(ユーザーが画像をアップロードしたがフォームを保存しなかったなど)を削除します。
AppMasterで構築する場合、アップロードをステータスフィールドと所有参照を持つ独立したエンティティとしてモデル化し、すべてのダウンロードBusiness Processで同じ権限チェックを強制します。
例:カスタマーポータルの請求書
ユーザーが請求書をPDFでアップロードするカスタマーポータルは、一見簡単ですが何千もの会社、複数の役割、同じ請求書が何度も置換される状況になると複雑になります。
ストレージ組織のために、検索のしやすさに合う予測可能なパスに生ファイルを置きます。例:invoices/<company_id>/<yyyy-mm>/<upload_id>.pdf。会社と月で分けるとクリーンアップやレポートがしやすく、upload_id は同名ファイルの衝突を回避します。
データベースでは、ファイルが何で誰がアクセスできるかを説明するメタデータを保存します:
company_idとbilling_monthuploaded_by_user_idとuploaded_atoriginal_filenameとcontent_typesize_bytesとチェックサム(任意)- ステータス(active, replaced, quarantined)
共有の場面:請求担当マネージャーが外部の会計士に請求書を24時間だけ送る場合、グローバルな権限を変える代わりにその請求書に結び付いた有効期限付きダウンロードリンクを生成します。厳格な有効期限と単一用途(ダウンロードのみ)を設定し、会計士がクリックしたらアプリがトークンを確認して期限内ならファイルを提供します。
ユーザーが間違ったPDFをアップロードしたりファイルを置換したら、古いオブジェクトを上書きしないでください。前のレコードを replaced にマークして監査用に保持し、請求書エントリは新しい upload_id を指すようにします。保持ルールを守る必要があれば、スケジュールジョブで置換されたファイルを後で削除できます。
サポートが「ダウンロードできない」というチケットを受けたとき、メタデータがあれば素早く診断できます:リンクが期限切れか、請求書が置換済みか、ユーザーが正しい会社に属しているか、ファイルが検疫中にフラグされているか。AppMasterではこれらのチェックをBusiness Processに置けば、すべてのダウンロードが同じルールに従います。
よくあるミスと回避方法
ファイルアップロードを初めてスケールで扱うチームのバグは、ほとんどが予測可能なショートカットから来ます。デモでは問題なく見えても後で困ることが多いです。
- 拡張子だけ、もしくはMIMEだけを信頼すること。拡張子は名前を変えれば済むし、ブラウザはMIMEを誤って送ることがある。両方をチェックし、さらにサーバー側でマジックバイトを検証する。
- パブリックなストレージに頼ること。公開バケットは小さなミスが即データ漏えいにつながる。デフォルトでプライベートにしてアプリ経由でアクセスを制御する。
- ユーザー提供の名前をストレージパスやURLに使うこと。invoice_john_smith.pdf のような名前は個人情報を漏らし、推測しやすくする。不透明なIDを使い、表示用の名前はメタデータに保存する。
- テナントファイルを同じパスに混ぜること。/uploads/2026/01/ のようなパスは権限モデルではない。ダウンロードを返す前に必ずテナントとユーザー権限を検証する。
- 失敗や放置されたアップロードのクリーンアップを怠ること。マルチパートアップロードや再試行はゴミを残しがち。未完のアップロードを削除するバックグラウンドジョブを追加する。
チームが忘れがちなもう一つのミスは再試行と重複に対する計画がないことです。モバイル回線は落ち、ユーザーは二度タップします。システムは「同じファイルを再度アップロードする」ことを普通として扱うようにしてください。
実用的なアプローチは、まずアップロードIDを生成し、そのIDに対してチャンクまたは単一ファイルを受け付け、検証が通るまでレコードを verified にしないことです。同じアップロードが繰り返されたら既存レコードを返して二重登録を避けます。
AppMasterで構築するなら、コアルールを一箇所に置き、バックエンドロジックに集約しておくことでUIが変わってもWebとモバイルが同じ動作をします。
出荷前のクイックチェックリスト
実際のユーザーに公開する前に基本を確認してください。大規模なファイルアップロードの問題の多くは、ユーザーやファイルが増えて初めて表面化する小さな抜け穴から来ます。
- 許可リストのファイルタイプとユースケースごとのサイズ制限を設定する(アバターと請求書で異なる)。拡張子と実際のコンテンツタイプの両方を検証する。
- 誰の所有物か(ユーザー、チーム、アカウント)、何の用途か、
pending/verified/blockedのような明確なステータスをデータベースに保存する。 - ストレージはデフォルトでプライベートにして、ダウンロードごとに権限チェックを強制する(隠しURLに頼らない)。
- 共有が必要な場合は有効期限付きダウンロードリンクを使い、寿命は短め(数分〜数時間)。
- パスやファイル名に個人データを入れない。ランダムIDを使い、UIではフレンドリーな表示名を出す。
放置されたアップロードに対する対処法を用意してください。ユーザーはアップロードを始めて完了しなかったり、頻繁にファイルを置換したりするのが普通です。
シンプルなクリーンアップ計画:
verifiedに達しなかった孤立したファイルを一定期間後に削除する。- 置換されたファイルは保持ウィンドウを設けた後に削除する。
- 主要イベント(アップロード、検証、ダウンロード、削除)をログに残し、サポートが調査できるようにする。
AppMasterを使う場合は、Data DesignerでPostgreSQLにメタデータを保存し、Business Process Editorでチェックを強制し、ファイル提供時に短命トークンを生成してください。
次の一手:安全に出荷してから少しずつ改善する
安全なリリースに最短で到達する方法は、一つのアップロードアプローチを選んで守ることです。ファイルをまずバックエンド経由にするか、短命トークンで直接オブジェクトストレージにアップロードさせるかを決めてください。次に正確な手順と各責任(クライアント、バックエンド、ストレージ)をドキュメント化します。スケールする際は一貫性が機知より重要です。
厳格なデフォルトから始めましょう。本当に必要なファイルタイプに限定し、サイズ制限は保守的に、公開すべきでないものには認証を要求します。ユーザーが大きなファイルや追加フォーマットを求めたら、ルールは一つずつ緩めて影響を測定してください。
早期に基本的なモニタリングを追加して問題が速く見つかるようにします:
- アップロード失敗率(デバイス、ブラウザ、ファイルタイプ別)
- 平均とp95のアップロードサイズ
- アップロード時間(特にモバイル回線)
- 日次・週次のストレージ増加量
- ダウンロードエラー(期限切れや禁止など)
このアップロードシステムが大きなアプリの一部なら、データモデルと権限をビジネスロジックの近くに置いてください。AppMasterを使うチームはしばしばアップロードレコードをPostgreSQLに入れ、Business Processesで検証とアクセス制御を実施し、同じロジックをバックエンド、Web、ネイティブモバイルで共有します。
次の改善案としては、一般的なフォーマットのプレビュー生成、機密文書向けの監査ログ、簡単な保持ルール(例:一時アップロードを30日で自動削除)などがあります。小さな改善を着実に積み重ねることで、利用が増えてもシステムの信頼性が保てます。
よくある質問
期待される実際のカテゴリを書き出すことから始めてください:アバター、請求書、契約書、チケット添付、エクスポートなど。各カテゴリについて、誰がアップロードできるか、誰が閲覧できるか、誰が置換/削除できるか、共有が期限付きか、保存期間はどれくらいかを決めます。これらの決定がデータベースモデルと権限チェックを駆動するため、後で全てを作り直す必要がなくなります。
許可リストを使い、ファイル名の拡張子とアップロードされたコンテンツから検出したMIMEタイプの両方をチェックします。用途ごとに明確なサイズ制限を設け、重要なところでは画像の寸法やPDFのページ数などの深いチェックを追加します。ファイル名は生成IDに置き換え、元の名前はメタデータとして保存して衝突や危険なファイル名を避けます。
拡張子は簡単に偽装できますし、MIMEタイプはデバイスやブラウザによって違うことがあります。両方をチェックすることで多くの明白ななりすましを防げますが、よりリスクの高いアップロードではサーバー側でファイルシグネチャ(マジックバイト)も検証すべきです。失敗したものはブロック扱いにし、レビューまたは削除までダウンロードさせないでください。
まずデータベースにレコードを作成してアップロードIDを返し、そのIDを使ってバイナリをアップロードさせる二段階の流れが有効です。これにより所有者や用途のない“謎のファイル”がバケットに残ることを防ぎ、バイトを移動させる前に権限を強制できます。また、放置されたpendingアップロードのクリーンアップも容易になります。
デフォルトでストレージをプライベートにし、アプリの権限ロジックを通してアクセスをゲートすること。オブジェクトキーはテナントやワークスペースIDと不透明なアップロードIDを組み合わせ、表示用の人間に優しい詳細はデータベースに保存します。オリジナルと派生物(サムネイルやプレビュー)は別プレフィックスにして保持と権限を分離すると管理が楽になります。
メタデータの閲覧権限とバイトのダウンロード権限を分けて考えてください。多くの場合、ユーザーはファイルが存在することを見られてもダウンロードは許可しないべきです。ダウンロードは拒否をデフォルトにして、許可が明確に与えられている場合だけ許可します。機密文書はダウンロードの記録を残すようにしてください(誰が、何を、いつ、どの理由で、どこから)。
署名付きURLはシンプルで高速ですが、一度共有されると取り消しが難しいです。トークンベースのダウンロードエンドポイントなら各リクエストで権限をチェックでき、トークンを無効化して即時にアクセスを取り消せます。実務上は短い有効期限とファイル単位・アクション単位の厳しいスコープがリスクを抑えます。
再試行は普通の挙動として設計してください:モバイルは回線が切れますし、ユーザーは二度タップすることもあります。まずアップロードIDを生成してから受け付け、完了確認ステップは冪等(idempotent)にして繰り返しても余計なコピーを作らないようにします。さらに重複を減らしたければ、アップロード後にチェックサムを保存して同一コンテンツの再アップロードを検出できます。
ユーザーがフォームを閉じたり接続が切れたりするとpendingアップロードが溜まるので開始日からクリーンアップを計画してください。古いpendingレコードとそのストレージオブジェクトを期限後に削除し、調査が必要なblocked項目は必要な期間だけ保持します。置換されたファイルは監査のために一定の保持期間を経てから自動削除すると良いでしょう。
PostgreSQLのエンティティとしてアップロードをモデル化し、ステータス、所有者、スコープ、用途フィールドを持たせます。ビジネスプロセスでルールを一箇所に置けばWebとモバイルで同じ振る舞いになります。検証と確認のステップをBusiness Processに入れ、ダウンロードはより厳しいプロセスで短命トークンを発行して提供するのが実践的です。


