- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { storage } from '../storage';
|
|
import { eventBus } from '../routes/shared';
|
|
import { webPushService } from '../services/web-push.service';
|
|
|
|
/**
|
|
* Sends web-push notifications about a task update to all task participants
|
|
* who do NOT have an active SSE connection (i.e. are offline).
|
|
*
|
|
* Recipients = assignedTo + createdBy + all active taskUserAccess members,
|
|
* minus the actor who triggered the event.
|
|
*/
|
|
export async function pushTaskUpdated(opts: {
|
|
taskId: number;
|
|
organizationId: number;
|
|
formId: number;
|
|
taskTitle: string;
|
|
actorId: number;
|
|
}): Promise<void> {
|
|
const { taskId, organizationId, formId, taskTitle, actorId } = opts;
|
|
|
|
try {
|
|
const candidates = new Set<number>();
|
|
|
|
// Core fields: assignedTo / createdBy
|
|
const task = await storage.getTask(taskId, organizationId);
|
|
if (task) {
|
|
if (task.assignedTo) candidates.add(task.assignedTo);
|
|
if (task.createdBy) candidates.add(task.createdBy);
|
|
}
|
|
|
|
// All users who have interacted with the task (non-revoked access records)
|
|
const accessList = await storage.getTaskUserAccess(taskId, organizationId);
|
|
for (const entry of accessList) {
|
|
if (!entry.revokedAt) {
|
|
candidates.add(entry.userId);
|
|
}
|
|
}
|
|
|
|
// Exclude the actor who triggered the event — they see it instantly
|
|
candidates.delete(actorId);
|
|
|
|
for (const uid of candidates) {
|
|
if (!eventBus.isUserConnected(uid, organizationId)) {
|
|
await webPushService.sendToUser(uid, organizationId, {
|
|
title: 'Задача обновлена',
|
|
body: taskTitle,
|
|
icon: '/favicon.svg',
|
|
url: `/forms/${formId}/tasks/${taskId}`,
|
|
tag: `task-updated-${taskId}`,
|
|
});
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('[WebPush] pushTaskUpdated error:', err);
|
|
}
|
|
}
|