feat(automations): ctx.tasks.scheduleStatusChange — отложенная смена статуса (воркер 5с, отмена при ручном переходе)
This commit is contained in:
@@ -32,8 +32,9 @@ const ALLOWED_STORAGE_METHODS = new Set([
|
||||
'updateUser',
|
||||
'setUserProfileFieldValueFromAutomation',
|
||||
'recalcUserFieldAverageFromAutomation',
|
||||
// Не storage-метод: обрабатывается отдельно в обработчике storage-call (сервис сообщений)
|
||||
// Не storage-методы: обрабатываются отдельно в обработчике storage-call
|
||||
'sendTaskMessageFromAutomation',
|
||||
'createDelayedStatusChangeFromAutomation',
|
||||
]);
|
||||
|
||||
interface WorkerStorageCall {
|
||||
@@ -99,6 +100,39 @@ export function runAutomationInWorker(
|
||||
return;
|
||||
}
|
||||
|
||||
// Отложенная смена статуса из автоматизации: планирует переход воркером
|
||||
// delayed-status-change.worker (отменяется, если задача сменит статус раньше)
|
||||
if (method === 'createDelayedStatusChangeFromAutomation') {
|
||||
try {
|
||||
const [taskId, orgId, targetStatusId, delayMs] = args as [number, number, number, number];
|
||||
const task = await storage.getTask(Number(taskId), Number(orgId));
|
||||
if (!task) throw new Error(`Задача ${taskId} не найдена`);
|
||||
const statuses = await storage.getFormStatuses(task.formId, Number(orgId));
|
||||
if (!statuses.some(s => s.id === Number(targetStatusId))) {
|
||||
throw new Error(`Статус ${targetStatusId} не принадлежит форме ${task.formId}`);
|
||||
}
|
||||
const delay = Number(delayMs);
|
||||
if (!Number.isFinite(delay) || delay < 0) throw new Error('delayMs должен быть неотрицательным числом');
|
||||
const created = await storage.createDelayedStatusChange({
|
||||
organizationId: Number(orgId),
|
||||
taskId: task.id,
|
||||
formId: task.formId,
|
||||
expectedStatusId: task.currentStatusId,
|
||||
targetStatusId: Number(targetStatusId),
|
||||
runAt: new Date(Date.now() + delay),
|
||||
});
|
||||
if (!settled) {
|
||||
try { worker.postMessage({ type: 'storage-response', callId, result: created }); } catch { /* terminated */ }
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
if (!settled) {
|
||||
try { worker.postMessage({ type: 'storage-response', callId, error: message }); } catch { /* terminated */ }
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Сообщение в чат задачи из автоматизации: не storage-метод,
|
||||
// идём через сервис сообщений (SSE, вложения, messageType 'status_change')
|
||||
if (method === 'sendTaskMessageFromAutomation') {
|
||||
|
||||
Reference in New Issue
Block a user