Sobes.tech
Senior

/* The company provides a mass notification sending service for other businesses. A product owner has approached you with a task to create a notification filtering system considering user preferences. ## Definitions Notification: - notification id - notification type (EMAIL, SMS, PUSH) - recipient (user id) - message text Recipient may have preference settings: - allowed notification channels (list of types) - blocked senders (list of sender ids) Notification sending history: - list of notifications sent to the user ## Important User settings and notification history are provided by other system components. You need to design contracts to obtain this data. Storage implementation is not required. ## Task Write a notification filtering system that: - takes a list of notifications for filtering and a sender id as input - excludes notifications that do not match user preferences - implements duplicate message protection, including messages sent in the last 24 hours. Duplicates are considered messages with the same id addressed to the same user - returns a filtered list of notifications ready to be sent. Sending notifications is not part of your task - another team will handle sending the filtered list. Your task is only filtering. */ class NotificationFilter { UserSettingsService userSettingsService; NotificationHistoryService notificationHistoryService; public ??? filter(??? senderId, List<???> msgs) { // TODO implement } } interface UserSettingsService { // TODO any functions } interface NotificationHistoryService { // TODO any functions }

sobes.tech AI

Answer from AI

java import java.time.Instant; import java.time.Duration; import java.util.*; import java.util.stream.Collectors;

class Notification { String id; NotificationType type; String recipientId; String text;

// Constructor, getters, setters

}

enum NotificationType { EMAIL, SMS, PUSH }

interface UserSettingsService { /** * Returns the allowed notification channels for a user. */ Set<NotificationType> getAllowedChannels(String userId);

/**
 * Returns the list of blocked senders for a user.
 */
Set<String> getBlockedSenders(String userId);

}

interface NotificationHistoryService { /** * Returns the list of notifications sent to a user in the last 24 hours. */ List<Notification> getNotificationsLast24h(String userId); }

class NotificationFilter { private final UserSettingsService userSettingsService; private final NotificationHistoryService notificationHistoryService;

public NotificationFilter(UserSettingsService userSettingsService, NotificationHistoryService notificationHistoryService) {
    this.userSettingsService = userSettingsService;
    this.notificationHistoryService = notificationHistoryService;
}

/**
 * Filters the list of notifications based on user preferences and excludes duplicates.
 * 
 * @param senderId sender's id
 * @param msgs list of notifications to filter
 * @return filtered list of notifications
 */
public List<Notification> filter(String senderId, List<Notification> msgs) {
    // Group notifications by recipient
    Map<String, List<Notification>> byRecipient = msgs.stream()
        .collect(Collectors.groupingBy(n -> n.recipientId));

    List<Notification> result = new ArrayList<>();

    for (Map.Entry<String, List<Notification>> entry : byRecipient.entrySet()) {
        String userId = entry.getKey();
        List<Notification> userNotifications = entry.getValue();

        Set<NotificationType> allowedChannels = userSettingsService.getAllowedChannels(userId);
        Set<String> blockedSenders = userSettingsService.getBlockedSenders(userId);

        // Skip all notifications for this user if sender is blocked
        if (blockedSenders.contains(senderId)) {
            continue;
        }

        // Get notification history for the last 24 hours
        List<Notification> history = notificationHistoryService.getNotificationsLast24h(userId);
        Set<String> recentNotificationIds = history.stream()
            .map(n -> n.id)
            .collect(Collectors.toSet());

        // Also consider current notifications to avoid duplicates
        Set<String> currentNotificationIds = new HashSet<>();

        for (Notification n : userNotifications) {
            // Filter by allowed channels
            if (!allowedChannels.contains(n.type)) {
                continue;
            }

            // Check for duplicates (by id)
            if (recentNotificationIds.contains(n.id) || currentNotificationIds.contains(n.id)) {
                continue;
            }

            currentNotificationIds.add(n.id);
            result.add(n);
        }
    }

    return result;
}

}