4 * @description Slack integration configuration endpoints. Manages tenant-specific Slack webhook
5 * settings for notifications and alerting. Stores webhook URLs in integrations table.
7 * @requires services/db
8 * @author RMM-PSA Development Team
9 * @copyright 2026 RMM-PSA Platform
10 * @license Proprietary
14 * @apiDefine Slack Slack Integration
15 * Slack notification integration configuration
18const express = require('express');
19const router = express.Router();
20const pool = require('../services/db');
23 * @api {post} /api/slack/settings/:tenant_id Save Slack settings
24 * @apiName SaveSlackSettings
26 * @apiDescription Save or update Slack webhook URL for a tenant. Webhook URL used for
27 * sending notifications to Slack channels. Stored in integrations table with type='slack'.
28 * @apiParam {string} tenant_id Tenant ID
29 * @apiParam {object} slack Slack configuration object
30 * @apiParam {string} slack.webhookUrl Slack incoming webhook URL
31 * @apiSuccess {boolean} success=true Settings saved successfully
32 * @apiError {string} error="Missing Slack webhook URL" (400) webhookUrl not provided
33 * @apiError {string} error="Failed to save Slack settings" (500) Database save failed
34 * @apiExample {curl} Example:
35 * curl -X POST http://localhost:3000/api/slack/settings/123 \\
36 * -H "Content-Type: application/json" \\
37 * -d '{"slack": {"webhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXX"}}'
38 * @apiSuccessExample {json} Success-Response:
44router.post('/settings/:tenant_id', async (req, res) => {
45 const { tenant_id } = req.params;
46 const { slack } = req.body;
47 if (!slack || !slack.webhookUrl) return res.status(400).json({ error: 'Missing Slack webhook URL' });
50 `INSERT INTO integrations (tenant_id, integration_type, config, is_active)
51 VALUES ($1, 'slack', $2, true)
52 ON CONFLICT (tenant_id, integration_type)
53 DO UPDATE SET config = EXCLUDED.config, is_active = true`,
54 [tenant_id, JSON.stringify(slack)]
56 res.json({ success: true });
58 res.status(500).json({ error: 'Failed to save Slack settings', details: err.message });
63 * @api {get} /api/slack/settings/:tenant_id Get Slack settings
64 * @apiName GetSlackSettings
66 * @apiDescription Retrieve Slack webhook configuration for a tenant. Returns the config
67 * object containing webhookUrl.
68 * @apiParam {string} tenant_id Tenant ID
69 * @apiSuccess {object} config Slack configuration object
70 * @apiSuccess {string} config.webhookUrl Slack incoming webhook URL
71 * @apiError {string} error="Slack not configured for tenant" (404) No Slack config found
72 * @apiError {string} error="Failed to fetch Slack settings" (500) Database query failed
73 * @apiExample {curl} Example:
74 * curl -X GET http://localhost:3000/api/slack/settings/123
75 * @apiSuccessExample {json} Success-Response:
78 * "webhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXX"
81router.get('/settings/:tenant_id', async (req, res) => {
82 const { tenant_id } = req.params;
84 const result = await pool.query(
85 `SELECT config FROM integrations WHERE tenant_id = $1 AND integration_type = 'slack' AND is_active = true LIMIT 1`,
88 if (!result.rows.length) return res.status(404).json({ error: 'Slack not configured for tenant' });
89 res.json(result.rows[0].config);
91 res.status(500).json({ error: 'Failed to fetch Slack settings', details: err.message });
95module.exports = router;