Files
OpenFrame/app/api/settings/storage/route.ts
T
Yusuf İpek 873945464d 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.
2026-04-15 19:53:43 +03:00

41 lines
1.2 KiB
TypeScript

import { auth } from '@/lib/auth';
import { apiErrors, successResponse, withCacheControl } from '@/lib/api-response';
import { getUserStorageInfo } from '@/lib/storage-quota';
import { hasBillingAccess } from '@/lib/billing';
import { db } from '@/lib/db';
// GET /api/settings/storage
export async function GET() {
const session = await auth();
if (!session?.user?.id) {
return apiErrors.unauthorized();
}
// Only users with active billing (or on a self-hosted instance where billing
// is disabled) should be able to enumerate their storage breakdown.
const user = await db.user.findUnique({
where: { id: session.user.id },
select: {
subscriptionStatus: true,
trialEndsAt: true,
stripeCurrentPeriodEnd: true,
billingAccessEndedAt: true,
},
});
if (!user || !hasBillingAccess(user)) {
return apiErrors.forbidden();
}
const info = await getUserStorageInfo(session.user.id);
const response = successResponse({
usedBytes: info.usedBytes.toString(),
limitBytes: info.limitBytes.toString(),
percentage: info.percentage,
});
// Cache for 60s — stale data is acceptable for a usage meter
return withCacheControl(response, 'private, max-age=60');
}