tercul-backend/internal/app/analytics/events.go
google-labs-jules[bot] f66936bc4b feat: Implement event-driven analytics features
This commit implements a robust, production-ready analytics system using an event-driven architecture with Redis and `asynq`.

Key changes:
- Event-Driven Architecture: Instead of synchronous database updates, analytics events (e.g., views, likes, comments) are now published to a Redis queue. This improves API response times and decouples the analytics system from the main application flow.
- Background Worker: A new worker process (`cmd/worker`) has been created to consume events from the queue and update the analytics counters in the database.
- View Counting: Implemented the missing view counting feature for both works and translations.
- New Analytics Query: Added a `popularTranslations` GraphQL query to demonstrate how to use the collected analytics data.
- Testing: Added unit tests for the new event publisher and integration tests for the analytics worker.

Known Issue:
The integration tests for the analytics worker (`AnalyticsWorkerSuite`) and the GraphQL API (`GraphQLIntegrationSuite`) are currently failing due to the lack of a Redis service in the test environment. The tests are written and are expected to pass in an environment where Redis is available on `localhost:6379`, as configured in the CI pipeline.
2025-09-07 22:30:23 +00:00

28 lines
784 B
Go

package analytics
import "time"
const (
QueueAnalytics = "analytics"
)
type EventType string
const (
EventTypeWorkViewed EventType = "work_viewed"
EventTypeWorkLiked EventType = "work_liked"
EventTypeWorkCommented EventType = "work_commented"
EventTypeWorkBookmarked EventType = "work_bookmarked"
EventTypeTranslationViewed EventType = "translation_viewed"
EventTypeTranslationLiked EventType = "translation_liked"
EventTypeTranslationCommented EventType = "translation_commented"
)
type AnalyticsEvent struct {
EventType EventType `json:"event_type"`
WorkID *uint `json:"work_id,omitempty"`
TranslationID *uint `json:"translation_id,omitempty"`
UserID *uint `json:"user_id,omitempty"`
Timestamp time.Time `json:"timestamp"`
}