Add sessionHolding template, unique 8-digit codes, reason slot for sessionCancelled, and disable unused notifications

This commit is contained in:
2026-08-21 10:44:51 +03:30
parent 5328f36f06
commit 091e519280
28 changed files with 2180 additions and 280 deletions
+102
View File
@@ -0,0 +1,102 @@
'use strict';
const config = require('../config/config');
const { Setting, SETTINGS_KEY } = require('../components/settings/settingModel');
const {
NOTIFICATION_ACTION_DEFS,
mergeNotificationSettings,
toPublicNotificationSettings,
normalizeStoredActionEntry,
findActionDef
} = require('../components/settings/notificationActions');
const {
isEnvChannelEnabled,
isDbChannelEnabled,
CHANNELS
} = require('./messagingChannels');
const { getDbMessagingFlags, invalidateMessagingCache } = require('../components/settings/messagingFlags');
let settingsCache = null;
let settingsCacheAt = 0;
const CACHE_TTL_MS = 10000;
const readStoredMap = (doc) => {
const stored = doc?.notificationSettings || {};
if (stored instanceof Map) {
return Object.fromEntries(stored.entries());
}
return { ...stored };
};
const getMergedSettingsMap = (doc) => mergeNotificationSettings(readStoredMap(doc));
const loadNotificationSettingsDoc = async () => {
const now = Date.now();
if (settingsCache && (now - settingsCacheAt) < CACHE_TTL_MS) {
return settingsCache;
}
const doc = await Setting.findOne({ key: SETTINGS_KEY })
.select('notificationSettings smsEnabled emailEnabled botEnabled')
.lean();
settingsCache = {
map: getMergedSettingsMap(doc),
dbMessaging: {
smsEnabled: doc?.smsEnabled,
emailEnabled: doc?.emailEnabled,
botEnabled: doc?.botEnabled
}
};
settingsCacheAt = now;
return settingsCache;
};
const invalidateNotificationSettingsCache = () => {
settingsCache = null;
settingsCacheAt = 0;
invalidateMessagingCache();
};
const isGlobalChannelEnabled = async (channel) => {
if (!CHANNELS.includes(channel)) return false;
if (!isEnvChannelEnabled(channel, config)) return false;
const db = await getDbMessagingFlags();
return isDbChannelEnabled(channel, db);
};
const isActionChannelEnabled = async (actionKey, channel) => {
if (!CHANNELS.includes(channel)) return false;
if (!(await isGlobalChannelEnabled(channel))) return false;
const cached = await loadNotificationSettingsDoc();
const def = findActionDef(actionKey);
if (!def) return true;
const entry = normalizeStoredActionEntry(cached.map[actionKey], def);
return entry[channel] === true;
};
const getActionChannelFlags = async (actionKey) => {
const result = { sms: false, email: false, bot: false };
await Promise.all(
CHANNELS.map(async (channel) => {
result[channel] = await isActionChannelEnabled(actionKey, channel);
})
);
return result;
};
const getPublicNotificationSettings = async (doc = null) => {
const resolved = doc || await Setting.findOne({ key: SETTINGS_KEY }).lean();
return toPublicNotificationSettings(getMergedSettingsMap(resolved));
};
module.exports = {
getMergedSettingsMap,
isActionChannelEnabled,
getActionChannelFlags,
getPublicNotificationSettings,
invalidateNotificationSettingsCache,
readStoredMap
};