const UnitOfWork = require('../../database/UnitOfWork'); const UserDocumentRepository = require('../../repositories/documents/UserDocumentRepository'); const { s3 } = require('../../utils/exoscaleUploader'); const { GetObjectCommand } = require('@aws-sdk/client-s3'); const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); const { logger } = require('../../middleware/logger'); class UserDocumentController { static async getAllDocumentsForUser(req, res) { const userId = req.params.id; logger.info(`[UserDocumentController] Fetching all documents for userId: ${userId}`); const unitOfWork = new UnitOfWork(); await unitOfWork.start(); try { const repo = new UserDocumentRepository(unitOfWork); // Use repository methods for queries const documents = await repo.getDocumentsForUser(userId); logger.info(`[UserDocumentController] Found ${documents.length} user_documents for userId: ${userId}`); const idDocs = await repo.getIdDocumentsForUser(userId); logger.info(`[UserDocumentController] Found ${idDocs.length} user_id_documents for userId: ${userId}`); await unitOfWork.commit(); // Generate signed URLs for each document in user_documents const signedDocuments = await Promise.all( documents.map(async doc => { let signedUrl = null; if (doc.object_storage_id) { try { const command = new GetObjectCommand({ Bucket: process.env.EXOSCALE_BUCKET, Key: doc.object_storage_id }); signedUrl = await getSignedUrl(s3, command, { expiresIn: 900 }); logger.info(`[UserDocumentController] Generated signedUrl for object_storage_id: ${doc.object_storage_id}`); } catch (err) { logger.error(`[UserDocumentController] Failed to generate signedUrl for object_storage_id: ${doc.object_storage_id}`, { error: err }); } } else { logger.warn(`[UserDocumentController] No object_storage_id for document id: ${doc.id}`); } return { ...doc, signedUrl }; }) ); // Generate signed URLs for front and back of each ID document in user_id_documents const idDocFiles = await Promise.all( idDocs.flatMap(doc => [ (async () => { let signedUrl = null; if (doc.front_object_storage_id) { try { const command = new GetObjectCommand({ Bucket: process.env.EXOSCALE_BUCKET, Key: doc.front_object_storage_id }); signedUrl = await getSignedUrl(s3, command, { expiresIn: 900 }); logger.info(`[UserDocumentController] Generated signedUrl for front_object_storage_id: ${doc.front_object_storage_id}`); } catch (err) { logger.error(`[UserDocumentController] Failed to generate signedUrl for front_object_storage_id: ${doc.front_object_storage_id}`, { error: err }); } } return { user_id_document_id: doc.id, user_id: doc.user_id, document_type: doc.document_type, side: 'front', object_storage_id: doc.front_object_storage_id, signedUrl, id_type: doc.id_type, id_number: doc.id_number, expiry_date: doc.expiry_date, original_filename: doc.original_filename_front }; })(), (async () => { let signedUrl = null; if (doc.back_object_storage_id) { try { const command = new GetObjectCommand({ Bucket: process.env.EXOSCALE_BUCKET, Key: doc.back_object_storage_id }); signedUrl = await getSignedUrl(s3, command, { expiresIn: 900 }); logger.info(`[UserDocumentController] Generated signedUrl for back_object_storage_id: ${doc.back_object_storage_id}`); } catch (err) { logger.error(`[UserDocumentController] Failed to generate signedUrl for back_object_storage_id: ${doc.back_object_storage_id}`, { error: err }); } } return { user_id_document_id: doc.id, user_id: doc.user_id, document_type: doc.document_type, side: 'back', object_storage_id: doc.back_object_storage_id, signedUrl, id_type: doc.id_type, id_number: doc.id_number, expiry_date: doc.expiry_date, original_filename: doc.original_filename_back }; })() ]) ); // Merge user_documents and idDocFiles for a complete list const allDocuments = [...signedDocuments, ...idDocFiles]; logger.info(`[UserDocumentController] Returning ${allDocuments.length} documents with signed URLs for userId: ${userId}`); res.json({ success: true, documents: allDocuments, idDocuments: idDocs }); } catch (error) { logger.error('[UserDocumentController] Error in getAllDocumentsForUser', { error }); await unitOfWork.rollback(error); res.status(500).json({ success: false, message: error.message }); } } } module.exports = UserDocumentController;