CentralBackend/controller/documents/ContractUploadController.js

146 lines
5.6 KiB
JavaScript

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;
logger.info(`[ContractUploadController] uploadPersonalContract called for userId: ${userId}`);
const file = req.file; // optional, we now generate from templates when absent
const contractData = req.body.contractData ? JSON.parse(req.body.contractData) : undefined;
const signatureImage = req.body.signatureImage;
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({
userId,
file,
documentType: 'contract',
contractCategory: 'personal',
unitOfWork,
contractData,
signatureImage: signatureMeta ? signatureMeta.base64 : null,
contract_type: 'contract',
user_type: 'personal'
}));
// GDPR contract (auto-generated from latest GDPR template)
uploads.push(await ContractUploadService.uploadContract({
userId,
documentType: 'contract',
contractCategory: 'personal',
unitOfWork,
contractData,
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) });
} catch (error) {
logger.error(`[ContractUploadController] uploadPersonalContract error for userId: ${userId}`, { error });
await unitOfWork.rollback(error);
res.status(400).json({ success: false, message: error.message });
}
}
static async uploadCompanyContract(req, res) {
const userId = req.user.userId;
logger.info(`[ContractUploadController] uploadCompanyContract called for userId: ${userId}`);
const file = req.file;
const contractData = req.body.contractData ? JSON.parse(req.body.contractData) : undefined;
const signatureImage = req.body.signatureImage;
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,
documentType: 'contract',
contractCategory: 'company',
unitOfWork,
contractData,
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) {
logger.error(`[ContractUploadController] uploadCompanyContract error for userId: ${userId}`, { error });
await unitOfWork.rollback(error);
res.status(400).json({ success: false, message: error.message });
}
}
}
module.exports = ContractUploadController;