Appearance
Bulk Upload Presigned URLs
Summary
POST /documents/upload-bulk prepares direct-upload form posts for multiple files in a single request. The handler validates every requested file first, then generates presigned uploads, reserves storage only for the files that received a presigned form successfully, and finally persists document rows for those successful items.
Business Rules
- The request is rejected when any file has an invalid route type, invalid content type, or exceeds the configured route max file size.
- Presigned upload generation is attempted for every validated file before any storage quota is reserved.
- Only files that receive a valid presigned form count toward storage reservation and document creation.
- The fallback storage limit currently uses a mocked plan value in the command until the Plans module becomes the source of truth for per-organization quotas.
- If every presign attempt fails, the endpoint returns
STORAGE.PRESIGN_OPERATION_FAILEDand does not reserve storage or create documents. - Storage usage increment and document persistence happen inside the same transaction so quota reservations roll back automatically if document registration fails.
API Contract
- Endpoint:
POST /documents/upload-bulk - Request body:
BulkUploadDocumentDtofrompackages/schemas/src/storage/bulk-upload-document.schema.ts - Response body:
BulkUploadDocumentResponseDto resultsincludes only successful uploads.- Each successful result now includes
index, which matches the file position in the original request array. - Frontend consumers should treat missing indexes as per-file presign failures.
Failure Modes
- When the successful presigned files would exceed the org quota, the command returns
STORAGE.QUOTA_EXCEEDEDeven if some presigns were generated already. - Failed presign attempts are omitted from the response instead of aborting the whole batch, unless every presign fails.
- If the storage stats row does not exist yet for the org, the command creates it inside the same transaction before reserving usage.
Change Log
- 2026-03-27: Changed bulk upload reservation to happen after presign generation, removed the env-based fallback from this flow, and added per-item request indexes to successful results.