feat: implement storage quota management for uploads

- Added storage quota enforcement for audio and image uploads in the respective routes.
- Introduced reservation system to manage concurrent uploads and prevent quota overages.
- Enhanced comment creation to account for audio and image attachment sizes against user quotas.
- Created new UploadReservation model to track in-flight upload reservations.
- Backfilled existing video assets with size information from R2.
- Added progress component for UI feedback during uploads.
- Updated API responses to include reservation IDs for better quota management.
- Adjusted error handling to return appropriate storage limit exceeded messages.
This commit is contained in:
Yusuf İpek
2026-04-15 19:53:43 +03:00
parent acf31b3d6b
commit 873945464d
21 changed files with 753 additions and 85 deletions
@@ -14,6 +14,7 @@ import { isBunnyUploadsFeatureEnabled } from '@/lib/feature-flags';
import { getShareSessionFromRequest } from '@/lib/share-session';
import { getVideoAssetAccessContext, SAFE_BUNNY_VIDEO_ID } from '@/lib/video-assets';
import { logError } from '@/lib/logger';
import { enforceStorageQuota } from '@/lib/storage-quota';
type RouteParams = { params: Promise<{ videoId: string }> };
@@ -36,6 +37,10 @@ export async function POST(request: NextRequest, { params }: RouteParams) {
return apiErrors.badRequest('Direct uploads are disabled by this host');
}
const billedUserId = context.video.project.workspace.ownerId;
const quotaError = await enforceStorageQuota(billedUserId, BigInt(0));
if (quotaError) return quotaError;
const shareSession = getShareSessionFromRequest(request, context.video.id);
if (!context.viewerUserId) {
const quotaError = await enforceGuestUploadQuota(request, context.video.id, 'bunny', shareSession?.token ?? null);