@@ -9,7 +9,6 @@ import { headers } from "next/headers";
99import { PutObjectCommand , GetObjectCommand } from "@aws-sdk/client-s3" ;
1010import { getSignedUrl } from "@aws-sdk/s3-request-presigner" ;
1111
12- // Helper to map MIME type to AttachmentType enum
1312function mapFileTypeToAttachmentType ( fileType : string ) : AttachmentType {
1413 const type = fileType . split ( "/" ) [ 0 ] ;
1514 switch ( type ) {
@@ -19,19 +18,17 @@ function mapFileTypeToAttachmentType(fileType: string): AttachmentType {
1918 return AttachmentType . video ;
2019 case "audio" :
2120 return AttachmentType . audio ;
22- // Add more specific checks if needed (e.g., application/pdf)
2321 case "application" :
2422 return AttachmentType . document ;
2523 default :
2624 return AttachmentType . other ;
2725 }
2826}
2927
30- // Update schema to include base64 file data
3128const uploadAttachmentSchema = z . object ( {
3229 fileName : z . string ( ) ,
3330 fileType : z . string ( ) ,
34- fileData : z . string ( ) , // Base64 encoded file content
31+ fileData : z . string ( ) ,
3532 entityId : z . string ( ) ,
3633 entityType : z . nativeEnum ( AttachmentEntityType ) ,
3734} ) ;
@@ -52,10 +49,8 @@ export const uploadFile = async (
5249 }
5350
5451 try {
55- // 1. Decode Base64 Data
5652 const fileBuffer = Buffer . from ( fileData , "base64" ) ;
5753
58- // --- Add file size check ---
5954 const MAX_FILE_SIZE_MB = 5 ;
6055 const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024 ;
6156 if ( fileBuffer . length > MAX_FILE_SIZE_BYTES ) {
@@ -65,51 +60,45 @@ export const uploadFile = async (
6560 data : null ,
6661 } ;
6762 }
68- // --- End file size check ---
6963
70- // 2. Prepare S3 Key
7164 const timestamp = Date . now ( ) ;
7265 const sanitizedFileName = fileName . replace ( / [ ^ a - z A - Z 0 - 9 . - ] / g, "_" ) ;
7366 const key = `${ organizationId } /attachments/${ entityType } /${ entityId } /${ timestamp } -${ sanitizedFileName } ` ;
7467
75- // 3. Upload directly to S3 using shared client and bucket name
7668 const putCommand = new PutObjectCommand ( {
7769 Bucket : BUCKET_NAME ,
7870 Key : key ,
7971 Body : fileBuffer ,
8072 ContentType : fileType ,
8173 } ) ;
82- await s3Client . send ( putCommand ) ;
8374
84- // 4. S3 Key is now stored in the DB. No need to construct full public URL here.
75+ await s3Client . send ( putCommand ) ;
8576
86- // 5. Create Attachment Record in DB
8777 const attachment = await db . attachment . create ( {
8878 data : {
8979 name : fileName ,
90- url : key , // Store the S3 key in the 'url' field
80+ url : key ,
9181 type : mapFileTypeToAttachmentType ( fileType ) ,
9282 entityId : entityId ,
9383 entityType : entityType ,
9484 organizationId : organizationId ,
9585 } ,
9686 } ) ;
9787
98- // 6. Generate Pre-signed URL for immediate access
9988 const getCommand = new GetObjectCommand ( {
10089 Bucket : BUCKET_NAME ,
10190 Key : key ,
10291 } ) ;
92+
10393 const signedUrl = await getSignedUrl ( s3Client , getCommand , {
104- expiresIn : 900 , // Expires in 15 minutes
94+ expiresIn : 900 ,
10595 } ) ;
10696
107- // 7. Return Success with Attachment Info AND Signed URL
10897 return {
10998 success : true ,
11099 data : {
111- ...attachment , // Include all DB record fields
112- signedUrl : signedUrl , // Add the temporary signed URL
100+ ...attachment ,
101+ signedUrl,
113102 } ,
114103 error : null ,
115104 } as const ;
0 commit comments