From 424992c5c208cb2bc241483421d1282aeb7a1158 Mon Sep 17 00:00:00 2001
From: shwtea <shwetagupta0711754@gmail.com>
Date: Wed, 11 Sep 2024 12:55:32 +0530
Subject: [PATCH] template map with widget

---
 .env                       |  2 +-
 api/template/business.js   | 43 ++++++++++--------
 api/template/controller.js | 59 ++++++++++++++++++++-----
 api/template/routes.js     |  2 +-
 api/template/service.js    | 85 +++++++++++++++++++++++++-----------
 api/utils/logger.js        | 15 +++++++
 api/widget/business.js     | 21 ++++++---
 api/widget/controller.js   | 35 ++++++++++++---
 api/widget/service.js      | 36 +++++++++++----
 app.log                    | 89 ++++++++++++++++++++++++++++++++++++++
 package.json               |  1 +
 swagger.yaml               |  8 +++-
 12 files changed, 317 insertions(+), 79 deletions(-)
 create mode 100644 api/utils/logger.js
 create mode 100644 app.log

diff --git a/.env b/.env
index 7182010..81d5399 100644
--- a/.env
+++ b/.env
@@ -1,4 +1,4 @@
 NODE_ENV=development
-SERVICE_BASE_URL=https://344e-206-84-239-127.ngrok-free.app
+SERVICE_BASE_URL=https://ecf8-206-84-239-127.ngrok-free.app
 SERVICE_PORT=5000
 LOG_LEVEL=debug
diff --git a/api/template/business.js b/api/template/business.js
index c42fc3b..fcebdae 100644
--- a/api/template/business.js
+++ b/api/template/business.js
@@ -2,39 +2,48 @@
 /* eslint-disable no-throw-literal */
 // const logger = require('utils/logger');
 const templateService = require('../template/service');
+const logger = require('../utils/logger'); 
 
-
-const updateAndMapWidget = async (page,widgetId,position, startTime, endTime) => {
+const updateAndMapWidget = async (page, widgetId, position, startTime, endTime,templateId) => {
   try {
-    const response = await templateService.updateAndMapWidget(page,widgetId,position, startTime, endTime);
-    return { status: '200', response }
+    logger.info(`Business Logic | updateAndMapWidget | Page: ${page}, Widget ID: ${widgetId}`);
+    const response = await templateService.updateAndMapWidget(page, widgetId, position, startTime, endTime,templateId);
+    
+    logger.info(`Widget mapping updated | Widget ID: ${widgetId} | Page: ${page}`);
+    return { status: 200, data: response };
   } catch (error) {
-    throw error
+    logger.error(`Error in Business Logic updateAndMapWidget: ${error.message}`);
+    throw error;
   }
-
 };
 
-const createTemplate = async (name, desc,platform, widgets, hashId) => {
+
+const createTemplate = async (name, desc, platform, widgets, hashId) => {
   try {
-    const response = await templateService.createTemplate(name, desc,platform, widgets, hashId);
-    return { status: '200', response }
+    logger.info(`Business logic: creating template for platform=${platform}`);
+    
+    const response = await templateService.createTemplate(name, desc, platform, widgets, hashId);
+    
+    return { status: 201, response };
   } catch (error) {
-    throw error
+    logger.error(`Error in business logic: ${error.message}`, { error });
+    throw error;
   }
-
 };
 
-const getParticularTemplate = async (page,platform) => {
+
+const getParticularTemplate = async (page, platform) => {
   try {
-    const response = await templateService.getParticularTemplate(page,platform);
-    console.log(page,"Pagessssssss");
-    return { status: '200', response }
+    logger.info(`Business logic: Fetching template for page: ${page}, platform: ${platform}`);
+    const response = await templateService.getParticularTemplate(page, platform);
+    return { status: 200, response };
   } catch (error) {
-    throw error
+    logger.error("Error in getParticularTemplate Business Logic:", error.message);
+    throw error;
   }
-
 };
 
+
 module.exports = {
   updateAndMapWidget,
   createTemplate,
diff --git a/api/template/controller.js b/api/template/controller.js
index d8c68cd..e610b80 100644
--- a/api/template/controller.js
+++ b/api/template/controller.js
@@ -1,41 +1,76 @@
 
 const templateBusiness = require('./business');
+const logger = require('../utils/logger');
 
 
 const updateAndMapWidget = async (req, res, next) => {
   try {
-    // logger.info(`Entering | updateAndMapWidget Controller | ${req.body}`);
-    const { page, widgetId } = req.params;
+    const { page, widgetId, templateId } = req.params;
     const { position, startTime, endTime } = req.body;
-    const response = await templateBusiness.updateAndMapWidget(page, widgetId, position, startTime, endTime);
-    // logger.info(`Entering | updateAndMapWidget Controller | ${widgetId}`);
+    console.log(templateId)
+    // Check for missing required fields and return 400 (Bad Request) if any are missing
+    if (!page || !widgetId || !position || !startTime || !endTime || !templateId) {
+      // Log the bad request
+     
+      logger.error(`Bad Request | Missing fields: ${JSON.stringify({ page, widgetId, position, startTime, endTime, templateId })}`);
+      return res.status(400).json({ error: 'Missing required fields' });
+    }
+
+    logger.info(`Entering | updateAndMapWidget Controller | ${widgetId} for page ${page}`);
+    const response = await templateBusiness.updateAndMapWidget(page, widgetId, position, startTime, endTime, templateId);
+
     return res.status(response.status).json({ data: response });
   } catch (error) {
-    throw error
+    logger.error(`Error in updateAndMapWidget Controller: ${error.message}`);
+    next(error); // Pass the error to the error handling middleware
   }
 };
 
+
 const createTemplate = async (req, res, next) => {
   try {
-    const { name, desc,platform, widgets, hashId } = req.body;
-    const response = await templateBusiness.createTemplate(name, desc,platform, widgets, hashId);
+    const { name, desc, platform, widgets, hashId } = req.body;
+
+    // Simple validation for required fields
+    if (!name || !platform || !widgets || widgets.length === 0) {
+      logger.error('Bad request: Missing required fields');
+      return res.status(400).json({ message: 'Bad request: Missing required fields' });
+    }
+
+    // Log the incoming request
+    logger.info(`Creating template: name=${name}, platform=${platform}`);
+
+    const response = await templateBusiness.createTemplate(name, desc, platform, widgets, hashId);
     return res.status(response.status).json({ data: response });
   } catch (error) {
-    throw error
+    logger.error(`Error creating template: ${error.message}`, { error });
+    next(error); // Pass the error to an error handler middleware
   }
 };
 
+
 const getParticularTemplate = async (req, res) => {
   try {
-    console.log("GET template details of a particular page");
-    const { page,platform } = req.params;
-    const response = await templateBusiness.getParticularTemplate(page,platform);
+    const { page } = req.params;
+    const { platform } = req.query;
+
+    // Basic validation
+    if (!page || !platform) {
+      logger.error("Bad Request: Missing required parameters.");
+      return res.status(400).json({ error: "Bad Request: Missing required parameters 'page' or 'platform'." });
+    }
+
+    logger.info(`GET request for template details of page: ${page}, platform: ${platform}`);
+    const response = await templateBusiness.getParticularTemplate(page, platform);
+
     return res.status(response.status).json({ data: response });
   } catch (error) {
-    throw error;
+    logger.error("Error in getParticularTemplate Controller:", error.message);
+    next(error);
   }
 };
 
+
 module.exports = {
   updateAndMapWidget,
   createTemplate,
diff --git a/api/template/routes.js b/api/template/routes.js
index 53e1013..d2ffffa 100644
--- a/api/template/routes.js
+++ b/api/template/routes.js
@@ -3,7 +3,7 @@ const templateRouter = require('express').Router();
 const {  updateAndMapWidget,createTemplate,getParticularTemplate } = require('./controller');
 
 
-templateRouter.put('/:page/widgets/:widgetId', updateAndMapWidget);
+templateRouter.put('/:page/widgets/:widgetId/:templateId', updateAndMapWidget);
 
 templateRouter.post('/createTemplate', createTemplate);
 
diff --git a/api/template/service.js b/api/template/service.js
index e1ac2b1..d1c4833 100644
--- a/api/template/service.js
+++ b/api/template/service.js
@@ -1,44 +1,70 @@
 // const logger = require('utils/logger');
 
 const Widget = require("../models/widget");
-const Template = require("../models/template")
+const Template = require("../models/template");
+const logger = require('../utils/logger'); 
 
 
-const updateAndMapWidget = async (page,widgetId,position, startTime, endTime) => {
+const updateAndMapWidget = async (page, widgetId, position, startTime, endTime, templateId) => {
   try {
-    const template = await Template.findOne({ name: page });
+    let template;
+
+    // Fetching template by templateId if it exists, else fallback to page name
+    if (templateId) {
+      logger.info(`Service | Fetching template by templateId: ${templateId}`);
+      template = await Template.findOne({ _id: templateId });
+    } else {
+      logger.info(`Service | Fetching template for page: ${page}`);
+      template = await Template.findOne({ name: page });
+    }
+
+    // If template is not found
     if (!template) {
-      return { status: 404,  error: 'template not found' };
+      logger.error(`Template not found | Page: ${page}, Template ID: ${templateId || 'N/A'}`);
+      return { status: 404, error: 'Template not found' };
     }
-    console.log(page,widgetId,position, startTime, endTime)
+
+    logger.info(`Mapping widget | Page: ${page}, Widget ID: ${widgetId}, Position: ${position}`);
+
+    // Find if the widget already exists in the template
     const widgetIndex = template.widgets.findIndex(w => w.widgetId.toString() === widgetId);
-    
+
+    // Update existing widget or add new one
     if (widgetIndex !== -1) {
+      logger.info(`Widget found | Updating existing widget | Widget ID: ${widgetId}`);
       template.widgets[widgetIndex] = {
-        ...template.widgets[widgetIndex], 
-        position,                         
-        startTime,                       
-        endTime                          
+        ...template.widgets[widgetIndex],
+        position,
+        startTime,
+        endTime
       };
     } else {
+      logger.info(`Widget not found | Adding new widget | Widget ID: ${widgetId}`);
       template.widgets.push({
-        widgetId: widgetId,  
-        position,            
-        startTime,           
-        endTime              
+        widgetId,
+        position,
+        startTime,
+        endTime
       });
     }
 
+    // Save the updated template
     await template.save();
-    return { status: 200, widgetId: widgetId, page: page };
+    logger.info(`Widget successfully saved | Widget ID: ${widgetId}, Page: ${page}, Template ID: ${templateId}`);
+
+    return { status: 200, widgetId, page, templateId: template._id };
+
   } catch (error) {
-    throw error
+    logger.error(`Error in Service updateAndMapWidget: ${error.message}`);
+    throw error;
   }
-
 };
 
+
 const createTemplate = async (name, desc, platform, widgets, hashId) => {
   try {
+    logger.info('Service: Creating new template in the database');
+
     const newTemplate = new Template({
       name,
       desc,
@@ -49,27 +75,36 @@ const createTemplate = async (name, desc, platform, widgets, hashId) => {
 
     // Save the template to the database
     await newTemplate.save();
-    return { status: 201,  message: 'Template created successfully', id: newTemplate._id };
+
+    logger.info(`Template created successfully with id=${newTemplate._id}`);
+    return { status: 201, message: 'Template created successfully', id: newTemplate._id };
   } catch (error) {
-    throw error
+    logger.error(`Error saving template to database: ${error.message}`, { error });
+    throw error;
   }
-
 };
 
-const getParticularTemplate = async (page,platform) => {
+
+const getParticularTemplate = async (page, platform) => {
   try {
-    const template = await Template.findOne({ name: page,platform}).populate('widgets.widgetId');
+    logger.info(`Service: Querying database for page: ${page}, platform: ${platform}`);
+    const template = await Template.find({ name: page, platform }).populate('widgets.widgetId');
+
     if (!template) {
-      return { status: 404,  message: 'Template not found'};
+      logger.warn(`Template not found for page: ${page}, platform: ${platform}`);
+      return { status: 404, message: 'Template not found' };
     }
+
+    logger.info(`Template found for page: ${page}, platform: ${platform}`);
     return template;
   } catch (error) {
-    throw error
+    logger.error("Error in getParticularTemplate Service:", error.message);
+    throw error;
   }
-
 };
 
 
+
 module.exports = {
   updateAndMapWidget,
   createTemplate,
diff --git a/api/utils/logger.js b/api/utils/logger.js
new file mode 100644
index 0000000..7f4f6cd
--- /dev/null
+++ b/api/utils/logger.js
@@ -0,0 +1,15 @@
+const winston = require('winston');
+
+const logger = winston.createLogger({
+  level: 'info',
+  format: winston.format.combine(
+    winston.format.timestamp(),
+    winston.format.json()
+  ),
+  transports: [
+    new winston.transports.Console(), // Log to console
+    new winston.transports.File({ filename: 'app.log' }) // Log to file
+  ]
+});
+
+module.exports = logger;
diff --git a/api/widget/business.js b/api/widget/business.js
index 5e03a21..c9c5e9a 100644
--- a/api/widget/business.js
+++ b/api/widget/business.js
@@ -2,30 +2,39 @@
 /* eslint-disable no-throw-literal */
 // const logger = require('utils/logger');
 const widgetService = require('./service');
+const logger = require('../utils/logger'); 
+
 
 
 
 const getAllWidget = async (page) => {
   try {
+    logger.info(`Business logic: Getting widgets for page ${page}`);
+    
     const response = await widgetService.getAllWidget(page);
-    return { status: '200', response }
+    return { status: 200, data: response };
   } catch (error) {
-    throw error
+    logger.error(`Error in business logic: ${error.message}`);
+    throw new Error('Failed to fetch widgets');
   }
-
 };
 
+
+
 const createWidget = async (data) => {
   try {
+    logger.info('Business Logic: Creating widget'); // Log business logic activity
     const response = await widgetService.createWidget(data);
-    return { status: '200', response }
+
+    return { status: 200, response };
   } catch (error) {
-    throw error
+    logger.error(`Error in business logic: ${error.message}`); // Log error
+    throw error; // Pass the error to the controller
   }
-
 };
 
 
+
 module.exports = {
   getAllWidget,
   createWidget,
diff --git a/api/widget/controller.js b/api/widget/controller.js
index ebeecb7..d9b63b7 100644
--- a/api/widget/controller.js
+++ b/api/widget/controller.js
@@ -1,30 +1,51 @@
-// const logger = require('utils/logger');
+const logger = require('../utils/logger'); 
 const widgetBusiness = require('./business');
-// const Joi = require('joi');
+
 
 const getAllWidget = async (req, res, next) => {
   try {
-    console.log("comign here")
     const { page } = req.params;
+    
+    // Log the page requested
+    logger.info(`Fetching widgets for page: ${page}`);
+    
+    if (!page) {
+      return res.status(400).json({ error: 'Page parameter is missing' });
+    }
+
     const response = await widgetBusiness.getAllWidget(page);
-    return res.status(response.status).json({ data: response });
+
+    return res.status(response.status).json({ data: response.data });
   } catch (error) {
-    throw error
+    logger.error(`Error in controller: ${error.message}`);
+    return res.status(500).json({ error: 'Internal server error' });
   }
 };
+
+
+
 const createWidget = async (req, res, next) => {
   try {
-    console.log("comign createWidget")
+    logger.info('createWidget API called'); // Log the API call
+
+    // Validate request body (basic validation)
+    if (!req.body || Object.keys(req.body).length === 0) {
+      logger.error('Bad Request: No data provided'); // Log bad request
+      return res.status(400).json({ message: 'Bad Request: No data provided' });
+    }
 
     const response = await widgetBusiness.createWidget(req.body);
+
     return res.status(response.status).json({ data: response });
   } catch (error) {
-    throw error
+    logger.error(`Error in createWidget controller: ${error.message}`); // Log error
+    return res.status(500).json({ message: 'Internal Server Error', error: error.message });
   }
 };
 
 
 
+
 module.exports = {
   getAllWidget,
   createWidget,
diff --git a/api/widget/service.js b/api/widget/service.js
index 705512b..579355a 100644
--- a/api/widget/service.js
+++ b/api/widget/service.js
@@ -1,34 +1,52 @@
 // const logger = require('utils/logger');
 
 const Widget = require("../models/widget");
-const Template = require("../models/template")
+const Template = require("../models/template");
+const logger = require('../utils/logger'); 
 
 const getAllWidget = async (page) => {
   try {
-    const template = await Template.findOne({ name: page}).populate('widgets.widgetId');
+    logger.info(`Service: Fetching template for page ${page}`);
+    
+    const template = await Template.find({ name: page }).populate('widgets.widgetId');
+    
     if (!template) {
-      return res.status(404).json({ error: 'Template not found' });
+      logger.info(`Template not found for page: ${page}`);
+      throw new Error('Template not found');
     }
-    res.status(200).json(template);
+    
+    logger.info(`Template found for page: ${page}`);
+    return template;
   } catch (error) {
-    throw error
+    logger.error(`Error in service: ${error.message}`);
+    throw new Error('Failed to retrieve template');
   }
-
 };
 
+
 const createWidget = async (data) => {
   try {
-    console.log("in service")
+    logger.info('Service: Creating new widget'); // Log service activity
+    
+    // Validate required fields in 'data'
+    if (!data.name || !data.type) { // Example validation
+      logger.error('Bad Request: Missing required fields'); // Log missing fields
+      return { status: 400, message: 'Bad Request: Missing required fields' };
+    }
+
     const widget = new Widget(data);
     await widget.save();
+
+    logger.info('Widget created successfully'); // Log successful creation
     return { status: 201, id: widget._id, message: 'Widget created successfully' };
   } catch (error) {
-    throw error
+    logger.error(`Error in widget service: ${error.message}`); // Log error
+    throw error; // Pass error to business logic
   }
-
 };
 
 
+
 module.exports = {
   getAllWidget,
   createWidget,
diff --git a/app.log b/app.log
new file mode 100644
index 0000000..ee5dfb5
--- /dev/null
+++ b/app.log
@@ -0,0 +1,89 @@
+{"level":"error","message":"Bad Request: Missing required parameters.","timestamp":"2024-09-11T05:37:41.312Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d5ea0f10ce7f6c00e00a92\",\"position\":0,\"startTime\":\"2024-09-11T05:37:56.769Z\",\"endTime\":\"2024-09-11T05:37:56.769Z\"}","timestamp":"2024-09-11T05:38:40.990Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage Template\",\"widgetId\":\"66d5ea0f10ce7f6c00e00a92\",\"position\":0,\"startTime\":\"2024-09-11T05:37:56.769Z\",\"endTime\":\"2024-09-11T05:37:56.769Z\"}","timestamp":"2024-09-11T05:41:14.359Z"}
+{"level":"info","message":"Creating template: name=contact Template, platform=web","timestamp":"2024-09-11T05:42:18.870Z"}
+{"level":"info","message":"Business logic: creating template for platform=web","timestamp":"2024-09-11T05:42:18.871Z"}
+{"level":"info","message":"Service: Creating new template in the database","timestamp":"2024-09-11T05:42:18.871Z"}
+{"level":"info","message":"Template created successfully with id=66e12dba9ee1f8773f1c0b56","timestamp":"2024-09-11T05:42:18.892Z"}
+{"level":"error","message":"Bad Request: Missing required parameters.","timestamp":"2024-09-11T05:44:13.537Z"}
+{"level":"error","message":"Bad Request: Missing required parameters.","timestamp":"2024-09-11T05:46:32.907Z"}
+{"level":"error","message":"Error in getParticularTemplate Controller:","timestamp":"2024-09-11T05:47:18.904Z"}
+{"level":"error","message":"Error in getParticularTemplate Controller:","timestamp":"2024-09-11T05:47:59.459Z"}
+{"level":"error","message":"Error in getParticularTemplate Controller:","timestamp":"2024-09-11T06:13:53.056Z"}
+{"level":"error","message":"Error in getParticularTemplate Business Logic:","timestamp":"2024-09-11T06:14:48.457Z"}
+{"level":"error","message":"Error in getParticularTemplate Business Logic:","timestamp":"2024-09-11T06:15:33.677Z"}
+{"level":"error","message":"Error in getParticularTemplate Business Logic:","timestamp":"2024-09-11T06:18:06.709Z"}
+{"level":"error","message":"Error in getParticularTemplate Controller:","timestamp":"2024-09-11T06:18:06.710Z"}
+{"level":"error","message":"Error in getParticularTemplate Service:","timestamp":"2024-09-11T06:18:38.593Z"}
+{"level":"error","message":"Error in getParticularTemplate Business Logic:","timestamp":"2024-09-11T06:18:38.595Z"}
+{"level":"error","message":"Error in getParticularTemplate Controller:","timestamp":"2024-09-11T06:18:38.596Z"}
+{"level":"warn","message":"Template not found for page: contact Template, platform: mobile","timestamp":"2024-09-11T06:20:02.500Z"}
+{"level":"info","message":"GET request for template details of page: contact Template, platform: web","timestamp":"2024-09-11T06:30:07.939Z"}
+{"level":"info","message":"Business logic: Fetching template for page: contact Template, platform: web","timestamp":"2024-09-11T06:30:07.943Z"}
+{"level":"info","message":"Service: Querying database for page: contact Template, platform: web","timestamp":"2024-09-11T06:30:07.943Z"}
+{"level":"info","message":"Template found for page: contact Template, platform: web","timestamp":"2024-09-11T06:30:07.959Z"}
+{"level":"info","message":"Creating template: name=Homepage, platform=web","timestamp":"2024-09-11T06:39:33.768Z"}
+{"level":"info","message":"Business logic: creating template for platform=web","timestamp":"2024-09-11T06:39:33.768Z"}
+{"level":"info","message":"Service: Creating new template in the database","timestamp":"2024-09-11T06:39:33.768Z"}
+{"level":"info","message":"Template created successfully with id=66e13b259d3a6362f23888de","timestamp":"2024-09-11T06:39:33.787Z"}
+{"level":"info","message":"Creating template: name=Homepage, platform=web","timestamp":"2024-09-11T06:45:35.593Z"}
+{"level":"info","message":"Business logic: creating template for platform=web","timestamp":"2024-09-11T06:45:35.593Z"}
+{"level":"info","message":"Service: Creating new template in the database","timestamp":"2024-09-11T06:45:35.593Z"}
+{"error":{"code":11000,"errorResponse":{"code":11000,"errmsg":"E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"level":"error","message":"Error saving template to database: E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","timestamp":"2024-09-11T06:45:35.606Z"}
+{"error":{"code":11000,"errorResponse":{"code":11000,"errmsg":"E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"level":"error","message":"Error in business logic: E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","timestamp":"2024-09-11T06:45:35.607Z"}
+{"error":{"code":11000,"errorResponse":{"code":11000,"errmsg":"E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"index":0,"keyPattern":{"hashId":1},"keyValue":{"hashId":"homepage-template-001"}},"level":"error","message":"Error creating template: E11000 duplicate key error collection: widgetTemplate.templates index: hashId_1 dup key: { hashId: \"homepage-template-001\" }","timestamp":"2024-09-11T06:45:35.607Z"}
+{"level":"info","message":"Creating template: name=Homepage, platform=web","timestamp":"2024-09-11T06:45:49.070Z"}
+{"level":"info","message":"Business logic: creating template for platform=web","timestamp":"2024-09-11T06:45:49.070Z"}
+{"level":"info","message":"Service: Creating new template in the database","timestamp":"2024-09-11T06:45:49.071Z"}
+{"level":"info","message":"Template created successfully with id=66e13c9d9d3a6362f23888e4","timestamp":"2024-09-11T06:45:49.079Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: web","timestamp":"2024-09-11T06:46:41.301Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: web","timestamp":"2024-09-11T06:46:41.301Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: web","timestamp":"2024-09-11T06:46:41.301Z"}
+{"level":"info","message":"Template found for page: Homepage, platform: web","timestamp":"2024-09-11T06:46:41.312Z"}
+{"level":"error","message":"Error in controller: Cannot create property 'Symbol(level)' on string 'Fetching widgets for page: Homepage'","timestamp":"2024-09-11T06:49:07.162Z"}
+{"level":"info","message":"Fetching widgets for page: Homepage","timestamp":"2024-09-11T06:50:19.280Z"}
+{"level":"info","message":"Business logic: Getting widgets for page Homepage","timestamp":"2024-09-11T06:50:19.284Z"}
+{"level":"info","message":"Service: Fetching template for page Homepage","timestamp":"2024-09-11T06:50:19.285Z"}
+{"level":"info","message":"Template found for page: Homepage","timestamp":"2024-09-11T06:50:19.309Z"}
+{"level":"info","message":"Fetching widgets for page: Homepage","timestamp":"2024-09-11T06:50:55.322Z"}
+{"level":"info","message":"Business logic: Getting widgets for page Homepage","timestamp":"2024-09-11T06:50:55.326Z"}
+{"level":"info","message":"Service: Fetching template for page Homepage","timestamp":"2024-09-11T06:50:55.327Z"}
+{"level":"info","message":"Template found for page: Homepage","timestamp":"2024-09-11T06:50:55.351Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: mobile","timestamp":"2024-09-11T06:52:07.214Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: mobile","timestamp":"2024-09-11T06:52:07.215Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: mobile","timestamp":"2024-09-11T06:52:07.215Z"}
+{"level":"warn","message":"Template not found for page: Homepage, platform: mobile","timestamp":"2024-09-11T06:52:07.217Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: web","timestamp":"2024-09-11T06:52:29.725Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: web","timestamp":"2024-09-11T06:52:29.726Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: web","timestamp":"2024-09-11T06:52:29.727Z"}
+{"level":"info","message":"Template found for page: Homepage, platform: web","timestamp":"2024-09-11T06:52:29.742Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: web","timestamp":"2024-09-11T06:53:06.593Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: web","timestamp":"2024-09-11T06:53:06.594Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: web","timestamp":"2024-09-11T06:53:06.595Z"}
+{"level":"info","message":"Template found for page: Homepage, platform: web","timestamp":"2024-09-11T06:53:06.612Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: web","timestamp":"2024-09-11T06:55:19.137Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: web","timestamp":"2024-09-11T06:55:19.141Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: web","timestamp":"2024-09-11T06:55:19.142Z"}
+{"level":"info","message":"Template found for page: Homepage, platform: web","timestamp":"2024-09-11T06:55:19.161Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:10:35.165Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:12:33.688Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:12:58.159Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:13:50.490Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:14:23.986Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":0,\"startTime\":\"2024-09-11T07:09:55.792Z\",\"endTime\":\"2024-09-11T07:09:55.792Z\"}","timestamp":"2024-09-11T07:14:26.936Z"}
+{"level":"error","message":"Bad Request | Missing fields: {\"page\":\"Homepage\",\"widgetId\":\"66d6b41c32e719cb9f992523\",\"position\":1,\"startTime\":\"2024-09-11T07:15:47.595Z\",\"endTime\":\"2024-09-11T07:15:47.595Z\"}","timestamp":"2024-09-11T07:16:23.582Z"}
+{"level":"info","message":"Entering | updateAndMapWidget Controller | 66d6b41c32e719cb9f992523 for page Homepage","timestamp":"2024-09-11T07:23:18.639Z"}
+{"level":"info","message":"Business Logic | updateAndMapWidget | Page: Homepage, Widget ID: 66d6b41c32e719cb9f992523","timestamp":"2024-09-11T07:23:18.640Z"}
+{"level":"info","message":"Service | Fetching template by templateId: 66e13b259d3a6362f23888de","timestamp":"2024-09-11T07:23:18.640Z"}
+{"level":"info","message":"Mapping widget | Page: Homepage, Widget ID: 66d6b41c32e719cb9f992523, Position: 1","timestamp":"2024-09-11T07:23:18.651Z"}
+{"level":"info","message":"Widget not found | Adding new widget | Widget ID: 66d6b41c32e719cb9f992523","timestamp":"2024-09-11T07:23:18.652Z"}
+{"level":"info","message":"Widget successfully saved | Widget ID: 66d6b41c32e719cb9f992523, Page: Homepage, Template ID: 66e13b259d3a6362f23888de","timestamp":"2024-09-11T07:23:18.671Z"}
+{"level":"info","message":"Widget mapping updated | Widget ID: 66d6b41c32e719cb9f992523 | Page: Homepage","timestamp":"2024-09-11T07:23:18.671Z"}
+{"level":"info","message":"GET request for template details of page: Homepage, platform: web","timestamp":"2024-09-11T07:23:57.079Z"}
+{"level":"info","message":"Business logic: Fetching template for page: Homepage, platform: web","timestamp":"2024-09-11T07:23:57.079Z"}
+{"level":"info","message":"Service: Querying database for page: Homepage, platform: web","timestamp":"2024-09-11T07:23:57.079Z"}
+{"level":"info","message":"Template found for page: Homepage, platform: web","timestamp":"2024-09-11T07:23:57.093Z"}
+{"level":"info","message":"Fetching widgets for page: Homepage","timestamp":"2024-09-11T07:24:21.078Z"}
+{"level":"info","message":"Business logic: Getting widgets for page Homepage","timestamp":"2024-09-11T07:24:21.078Z"}
+{"level":"info","message":"Service: Fetching template for page Homepage","timestamp":"2024-09-11T07:24:21.079Z"}
+{"level":"info","message":"Template found for page: Homepage","timestamp":"2024-09-11T07:24:21.091Z"}
diff --git a/package.json b/package.json
index 0e24b61..c148af9 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "mongoose": "^8.6.0",
     "nodemon": "^3.1.4",
     "swagger-ui-express": "^5.0.1",
+    "winston": "^3.14.2",
     "yamljs": "^0.3.0"
   }
 }
diff --git a/swagger.yaml b/swagger.yaml
index f85f05f..087c96c 100644
--- a/swagger.yaml
+++ b/swagger.yaml
@@ -239,7 +239,7 @@ paths:
                   error:
                     type: string
 
-  /template/{page}/widgets/{widgetId}:
+  /template/{page}/widgets/{widgetId}/{templateId}:
     put:
       tags:
         - "Template"
@@ -257,6 +257,12 @@ paths:
           schema:
             type: string
           description: The widget ID that needs to be mapped.
+        - in: path
+          name: templateId
+          required: true
+          schema:
+            type: string
+          description: The template ID that needs to be mapped.
       requestBody:
         required: true
         content:
-- 
GitLab