| 22 | } |
| 23 | |
| 24 | func NewUsageService(db *db.DB, cfg *cfg.Cfg, logger *logger.Logger) *UsageService { |
| 25 | base := NewBaseService(db, cfg, logger) |
| 26 | hourlyCollection := base.db.Collection((models.HourlyUsage{}).CollectionName()) |
| 27 | weeklyCollection := base.db.Collection((models.WeeklyUsage{}).CollectionName()) |
| 28 | lifetimeCollection := base.db.Collection((models.LifetimeUsage{}).CollectionName()) |
| 29 | |
| 30 | // Hourly usage indexes |
| 31 | hourlyIndexModels := []mongo.IndexModel{ |
| 32 | { |
| 33 | Keys: bson.D{ |
| 34 | {Key: "user_id", Value: 1}, |
| 35 | {Key: "project_id", Value: 1}, |
| 36 | {Key: "hour_bucket", Value: 1}, |
| 37 | }, |
| 38 | Options: options.Index().SetUnique(true), |
| 39 | }, |
| 40 | { |
| 41 | Keys: bson.D{ |
| 42 | {Key: "project_id", Value: 1}, |
| 43 | {Key: "hour_bucket", Value: 1}, |
| 44 | }, |
| 45 | }, |
| 46 | { |
| 47 | Keys: bson.D{ |
| 48 | {Key: "hour_bucket", Value: 1}, |
| 49 | }, |
| 50 | Options: options.Index().SetExpireAfterSeconds(14 * 24 * 60 * 60), // 2 weeks TTL |
| 51 | }, |
| 52 | } |
| 53 | _, err := hourlyCollection.Indexes().CreateMany(context.Background(), hourlyIndexModels) |
| 54 | if err != nil { |
| 55 | logger.Error("Failed to create indexes for hourly_usages collection", err) |
| 56 | } |
| 57 | |
| 58 | // Weekly usage indexes |
| 59 | weeklyIndexModels := []mongo.IndexModel{ |
| 60 | { |
| 61 | Keys: bson.D{ |
| 62 | {Key: "user_id", Value: 1}, |
| 63 | {Key: "project_id", Value: 1}, |
| 64 | {Key: "week_bucket", Value: 1}, |
| 65 | }, |
| 66 | Options: options.Index().SetUnique(true), |
| 67 | }, |
| 68 | { |
| 69 | Keys: bson.D{ |
| 70 | {Key: "project_id", Value: 1}, |
| 71 | {Key: "week_bucket", Value: 1}, |
| 72 | }, |
| 73 | }, |
| 74 | { |
| 75 | Keys: bson.D{ |
| 76 | {Key: "week_bucket", Value: 1}, |
| 77 | }, |
| 78 | Options: options.Index().SetExpireAfterSeconds(14 * 24 * 60 * 60), // 2 weeks TTL |
| 79 | }, |
| 80 | } |
| 81 | _, err = weeklyCollection.Indexes().CreateMany(context.Background(), weeklyIndexModels) |