package growth import ( "slices" "time" ) type Session struct { CreatedAt time.Time `json:"createdAt"` Status string `json:"status"` AmountRial int64 `json:"amountRial"` } // AggregateDaily groups already-authorized, scope-filtered sessions by Tehran // local day. Paid and Verified are the only successful bank-payment statuses. func AggregateDaily(sessions []Session, catalog []Event) []DailyPoint { byDate := make(map[string]DailyPoint) for _, session := range sessions { local := session.CreatedAt.In(tehranLocation()) date := time.Date(local.Year(), local.Month(), local.Day(), 0, 0, 0, 0, tehranLocation()) key := dayKey(date) point := byDate[key] point.Date = date point.SessionCount++ if session.Status == "Paid" || session.Status == "Verified" { point.PaidSessionCount++ point.PaidAmountRial += session.AmountRial } byDate[key] = point } points := make([]DailyPoint, 0, len(byDate)) for _, point := range byDate { for _, event := range catalog { if !dateBefore(point.Date, event.StartDate) && !dateAfter(point.Date, event.EndDate) { point.EventIDs = append(point.EventIDs, event.ID) } } slices.Sort(point.EventIDs) points = append(points, point) } slices.SortFunc(points, func(a, b DailyPoint) int { return a.Date.Compare(b.Date) }) return points }