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
static async checkForDuplicate(templateData) {
const normalizedTitle = (templateData.title || '').toLowerCase();
console.log('[CustomTemplate.checkForDuplicate] Checking for duplicates:', {
type: templateData.type,
title: templateData.title,
normalizedTitle,
category: templateData.category,
user_id: templateData.user_id
});
@ -58,24 +60,53 @@ class CustomTemplate {
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) {
const titleQuery = `
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, [
templateData.title,
templateData.category,
templateData.user_id
]);
const titleParams = [templateData.title, templateData.user_id];
console.log('[CustomTemplate.checkForDuplicate] title check params:', titleParams);
const titleResult = await database.query(titleQuery, titleParams);
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];
}
}
// 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');
return null;

View File

@ -87,23 +87,54 @@ class Template {
// Check for duplicate templates based on title, type, and category
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 = `
SELECT id, title, type, category FROM templates
WHERE is_active = true AND (
type = $1 OR
(LOWER(title) = LOWER($2) AND category = $3)
LOWER(title) = LOWER($2)
)
`;
const result = await database.query(query, [
templateData.type,
templateData.title,
templateData.category
]);
const params = [incomingType, templateData.title];
console.log('[Template.checkForDuplicate] query params:', params);
const result = await database.query(query, params);
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;
}
// 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
static async create(templateData) {
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) => {
try {
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
const requiredFields = ['type', 'title', 'category'];
@ -579,10 +589,16 @@ router.post('/', async (req, res) => {
// Check for duplicates in regular templates first
const existingTemplate = await Template.checkForDuplicate(templateData);
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({
success: false,
error: 'Duplicate template detected',
message: `A template with similar characteristics already exists: "${existingTemplate.title}" (type: ${existingTemplate.type})`,
error: isTitleDuplicate ? 'Template name already exists' : 'Template type already exists',
message,
existing_template: {
id: existingTemplate.id,
title: existingTemplate.title,
@ -631,12 +647,19 @@ router.post('/', async (req, res) => {
user_id: incomingUserId
};
console.log('[POST /api/templates - custom] duplicate payload:', duplicatePayload);
const existingCustomTemplate = await CustomTemplate.checkForDuplicate(duplicatePayload);
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({
success: false,
error: 'Duplicate custom template detected',
message: `You already have a similar template: "${existingCustomTemplate.title}" (type: ${existingCustomTemplate.type})`,
error: isTitleDuplicate ? 'Template name already exists' : 'Template type already exists',
message,
existing_template: {
id: existingCustomTemplate.id,
title: existingCustomTemplate.title,