diff --git a/.env b/.env
index 94e0ef4960f6ecef603b2ffccd7e884be6c75400..435ebf9c230036e5c8c82538d43775d4e3253441 100644
--- a/.env
+++ b/.env
@@ -1,8 +1,18 @@
-PORT=3009
-BAP_ID=ps-bap-network.becknprotocol.io
-BAP_URI=https://ps-bap-network.becknprotocol.io
-BAP_CLIENT_URI=https://ps-bap-client.becknprotocol.io
-CITY_NAME=Bangalore
-CITY_CODE=std:080
-COUNTRY_NAME=India
-COUNTRY_CODE=IND
\ No newline at end of file
+APP_NAME="Generic Client Layer"
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_PORT=3002
+APP_URL=http://localhost
+
+LOG_CHANNEL=stack
+LOG_DEPRECATIONS_CHANNEL=null
+LOG_LEVEL=debug
+
+PS_BASE_URI=https://ps-bap-client.becknprotocol.io
+PS_BAP_ID=ps-bap-network.becknprotocol.io
+PS_BAP_URI=https://ps-bap-network.becknprotocol.io
+PS_CITY_NAME=Bangalore
+PS_CITY_CODE=std:080
+PS_COUNTRY_NAME=India
+PS_COUNTRY_CODE=IND
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..2a3ccdae9971baadfbff1a76faf0461ee2dd4b2f
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,18 @@
+APP_NAME=Laravel
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_PORT=3002
+APP_URL=http://localhost
+
+LOG_CHANNEL=stack
+LOG_DEPRECATIONS_CHANNEL=null
+LOG_LEVEL=debug
+
+PS_BASE_URI=https://ps-bap-client.becknprotocol.io
+PS_BAP_ID=ps-bap-network.becknprotocol.io
+PS_BAP_URI=https://ps-bap-network.becknprotocol.io
+PS_CITY_NAME=Bangalore
+PS_CITY_CODE=std:080
+PS_COUNTRY_NAME=India
+PS_COUNTRY_CODE=IND
diff --git a/.gitignore b/.gitignore
index 4db21bf294b243ddfc06d9c2de73ba990ca24a8d..036d692a1b36458a1a0bbf24981a9728541b3810 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ dist/
 package-lock.json
 .DS_Store
 coverage/
+logs/
diff --git a/mappings/context.jsonata b/mappings/context.jsonata
new file mode 100644
index 0000000000000000000000000000000000000000..bbceac814d641bda0a25093a60ce4bf2366b8343
--- /dev/null
+++ b/mappings/context.jsonata
@@ -0,0 +1,24 @@
+{
+    "domain": domain,
+    "bpp_id": bpp_id,
+    "bpp_uri": bpp_uri,
+    "bap_id": $env.PS_BAP_ID,
+    "action": $action,
+    "bap_uri": $env.PS_BAP_URI,
+    "version": "1.1.0",
+    "transaction_id": transaction_id ? transaction_id : $uuid(),
+    "message_id": message_id ? message_id : $uuid(),
+    "location": {
+      "country": {
+        "name": $env.PS_COUNTRY_NAME,
+        "code": $env.PS_COUNTRY_CODE
+      },
+      "city": {
+        "name": $env.PS_CITY_NAME,
+        "code": $env.PS_CITY_CODE
+      }
+    },
+    "ttl": "PT10M",
+    "key": key,
+    "timestamp": $moment().toISOString()
+}
diff --git a/mappings/init.jsonata b/mappings/init.jsonata
new file mode 100644
index 0000000000000000000000000000000000000000..64fe7ea89bfa2b7380761d50354d7ca2d43acd8c
--- /dev/null
+++ b/mappings/init.jsonata
@@ -0,0 +1,6 @@
+$.data.message.orders.{
+        "context": $context(%.%.context, $action),
+        "message": {
+            "order": $
+        }
+}[]
diff --git a/mappings/on_init.jsonata b/mappings/on_init.jsonata
new file mode 100644
index 0000000000000000000000000000000000000000..7d8f731b948bb51a0cfa99f6c435bd53ac29f4e9
--- /dev/null
+++ b/mappings/on_init.jsonata
@@ -0,0 +1,61 @@
+$.responses.{   
+    "context":context,
+    "message": {
+        "order": {
+            "type": message.order.type,
+            "provider": {
+                "id": message.order.provider.id,
+                "name": message.order.provider.descriptor.name,
+                "short_desc": message.order.provider.descriptor.short_desc,
+                "long_desc": message.order.provider.descriptor.long_desc,
+                "rating": message.order.provider.rating,
+                "images": message.order.provider.descriptor.images.{
+                    "url": url,
+                    "size_type": size_type
+                },
+                "media": message.order.provider.descriptor.media.{
+                    "url": url
+                }
+            },
+            "items": message.order.items.{
+                "id": id,
+                "name": descriptor.name,
+                "short_desc": descriptor.short_desc,
+                "long_desc": descriptor.long_desc,
+                "price": price,
+                "rating": rating,
+                "rateable": rateable,
+                "time": time,
+                "quantity": quantity,
+                "categories": $map(
+                    $filter(%.provider.categories, function($category) { $boolean($category.id in category_ids)}),
+                    function($category) {
+                        { "id": $category.id, "name": $category.descriptor.name, "code": $category.descriptor.code }
+                    }
+                )[],
+                "locations": $map(
+                    $filter(%.provider.locations, function($location) { $boolean($location.id in location_ids)}),
+                    function($location) { 
+                        {
+                            "id": $location.id,
+                            "city": $location.city.name,
+                            "state": $location.state.name,
+                            "country": $location.country.name
+                        }
+                    }
+                )[],
+                "tags": tags.{
+                    "code": descriptor.code,
+                    "name": descriptor.name,
+                    "display": display,
+                    "list": list.{ "code": descriptor.code, "name": descriptor.name, "value": value }[]
+                }[]
+            },
+            "fulfillments": message.order.fulfillments,
+            "quote": message.order.quote,
+            "billing": message.order.billing,
+            "payments": message.order.payments,
+            "cancellation_terms": message.order.cancellation_terms
+        }
+    }
+}[]
diff --git a/mappings/on_select.jsonata b/mappings/on_select.jsonata
index 97ced2b8b6d5870fdbb1093c0684b4e08106479e..ddd202454d9aa934226c69269a4d2b26b8826af3 100644
--- a/mappings/on_select.jsonata
+++ b/mappings/on_select.jsonata
@@ -1,5 +1,6 @@
-{
-    "data": responses.{
+$.responses.{
+    "context": context,
+    "message": {
         "order": {
             "type": message.order.type,
             "quote": message.order.quote,
@@ -52,5 +53,5 @@
                 }[]
             }
         }
-    }[]
-}
+    }
+}[]
diff --git a/mappings/search.jsonata b/mappings/search.jsonata
index a9db61437d64bd3074a7a4c8c13536c12f79d6ec..711b24f083721fe3c5571aa318ab80b7bdc8ebf1 100644
--- a/mappings/search.jsonata
+++ b/mappings/search.jsonata
@@ -1,5 +1,5 @@
 {
-    "context":context,
+    "context": $context(context, $action), 
     "message":{
         "intent":{
             "item":{
@@ -26,7 +26,8 @@
                     "name":provider.providerName
                 },
                 "locations":$map( provider.providerCity, function($location) {
-                    {"city":{
+                    {
+                        "city":{
                         "name":$location
                     }}
                 })[],
@@ -51,4 +52,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/mappings/select.jsonata b/mappings/select.jsonata
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..64fe7ea89bfa2b7380761d50354d7ca2d43acd8c 100644
--- a/mappings/select.jsonata
+++ b/mappings/select.jsonata
@@ -0,0 +1,6 @@
+$.data.message.orders.{
+        "context": $context(%.%.context, $action),
+        "message": {
+            "order": $
+        }
+}[]
diff --git a/package.json b/package.json
index 7a05548947f4cd75019196698988ac76f0fc05cc..d455fbd8d7c12e2b71e29331b7eb956aac5b51db 100644
--- a/package.json
+++ b/package.json
@@ -1,47 +1,34 @@
 {
-  "name": "generic-client-layer",
+  "name": "gcl",
   "version": "1.0.0",
-  "description": "Beckn Generic Client Layer",
-  "main": "index.ts",
+  "description": "",
+  "main": "index.js",
   "scripts": {
-    "test": "node dist/index.js",
-    "start": "node dist/index.js",
-    "start:dev": "concurrently \"npx tsc --watch\" \"nodemon --delay 1000ms -q dist/index.js\"",
-    "dev": "nodemon src/index.ts",
-    "build": "npx tsc"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "start": "nodemon src/app.ts"
   },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/beckn/generic-client-layer.git"
-  },
-  "author": "beckn",
+  "keywords": [],
+  "author": "",
   "license": "ISC",
-  "bugs": {
-    "url": "https://github.com/beckn/generic-client-layer/issues"
-  },
-  "homepage": "https://github.com/beckn/generic-client-layer#readme",
   "dependencies": {
     "app-root-path": "^3.1.0",
-    "axios": "^1.6.1",
-    "class-transformer": "^0.5.1",
-    "concurrently": "^8.2.2",
-    "cors": "^2.8.5",
+    "axios": "^1.6.2",
     "dotenv": "^16.3.1",
     "express": "^4.18.2",
-    "joi": "^17.11.0",
+    "ini": "^4.1.1",
+    "inversify": "^6.0.2",
+    "inversify-express-utils": "^6.4.6",
     "jsonata": "^2.0.3",
-    "lodash": "^4.17.21",
     "moment": "^2.29.4",
     "reflect-metadata": "^0.1.13",
-    "uuid": "^9.0.1"
+    "uuid": "^9.0.1",
+    "winston": "^3.11.0",
+    "winston-express": "^0.1.1"
   },
   "devDependencies": {
-    "@types/cors": "^2.8.15",
-    "@types/express": "^4.17.20",
-    "@types/lodash": "^4.14.200",
-    "@types/node": "^20.8.7",
-    "@types/uuid": "^9.0.6",
-    "nodemon": "^3.0.1",
-    "typescript": "^5.2.2"
+    "@types/express": "^4.17.21",
+    "@types/ini": "^1.3.33",
+    "@types/uuid": "^9.0.7",
+    "nodemon": "^3.0.1"
   }
 }
diff --git a/src/App.ts b/src/App.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b594afaf3f27004c8e8d80a10faa846fc7ffd984
--- /dev/null
+++ b/src/App.ts
@@ -0,0 +1,39 @@
+import express, { Application } from 'express';
+import { container, server } from './inversify/inversify.config';
+import './gcl/gcl.controller';
+import { ConfigService } from './config/config.service';
+import { AppLogger } from './app/app.logger';
+import { ErrorHandlerMiddleware } from './middleware/errorhandler.middleware';
+
+class App {
+    public app: Application;
+
+    constructor() {
+        this.app = express();
+        this.config();
+        this.setupMiddlewares();
+    }
+
+    private config(): void {
+        server.setConfig((app) => {
+            app.use(express.json());
+            app.use(express.urlencoded({ extended: true }))
+        });
+        this.app.use(server.build());
+    }
+
+    private setupMiddlewares() {
+        const errorHandlerMiddleware = container.get<ErrorHandlerMiddleware>(ErrorHandlerMiddleware);
+        this.app.use(errorHandlerMiddleware.handleError.bind(errorHandlerMiddleware));
+    }
+}
+
+const configService = container.resolve<ConfigService>(ConfigService);
+const logger = container.resolve<AppLogger>(AppLogger);
+
+const app = new App().app;
+const port = configService.getAppPort();
+
+app.listen(port, () => {
+    logger.info(`Server is running on http://localhost:${port}`);
+});
diff --git a/src/app/app.logger.ts b/src/app/app.logger.ts
new file mode 100644
index 0000000000000000000000000000000000000000..888ce871835982285a923a2cdaf8a28f733faed3
--- /dev/null
+++ b/src/app/app.logger.ts
@@ -0,0 +1,39 @@
+import { injectable } from "inversify";
+import winston, { Logger, format } from "winston";
+import { format as printf } from 'util';
+
+@injectable()
+export class AppLogger {
+    private logger: Logger;
+
+    constructor() {
+        const logFormat = format.printf(info => `\n${info.timestamp} [${info.level}]: ${info.message}`)
+        this.logger = winston.createLogger({
+            level: 'info',
+            format: winston.format.combine(
+                winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), // Add timestamp to the log message
+                winston.format.simple()
+            ),
+            transports: [
+                new winston.transports.Console({
+                    format: format.combine(format.colorize(), logFormat, format.splat()),
+                }),
+                new winston.transports.File({ filename: 'logs/error.log', level: 'error', format: format.combine(format.colorize(), format.json()) }),
+                new winston.transports.File({ filename: 'logs/combined.log', format: format.combine(format.colorize(), format.json()) }),
+            ],
+            exitOnError: false
+        });
+    }
+
+    public info(message: string, ...args: any[]): void {
+        this.logger.info(this.formatMessage(message, args));
+    }
+
+    public error(message: string, ...args: any[]): void {
+        this.logger.error(this.formatMessage(message, args));
+    }
+
+    private formatMessage(message: string, args: any[]): string {
+        return args.length > 0 ? printf(message, ...args) : message;
+    }
+}
diff --git a/src/app/app.ts b/src/app/app.ts
deleted file mode 100644
index 68823c965eb37b2bb5b92eb06029e91139bde1c1..0000000000000000000000000000000000000000
--- a/src/app/app.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import express, { Express, Router, Request, Response } from "express";
-import cors from "cors";
-import dotenv from "dotenv";
-import { clientLayerRoutes } from "./routes";
-
-interface InitAppParams {
-  app: Express;
-}
-
-const initApp = ({ app }: InitAppParams) => {
-  const router: Router = express.Router();
-  dotenv.config();
-  app.options(
-    "*",
-    cors<Request>({
-      origin: process.env.NODE_ENV === "*",
-      optionsSuccessStatus: 200,
-      credentials: true,
-      methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"]
-    })
-  );
-
-  app.use(
-    cors({
-      origin: process.env.NODE_ENV === "*",
-      methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"]
-    })
-  );
-
-  app.set("trust proxy", true);
-  app.use(express.urlencoded({ extended: true, limit: "200mb" }));
-  app.use(express.json({ limit: "200mb" }));
-  app.use(router);
-
-  router.use("/ping", (req: Request, res: Response) => {
-    res.json({
-      status: 200,
-      message: "Generic Client Layer Started"
-    });
-  });
-  router.use(clientLayerRoutes());
-  return app;
-};
-
-export { initApp };
diff --git a/src/app/index.ts b/src/app/index.ts
deleted file mode 100644
index 9bf9b1b68aa2e1dd6e9b33eefc7fd18cce761d4d..0000000000000000000000000000000000000000
--- a/src/app/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./routes";
diff --git a/src/app/routes.ts b/src/app/routes.ts
deleted file mode 100644
index a588241a92298056e7c15ef36b9747269f779c2b..0000000000000000000000000000000000000000
--- a/src/app/routes.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import express, { Router } from "express";
-import { validateRequest } from "../common";
-import { searchController } from "../modules/search/controller";
-import { selectController } from "../modules/select/controller";
-const router: Router = express.Router();
-
-export const clientLayerRoutes = () => {
-  router.post("/search", validateRequest, searchController);
-  router.post("/select", validateRequest, selectController);
-  router.post("/init", validateRequest, () => {});
-  router.post("/confirm", validateRequest, () => {});
-  router.post("/update", validateRequest, () => {});
-  router.post("/status", validateRequest, () => {});
-  router.post("/cancel", validateRequest, () => {});
-  router.post("/track", validateRequest, () => {});
-  router.post("/support", validateRequest, () => {});
-  router.post("/rating", validateRequest, () => {});
-
-  return router;
-};
diff --git a/src/app/server.ts b/src/app/server.ts
deleted file mode 100644
index ca01a2611d7291fe6a362b2ba4ace425a9106951..0000000000000000000000000000000000000000
--- a/src/app/server.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { initApp } from "./app";
-import { Express } from "express";
-export const startServer = async (app: Express) => {
-  const serverApp = initApp({ app });
-  const PORT: string = process.env.PORT || "3009";
-
-  serverApp.listen(PORT, () => {
-    console.log(`Server is running on port ${PORT}`);
-  });
-};
diff --git a/src/common/context.ts b/src/common/context.ts
deleted file mode 100644
index 4e11d94e2c2236aac013078ff22cd379c13431f0..0000000000000000000000000000000000000000
--- a/src/common/context.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import { IRequestContext, requestContextSchema } from "./schemaValidator";
-import { v4 as uuid } from "uuid";
-import moment from "moment";
-export interface IRequestContextStructure_ver_1_1_0 {
-  domain: string;
-  location: {
-    id?: string;
-    descriptor?: {
-      name?: string;
-      code?: string;
-      short_desc?: string;
-      long_desc?: string;
-      additional_desc?: {
-        url?: string;
-        content_type?: "text/plain";
-      };
-      media?: [
-        {
-          mimetype?: string;
-          url?: string;
-          signature?: string;
-          dsa?: string;
-        }
-      ];
-      images?: [
-        {
-          url?: string;
-          size_type?: string;
-          width?: string;
-          height?: string;
-        }
-      ];
-    };
-    map_url?: string;
-    gps?: string;
-    address?: string;
-    city?: {
-      name?: string;
-      code?: string;
-    };
-    district?: string;
-    state?: {
-      name?: string;
-      code?: string;
-    };
-    country?: {
-      name?: string;
-      code?: string;
-    };
-    area_code?: string;
-    circle?: {
-      gps?: string;
-      radius?: {
-        type?: string;
-        value?: string;
-        estimated_value?: string;
-        computed_value?: string;
-        range?: {
-          min?: string;
-          max?: string;
-        };
-        unit?: string;
-      };
-    };
-    polygon?: string;
-    rating?: string;
-  };
-  action: string;
-  version: string;
-  bap_id: string;
-  bap_uri: string;
-  bpp_id?: string;
-  bpp_uri?: string;
-  transaction_id: string;
-  message_id: string;
-  timestamp?: string;
-  key?: string;
-  ttl?: string;
-}
-
-interface IResponseContextStructure_ver_1_1_0 {
-  bapId?: string;
-  messageId?: string;
-  transactionId?: string;
-  bapUri?: string;
-  bppId?: string;
-  bppUri?: string;
-  domain?: string;
-}
-
-export const buildRequestContextVer1_1_0 = (
-  input: IRequestContext,
-  action: string
-) => {
-  const {
-    bppId,
-    bppUri,
-    domain,
-    messageId,
-    transactionId,
-    bapId,
-    bapUri,
-    key
-  } = input;
-  const context: IRequestContextStructure_ver_1_1_0 = {
-    domain: domain,
-    bpp_id: bppId,
-    bpp_uri: bppUri,
-    bap_id: bapId || `${process.env.BAP_ID}`,
-    action: action,
-    bap_uri: bapUri || `${process.env.BAP_URI}`,
-    version: "1.1.0",
-    transaction_id: transactionId || uuid(),
-    message_id: messageId || uuid(),
-    location: {
-      country: {
-        name: `${process.env.COUNTRY_NAME}`,
-        code: `${process.env.COUNTRY_CODE}`
-      },
-      city: {
-        name: `${process.env.CITY_NAME}`,
-        code: `${process.env.CITY_CODE}`
-      }
-    },
-    ttl: "PT10M",
-    key: key,
-    timestamp: moment().toISOString()
-  };
-  return context;
-};
-
-export const responseContextBuilderVer1_1_0 = (
-  context: IRequestContextStructure_ver_1_1_0
-): IResponseContextStructure_ver_1_1_0 => {
-  return {
-    messageId: context?.message_id,
-    transactionId: context?.transaction_id,
-    bppId: context?.bpp_id,
-    bppUri: context?.bpp_uri,
-    domain: context?.domain
-  };
-};
diff --git a/src/common/index.ts b/src/common/index.ts
deleted file mode 100644
index 69d98a97d487e0f6141cc34bb96b4451893ccfaf..0000000000000000000000000000000000000000
--- a/src/common/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./context";
-export * from "./schemaValidator";
-export * from "./schemaObjectGenerator";
diff --git a/src/common/mapper.service.ts b/src/common/mapper.service.ts
deleted file mode 100644
index 26d34b4931462636038e0e4723069bc655975328..0000000000000000000000000000000000000000
--- a/src/common/mapper.service.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import fs from "fs";
-import path from "path";
-import appRootPath from 'app-root-path';
-import jsonata from 'jsonata';
-import { removeEmptyObjectKeys } from './utils'
-
-export const map = async (data: any, action?: string) => {
-  const expression = jsonata(fs.readFileSync(path.join(appRootPath.toString(), `/mappings/${action}.jsonata`), "utf8"));
-
-  let mapped = await expression.evaluate(data);
-  mapped = removeEmptyObjectKeys(mapped);
-  return mapped;
-};
diff --git a/src/common/mappingJsons/request/searchJson.json b/src/common/mappingJsons/request/searchJson.json
deleted file mode 100644
index f7fc8f155d2d115834826711a027ed15ab859267..0000000000000000000000000000000000000000
--- a/src/common/mappingJsons/request/searchJson.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "searchString": {
-    "path": "message.intent.item.descriptor.name"
-  },
-  "itemId": { "path": "message.intent.item.id" },
-  "fulfillment.agentName": {
-    "path": "message.intent.fulfillment.agent.person.name"
-  },
-  "fulfillment.customerGender": {
-    "path": "message.intent.fulfillment.customer.person.gender"
-  },
-
-  "provider.providerName": {
-    "path": "message.intent.provider.descriptor.name"
-  },
-  "provider.providerCity": {
-    "path": "message.intent.provider.locations[0].city.name"
-  },
-  "provider.providerId": { "path": "message.intent.provider.id" },
-  "category.categoryCode": {
-    "path": "message.intent.category.descriptor.code"
-  },
-  "category.categoryName": {
-    "path": "message.intent.category.descriptor.name"
-  },
-  "category.categoryId": {
-    "path": "message.intent.category.id"
-  },
-  "location": { "path": "message.intent.location.circle.gps" }
-}
diff --git a/src/common/mappingJsons/response/on_search.json b/src/common/mappingJsons/response/on_search.json
deleted file mode 100644
index 62bbba3f690865e6e9be7991ef2692b8b8baa2a2..0000000000000000000000000000000000000000
--- a/src/common/mappingJsons/response/on_search.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "context": {
-        "path": "context"
-    },
-    "message.catalog.descriptor.name": {
-        "path": "title"
-    }
-}
diff --git a/src/common/protocol-server.service.ts b/src/common/protocol-server.service.ts
deleted file mode 100644
index eb98b925e423252dcbad33ce6562a13bb33cb3f4..0000000000000000000000000000000000000000
--- a/src/common/protocol-server.service.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { IRequestContextStructure_ver_1_1_0 } from "../common/context";
-import axios from "axios";
-
-export class ProtocolServer {
-  bap_client_URL = process.env.BAP_CLIENT_URI as string;
-  context: IRequestContextStructure_ver_1_1_0;
-  message: any;
-  constructor(payload: {
-    context: IRequestContextStructure_ver_1_1_0;
-    message: any;
-  }) {
-    this.context = payload.context;
-    this.message = payload.message;
-  }
-  async call() {
-    const payload = {
-      context: this.context,
-      message: this.message
-    };
-    return axios.post(`${this.bap_client_URL}/${this.context.action}`, payload);
-  }
-}
diff --git a/src/common/schemaObjectGenerator.ts b/src/common/schemaObjectGenerator.ts
deleted file mode 100644
index 41df5692d49eac133f31ea7bb6b41237d0cedb7f..0000000000000000000000000000000000000000
--- a/src/common/schemaObjectGenerator.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import _ from "lodash";
-export interface IDescriptorOutput {
-  name?: string;
-  code?: string;
-  short_desc?: string;
-  long_desc?: string;
-  additional_desc?: {
-    url?: string;
-    content_type?: "text/plain" | "text/html" | "application/json";
-  };
-  media?: {
-    mimetype?: string;
-    url?: string;
-    signature?: string;
-    dsa?: string;
-  }[];
-  images?: {
-    url?: string;
-    size_type?: "xs" | "sm" | "md" | "lg" | "xl" | "custom";
-    width?: string;
-    height?: string;
-  }[];
-}
-interface DescriptorGeneratorInput {
-  descriptionName?: string;
-  descriptionCode?: string;
-  shortDesc?: string;
-  longDesc?: string;
-  media?: any[];
-  images?: any[];
-  descriptionUrl?: string;
-  descriptionUrlContentType?: string;
-}
-
-export const descriptorGenerator = (
-  input: DescriptorGeneratorInput
-): IDescriptorOutput => {
-  let obj: any = {
-    ...(input?.descriptionName && { name: input?.descriptionName }),
-    ...(input?.descriptionCode && { code: input?.descriptionCode }),
-    ...(input?.shortDesc && { short_desc: input?.shortDesc }),
-    ...(input?.longDesc && { long_desc: input?.longDesc }),
-    ...(() => {
-      if (input?.media?.length) {
-        return {
-          media: input?.media?.map((medi: any) => ({
-            mimetype: medi?.mimetype,
-            url: medi?.url,
-            signature: medi?.signature,
-            dsa: medi?.dsa
-          }))
-        };
-      }
-    })(),
-    ...(() => {
-      if (input?.images?.length) {
-        return {
-          images: input?.images?.map((image: any) => ({
-            url: image?.url,
-            size_type: image?.sizeType,
-            width: image?.width,
-            height: image?.height
-          }))
-        };
-      }
-    })(),
-    ...(() => {
-      if (input?.descriptionUrl)
-        return {
-          additional_desc: {
-            url: input?.descriptionUrl,
-            content_type: input?.descriptionUrlContentType
-          }
-        };
-    })()
-  };
-
-  return obj;
-};
diff --git a/src/common/schemaValidator.ts b/src/common/schemaValidator.ts
deleted file mode 100644
index 847c6d67a0a0f44b4f3547e69c7c3b2241f842f0..0000000000000000000000000000000000000000
--- a/src/common/schemaValidator.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import Joi from "joi";
-import { Request, Response, NextFunction } from "express";
-
-export interface IRequestContext {
-  domain: string;
-  bppId?: string;
-  bppUri?: string;
-  transactionId: string;
-  messageId: string;
-  bapId?: string;
-  bapUri?: string;
-  key?: string;
-}
-
-export const requestContextSchema = Joi.object({
-  domain: Joi.string().required(),
-  bppId: Joi.string().optional(),
-  bppUri: Joi.string().optional(),
-  transactionId: Joi.string().optional(),
-  messageId: Joi.string().optional(),
-  key: Joi.string().optional()
-});
-
-export const requestSchema = Joi.object({
-  context: requestContextSchema.required()
-});
-
-export const validateRequest = (
-  req: Request,
-  res: Response,
-  next: NextFunction
-) => {
-  const { error } = requestSchema.validate(req.body, { allowUnknown: true });
-  if (error) {
-    return res.status(400).send({
-      message: "Invalid Request",
-      data: error.message,
-      success: false
-    });
-  }
-  return next();
-};
diff --git a/src/common/utils.ts b/src/common/utils.ts
deleted file mode 100644
index 1e4863712044b49931145d23915c7bfcfe3eeb72..0000000000000000000000000000000000000000
--- a/src/common/utils.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export function removeEmptyObjectKeys(obj: any) {
-    for (const key in obj) {
-        if (typeof obj[key] === 'object' && obj[key] !== null) {
-            removeEmptyObjectKeys(obj[key]);
-            if (Object.keys(obj[key]).length === 0) {
-                delete obj[key];
-            }
-        }
-    }
-    return obj;
-}
diff --git a/src/config/config.service.ts b/src/config/config.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4dfff5094b0e9efe0b88a0e33cbf108820bb6bb7
--- /dev/null
+++ b/src/config/config.service.ts
@@ -0,0 +1,100 @@
+import { injectable } from 'inversify';
+import 'reflect-metadata';
+import * as dotenv from 'dotenv';
+
+@injectable()
+export class ConfigService {
+    private readonly apiKey: string;
+    private readonly appName;
+    private readonly appEnv;
+    private readonly appKey;
+    private readonly appDebug;
+    private readonly appPort;
+    private readonly appUrl;
+    private readonly psBaseUri;
+    private readonly psBapId;
+    private readonly psBapUri;
+    private readonly psCityName;
+    private readonly psCityCode;
+    private readonly psCountryName;
+    private readonly psCountryCode;
+
+
+    constructor() {
+        // Load environment variables from .env file
+        dotenv.config();
+
+        // Retrieve the API_KEY from environment variables
+        this.apiKey = process.env.APP_KEY || '';
+        this.appName = process.env.APP_NAME || '';
+        this.appEnv = process.env.APP_ENV || '';
+        this.appKey = process.env.APP_KEY || '';
+        this.appDebug = process.env.APP_DEBUG || '';
+        this.appPort = process.env.APP_PORT || '';
+        this.appUrl = process.env.APP_URL || '';
+        this.psBaseUri = process.env.PS_BASE_URI || '';
+        this.psBapId = process.env.PS_BAP_ID || '';
+        this.psBapUri = process.env.PS_BAP_URI || '';
+        this.psCityName = process.env.PS_CITY_NAME || '';
+        this.psCityCode = process.env.PS_CITY_CODE || '';
+        this.psCountryName = process.env.PS_COUNTRY_NAME || '';
+        this.psCountryCode = process.env.PS_COUNTRY_CODE || '';
+    }
+
+    getApiKey(): string {
+        return this.apiKey;
+    }
+
+    getAppName(): string {
+        return this.appName;
+    };
+
+    getAppEnv(): string {
+        return this.appEnv;
+    };
+
+    getAppKey(): string {
+        return this.appKey;
+    };
+
+    getAppDebug(): string {
+        return this.appDebug;
+    };
+
+    getAppPort(): string {
+        return this.appPort;
+    };
+
+    getAppUrl(): string {
+        return this.appUrl;
+    };
+
+    getPsBaseUri(): string {
+        return this.psBaseUri;
+    };
+
+    getPsBapId(): string {
+        return this.psBapId;
+    };
+
+    getPsBapUri(): string {
+        return this.psBapUri;
+    };
+
+    getPsCityName(): string {
+        return this.psCityName;
+    };
+
+    getPsCityCode(): string {
+        return this.psCityCode;
+    };
+
+    getPsCountryName(): string {
+        return this.psCountryName;
+    };
+
+    getPsCountryCode(): string {
+        return this.psCountryCode;
+    };
+
+}
diff --git a/src/gcl/gcl.controller.ts b/src/gcl/gcl.controller.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6e9bfa46f94a69075cb2a8977693faa4a482e9d
--- /dev/null
+++ b/src/gcl/gcl.controller.ts
@@ -0,0 +1,39 @@
+import { inject } from "inversify";
+import { controller, httpPost, requestBody } from "inversify-express-utils";
+import { GCLService } from "./gcl.service";
+
+@controller('/')
+export class GCLController {
+
+    constructor(@inject(GCLService) private service: GCLService) { }
+
+    @httpPost('search')
+    public async search(@requestBody() body: any): Promise<any> {
+        const searchResult = await this.service.search(body);
+        return searchResult;
+    }
+
+    @httpPost('select')
+    public async select(@requestBody() body: any): Promise<any> {
+        const selectResult = await this.service.select(body);
+        return selectResult;
+    }
+
+    @httpPost('init')
+    public async init(@requestBody() body: any): Promise<any> {
+        const initResult = await this.service.init(body);
+        return initResult;
+    }
+
+    @httpPost('confirm')
+    public async confirm(@requestBody() body: any): Promise<any> {
+        const confirmResult = await this.service.confirm(body);
+        return confirmResult;
+    }
+
+    @httpPost('status')
+    public async status(@requestBody() body: any): Promise<any> {
+        const statusResult = await this.service.status(body);
+        return statusResult;
+    }
+}
diff --git a/src/gcl/gcl.service.ts b/src/gcl/gcl.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a490664626e6085f2730c6d96bd60d3dbd54b396
--- /dev/null
+++ b/src/gcl/gcl.service.ts
@@ -0,0 +1,55 @@
+import { inject, injectable } from "inversify";
+import { TLService } from "../tl/tl.service";
+import { PSClientService } from "../psclient/psclient.service";
+
+@injectable()
+export class GCLService {
+    constructor(
+        @inject(TLService) private tlService: TLService,
+        @inject(PSClientService) private psClientService: PSClientService
+    ) { }
+
+    async search(body: any) {
+        const payload = await this.tlService.transform(body, "search");
+        const psResponse = await this.psClientService.post(payload);
+        const response = await this.tlService.transform(psResponse, "on_search");
+
+        return response;
+    }
+
+    async select(body: any) {
+        const payload = await this.tlService.transform(body, "select");
+        const psResponse = await this.psClientService.postMany(payload);
+        const response = await this.tlService.transform(psResponse, "on_select");
+
+        return response;
+    }
+
+    async init(body: any) {
+        const payload = await this.tlService.transform(body, "init");
+        const psResponse = await this.psClientService.postMany(payload);
+        const response = await this.tlService.transform(psResponse, "on_init");
+
+        return response;
+    }
+
+    async confirm(body: any) {
+        // const payload = await this.tlService.transform(body, "select");
+        // const psResponse = await this.psClientService.postMany(payload);
+        // const response = await this.tlService.transform(psResponse, "on_select");
+
+        // return response;
+
+        return "In Progress";
+    }
+
+    async status(body: any) {
+        // const payload = await this.tlService.transform(body, "select");
+        // const psResponse = await this.psClientService.postMany(payload);
+        // const response = await this.tlService.transform(psResponse, "on_select");
+
+        // return response;
+
+        return "In Progress";
+    }
+}
diff --git a/src/httpclient/http.service.ts b/src/httpclient/http.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..266567786e9200d8ada701233e8de0aef317c64e
--- /dev/null
+++ b/src/httpclient/http.service.ts
@@ -0,0 +1,60 @@
+import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
+import { inject, injectable } from 'inversify';
+import { AppLogger } from '../app/app.logger';
+
+@injectable()
+class HttpClient {
+    private readonly client: AxiosInstance;
+
+    constructor(@inject(AppLogger) private logger: AppLogger) {
+        this.client = axios.create({
+            headers: {
+                'Content-Type': 'application/json',
+            },
+        });
+
+        // Add request interceptor
+        this.client.interceptors.request.use((config: InternalAxiosRequestConfig) => {
+            // Modify the request config if needed
+            logger.info("Making network request: \n%s %s\nHEADERS %s \nDATA %o", config.method?.toUpperCase(), config.url, JSON.stringify(config.headers), JSON.stringify(config.data));
+            return config;
+        }, (error: any) => {
+            // Handle request error
+            logger.error("Request error: \n%o", error.data);
+            return Promise.reject(error);
+        });
+
+        // Add response interceptor
+        this.client.interceptors.response.use((response: AxiosResponse) => {
+            // Modify the response data if needed
+            logger.info("Response received: %o\n", JSON.stringify(response.data));
+            return response;
+        }, (error: any) => {
+            // Handle response error
+            logger.error("Response error: %o", error.message);
+            return Promise.reject(error);
+        });
+    }
+
+    async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
+        const response: AxiosResponse<T> = await this.client.get(url, config);
+        return response.data;
+    }
+
+    async post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<T> {
+        const response: AxiosResponse<T> = await this.client.post(url, data, config);
+        return response.data;
+    }
+
+    async put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<T> {
+        const response: AxiosResponse<T> = await this.client.put(url, data, config);
+        return response.data;
+    }
+
+    async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
+        const response: AxiosResponse<T> = await this.client.delete(url, config);
+        return response.data;
+    }
+}
+
+export default HttpClient;
diff --git a/src/index.ts b/src/index.ts
deleted file mode 100644
index b0bbbe55b73d2a18ccc46774ba3c41fc35ad0d6a..0000000000000000000000000000000000000000
--- a/src/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import express, { Express } from "express";
-import { startServer } from "./app/server";
-import dotenv from "dotenv";
-const app: Express = express();
-
-dotenv.config();
-
-startServer(app);
diff --git a/src/inversify/inversify.config.ts b/src/inversify/inversify.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6e05b460ede0d1d096f1dda6836d8de68f2c446
--- /dev/null
+++ b/src/inversify/inversify.config.ts
@@ -0,0 +1,23 @@
+import { Container } from 'inversify';
+import "reflect-metadata";
+import { ConfigService } from '../config/config.service';
+import { GCLService } from '../gcl/gcl.service';
+import { TLService } from '../tl/tl.service';
+import { InversifyExpressServer } from 'inversify-express-utils';
+import { PSClientService } from '../psclient/psclient.service';
+import { AppLogger } from '../app/app.logger';
+import HttpClient from '../httpclient/http.service';
+import { ErrorHandlerMiddleware } from '../middleware/errorhandler.middleware';
+
+const container = new Container();
+const server = new InversifyExpressServer(container);
+
+container.bind<ConfigService>(ConfigService).to(ConfigService);
+container.bind<GCLService>(GCLService).to(GCLService);
+container.bind<TLService>(TLService).to(TLService);
+container.bind<PSClientService>(PSClientService).to(PSClientService);
+container.bind<AppLogger>(AppLogger).to(AppLogger);
+container.bind<HttpClient>(HttpClient).to(HttpClient);
+container.bind<ErrorHandlerMiddleware>(ErrorHandlerMiddleware).toSelf();
+
+export { server, container };
diff --git a/src/middleware/errorhandler.middleware.ts b/src/middleware/errorhandler.middleware.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ed854f39a9b822b3f36eb6fae4580a5821cfb4ec
--- /dev/null
+++ b/src/middleware/errorhandler.middleware.ts
@@ -0,0 +1,18 @@
+import { inject, injectable } from 'inversify';
+import { Request, Response, NextFunction } from 'express';
+import { AppLogger } from '../app/app.logger';
+
+@injectable()
+export class ErrorHandlerMiddleware {
+    constructor(@inject(AppLogger) private logger: AppLogger) { }
+
+    public handleError(error: Error, req: Request, res: Response, next: NextFunction): void {
+        this.logger.error("%s", error.stack);
+        const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
+        res.status(statusCode).json({
+            error: {
+                message: error.message
+            },
+        });
+    }
+}
diff --git a/src/modules/cancel/controller.ts b/src/modules/cancel/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/cancel/schemaHelper.ts b/src/modules/cancel/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/cancel/service.ts b/src/modules/cancel/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/confirm/controller.ts b/src/modules/confirm/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/confirm/schemaHelper.ts b/src/modules/confirm/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/confirm/service.ts b/src/modules/confirm/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/init/controller.ts b/src/modules/init/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/init/schemaHelper.ts b/src/modules/init/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/init/service.ts b/src/modules/init/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/rating/controller.ts b/src/modules/rating/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/rating/schemaHelper.ts b/src/modules/rating/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/rating/service.ts b/src/modules/rating/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/search/controller.ts b/src/modules/search/controller.ts
deleted file mode 100644
index 3a9cdad63f2664d18614a90a32ce18a93b90489f..0000000000000000000000000000000000000000
--- a/src/modules/search/controller.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Request, Response, NextFunction } from "express";
-import { searchService } from "./service";
-
-export const searchController = async (
-  req: Request,
-  res: Response,
-  next: NextFunction
-) => {
-  try {
-    const payloadForBAP = await searchService(req?.body);
-    return res.status(200).send(payloadForBAP);
-  } catch (error: any) {
-    return res.status(400).json({ success: false, message: error.message });
-  }
-};
diff --git a/src/modules/search/service.ts b/src/modules/search/service.ts
deleted file mode 100644
index 3b1d449f7bd17e63b03894be68ee0f5bf7a3015b..0000000000000000000000000000000000000000
--- a/src/modules/search/service.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { buildRequestContextVer1_1_0 } from "../../common";
-import * as mapperService from "../../common/mapper.service";
-import { ProtocolServer } from "../../common/protocol-server.service";
-
-export const searchService = async (body: any) => {
-  try {
-    const context = buildRequestContextVer1_1_0(body?.context, "search");
-    const request = await mapperService.map({ ...body, context }, "search");
-    console.log(JSON.stringify(request));
-    const response = await new ProtocolServer(request).call();
-
-    return await mapperService.map(response.data, "on_search");
-  } catch (error: any) {
-    console.log(error.response.data.error.data.errors);
-  }
-};
diff --git a/src/modules/select/controller.ts b/src/modules/select/controller.ts
deleted file mode 100644
index 9140b1d62e1b8f3864388c2ca5e92d67f32f82c8..0000000000000000000000000000000000000000
--- a/src/modules/select/controller.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Request, Response, NextFunction } from "express";
-import { selectService } from "./service";
-
-export const selectController = async (
-    req: Request,
-    res: Response,
-    next: NextFunction
-) => {
-    try {
-        const payloadForBAP = await selectService(req?.body);
-        return res.status(200).send(payloadForBAP);
-    } catch (error: any) {
-        return res.status(400).json({ success: false, message: error.message });
-    }
-};
diff --git a/src/modules/select/schemaHelper.ts b/src/modules/select/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/select/service.ts b/src/modules/select/service.ts
deleted file mode 100644
index bf8c3ad4dfa87d868facf3a02e6eaeddf8ef39b1..0000000000000000000000000000000000000000
--- a/src/modules/select/service.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { buildRequestContextVer1_1_0 } from "../../common";
-import * as mapperService from "../../common/mapper.service";
-import { ProtocolServer } from "../../common/protocol-server.service";
-
-export const selectService = async (body: any) => {
-    try {
-        return await mapperService.map(response.data, "on_select");     // Response will hold response from PS
-    } catch (error: any) {
-        console.log(error.response.data.error.data.errors);
-    }
-};
diff --git a/src/modules/status/controller.ts b/src/modules/status/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/status/schemaHelper.ts b/src/modules/status/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/status/service.ts b/src/modules/status/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/support/controller.ts b/src/modules/support/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/support/schemaHelper.ts b/src/modules/support/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/support/service.ts b/src/modules/support/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/track/controller.ts b/src/modules/track/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/track/schemaHelper.ts b/src/modules/track/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/track/service.ts b/src/modules/track/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/update/controller.ts b/src/modules/update/controller.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/update/schemaHelper.ts b/src/modules/update/schemaHelper.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/modules/update/service.ts b/src/modules/update/service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/psclient/psclient.service.ts b/src/psclient/psclient.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ef5d300d79fa804cf1b698d529d062096a72825c
--- /dev/null
+++ b/src/psclient/psclient.service.ts
@@ -0,0 +1,34 @@
+import { inject, injectable } from "inversify";
+import { ConfigService } from "../config/config.service";
+import HttpClient from "../httpclient/http.service";
+
+@injectable()
+export class PSClientService {
+    private psBaseUri: string;
+
+    constructor(
+        @inject(ConfigService) private config: ConfigService,
+        @inject(HttpClient) private httpClient: HttpClient
+    ) {
+        this.psBaseUri = this.config.getPsBaseUri()
+    }
+
+    private buildUri(action: string) {
+        return `${this.psBaseUri}/${action}`;
+    }
+
+    private postPromise(payload: any): Promise<any> {
+        return this.httpClient.post(this.buildUri(payload.context.action), payload)
+    }
+
+    async post(payload: any): Promise<any> {
+        const response = await this.postPromise(payload);
+        return response;
+    }
+
+    async postMany(payloads: any[]): Promise<any> {
+        return await Promise.all(payloads.map((payload: any) =>
+            this.postPromise(payload)
+        ));
+    }
+}
diff --git a/src/tl/tl.helper.ts b/src/tl/tl.helper.ts
new file mode 100644
index 0000000000000000000000000000000000000000..470481644bf949073c7bdbce970ec617b108de06
--- /dev/null
+++ b/src/tl/tl.helper.ts
@@ -0,0 +1,11 @@
+import jsonata from "jsonata";
+import path from 'path';
+import fs from 'fs';
+import appRootPath from 'app-root-path';
+import moment from 'moment';
+import { v4 as uuid } from 'uuid';
+
+export const context = async (data: any, action: string) => {
+    const expression = jsonata(fs.readFileSync(path.join(appRootPath.toString(), `/mappings/context.jsonata`), "utf8"));
+    return await expression.evaluate(data, { env: process.env, moment, uuid, action });
+}
diff --git a/src/tl/tl.service.ts b/src/tl/tl.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..728d19d9c77a84fb15b0bc30c67899a82ee496f5
--- /dev/null
+++ b/src/tl/tl.service.ts
@@ -0,0 +1,23 @@
+import { inject, injectable } from "inversify";
+import jsonata from "jsonata";
+import path from 'path';
+import appRootPath from "app-root-path";
+import fs from 'fs';
+import { ObjectUtil } from "../util/object.util";
+import * as tlHelpers from './tl.helper'
+import { AppLogger } from "../app/app.logger";
+
+@injectable()
+export class TLService {
+    constructor(@inject(AppLogger) private logger: AppLogger) { }
+    async transform(data: any, action: string) {
+        const expression = jsonata(fs.readFileSync(path.join(appRootPath.toString(), `/mappings/${action}.jsonata`), "utf8"));
+
+        this.logger.info("Transforming %s data: \n%o", action, JSON.stringify(data));
+        let transformed = await expression.evaluate(data, { action, ...tlHelpers });
+        transformed = ObjectUtil.removeEmptyObjectKeys(transformed)
+        this.logger.info("Transformed %s data: \n%o", action, JSON.stringify(transformed));
+
+        return transformed;
+    }
+}
diff --git a/src/util/object.util.ts b/src/util/object.util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d9dd1294a99a2283eb66ef74f1f00cd3102a491e
--- /dev/null
+++ b/src/util/object.util.ts
@@ -0,0 +1,13 @@
+export class ObjectUtil {
+
+    static removeEmptyObjectKeys(obj: any) {
+        for (const key in obj) {
+            if (typeof obj[key] === 'object' && obj[key] !== null) {
+                this.removeEmptyObjectKeys(obj[key]);
+                if (Object.keys(obj[key]).length === 0) delete obj[key];
+            }
+        }
+        return obj;
+    }
+
+}
diff --git a/src/utils/index.ts b/src/utils/index.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tsconfig.json b/tsconfig.json
index 05fd2ca086c11389a4844d79c1c1f676c733006b..7c78d7f221fd6d9f9d355543e9844f495b9f4ec0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -100,6 +100,7 @@
 
     /* Completeness */
     // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
-    "skipLibCheck": true /* Skip type checking all .d.ts files. */
+    "skipLibCheck": true, /* Skip type checking all .d.ts files. */
+    "experimentalDecorators": true
   }
 }