diff --git a/controller/documents/ContractUploadController.js b/controller/documents/ContractUploadController.js index ceada97..2bf66da 100644 --- a/controller/documents/ContractUploadController.js +++ b/controller/documents/ContractUploadController.js @@ -1,7 +1,27 @@ const UnitOfWork = require('../../database/UnitOfWork'); const ContractUploadService = require('../../services/contracts/ContractUploadService'); +const UserDocumentRepository = require('../../repositories/documents/UserDocumentRepository'); const { logger } = require('../../middleware/logger'); +function normalizeSignature(signatureImage) { + if (!signatureImage) return null; + const str = String(signatureImage); + const m = str.match(/^data:(.+);base64,(.+)$/); + if (m && m[2]) { + const mime = m[1] || 'image/png'; + const base64 = m[2]; + const size = Buffer.from(base64, 'base64').length; + return { base64, mime, size }; + } + try { + const size = Buffer.from(str, 'base64').length; + return { base64: str, mime: 'image/png', size }; + } catch (e) { + logger.warn('[ContractUploadController] normalizeSignature failed to parse provided signature'); + return null; + } +} + class ContractUploadController { static async uploadPersonalContract(req, res) { const userId = req.user.userId; @@ -13,6 +33,22 @@ class ContractUploadController { const unitOfWork = new UnitOfWork(); await unitOfWork.start(); try { + const signatureMeta = normalizeSignature(signatureImage); + const repo = new UserDocumentRepository(unitOfWork); + if (signatureMeta) { + await repo.insertDocument({ + userId, + documentType: 'signature', + contractType: 'contract', + objectStorageId: null, + signatureBase64: signatureMeta.base64, + originalFilename: 'signature.png', + fileSize: signatureMeta.size, + mimeType: signatureMeta.mime + }); + logger.info('[ContractUploadController] signature stored for user', { userId, bytes: signatureMeta.size }); + } + const uploads = []; // Primary contract uploads.push(await ContractUploadService.uploadContract({ @@ -22,7 +58,7 @@ class ContractUploadController { contractCategory: 'personal', unitOfWork, contractData, - signatureImage, + signatureImage: signatureMeta ? signatureMeta.base64 : null, contract_type: 'contract', user_type: 'personal' })); @@ -34,11 +70,17 @@ class ContractUploadController { contractCategory: 'personal', unitOfWork, contractData, - signatureImage, + signatureImage: signatureMeta ? signatureMeta.base64 : null, contract_type: 'gdpr', user_type: 'personal' })); + // Cleanup standalone signature record after contracts are saved + if (signatureMeta) { + await repo.deleteSignatureDocumentsForUser(userId); + logger.info('[ContractUploadController] signature cleanup completed for user', { userId }); + } + await unitOfWork.commit(); logger.info(`[ContractUploadController] uploadPersonalContract success for userId: ${userId}`); res.json({ success: true, uploads, downloadUrls: uploads.map(u => u.url || null) }); @@ -58,6 +100,22 @@ class ContractUploadController { const unitOfWork = new UnitOfWork(); await unitOfWork.start(); try { + const signatureMeta = normalizeSignature(signatureImage); + const repo = new UserDocumentRepository(unitOfWork); + if (signatureMeta) { + await repo.insertDocument({ + userId, + documentType: 'signature', + contractType: 'contract', + objectStorageId: null, + signatureBase64: signatureMeta.base64, + originalFilename: 'signature.png', + fileSize: signatureMeta.size, + mimeType: signatureMeta.mime + }); + logger.info('[ContractUploadController] signature stored for company user', { userId, bytes: signatureMeta.size }); + } + const result = await ContractUploadService.uploadContract({ userId, file, @@ -65,11 +123,15 @@ class ContractUploadController { contractCategory: 'company', unitOfWork, contractData, - signatureImage, + signatureImage: signatureMeta ? signatureMeta.base64 : null, contract_type: 'contract', user_type: 'company' }); await unitOfWork.commit(); + if (signatureMeta) { + await repo.deleteSignatureDocumentsForUser(userId); + logger.info('[ContractUploadController] signature cleanup completed for company user', { userId }); + } logger.info(`[ContractUploadController] uploadCompanyContract success for userId: ${userId}`); res.json({ success: true, upload: result, downloadUrl: result.url || null }); } catch (error) {