Back to Demos

Suspicious User Detection

Based on DailySuspiciousUserScheduler from transaction-realtime-tracking

Detection Algorithm

DEPOSIT+NO BET+CHAT > 5=SUSPICIOUS

Simulate Activity

Detection Results

Activity Log

Production Code (Java)

// From transaction-realtime-tracking - DailySuspiciousUserScheduler.java
@Scheduled(cron = "0 5 0 * * ?") // Run daily at 00:05
public void exportSuspiciousUsers() {
    String yesterday = LocalDate.now().minusDays(1).format(DateTimeFormatter.ISO_DATE);

    // Distributed lock for cluster safety
    Optional<AcquiredLock> lockOpt = cacheService.tryAcquireLock(lockKey, 60);
    if (lockOpt.isEmpty()) {
        log.info("Skipping - another node is processing");
        return;
    }

    try (AcquiredLock lock = lockOpt.get()) {
        // Get all data from Redis
        Set<String> depositUsers = suspiciousUserCacheService.getDepositUsers(date);
        Set<String> betUsers = suspiciousUserCacheService.getBetUsers(date);
        Map<String, Integer> chatCounts = suspiciousUserCacheService.getChatCounts(date);

        // Filter suspicious users: deposit + NO BET + chat > threshold
        List<SuspiciousUser> suspiciousUsers = depositUsers.stream()
            .filter(user -> !betUsers.contains(user))     // No bet
            .map(user -> new SuspiciousUser(user, chatCounts.getOrDefault(user, 0)))
            .filter(su -> su.chatCount() > chatThreshold) // High chat activity
            .sorted((a, b) -> Integer.compare(b.chatCount(), a.chatCount()))
            .collect(Collectors.toList());

        // Export to VipTalk
        vipTalkClient.sendMessageFile(buildVipTalkMessage(date), ...);
    }
}