/**
* Controller functions for Action Template operations
*/
// @ts-check
/**
* @import {ExpressRequestAuthorized, ExpressResponse} from './../../types.js'
*/
import { HEX2uuid, UUID2hex } from '@commtool/sql-query';
import { Templates } from '../../utils/compileTemplates.js';
import { isAdmin } from '../../utils/authChecks.js';
import { validateRegisterInput, mergeTemplateData } from './helpers.js';
import * as actionTemplateService from './service.js';
import { errorLoggerUpdate, errorLoggerRead } from '../../utils/requestLogger.js';
import { publishEvent } from '../../utils/events.js';
/**
* Create or update action template (PUT /)
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
* @returns {Promise<void>}
*/
export const createOrUpdateActionTemplate = async (req, res) => {
try {
const result = await actionTemplateService.createOrUpdateActionTemplate(req, req.body);
if (result.success) {
res.json({ success: true, result: result.result });
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerUpdate(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Restart action template (POST /restart/:UID)
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
* @returns {Promise<void>}
*/
export const restartActionTemplate = async (req, res) => {
try {
const result = await actionTemplateService.restartActionTemplate(req.params.UID);
if (result.success) {
res.json({ success: true });
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerUpdate(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Delete action template (DELETE /:UID)
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
* @returns {Promise<void>}
*/
export const deleteActionTemplate = async (req, res) => {
try {
const result = await actionTemplateService.deleteActionTemplate(req.params.UID, req.session.root);
if (result.success) {
res.json({ success: true });
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerUpdate(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Get all action templates for organization (GET /)
*/
export const getActionTemplates = async (req, res) => {
try {
const result = await actionTemplateService.getActionTemplatesForOrg(req.session.root,req);
if (result.success) {
res.json({ success: true, result: result.result });
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerRead(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Get specific action template (GET /:UID)
*/
export const getActionTemplate = async (req, res) => {
try {
const result = await actionTemplateService.getActionTemplate(req.params.UID, req.session.root);
if (result.success) {
res.json({ success: true, result: result.result });
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerRead(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Register bot action templates (POST /register)
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
* @returns {Promise<ExpressResponse>}
*/
export const registerBotActionTemplates = async ( req, res) => {
try {
const { botUID, organizationUIDs, template } = req.body;
// Validate input
const validation = validateRegisterInput(req.body);
if (!validation.success) {
return res.json(validation);
}
// Get target organizations
const orgResult = await actionTemplateService.getOrganizationsByUIDs(organizationUIDs);
if (!orgResult.success) {
return res.json({ success: false, message: 'Error fetching organizations' });
}
if (orgResult.result.length === 0) {
return res.json({
success: false,
message: 'No valid organizations found for provided UIDs'
});
}
const results = [];
const actionTemplates =[]
// Create or modify action templates for each target organization,
for (const org of orgResult.result) {
const orgUID = org.UID;
try {
// Set organization context for this template creation
const originalRoot = req.session.root;
req.session.root = orgUID;
// Create the action template
const createResult = await actionTemplateService.createOrUpdateActionTemplate(req, template);
if (createResult.success) {
// Create bot link
const linkResult = await actionTemplateService.createBotLink(botUID, createResult.UIDaction);
if (linkResult.success) {
actionTemplates.push({ ...createResult.result, OrgUID: orgUID, OrgDisplay: org.Display, OrgLoginUID: org.OrgLoginUID });
results.push({
organization: orgUID,
organizationName: org.Display,
success: true,
actionTemplateUID: createResult.UIDaction
});
} else {
results.push({
organization: orgUID,
organizationName: org.Display,
success: false,
error: 'Failed to create bot link'
});
}
} else {
results.push({
organization: orgUID,
organizationName: org.Display,
success: false,
error: createResult.error
});
}
// Restore original session root
req.session.root = originalRoot;
} catch (templateError) {
console.error(`[register] Error creating template for org ${orgUID}:`, templateError);
results.push({
organization: orgUID,
organizationName: org.Display,
success: false,
error: templateError.message
});
}
}
res.json({
success: true,
message: `Processed ${orgResult.result.length} organizations `,
organizationsProcessed: orgResult.result.length,
results: results,
actionTemplates: actionTemplates
});
} catch (e) {
console.error('[register] Error:', e);
errorLoggerUpdate(e);
res.json({
success: false,
message: 'Internal error during registration'
});
}
};
/**
* Get all action templates for a specific bot (GET /bot/:botUID)
*/
export const getActionTemplatesForBot = async (req, res) => {
try {
const result = await actionTemplateService.getActionTemplatesForBot(req.params.botUID, req);
if (result.success) {
res.json({
success: true,
botUID: req.params.botUID,
actionTemplates: result.result
});
} else {
res.status(500).json({ success: false, message: result.error });
}
} catch (e) {
errorLoggerRead(e);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};
/**
* Delete all action Templates for a specific bot, where the organizations are not in the provided list (DELETE /bot/:botUID)
*/
export const deleteActionTemplatesForBotNotInOrgs = async (req, res) => {
try {
const { botUID } = req.body;
const { organizationUIDs } = req.body;
if (!organizationUIDs || !Array.isArray(organizationUIDs)) {
return res.status(400).json({
success: false,
message: 'OrgUIDs must be provided as an array'
});
}
const result = await actionTemplateService.getActionTemplatesForBot(botUID, req);
if (!result.success) {
return res.status(500).json({ success: false, message: result.error });
}
let deletedCount = 0;
for (const template of result.result) {
if (!organizationUIDs.includes(template.OrgUID)) {
const deleteResult = await actionTemplateService.deleteActionTemplate(template.UID, template.OrgUID);
if (deleteResult.success) {
deletedCount++;
}
}
}
res.json({
success: true,
deletedCount: deletedCount,
message: `Deleted ${deletedCount} action templates`
});
} catch (error) {
errorLoggerUpdate(error);
res.status(500).json({ success: false, message: 'Internal server error' });
}
};