Skip to content

Commit 7750b81

Browse files
heiytorgustavosbarreto
authored andcommitted
refactor(api): decompose GetStats into specialized query builders #5476
- Extract device query builders to separate functions (buildOnlineDevicesQuery, etc.) - Remove duplicate $count stages that conflict with CountAllMatchingDocuments - Eliminate malformed aggregation pipelines causing incorrect counts - Fix query variable mutation between different device metrics
1 parent caf0b5e commit 7750b81

File tree

1 file changed

+60
-91
lines changed

1 file changed

+60
-91
lines changed

api/store/mongo/stats.go

Lines changed: 60 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -11,129 +11,98 @@ import (
1111
)
1212

1313
func (s *Store) GetStats(ctx context.Context) (*models.Stats, error) {
14-
query := []bson.M{
15-
{"$group": bson.M{"_id": bson.M{"uid": "$uid"}, "count": bson.M{"$sum": 1}}},
16-
{"$group": bson.M{"_id": bson.M{"uid": "$uid"}, "count": bson.M{"$sum": 1}}},
17-
}
18-
19-
// Only match for the respective tenant if requested
14+
var tenantID string
2015
if tenant := gateway.TenantFromContext(ctx); tenant != nil {
21-
query = append([]bson.M{{
22-
"$match": bson.M{
23-
"tenant_id": tenant.ID,
24-
},
25-
}}, query...)
16+
tenantID = tenant.ID
2617
}
2718

28-
query = append([]bson.M{
29-
{
30-
"$match": bson.M{
31-
"disconnected_at": nil,
32-
"last_seen": bson.M{"$gt": primitive.NewDateTimeFromTime(time.Now().Add(-2 * time.Minute))},
33-
"status": "accepted",
34-
},
35-
},
36-
}, query...)
37-
38-
onlineDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), query)
19+
onlineDevicesQuery := buildOnlineDevicesQuery(tenantID)
20+
onlineDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), onlineDevicesQuery)
3921
if err != nil {
4022
return nil, err
4123
}
4224

43-
query = []bson.M{}
25+
registeredDevicesQuery := buildRegisteredDevicesQuery(tenantID)
26+
registeredDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), registeredDevicesQuery)
27+
if err != nil {
28+
return nil, err
29+
}
4430

45-
// Only match for the respective tenant if requested
46-
if tenant := gateway.TenantFromContext(ctx); tenant != nil {
47-
query = append([]bson.M{{
48-
"$match": bson.M{
49-
"tenant_id": tenant.ID,
50-
},
51-
}}, query...)
31+
pendingDevicesQuery := buildPendingDevicesQuery(tenantID)
32+
pendingDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), pendingDevicesQuery)
33+
if err != nil {
34+
return nil, err
5235
}
53-
query = append([]bson.M{{
54-
"$match": bson.M{
55-
"status": "accepted",
56-
},
57-
}}, query...)
5836

59-
registeredDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), query)
37+
rejectedDevicesQuery := buildRejectedDevicesQuery(tenantID)
38+
rejectedDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), rejectedDevicesQuery)
6039
if err != nil {
6140
return nil, err
6241
}
6342

64-
query = []bson.M{
65-
{"$count": "count"},
43+
activeSessionsQuery := buildActiveSessionsQuery(tenantID)
44+
activeSessions, err := CountAllMatchingDocuments(ctx, s.db.Collection("active_sessions"), activeSessionsQuery)
45+
if err != nil {
46+
return nil, err
6647
}
6748

68-
// Only match for the respective tenant if requested
69-
if tenant := gateway.TenantFromContext(ctx); tenant != nil {
70-
query = append([]bson.M{{
71-
"$match": bson.M{
72-
"tenant_id": tenant.ID,
73-
},
74-
}}, query...)
49+
stats := &models.Stats{
50+
RegisteredDevices: registeredDevices,
51+
OnlineDevices: onlineDevices,
52+
PendingDevices: pendingDevices,
53+
RejectedDevices: rejectedDevices,
54+
ActiveSessions: activeSessions,
7555
}
7656

77-
query = append([]bson.M{{
78-
"$match": bson.M{
79-
"status": "pending",
80-
},
81-
}}, query...)
57+
return stats, nil
58+
}
8259

83-
pendingDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), query)
84-
if err != nil {
85-
return nil, err
60+
func buildOnlineDevicesQuery(tenantID string) []bson.M {
61+
match := bson.M{
62+
"disconnected_at": nil,
63+
"last_seen": bson.M{"$gt": primitive.NewDateTimeFromTime(time.Now().Add(-2 * time.Minute))},
64+
"status": models.DeviceStatusAccepted,
8665
}
8766

88-
query = []bson.M{
89-
{"$count": "count"},
67+
if tenantID != "" {
68+
match["tenant_id"] = tenantID
9069
}
9170

92-
// Only match for the respective tenant if requested
93-
if tenant := gateway.TenantFromContext(ctx); tenant != nil {
94-
query = append([]bson.M{{
95-
"$match": bson.M{
96-
"tenant_id": tenant.ID,
97-
},
98-
}}, query...)
71+
return []bson.M{{"$match": match}}
72+
}
73+
74+
func buildRegisteredDevicesQuery(tenantID string) []bson.M {
75+
match := bson.M{"status": models.DeviceStatusAccepted}
76+
if tenantID != "" {
77+
match["tenant_id"] = tenantID
9978
}
10079

101-
query = append([]bson.M{{
102-
"$match": bson.M{
103-
"status": "rejected",
104-
},
105-
}}, query...)
80+
return []bson.M{{"$match": match}}
81+
}
10682

107-
rejectedDevices, err := CountAllMatchingDocuments(ctx, s.db.Collection("devices"), query)
108-
if err != nil {
109-
return nil, err
83+
func buildPendingDevicesQuery(tenantID string) []bson.M {
84+
match := bson.M{"status": models.DeviceStatusPending}
85+
if tenantID != "" {
86+
match["tenant_id"] = tenantID
11087
}
11188

112-
query = []bson.M{}
89+
return []bson.M{{"$match": match}}
90+
}
11391

114-
// Only match for the respective tenant if requested
115-
if tenant := gateway.TenantFromContext(ctx); tenant != nil {
116-
query = append(query, bson.M{
117-
"$match": bson.M{
118-
"tenant_id": tenant.ID,
119-
},
120-
})
92+
func buildRejectedDevicesQuery(tenantID string) []bson.M {
93+
match := bson.M{"status": models.DeviceStatusRejected}
94+
if tenantID != "" {
95+
match["tenant_id"] = tenantID
12196
}
12297

123-
query = append(query, bson.M{
124-
"$count": "count",
125-
})
98+
return []bson.M{{"$match": match}}
99+
}
126100

127-
activeSessions, err := CountAllMatchingDocuments(ctx, s.db.Collection("active_sessions"), query)
128-
if err != nil {
129-
return nil, err
101+
func buildActiveSessionsQuery(tenantID string) []bson.M {
102+
match := bson.M{}
103+
if tenantID != "" {
104+
match["tenant_id"] = tenantID
130105
}
131106

132-
return &models.Stats{
133-
RegisteredDevices: registeredDevices,
134-
OnlineDevices: onlineDevices,
135-
PendingDevices: pendingDevices,
136-
RejectedDevices: rejectedDevices,
137-
ActiveSessions: activeSessions,
138-
}, nil
107+
return []bson.M{{"$match": match}}
139108
}

0 commit comments

Comments
 (0)