@simtlix/simfinity-js 2.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,235 @@
1
+ # Aggregation Feature Implementation Summary
2
+
3
+ ## Overview
4
+ Successfully added support for GraphQL aggregation queries with group by functionality to simfinity.js. This allows users to perform aggregate operations (SUM, COUNT, AVG, MIN, MAX) on entity data with flexible grouping capabilities.
5
+
6
+ ## Changes Made
7
+
8
+ ### 1. Custom JSON Scalar Type
9
+ **File:** `src/index.js`
10
+ - Created a custom `GraphQLJSON` scalar type for flexible JSON output in aggregation results
11
+ - No external dependencies required - uses only the standard GraphQL package
12
+
13
+ ### 2. Core Implementation Files
14
+ **File:** `src/index.js`
15
+
16
+ #### Custom JSON Scalar
17
+ - Created a custom `GraphQLJSON` scalar type implementation
18
+ - Supports serialization, parsing, and literal parsing of JSON values
19
+ - Handles objects, arrays, strings, numbers, booleans, and null values
20
+
21
+ #### New GraphQL Types
22
+
23
+ ##### QLAggregationOperation (Enum)
24
+ ```javascript
25
+ const QLAggregationOperation = new GraphQLEnumType({
26
+ name: 'QLAggregationOperation',
27
+ values: {
28
+ SUM: { value: 'SUM' },
29
+ COUNT: { value: 'COUNT' },
30
+ AVG: { value: 'AVG' },
31
+ MIN: { value: 'MIN' },
32
+ MAX: { value: 'MAX' },
33
+ },
34
+ });
35
+ ```
36
+
37
+ ##### QLTypeAggregationFact (Input Type)
38
+ - Defines a single aggregation metric
39
+ - Fields:
40
+ - `operation` (required): The aggregation operation to perform
41
+ - `factName` (required): Name for the metric in the result
42
+ - `path` (required): Field path to aggregate (supports dot notation for related entities)
43
+
44
+ ##### QLTypeAggregationExpression (Input Type)
45
+ - Defines the complete aggregation configuration
46
+ - Fields:
47
+ - `groupId` (required): Field path to group by (supports dot notation)
48
+ - `facts` (required): Array of aggregation facts to calculate
49
+
50
+ ##### QLTypeAggregationResult (Output Type)
51
+ - Result structure for aggregation queries
52
+ - Fields:
53
+ - `groupId` (JSON): The value used for grouping
54
+ - `facts` (JSON): Object containing all calculated metrics
55
+
56
+ #### New Functions
57
+
58
+ ##### buildFieldPath(gqltype, fieldPath)
59
+ - Resolves a field path string (e.g., "category" or "country.name") to MongoDB field paths
60
+ - Handles:
61
+ - Direct scalar fields
62
+ - Embedded object fields
63
+ - Non-embedded related entity fields (generates $lookup operations)
64
+ - Returns: `{ mongoPath, lookups }` where lookups are MongoDB aggregation stages needed
65
+
66
+ ##### buildAggregationQuery(input, gqltype, aggregationExpression)
67
+ - Generates MongoDB aggregation pipeline for group by queries
68
+ - Reuses filtering logic from `buildQuery` function
69
+ - Process:
70
+ 1. Applies filters (same as regular queries)
71
+ 2. Adds lookups for related entities referenced in groupId or facts
72
+ 3. Creates $group stage with _id set to groupId field
73
+ 4. Adds aggregation operations for each fact
74
+ 5. Projects final output format with groupId and facts fields
75
+ - Returns: Array of MongoDB aggregation pipeline stages
76
+
77
+ #### Endpoint Generation
78
+ **Modified:** `buildRootQuery` function
79
+ - For each entity type with an endpoint, automatically generates an `{entityname}_aggregate` endpoint
80
+ - Endpoint configuration:
81
+ - Inherits all filter arguments from the main query endpoint
82
+ - Adds required `aggregation` parameter of type `QLTypeAggregationExpression`
83
+ - Returns `GraphQLList(QLTypeAggregationResult)`
84
+ - Resolver calls `buildAggregationQuery` and executes the MongoDB aggregation pipeline
85
+
86
+ ### 3. Tests
87
+ **File:** `tests/aggregation.test.js`
88
+ - Created comprehensive test suite with 5 tests
89
+ - Tests verify:
90
+ - Aggregation endpoint exists in schema
91
+ - Correct GraphQL type structure
92
+ - QLTypeAggregationResult has proper fields
93
+ - Filter arguments are inherited
94
+ - All aggregation types are present in schema
95
+ - Tests pass without requiring database connection (schema validation only)
96
+
97
+ ### 4. Documentation
98
+ **File:** `AGGREGATION_EXAMPLE.md`
99
+ - Comprehensive usage guide with examples
100
+ - Covers:
101
+ - Basic group by with COUNT
102
+ - Grouping by related entity fields
103
+ - Multiple aggregation facts
104
+ - Filtering with aggregation
105
+ - Pagination with aggregation
106
+ - Field path resolution rules
107
+
108
+ ## Key Features
109
+
110
+ ### 1. Field Path Resolution
111
+ Supports multiple path formats:
112
+ - **Direct fields**: `"category"`, `"rating"`, `"id"`
113
+ - **Related entity fields**: `"country.name"`, `"studio.foundedYear"`
114
+ - **Nested relations**: `"country.region.name"`
115
+
116
+ ### 2. Aggregation Operations
117
+ All standard MongoDB aggregation operations:
118
+ - **SUM**: Sum of numeric values
119
+ - **COUNT**: Count of records in group
120
+ - **AVG**: Average of numeric values
121
+ - **MIN**: Minimum value
122
+ - **MAX**: Maximum value
123
+
124
+ ### 3. Filtering Support
125
+ - All filter parameters from regular queries work with aggregation
126
+ - Filters are applied before grouping
127
+ - Uses existing `buildQueryTerms` function for consistency
128
+
129
+ ### 4. Automatic Lookups
130
+ - Automatically generates MongoDB $lookup stages for non-embedded related entities
131
+ - Handles complex field paths with multiple levels of relations
132
+ - Prevents duplicate lookups when multiple facts reference the same entity
133
+
134
+ ### 5. Result Format
135
+ Consistent JSON output structure:
136
+ ```json
137
+ {
138
+ "groupId": <value>,
139
+ "facts": {
140
+ "factName1": <calculated_value>,
141
+ "factName2": <calculated_value>
142
+ }
143
+ }
144
+ ```
145
+
146
+ ## MongoDB Translation
147
+
148
+ The implementation generates efficient MongoDB aggregation pipelines:
149
+
150
+ 1. **$lookup**: Joins with related entity collections
151
+ 2. **$unwind**: Flattens joined arrays
152
+ 3. **$match**: Applies filters
153
+ 4. **$group**: Groups by field with aggregation operations
154
+ 5. **$project**: Formats final output structure
155
+
156
+ ## Testing Results
157
+
158
+ All tests pass successfully:
159
+ - ✅ 5 new aggregation tests
160
+ - ✅ 22 existing tests (all still passing)
161
+ - ✅ No linting errors
162
+ - ✅ No breaking changes to existing functionality
163
+
164
+ ## Example Usage
165
+
166
+ ### Simple Group By
167
+ ```graphql
168
+ query {
169
+ series_aggregate(
170
+ aggregation: {
171
+ groupId: "category"
172
+ facts: [
173
+ { operation: COUNT, factName: "total", path: "id" }
174
+ ]
175
+ }
176
+ ) {
177
+ groupId
178
+ facts
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### Group By Related Entity
184
+ ```graphql
185
+ query {
186
+ series_aggregate(
187
+ aggregation: {
188
+ groupId: "country.name"
189
+ facts: [
190
+ { operation: COUNT, factName: "count", path: "id" }
191
+ { operation: AVG, factName: "avgRating", path: "rating" }
192
+ ]
193
+ }
194
+ ) {
195
+ groupId
196
+ facts
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### With Filtering
202
+ ```graphql
203
+ query {
204
+ series_aggregate(
205
+ rating: { operator: GTE, value: 8.0 }
206
+ aggregation: {
207
+ groupId: "category"
208
+ facts: [
209
+ { operation: COUNT, factName: "highRated", path: "id" }
210
+ ]
211
+ }
212
+ ) {
213
+ groupId
214
+ facts
215
+ }
216
+ }
217
+ ```
218
+
219
+ ## Backwards Compatibility
220
+
221
+ ✅ All changes are additive and non-breaking:
222
+ - Existing endpoints continue to work unchanged
223
+ - No modifications to existing input/output types
224
+ - Aggregation feature is opt-in (users can ignore it if not needed)
225
+ - All existing tests pass without modification
226
+
227
+ ## Future Enhancements (Optional)
228
+
229
+ Potential improvements for future versions:
230
+ 1. Support for multiple grouping fields
231
+ 2. Having clause for filtering after aggregation
232
+ 3. Support for more complex aggregation expressions
233
+ 4. Aggregation result caching
234
+ 5. Aggregation pagination optimization
235
+