← Назад к вопросам

В какой момент оповещать пользователя об изменении текущего документа

2.0 Middle🔥 81 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Уведомление пользователя об изменении документа: правильный момент

Время и механизм уведомления пользователя об изменении документа зависит от требований приложения. Рассмотрим различные подходы и когда их использовать.

Сценарий: Совместное редактирование документа

Задача: несколько пользователей редактируют документ одновременно, и нужно оповещать их об изменениях друг друга.

1. Немедленное уведомление (Real-time)

Когда: Для синхронных операций редактирования, когда нужна мгновенная реакция

// WebSocket подход для real-time уведомлений
@Component
public class DocumentWebSocketHandler extends TextWebSocketHandler {
    private final DocumentService documentService;
    private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        // Получаем изменение от пользователя
        DocumentChange change = parseChange(message.getPayload());
        
        // Сохраняем в БД
        documentService.applyChange(change);
        
        // Немедленно оповещаем ДРУГИХ пользователей
        broadcastToOthers(session, change);
    }

    private void broadcastToOthers(WebSocketSession sender, DocumentChange change) {
        String notification = createNotification(change);
        
        for (WebSocketSession s : sessions) {
            if (!s.getId().equals(sender.getId()) && s.isOpen()) {
                try {
                    s.sendMessage(new TextMessage(notification));
                } catch (IOException e) {
                    // Handle error
                }
            }
        }
    }
}

Преимущества: Мгновенная синхронизация, лучший UX Недостатки: Высокие требования к серверу, сложнее масштабировать


2. Отложенное уведомление (После сохранения в БД)

Когда: Для асинхронных операций, когда нужна гарантия сохранения

@RestController
@RequestMapping("/api/v1/documents")
public class DocumentController {
    @PostMapping("/{id}/update")
    public ResponseEntity<DocumentDTO> updateDocument(
            @PathVariable String id,
            @RequestBody DocumentUpdateRequest request) {
        
        // 1. Сохраняем в БД
        Document document = documentService.update(id, request.getContent());
        
        // 2. ПОСЛЕ сохранения оповещаем пользователей
        notificationService.notifyDocumentChanged(id, document);
        
        return ResponseEntity.ok(DocumentDTO.from(document));
    }
}

@Service
public class NotificationService {
    @Async // Асинхронно, не блокируя HTTP ответ
    public void notifyDocumentChanged(String documentId, Document document) {
        // Отправляем уведомления:
        // - Email
        // - Push-notification
        // - WebSocket
        // - Обновляем версию документа
    }
}

Преимущества: Гарантия сохранения, проще реализовать Недостатки: Некоторая задержка, может быть асинхронность


3. Уведомление при открытии документа (Polling)

Когда: Для периодического обновления статуса

@RestController
@RequestMapping("/api/v1/documents")
public class DocumentController {
    
    @GetMapping("/{id}/status")
    public ResponseEntity<DocumentStatusDTO> getDocumentStatus(
            @PathVariable String id) {
        
        Document document = documentService.getById(id);
        
        // Возвращаем информацию об изменениях
        return ResponseEntity.ok(DocumentStatusDTO.builder()
            .id(id)
            .version(document.getVersion())
            .lastModified(document.getLastModified())
            .modifiedBy(document.getModifiedBy())
            .hasUnreadChanges(true) // Были ли изменения
            .build());
    }
}

// Frontend: Периодический опрос
setInterval(() => {
    fetch(`/api/v1/documents/${docId}/status`)
        .then(res => res.json())
        .then(data => {
            if (data.hasUnreadChanges) {
                showNotification(`Document updated by ${data.modifiedBy}`);
                reloadDocument();
            }
        });
}, 5000); // Каждые 5 секунд

Преимущества: Просто реализовать, работает везде Недостатки: Задержка, нагрузка на сервер


4. Уведомление на основе событий (Event-driven)

Когда: Для сложных систем с множеством действий

@Service
public class DocumentService {
    private final ApplicationEventPublisher eventPublisher;

    public void updateDocument(String id, String content) {
        Document document = documentRepository.findById(id).orElseThrow();
        document.setContent(content);
        document.setLastModified(LocalDateTime.now());
        document.setModifiedBy(getCurrentUser());
        
        documentRepository.save(document);
        
        // Публикуем событие
        eventPublisher.publishEvent(
            new DocumentChangedEvent(this, id, content, getCurrentUser())
        );
    }
}

@Component
public class DocumentChangeListener {
    private final NotificationService notificationService;
    private final WebSocketService webSocketService;

    @EventListener
    public void onDocumentChanged(DocumentChangedEvent event) {
        // Обработаем событие несколькими способами
        notificationService.notifyViaEmail(event);
        webSocketService.broadcastChange(event);
        // Логирование, аналитика, кэширование и т.д.
    }
}

Преимущества: Гибкость, расширяемость, разделение ответственности Недостатки: Сложнее реализовать


5. Уведомление при конкретных изменениях

Когда: Нужно уведомлять только при критичных изменениях

@Service
public class DocumentChangeDetectionService {
    public void detectAndNotify(Document oldDoc, Document newDoc) {
        // Уведомляем только если изменился статус
        if (!oldDoc.getStatus().equals(newDoc.getStatus())) {
            notificationService.notifyStatusChange(
                newDoc.getId(),
                oldDoc.getStatus(),
                newDoc.getStatus()
            );
        }
        
        // Уведомляем, если изменена важная информация
        if (!oldDoc.getTitle().equals(newDoc.getTitle())) {
            notificationService.notifyTitleChange(
                newDoc.getId(),
                newDoc.getTitle()
            );
        }
        
        // Но НЕ уведомляем при каждом нажатии Enter
    }
}

Рекомендации

Для Google Docs-подобного приложения:

  • WebSocket для мгновенных изменений (real-time)
  • Отправляй после каждого действия или с debounce (500ms)
  • Версионирование документа для отслеживания изменений
@PostMapping("/{id}/edit")
@Debounce(delay = 500) // Custom аннотация
public void editDocument(@PathVariable String id, @RequestBody String content) {
    documentService.update(id, content);
    // Уведомление отправится один раз за 500ms всех изменений
}

Для внутренних приложений:

  • Polling каждые 5-10 секунд
  • Или уведомления при критичных изменениях

Для социальных сетей:

  • Push-notification при упоминаниях
  • Email уведомления одно в день
  • WebSocket для чатов

Вывод

Правильный момент уведомления зависит от:

  1. Типа приложения (real-time / асинхронное)
  2. Критичности данных (важны ли мелкие изменения?)
  3. Требований к UX (быстрый отклик или ресурсоэффективность?)
  4. Масштабируемости (сколько пользователей одновременно?)

Не всегда нужен real-time — часто достаточно уведомления после сохранения в БД или периодического polling'а!

В какой момент оповещать пользователя об изменении текущего документа | PrepBro