非公開ファイルのアップロード
ポリシー、エンタイトルメント、容量上限、チェックサム、永続削除を備えた S3 互換の非公開アップロードを設定します。
スターターのコミット
2a1a04aと同期済みです。
アバター、文書、インポート、生成物を公開せず、すべてのバイトを Next.js サーバー経由にもしたくない場合に使います。完了後は、ログインしたユーザーが アカウント → ファイル でアップロード、ダウンロード、削除でき、別の組織からはアクセスできない状態になります。
製品に合うストレージ方針を選ぶ
- Docker Compose は保守されている open-source Garage を local default として private bucket を作成します。本番では Cloudflare R2 や AWS S3 が一般的です。自社運用の
minioも対応しますが、同梱 default ではありません。全 provider は同じ adapter を使います。 - 混在ファイルは
general、画像のみ(方針上限 10 MB)はimages、文書はdocuments、ブラウザに SHA-256 を必須にするならverifiedを選びます。 - 実際の上限は、プラン、
STORAGE_MAX_UPLOAD_MB、ポリシーのうち最も小さい値です。バケットは非公開のままにし、短時間だけ有効な署名付き URL で配信します。
本番準備完了の条件: UI の一連の操作が成功し、CORS は運用するオリジンだけを許可し、直接の公開 URL では取得できず、組織をまたぐアクセスが拒否され、削除対象のオブジェクトを cron が最終的に消去します。
STORAGE_PROVIDER を garage、s3、r2、minio から選び、bucket、region、endpoint、credentials を設定します。Object は private で、browser は短時間 signed URL だけを受け取ります。Image example も同じ private file lifecycle を使います。
アップロードの契約
POST /api/storage/uploadsは、組織、storage.upload、ポリシー(general、images、documents、verified)、種類、プラン・環境・ポリシーのうち最小のサイズ上限を検証し、容量を原子的に予約します。- ブラウザーはオブジェクトストレージへ直接 PUT し、XHR は進捗表示のためだけに使います。
POST /api/storage/uploads/completeがメタデータと任意の SHA-256 を確認して、状態をactiveにします。GET /api/storage/files/[uuid]?download=1が組織限定の署名 URL を返します。DELETE /api/storage/files/[uuid]が論理削除し、永続的なstorage_object_deleteジョブを登録します。
未完了のアップロードは一時間後に容量予約を解放します。削除はキューで再試行するため、cron が必要です。オブジェクトキーはサービスが生成し、クライアントには選ばせません。
一連の処理、不正な MIME タイプとチェックサム、容量予約の競合、期限切れ URL、組織をまたぐアクセス、削除の再試行、後片付けをテストします。削除などの非同期処理を動かす方法は永続ジョブと稼働準備、CORS の詳細はスターターの docs/storage-providers.md を参照してください。