Overview
Asset documents (invoices, warranties, manuals) and images need to be stored in cloud object storage. @aws-sdk/client-s3 and multer are installed but no upload service exists. This is a dependency for asset document management (BE-25) and user avatar uploads (BE-16).
Context
package.json has @aws-sdk/client-s3@3.975.0 and multer@2.0.2
backend/.env.example does not yet have S3 env vars — they need to be added
- Uploaded files must be stored under unique UUID-based keys, never original filenames (prevents path traversal)
- Files must not be publicly accessible by default — use pre-signed URLs for retrieval
Acceptance Criteria
Overview
Asset documents (invoices, warranties, manuals) and images need to be stored in cloud object storage.
@aws-sdk/client-s3andmulterare installed but no upload service exists. This is a dependency for asset document management (BE-25) and user avatar uploads (BE-16).Context
package.jsonhas@aws-sdk/client-s3@3.975.0andmulter@2.0.2backend/.env.exampledoes not yet have S3 env vars — they need to be addedAcceptance Criteria
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION,AWS_S3_BUCKETtobackend/.env.examplesrc/file/file.service.tswithupload(file: Express.Multer.File, folder: string): Promise<string>returning the S3 object keyfile.service.tsmethodgetPresignedUrl(key: string, expiresInSeconds: number): Promise<string>file.service.tsmethoddelete(key: string): Promise<void>image/jpeg,image/png,image/webp,application/pdfand enforces a 10MB max file sizeFileModuleinAppModuleand exportFileServicefor use by other modules