feat: add user type handling and Exoscale contract folder structure validation in previewLatestForUser function

This commit is contained in:
seaznCode 2026-01-19 22:53:49 +01:00
parent 879c504abd
commit f6067c48fc

View File

@ -1,6 +1,6 @@
const DocumentTemplateService = require('../../services/template/DocumentTemplateService');
const ContractUploadService = require('../../services/contracts/ContractUploadService');
const { S3Client, PutObjectCommand, GetObjectCommand } = require('@aws-sdk/client-s3');
const { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const PDFDocument = require('pdfkit');
const stream = require('stream');
@ -1428,6 +1428,48 @@ exports.previewLatestForUser = async (req, res) => {
logger.error('[previewLatestForUser] failed to load users row', e && e.message);
}
const userTypeParam = (req.query.userType || req.query.user_type || '').toString().toLowerCase();
const userType = ['personal', 'company'].includes(userTypeParam)
? userTypeParam
: ((userRow && userRow.user_type) ? String(userRow.user_type).toLowerCase() : 'personal');
const contractCategory = userType === 'company' ? 'company' : 'personal';
// Check if there are files in the user's Exoscale contracts folder but no contract/gdpr subfolders.
try {
const s3ForList = sharedExoscaleClient || new S3Client({
region: process.env.EXOSCALE_REGION,
endpoint: process.env.EXOSCALE_ENDPOINT,
forcePathStyle: true,
credentials: {
accessKeyId: process.env.EXOSCALE_ACCESS_KEY,
secretAccessKey: process.env.EXOSCALE_SECRET_KEY
}
});
const basePrefix = `contracts/${contractCategory}/${targetUserId}/`;
const listResp = await s3ForList.send(new ListObjectsV2Command({
Bucket: process.env.EXOSCALE_BUCKET,
Prefix: basePrefix,
MaxKeys: 200
}));
const keys = (listResp && listResp.Contents ? listResp.Contents : [])
.map(item => item && item.Key)
.filter(Boolean);
if (keys.length > 0) {
const hasContractFolder = keys.some(k => k.startsWith(`${basePrefix}contract/`));
const hasGdprFolder = keys.some(k => k.startsWith(`${basePrefix}gdpr/`));
if (!hasContractFolder && !hasGdprFolder) {
logger.error('[previewLatestForUser] contract folder structure invalid: Admin user has to clean up and move the files in exoscale folder', {
userId: targetUserId,
contractCategory,
prefix: basePrefix,
sampleKeys: keys.slice(0, 10)
});
}
}
} catch (e) {
logger.warn('[previewLatestForUser] contract folder structure check failed', e && (e.stack || e.message));
}
// Choose document_type set based on contractType (aligned with ContractUploadService paths)
// uploadContract stores under contracts/<category>/<userId>/<contract_type> with document_type 'contract'
// so use contract_type column to disambiguate between contract vs gdpr