ui related fixes in validations

This commit is contained in:
Chandini 2025-08-28 14:06:04 +05:30
parent c88a6123e8
commit ac13a80726
3 changed files with 104 additions and 19 deletions

View File

@ -39,9 +39,11 @@ class CustomTemplate {
// Check for duplicate custom templates based on title, type, category, and user_id // Check for duplicate custom templates based on title, type, category, and user_id
static async checkForDuplicate(templateData) { static async checkForDuplicate(templateData) {
const normalizedTitle = (templateData.title || '').toLowerCase();
console.log('[CustomTemplate.checkForDuplicate] Checking for duplicates:', { console.log('[CustomTemplate.checkForDuplicate] Checking for duplicates:', {
type: templateData.type, type: templateData.type,
title: templateData.title, title: templateData.title,
normalizedTitle,
category: templateData.category, category: templateData.category,
user_id: templateData.user_id user_id: templateData.user_id
}); });
@ -58,25 +60,54 @@ class CustomTemplate {
return typeResult.rows[0]; return typeResult.rows[0];
} }
// Check for same title + category for same user // Check for same title for same user (category-agnostic)
if (templateData.user_id) { if (templateData.user_id) {
const titleQuery = ` const titleQuery = `
SELECT id, title, type, category, user_id FROM custom_templates SELECT id, title, type, category, user_id FROM custom_templates
WHERE LOWER(title) = LOWER($1) AND category = $2 AND user_id = $3 WHERE LOWER(title) = LOWER($1) AND user_id = $2
`; `;
const titleResult = await database.query(titleQuery, [ const titleParams = [templateData.title, templateData.user_id];
templateData.title, console.log('[CustomTemplate.checkForDuplicate] title check params:', titleParams);
templateData.category, const titleResult = await database.query(titleQuery, titleParams);
templateData.user_id
]);
if (titleResult.rows.length > 0) { if (titleResult.rows.length > 0) {
console.log('[CustomTemplate.checkForDuplicate] Found duplicate by title+category+user:', titleResult.rows[0]); const row = titleResult.rows[0];
const titleMatch = (row.title || '').toLowerCase() === normalizedTitle;
console.log('[CustomTemplate.checkForDuplicate] Found duplicate by title+user:', {
id: row.id,
title: row.title,
type: row.type,
category: row.category,
user_id: row.user_id,
titleMatch
});
return titleResult.rows[0]; return titleResult.rows[0];
} }
} }
// Also check if main templates already have the same title (case-insensitive)
const mainTitleQuery = `
SELECT id, title, type, category FROM templates
WHERE is_active = true AND LOWER(title) = LOWER($1)
LIMIT 1
`;
const mainTitleParams = [templateData.title];
console.log('[CustomTemplate.checkForDuplicate] main title check params:', mainTitleParams);
const mainTitleResult = await database.query(mainTitleQuery, mainTitleParams);
if (mainTitleResult.rows.length > 0) {
const row = mainTitleResult.rows[0];
const titleMatch = (row.title || '').toLowerCase() === normalizedTitle;
console.log('[CustomTemplate.checkForDuplicate] Found duplicate title in main templates:', {
id: row.id,
title: row.title,
type: row.type,
category: row.category,
titleMatch
});
return mainTitleResult.rows[0];
}
console.log('[CustomTemplate.checkForDuplicate] No duplicates found'); console.log('[CustomTemplate.checkForDuplicate] No duplicates found');
return null; return null;
} }

View File

@ -87,23 +87,54 @@ class Template {
// Check for duplicate templates based on title, type, and category // Check for duplicate templates based on title, type, and category
static async checkForDuplicate(templateData) { static async checkForDuplicate(templateData) {
const normalizedTitle = (templateData.title || '').toLowerCase();
const incomingType = templateData.type;
console.log('[Template.checkForDuplicate] input:', {
type: incomingType,
title: templateData.title,
normalizedTitle
});
const query = ` const query = `
SELECT id, title, type, category FROM templates SELECT id, title, type, category FROM templates
WHERE is_active = true AND ( WHERE is_active = true AND (
type = $1 OR type = $1 OR
(LOWER(title) = LOWER($2) AND category = $3) LOWER(title) = LOWER($2)
) )
`; `;
const result = await database.query(query, [ const params = [incomingType, templateData.title];
templateData.type, console.log('[Template.checkForDuplicate] query params:', params);
templateData.title, const result = await database.query(query, params);
templateData.category if (result.rows.length > 0) {
]); const row = result.rows[0];
const titleMatch = (row.title || '').toLowerCase() === normalizedTitle;
const typeMatch = (row.type || '') === incomingType;
console.log('[Template.checkForDuplicate] found duplicate:', {
id: row.id,
title: row.title,
type: row.type,
category: row.category,
titleMatch,
typeMatch
});
} else {
console.log('[Template.checkForDuplicate] no duplicates found');
}
return result.rows.length > 0 ? result.rows[0] : null; return result.rows.length > 0 ? result.rows[0] : null;
} }
// Get a template by title (case-insensitive)
static async getByTitle(title) {
const query = `
SELECT * FROM templates
WHERE is_active = true AND LOWER(title) = LOWER($1)
LIMIT 1
`;
const result = await database.query(query, [title]);
return result.rows.length > 0 ? new Template(result.rows[0]) : null;
}
// Create new template // Create new template
static async create(templateData) { static async create(templateData) {
const id = uuidv4(); const id = uuidv4();

View File

@ -562,7 +562,17 @@ router.get('/:id([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/f
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
try { try {
const templateData = req.body; const templateData = req.body;
console.log('🏗️ Creating new template - incoming body:', JSON.stringify(templateData)); const debugPayload = {
raw: templateData,
normalized: {
title: (templateData.title || '').toLowerCase(),
type: templateData.type,
category: templateData.category,
isCustom: templateData.isCustom ?? templateData.is_custom ?? false,
user_id: templateData.user_id || templateData.userId || null
}
};
console.log('🏗️ Creating new template - incoming body:', JSON.stringify(debugPayload));
// Validate required fields // Validate required fields
const requiredFields = ['type', 'title', 'category']; const requiredFields = ['type', 'title', 'category'];
@ -579,10 +589,16 @@ router.post('/', async (req, res) => {
// Check for duplicates in regular templates first // Check for duplicates in regular templates first
const existingTemplate = await Template.checkForDuplicate(templateData); const existingTemplate = await Template.checkForDuplicate(templateData);
if (existingTemplate) { if (existingTemplate) {
const isTitleDuplicate = (existingTemplate.title || '').toLowerCase() === (templateData.title || '').toLowerCase();
const isTypeDuplicate = (existingTemplate.type || '') === (templateData.type || '');
console.log('[POST /api/templates] duplicate detected in main templates:', { existingTemplate, isTitleDuplicate, isTypeDuplicate });
const message = isTitleDuplicate
? `A template with this name already exists: "${existingTemplate.title}"`
: `A template with this type already exists: "${existingTemplate.title}" (type: ${existingTemplate.type})`;
return res.status(409).json({ return res.status(409).json({
success: false, success: false,
error: 'Duplicate template detected', error: isTitleDuplicate ? 'Template name already exists' : 'Template type already exists',
message: `A template with similar characteristics already exists: "${existingTemplate.title}" (type: ${existingTemplate.type})`, message,
existing_template: { existing_template: {
id: existingTemplate.id, id: existingTemplate.id,
title: existingTemplate.title, title: existingTemplate.title,
@ -631,12 +647,19 @@ router.post('/', async (req, res) => {
user_id: incomingUserId user_id: incomingUserId
}; };
console.log('[POST /api/templates - custom] duplicate payload:', duplicatePayload);
const existingCustomTemplate = await CustomTemplate.checkForDuplicate(duplicatePayload); const existingCustomTemplate = await CustomTemplate.checkForDuplicate(duplicatePayload);
if (existingCustomTemplate) { if (existingCustomTemplate) {
const isTitleDuplicate = (existingCustomTemplate.title || '').toLowerCase() === (templateData.title || '').toLowerCase();
const isTypeDuplicate = (existingCustomTemplate.type || '') === (templateData.type || '');
console.log('[POST /api/templates - custom] duplicate detected in custom/main:', { existingCustomTemplate, isTitleDuplicate, isTypeDuplicate });
const message = isTitleDuplicate
? `You already have a template with this name: "${existingCustomTemplate.title}"`
: `You already have a template with this type: "${existingCustomTemplate.title}" (type: ${existingCustomTemplate.type})`;
return res.status(409).json({ return res.status(409).json({
success: false, success: false,
error: 'Duplicate custom template detected', error: isTitleDuplicate ? 'Template name already exists' : 'Template type already exists',
message: `You already have a similar template: "${existingCustomTemplate.title}" (type: ${existingCustomTemplate.type})`, message,
existing_template: { existing_template: {
id: existingCustomTemplate.id, id: existingCustomTemplate.id,
title: existingCustomTemplate.title, title: existingCustomTemplate.title,