package repository import ( "context" "time" "github.com/gochat/gochat/internal/model" "gorm.io/gorm" ) // ReportingEventRepo provides data access for ReportingEvent. type ReportingEventRepo struct { db *gorm.DB } func NewReportingEventRepo(db *gorm.DB) *ReportingEventRepo { return &ReportingEventRepo{db: db} } func (r *ReportingEventRepo) Create(ctx context.Context, event *model.ReportingEvent) error { return r.db.WithContext(ctx).Create(event).Error } func (r *ReportingEventRepo) FindByAccountID(ctx context.Context, accountID uint, since, until time.Time) ([]model.ReportingEvent, error) { var events []model.ReportingEvent err := r.db.WithContext(ctx). Where("account_id = ? AND created_at >= ? AND created_at <= ?", accountID, since, until). Find(&events).Error return events, err } func (r *ReportingEventRepo) FindByDateRange(ctx context.Context, accountID uint, since, until time.Time) ([]model.ReportingEvent, error) { var events []model.ReportingEvent err := r.db.WithContext(ctx). Where("account_id = ? AND event_start_time >= ? AND event_end_time <= ?", accountID, since, until). Find(&events).Error return events, err } func (r *ReportingEventRepo) FindByMetric(ctx context.Context, accountID uint, metricName string, since, until time.Time) ([]model.ReportingEvent, error) { var events []model.ReportingEvent err := r.db.WithContext(ctx). Where("account_id = ? AND name = ? AND created_at >= ? AND created_at <= ?", accountID, metricName, since, until). Find(&events).Error return events, err } func (r *ReportingEventRepo) FindByInboxID(ctx context.Context, accountID, inboxID uint, since, until time.Time) ([]model.ReportingEvent, error) { var events []model.ReportingEvent err := r.db.WithContext(ctx). Where("account_id = ? AND inbox_id = ? AND created_at >= ? AND created_at <= ?", accountID, inboxID, since, until). Find(&events).Error return events, err } // AggregateByMetric returns aggregated values (average, count) for a given metric name. func (r *ReportingEventRepo) AggregateByMetric(ctx context.Context, accountID uint, metricName string, since, until time.Time) (float64, int64, error) { var result struct { SumValue float64 Count int64 } err := r.db.WithContext(ctx). Model(&model.ReportingEvent{}). Where("account_id = ? AND name = ? AND created_at >= ? AND created_at <= ?", accountID, metricName, since, until). Select("COALESCE(SUM(value), 0) as sum_value, COUNT(*) as count"). Take(&result).Error return result.SumValue, result.Count, err } // FindByAccountIDAndTimeRange retrieves all events for an account in a time range, // using event_start_time / event_end_time for precise boundary matching. func (r *ReportingEventRepo) FindByAccountIDAndTimeRange(ctx context.Context, accountID uint, since, until time.Time) ([]model.ReportingEvent, error) { var events []model.ReportingEvent err := r.db.WithContext(ctx). Where("account_id = ? AND event_start_time >= ? AND event_end_time <= ?", accountID, since, until). Find(&events).Error return events, err }