const UserDocumentRepository = require('../../../repositories/documents/UserDocumentRepository'); const { uploadBuffer } = require('../../../utils/exoscaleUploader'); const { logger } = require('../../../middleware/logger'); class PersonalDocumentService { static async uploadPersonalId({ userId, idType, idNumber, expiryDate, files, unitOfWork }) { logger.info('PersonalDocumentService.uploadPersonalId:start', { userId, idType, idNumber, expiryDate }); try { // Validate required fields if (!idType || !idNumber || !expiryDate || !files || !files.front) { logger.warn('PersonalDocumentService.uploadPersonalId:missing_fields', { userId }); throw new Error('Missing required fields or front image'); } // Validate file types (images only) const allowedTypes = ['image/jpeg', 'image/png', 'image/webp']; if (!allowedTypes.includes(files.front.mimetype)) { logger.warn('PersonalDocumentService.uploadPersonalId:invalid_front_type', { userId, mimetype: files.front.mimetype }); throw new Error('Invalid file type for front image'); } if (files.back && !allowedTypes.includes(files.back.mimetype)) { logger.warn('PersonalDocumentService.uploadPersonalId:invalid_back_type', { userId, mimetype: files.back.mimetype }); throw new Error('Invalid file type for back image'); } logger.info('PersonalDocumentService.uploadPersonalId:uploading_front', { userId }); // Upload front image const frontUpload = await uploadBuffer( files.front.buffer, files.front.originalname, files.front.mimetype, `personal-id/${userId}` ); // Upload back image if present let backUpload = null; if (files.back) { logger.info('PersonalDocumentService.uploadPersonalId:uploading_back', { userId }); backUpload = await uploadBuffer( files.back.buffer, files.back.originalname, files.back.mimetype, `personal-id/${userId}` ); } // Insert a single row in user_id_documents for both images (back may be null) const repo = new UserDocumentRepository(unitOfWork); await repo.insertIdDocument({ userId, documentType: 'personal_id', frontObjectStorageId: frontUpload.objectKey, backObjectStorageId: backUpload ? backUpload.objectKey : null, idType, idNumber, expiryDate, originalFilenameFront: files.front.originalname, originalFilenameBack: files.back ? files.back.originalname : null }); logger.info('PersonalDocumentService.uploadPersonalId:id_document_inserted', { userId }); // Set documents_uploaded in user_status await unitOfWork.connection.query( `UPDATE user_status SET documents_uploaded = 1, documents_uploaded_at = NOW() WHERE user_id = ?`, [userId] ); logger.info('PersonalDocumentService.uploadPersonalId:user_status_updated', { userId }); // Check if all steps are complete and set status to 'pending' if so const UserStatusService = require('./UserStatusService'); await UserStatusService.checkAndSetPendingIfComplete(userId, unitOfWork); logger.info('PersonalDocumentService.uploadPersonalId:pending_check_complete', { userId }); logger.info('PersonalDocumentService.uploadPersonalId:success', { userId }); return { front: frontUpload, back: backUpload }; } catch (error) { logger.error('PersonalDocumentService.uploadPersonalId:error', { userId, error: error.message }); throw error; } } } module.exports = PersonalDocumentService;