as view
This commit is contained in:
@@ -2,12 +2,16 @@ package com.posthub.analytics.controller;
|
|||||||
|
|
||||||
import com.posthub.analytics.dto.DailyStatsResponse;
|
import com.posthub.analytics.dto.DailyStatsResponse;
|
||||||
import com.posthub.analytics.dto.DashboardResponse;
|
import com.posthub.analytics.dto.DashboardResponse;
|
||||||
|
import com.posthub.analytics.dto.EventLogResponse;
|
||||||
import com.posthub.analytics.model.UserStats;
|
import com.posthub.analytics.model.UserStats;
|
||||||
import com.posthub.analytics.service.AnalyticsQueryService;
|
import com.posthub.analytics.service.AnalyticsQueryService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -34,4 +38,14 @@ public class AnalyticsController {
|
|||||||
return ResponseEntity.ok(queryService.getDailyStats(days));
|
return ResponseEntity.ok(queryService.getDailyStats(days));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/events")
|
||||||
|
public ResponseEntity<Page<EventLogResponse>> getEvents(
|
||||||
|
@RequestParam(required = false) String eventType,
|
||||||
|
@RequestParam(required = false) String userId,
|
||||||
|
@RequestParam(required = false) LocalDate dateFrom,
|
||||||
|
@RequestParam(required = false) LocalDate dateTo,
|
||||||
|
Pageable pageable) {
|
||||||
|
return ResponseEntity.ok(queryService.getEvents(eventType, userId, dateFrom, dateTo, pageable));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.posthub.analytics.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EventLogResponse {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String eventType;
|
||||||
|
private String userId;
|
||||||
|
private String chatId;
|
||||||
|
private Instant eventTimestamp;
|
||||||
|
private LocalDate eventDate;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.posthub.analytics.repository;
|
|||||||
|
|
||||||
import com.posthub.analytics.model.EventLog;
|
import com.posthub.analytics.model.EventLog;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
@@ -10,7 +11,7 @@ import java.time.LocalDate;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface EventLogRepository extends JpaRepository<EventLog, Long> {
|
public interface EventLogRepository extends JpaRepository<EventLog, Long>, JpaSpecificationExecutor<EventLog> {
|
||||||
|
|
||||||
@Query("SELECT COUNT(DISTINCT e.userId) FROM EventLog e " +
|
@Query("SELECT COUNT(DISTINCT e.userId) FROM EventLog e " +
|
||||||
"WHERE e.eventDate BETWEEN :from AND :to")
|
"WHERE e.eventDate BETWEEN :from AND :to")
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.posthub.analytics.repository;
|
||||||
|
|
||||||
|
import com.posthub.analytics.model.EventLog;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public final class EventLogSpecification {
|
||||||
|
|
||||||
|
private EventLogSpecification() {}
|
||||||
|
|
||||||
|
public static Specification<EventLog> hasEventType(String eventType) {
|
||||||
|
return (root, query, cb) -> eventType == null || eventType.isBlank()
|
||||||
|
? null
|
||||||
|
: cb.equal(root.get("eventType"), eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Specification<EventLog> hasUserId(String userId) {
|
||||||
|
return (root, query, cb) -> userId == null || userId.isBlank()
|
||||||
|
? null
|
||||||
|
: cb.equal(root.get("userId"), userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Specification<EventLog> dateFrom(LocalDate dateFrom) {
|
||||||
|
return (root, query, cb) -> dateFrom == null
|
||||||
|
? null
|
||||||
|
: cb.greaterThanOrEqualTo(root.get("eventDate"), dateFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Specification<EventLog> dateTo(LocalDate dateTo) {
|
||||||
|
return (root, query, cb) -> dateTo == null
|
||||||
|
? null
|
||||||
|
: cb.lessThanOrEqualTo(root.get("eventDate"), dateTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,18 @@ package com.posthub.analytics.service;
|
|||||||
|
|
||||||
import com.posthub.analytics.dto.DailyStatsResponse;
|
import com.posthub.analytics.dto.DailyStatsResponse;
|
||||||
import com.posthub.analytics.dto.DashboardResponse;
|
import com.posthub.analytics.dto.DashboardResponse;
|
||||||
|
import com.posthub.analytics.dto.EventLogResponse;
|
||||||
import com.posthub.analytics.model.DailyStats;
|
import com.posthub.analytics.model.DailyStats;
|
||||||
|
import com.posthub.analytics.model.EventLog;
|
||||||
import com.posthub.analytics.model.UserStats;
|
import com.posthub.analytics.model.UserStats;
|
||||||
import com.posthub.analytics.repository.DailyStatsRepository;
|
import com.posthub.analytics.repository.DailyStatsRepository;
|
||||||
import com.posthub.analytics.repository.EventLogRepository;
|
import com.posthub.analytics.repository.EventLogRepository;
|
||||||
|
import com.posthub.analytics.repository.EventLogSpecification;
|
||||||
import com.posthub.analytics.repository.UserStatsRepository;
|
import com.posthub.analytics.repository.UserStatsRepository;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -76,4 +82,28 @@ public class AnalyticsQueryService {
|
|||||||
.activeUsers(ds.getActiveUsers())
|
.activeUsers(ds.getActiveUsers())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Page<EventLogResponse> getEvents(String eventType, String userId,
|
||||||
|
LocalDate dateFrom, LocalDate dateTo,
|
||||||
|
Pageable pageable) {
|
||||||
|
Specification<EventLog> spec = Specification
|
||||||
|
.where(EventLogSpecification.hasEventType(eventType))
|
||||||
|
.and(EventLogSpecification.hasUserId(userId))
|
||||||
|
.and(EventLogSpecification.dateFrom(dateFrom))
|
||||||
|
.and(EventLogSpecification.dateTo(dateTo));
|
||||||
|
|
||||||
|
return eventLogRepository.findAll(spec, pageable)
|
||||||
|
.map(this::toEventResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventLogResponse toEventResponse(EventLog e) {
|
||||||
|
return EventLogResponse.builder()
|
||||||
|
.id(e.getId())
|
||||||
|
.eventType(e.getEventType())
|
||||||
|
.userId(e.getUserId())
|
||||||
|
.chatId(e.getChatId())
|
||||||
|
.eventTimestamp(e.getEventTimestamp())
|
||||||
|
.eventDate(e.getEventDate())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -61,6 +61,15 @@ spring:
|
|||||||
- RewritePath=/api/rag(?<segment>/?.*), ${segment}
|
- RewritePath=/api/rag(?<segment>/?.*), ${segment}
|
||||||
- AddRequestHeader=X-Forwarded-Prefix, /api/rag
|
- AddRequestHeader=X-Forwarded-Prefix, /api/rag
|
||||||
|
|
||||||
|
# Analytics Service - API endpoints
|
||||||
|
- id: analytics-service-api
|
||||||
|
uri: lb://analytics-service
|
||||||
|
predicates:
|
||||||
|
- Path=/api/analytics/**
|
||||||
|
- Method=GET,POST
|
||||||
|
filters:
|
||||||
|
- AddRequestHeader=X-Forwarded-Prefix, /api/analytics
|
||||||
|
|
||||||
# ---- JWT ----
|
# ---- JWT ----
|
||||||
jwt:
|
jwt:
|
||||||
secret: ${JWT_SECRET:}
|
secret: ${JWT_SECRET:}
|
||||||
|
|||||||
Reference in New Issue
Block a user