364 lines
14 KiB
JavaScript
364 lines
14 KiB
JavaScript
const express = require('express');
|
|
const Joi = require('joi');
|
|
const {
|
|
getData, getServices, getResources, getPortals, getAllProjects, getAllProjectTasks,
|
|
getAllProjectTaskLists, getAllProjectIssues, getAllProjectPhases, getSalesOrders,
|
|
getPurchaseOrders, getInvoices, getDepartments, getLeaveRequests, getAttendance,
|
|
getOrganizations, getCustomers, getVendors, getItems, getEstimates, getBills,
|
|
getExpenses, getBankAccounts, getBankTransactions, getReports, getBooksSalesOrders,
|
|
getBooksPurchaseOrders, getContacts, getBooksContacts, getBooksInvoices, getEmployeeForms, getEmployeeById,
|
|
getAttendanceEntries, getShiftConfiguration, getLeaveData, getGoalsData, getPerformanceData,
|
|
getUserReport, getLeaveTrackerReport, getHolidays
|
|
} = require('../controllers/integrationController');
|
|
const auth = require('../middlewares/auth');
|
|
const ZohoHandler = require('../../integrations/zoho/handler');
|
|
|
|
const router = express.Router();
|
|
|
|
function validate(schema, source = 'query') {
|
|
return (req, res, next) => {
|
|
const data = source === 'body' ? req.body : req.query;
|
|
const { error, value } = schema.validate(data, { abortEarly: false, stripUnknown: true });
|
|
if (error) {
|
|
return res.status(400).json({
|
|
status: 'error',
|
|
message: 'Validation failed',
|
|
errorCode: 'VALIDATION_ERROR',
|
|
details: error.details,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
}
|
|
if (source === 'body') {
|
|
req.body = value;
|
|
} else {
|
|
req.query = value;
|
|
}
|
|
next();
|
|
};
|
|
}
|
|
|
|
// Get data from any provider/service/resource
|
|
const dataSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho', 'hubspot', 'quickbooks', 'bamboohr').required(),
|
|
service: Joi.string().required(),
|
|
resource: Joi.string().required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/data', auth, validate(dataSchema), getData);
|
|
|
|
// Get available services
|
|
const servicesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho', 'hubspot', 'quickbooks', 'bamboohr').required()
|
|
});
|
|
|
|
router.get('/services', auth, validate(servicesSchema), getServices);
|
|
|
|
// Get available resources
|
|
const resourcesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho', 'hubspot', 'quickbooks', 'bamboohr').required(),
|
|
service: Joi.string().required()
|
|
});
|
|
|
|
router.get('/resources', auth, validate(resourcesSchema), getResources);
|
|
|
|
// Get Zoho portals
|
|
const portalsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required()
|
|
});
|
|
|
|
// Zoho Projects specific routes with clear service identification
|
|
router.get('/zoho/projects/portals', auth, validate(portalsSchema), getPortals);
|
|
|
|
// Get all Zoho projects (across all portals)
|
|
const allProjectsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/projects/all-projects', auth, validate(allProjectsSchema), getAllProjects);
|
|
|
|
// Get all project tasks for a specific portal
|
|
const allProjectTasksSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
portal_id: Joi.string().required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/projects/all-project-tasks', auth, validate(allProjectTasksSchema), getAllProjectTasks);
|
|
|
|
// Get all project task lists for a specific portal
|
|
const allProjectTaskListsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
portal_id: Joi.string().required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/projects/all-project-tasklists', auth, validate(allProjectTaskListsSchema), getAllProjectTaskLists);
|
|
|
|
// Get all project issues for a specific portal
|
|
const allProjectIssuesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
portal_id: Joi.string().required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/projects/all-project-issues', auth, validate(allProjectIssuesSchema), getAllProjectIssues);
|
|
|
|
// Get all project phases for a specific portal
|
|
const allProjectPhasesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
portal_id: Joi.string().required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/projects/all-project-phases', auth, validate(allProjectPhasesSchema), getAllProjectPhases);
|
|
|
|
// Get Zoho Sales Orders
|
|
const salesOrdersSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
// Zoho CRM specific routes with clear service identification
|
|
router.get('/zoho/crm/sales-orders', auth, validate(salesOrdersSchema), getSalesOrders);
|
|
|
|
// Get Zoho Purchase Orders
|
|
const purchaseOrdersSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/crm/purchase-orders', auth, validate(purchaseOrdersSchema), getPurchaseOrders);
|
|
|
|
// Get Zoho Invoices
|
|
const invoicesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
router.get('/zoho/crm/invoices', auth, validate(invoicesSchema), getInvoices);
|
|
router.get('/zoho/crm/contacts', auth, validate(invoicesSchema), getContacts);
|
|
|
|
// Zoho People specific routes
|
|
const departmentsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const leaveRequestsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const attendanceSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
// Zoho People Forms API schemas
|
|
const employeeFormsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const employeeByIdSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
recordId: Joi.string().required(),
|
|
formLinkName: Joi.string().default('employee')
|
|
});
|
|
|
|
const attendanceEntriesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const shiftConfigurationSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const leaveDataSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
formLinkName: Joi.string().default('leave'),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const goalsDataSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
formLinkName: Joi.string().default('goals'),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const performanceDataSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
formLinkName: Joi.string().default('performance'),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
// Zoho People specific routes with clear service identification
|
|
router.get('/zoho/people/departments', auth, validate(departmentsSchema), getDepartments);
|
|
router.get('/zoho/people/leave-requests', auth, validate(leaveRequestsSchema), getLeaveRequests);
|
|
router.get('/zoho/people/attendance', auth, validate(attendanceSchema), getAttendance);
|
|
|
|
// Zoho People Forms API routes
|
|
router.get('/zoho/people/employee-forms', auth, validate(employeeFormsSchema), getEmployeeForms);
|
|
router.get('/zoho/people/employee/:recordId', auth, validate(employeeByIdSchema), getEmployeeById);
|
|
router.get('/zoho/people/attendance-entries', auth, validate(attendanceEntriesSchema), getAttendanceEntries);
|
|
router.get('/zoho/people/shift-configuration', auth, validate(shiftConfigurationSchema), getShiftConfiguration);
|
|
router.get('/zoho/people/leave-data', auth, validate(leaveDataSchema), getLeaveData);
|
|
router.get('/zoho/people/goals-data', auth, validate(goalsDataSchema), getGoalsData);
|
|
router.get('/zoho/people/performance-data', auth, validate(performanceDataSchema), getPerformanceData);
|
|
|
|
// Zoho People Reports API routes
|
|
router.get('/zoho/people/attendance-report', auth, getUserReport);
|
|
router.get('/zoho/people/leave-tracker-report', auth, getLeaveTrackerReport);
|
|
router.get('/zoho/people/holidays', auth, getHolidays);
|
|
|
|
// Zoho Books specific routes
|
|
const organizationsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const customersSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const vendorsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const itemsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const estimatesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const billsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const expensesSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const bankAccountsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const bankTransactionsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const reportsSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const booksSalesOrdersSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
const booksPurchaseOrdersSchema = Joi.object({
|
|
provider: Joi.string().valid('zoho').required(),
|
|
page: Joi.number().min(1).default(1),
|
|
limit: Joi.number().min(1).max(100).default(20),
|
|
filters: Joi.string().optional()
|
|
});
|
|
|
|
// Zoho Books specific routes with clear service identification
|
|
router.get('/zoho/books/organizations', auth, validate(organizationsSchema), getOrganizations);
|
|
router.get('/zoho/books/contacts', auth, validate(customersSchema), getBooksContacts);
|
|
router.get('/zoho/books/vendors', auth, validate(vendorsSchema), getVendors);
|
|
router.get('/zoho/books/items', auth, validate(itemsSchema), getItems);
|
|
router.get('/zoho/books/customers', auth, validate(customersSchema), getCustomers);
|
|
router.get('/zoho/books/invoices', auth, validate(invoicesSchema), getBooksInvoices);
|
|
router.get('/zoho/books/estimates', auth, validate(estimatesSchema), getEstimates);
|
|
router.get('/zoho/books/bills', auth, validate(billsSchema), getBills);
|
|
router.get('/zoho/books/expenses', auth, validate(expensesSchema), getExpenses);
|
|
router.get('/zoho/books/bank-accounts', auth, validate(bankAccountsSchema), getBankAccounts);
|
|
router.get('/zoho/books/bank-transactions', auth, validate(bankTransactionsSchema), getBankTransactions);
|
|
router.get('/zoho/books/reports', auth, validate(reportsSchema), getReports);
|
|
router.get('/zoho/books/sales-orders', auth, validate(booksSalesOrdersSchema), getBooksSalesOrders);
|
|
router.get('/zoho/books/purchase-orders', auth, validate(booksPurchaseOrdersSchema), getBooksPurchaseOrders);
|
|
|
|
// Webhook endpoints (no auth required - uses signature verification)
|
|
const zohoHandler = new ZohoHandler();
|
|
router.post('/webhooks/zoho/crm', zohoHandler.handleCrmWebhook.bind(zohoHandler));
|
|
router.post('/webhooks/zoho/people', zohoHandler.handlePeopleWebhook.bind(zohoHandler));
|
|
router.post('/webhooks/zoho/books', zohoHandler.handleBooksWebhook.bind(zohoHandler));
|
|
router.post('/webhooks/zoho/projects', zohoHandler.handleProjectsWebhook.bind(zohoHandler));
|
|
router.post('/webhooks/zoho/bulkread', zohoHandler.handleBulkReadWebhook.bind(zohoHandler));
|
|
|
|
module.exports = router;
|