feat: contract adjustments + refferral adjustments
This commit is contained in:
parent
b73f8b9b4b
commit
440aa8323b
@ -125,7 +125,8 @@ async function enrichTemplate(template, s3, serverBaseUrl = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serverBaseUrl) {
|
if (serverBaseUrl) {
|
||||||
previewUrl = `${serverBaseUrl}/api/document-templates/${template.id}/preview`;
|
// CHANGED: route path must match getRoutes.js
|
||||||
|
previewUrl = `${serverBaseUrl}/document-templates/${template.id}/preview`;
|
||||||
} else {
|
} else {
|
||||||
previewUrl = fileUrl;
|
previewUrl = fileUrl;
|
||||||
}
|
}
|
||||||
@ -1253,7 +1254,7 @@ exports.previewPdf = async (req, res) => {
|
|||||||
html = html.replace(/{{\s*currentDate\s*}}/g, formatDateTime());
|
html = html.replace(/{{\s*currentDate\s*}}/g, formatDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply stamps/signature placeholders where appropriate (harmless for sanitized content)
|
// Apply stamps/signature where appropriate (harmless for sanitized content)
|
||||||
try { html = await applyCompanyStampPlaceholders(html, req); } catch (e) { logger.warn('[previewPdf] applyCompanyStampPlaceholders failed', e && e.message); }
|
try { html = await applyCompanyStampPlaceholders(html, req); } catch (e) { logger.warn('[previewPdf] applyCompanyStampPlaceholders failed', e && e.message); }
|
||||||
try { html = await applyProfitPlanetSignature(html); } catch (e) { logger.warn('[previewPdf] applyProfitPlanetSignature failed', e && e.message); }
|
try { html = await applyProfitPlanetSignature(html); } catch (e) { logger.warn('[previewPdf] applyProfitPlanetSignature failed', e && e.message); }
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// This file is now just a field reference for document_templates table
|
// This file is now just a field reference for document_templates table
|
||||||
module.exports = {
|
module.exports = {
|
||||||
fields: ['id', 'name', 'type', 'storageKey', 'description', 'lang', 'version', 'state', 'createdAt', 'updatedAt']
|
fields: ['id', 'name', 'type', 'storageKey', 'description', 'lang', 'user_type', 'version', 'state', 'createdAt', 'updatedAt']
|
||||||
};
|
};
|
||||||
@ -75,8 +75,6 @@ class ReferralTokenRepository {
|
|||||||
rt.status,
|
rt.status,
|
||||||
rt.created_at,
|
rt.created_at,
|
||||||
rt.updated_at,
|
rt.updated_at,
|
||||||
rt.max_uses_label AS max_uses_label,
|
|
||||||
rt.uses_remaining_label AS uses_remaining_label,
|
|
||||||
(SELECT COUNT(*) FROM referral_token_usage rtu WHERE rtu.referral_token_id = rt.id) AS usage_count,
|
(SELECT COUNT(*) FROM referral_token_usage rtu WHERE rtu.referral_token_id = rt.id) AS usage_count,
|
||||||
CASE
|
CASE
|
||||||
WHEN rt.max_uses = -1 THEN 0
|
WHEN rt.max_uses = -1 THEN 0
|
||||||
@ -94,8 +92,6 @@ class ReferralTokenRepository {
|
|||||||
id: r.id,
|
id: r.id,
|
||||||
max_uses: r.max_uses,
|
max_uses: r.max_uses,
|
||||||
uses_remaining: r.uses_remaining,
|
uses_remaining: r.uses_remaining,
|
||||||
max_uses_label: r.max_uses_label,
|
|
||||||
uses_remaining_label: r.uses_remaining_label,
|
|
||||||
used_count: r.used_count
|
used_count: r.used_count
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -191,8 +187,6 @@ class ReferralTokenRepository {
|
|||||||
rt.expires_at,
|
rt.expires_at,
|
||||||
rt.max_uses AS max_uses,
|
rt.max_uses AS max_uses,
|
||||||
rt.uses_remaining AS uses_remaining,
|
rt.uses_remaining AS uses_remaining,
|
||||||
rt.max_uses_label AS max_uses_label,
|
|
||||||
rt.uses_remaining_label AS uses_remaining_label,
|
|
||||||
CASE
|
CASE
|
||||||
WHEN rt.max_uses = -1 THEN 0
|
WHEN rt.max_uses = -1 THEN 0
|
||||||
WHEN rt.max_uses IS NULL OR rt.uses_remaining IS NULL THEN 0
|
WHEN rt.max_uses IS NULL OR rt.uses_remaining IS NULL THEN 0
|
||||||
@ -215,8 +209,6 @@ class ReferralTokenRepository {
|
|||||||
token: r.token,
|
token: r.token,
|
||||||
max_uses: r.max_uses,
|
max_uses: r.max_uses,
|
||||||
uses_remaining: r.uses_remaining,
|
uses_remaining: r.uses_remaining,
|
||||||
max_uses_label: r.max_uses_label,
|
|
||||||
uses_remaining_label: r.uses_remaining_label,
|
|
||||||
used_count: r.used_count
|
used_count: r.used_count
|
||||||
});
|
});
|
||||||
logger.info('ReferralTokenRepository.getReferrerInfoByToken:success', { token });
|
logger.info('ReferralTokenRepository.getReferrerInfoByToken:success', { token });
|
||||||
|
|||||||
@ -4,8 +4,25 @@ const { logger } = require('../../middleware/logger');
|
|||||||
class DocumentTemplateRepository {
|
class DocumentTemplateRepository {
|
||||||
async create(data, conn) {
|
async create(data, conn) {
|
||||||
logger.info('DocumentTemplateRepository.create:start', { name: data.name, type: data.type });
|
logger.info('DocumentTemplateRepository.create:start', { name: data.name, type: data.type });
|
||||||
const { name, type, storageKey, description, lang } = data;
|
// ADDED: validate required fields + normalize optional fields
|
||||||
const user_type = (data.user_type || data.userType || 'both');
|
const required = ['name', 'type', 'storageKey', 'lang'];
|
||||||
|
for (const k of required) {
|
||||||
|
const v = data[k];
|
||||||
|
if (v === undefined || v === null || String(v).trim() === '') {
|
||||||
|
const err = new Error(`Invalid document template: missing field "${k}"`);
|
||||||
|
err.code = 'INVALID_TEMPLATE_DATA';
|
||||||
|
logger.error('DocumentTemplateRepository.create:invalid', { field: k });
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const name = String(data.name);
|
||||||
|
const type = String(data.type);
|
||||||
|
const storageKey = String(data.storageKey);
|
||||||
|
const description = data.description === undefined ? null : data.description; // avoid undefined bind
|
||||||
|
const lang = String(data.lang);
|
||||||
|
const allowedUserTypes = new Set(['personal', 'company', 'both']);
|
||||||
|
const user_type = allowedUserTypes.has(data.user_type || data.userType) ? (data.user_type || data.userType) : 'both';
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
INSERT INTO document_templates (name, type, storageKey, description, lang, user_type, version, state, createdAt, updatedAt)
|
INSERT INTO document_templates (name, type, storageKey, description, lang, user_type, version, state, createdAt, updatedAt)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, 1, 'inactive', NOW(), NOW())
|
VALUES (?, ?, ?, ?, ?, ?, 1, 'inactive', NOW(), NOW())
|
||||||
|
|||||||
@ -103,6 +103,8 @@ router.get('/document-templates/:id', authMiddleware, DocumentTemplateController
|
|||||||
router.get('/document-templates-public', authMiddleware, adminOnly, DocumentTemplateController.listTemplatesPublic);
|
router.get('/document-templates-public', authMiddleware, adminOnly, DocumentTemplateController.listTemplatesPublic);
|
||||||
router.get('/document-templates/:id/generate-pdf', authMiddleware, DocumentTemplateController.generatePdf);
|
router.get('/document-templates/:id/generate-pdf', authMiddleware, DocumentTemplateController.generatePdf);
|
||||||
router.get('/document-templates/:id/preview', authMiddleware, DocumentTemplateController.previewTemplate);
|
router.get('/document-templates/:id/preview', authMiddleware, DocumentTemplateController.previewTemplate);
|
||||||
|
router.get('/document-templates/:id/preview-pdf', authMiddleware, DocumentTemplateController.previewPdf);
|
||||||
|
router.get('/document-templates/active/mine', authMiddleware, DocumentTemplateController.listMyActiveTemplates);
|
||||||
router.get('/document-templates/:id/download-pdf', authMiddleware, DocumentTemplateController.downloadPdf);
|
router.get('/document-templates/:id/download-pdf', authMiddleware, DocumentTemplateController.downloadPdf);
|
||||||
router.get('/api/document-templates', authMiddleware, adminOnly, DocumentTemplateController.listTemplatesFiltered);
|
router.get('/api/document-templates', authMiddleware, adminOnly, DocumentTemplateController.listTemplatesFiltered);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user