@auto-engineer/server-generator-apollo-emmett 1.78.0 → 1.80.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.
package/ketchup-plan.md CHANGED
@@ -1,8 +1,7 @@
1
- # Ketchup Plan: Fix query resolver collection name casing mismatch
1
+ # Ketchup Plan: Slim ReadModel API add findOne, remove redundant methods
2
2
 
3
3
  ## TODO
4
4
 
5
5
  ## DONE
6
6
 
7
- - [x] Burst 1: Add regression test + fix EJS template to use projectionName for collection name (5df3ae89)
8
- - [x] Burst 2: Remove unused projectionType from scaffoldFromSchema template locals
7
+ - [x] Burst 1: Slim ReadModel to find + findOne, update EJS template API docs, update all inline snapshots
package/package.json CHANGED
@@ -32,8 +32,8 @@
32
32
  "uuid": "^11.0.0",
33
33
  "web-streams-polyfill": "^4.1.0",
34
34
  "zod": "^3.22.4",
35
- "@auto-engineer/message-bus": "1.78.0",
36
- "@auto-engineer/narrative": "1.78.0"
35
+ "@auto-engineer/narrative": "1.80.0",
36
+ "@auto-engineer/message-bus": "1.80.0"
37
37
  },
38
38
  "publishConfig": {
39
39
  "access": "public"
@@ -44,9 +44,9 @@
44
44
  "typescript": "^5.8.3",
45
45
  "vitest": "^3.2.4",
46
46
  "tsx": "^4.19.2",
47
- "@auto-engineer/cli": "1.78.0"
47
+ "@auto-engineer/cli": "1.80.0"
48
48
  },
49
- "version": "1.78.0",
49
+ "version": "1.80.0",
50
50
  "scripts": {
51
51
  "generate:server": "tsx src/cli/index.ts",
52
52
  "build": "tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp src/server.ts dist/src && cp -r src/utils dist/src && cp -r src/domain dist/src",
@@ -377,15 +377,12 @@ describe('projection.ts.ejs', () => {
377
377
  ): Promise<Wishlist[]> {
378
378
  const model = new ReadModel<Wishlist>(ctx.database, 'WishlistProjection');
379
379
 
380
- // ## IMPLEMENTATION INSTRUCTIONS ##
381
- // You can query the projection using the ReadModel API:
382
- // - model.getAll() fetch all documents
383
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
384
- // - model.find(filterFn) — filter documents using a predicate
385
- // - model.first(filterFn) — fetch the first document matching a predicate
380
+ // ReadModel API:
381
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
382
+ // - model.findOne(filterFn) T | null returns the first match
386
383
  //
387
- // Example below uses \\\`.find()\\\` to filter
388
- // change the logic for the query as needed to meet the requirements for the current slice.
384
+ // The scaffolded code below uses find() returning an array.
385
+ // If this query should return a single item, switch to findOne().
389
386
 
390
387
  return model.find((item) => {
391
388
  if (sessionId !== undefined && item.sessionId !== sessionId) return false;
@@ -104,15 +104,12 @@ describe('query.resolver.ts.ejs', () => {
104
104
  ): Promise<AvailableListings[]> {
105
105
  const model = new ReadModel<AvailableListings>(ctx.database, 'AvailablePropertiesProjection');
106
106
 
107
- // ## IMPLEMENTATION INSTRUCTIONS ##
108
- // You can query the projection using the ReadModel API:
109
- // - model.getAll() fetch all documents
110
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
111
- // - model.find(filterFn) — filter documents using a predicate
112
- // - model.first(filterFn) — fetch the first document matching a predicate
107
+ // ReadModel API:
108
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
109
+ // - model.findOne(filterFn) T | null returns the first match
113
110
  //
114
- // Example below uses \\\`.find()\\\` to filter
115
- // change the logic for the query as needed to meet the requirements for the current slice.
111
+ // The scaffolded code below uses find() returning an array.
112
+ // If this query should return a single item, switch to findOne().
116
113
 
117
114
  return model.find((item) => {
118
115
  if (location !== undefined && item.location !== location) return false;
@@ -235,15 +232,12 @@ describe('query.resolver.ts.ejs', () => {
235
232
  ): Promise<SuggestedItems[]> {
236
233
  const model = new ReadModel<SuggestedItems>(ctx.database, 'SuggestedItemsProjection');
237
234
 
238
- // ## IMPLEMENTATION INSTRUCTIONS ##
239
- // You can query the projection using the ReadModel API:
240
- // - model.getAll() fetch all documents
241
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
242
- // - model.find(filterFn) — filter documents using a predicate
243
- // - model.first(filterFn) — fetch the first document matching a predicate
235
+ // ReadModel API:
236
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
237
+ // - model.findOne(filterFn) T | null returns the first match
244
238
  //
245
- // Example below uses \\\`.find()\\\` to filter
246
- // change the logic for the query as needed to meet the requirements for the current slice.
239
+ // The scaffolded code below uses find() returning an array.
240
+ // If this query should return a single item, switch to findOne().
247
241
 
248
242
  return model.find((item) => {
249
243
  if (sessionId !== undefined && item.sessionId !== sessionId) return false;
@@ -411,15 +405,12 @@ describe('query.resolver.ts.ejs', () => {
411
405
  ): Promise<QuestionnaireProgress[]> {
412
406
  const model = new ReadModel<QuestionnaireProgress>(ctx.database, 'Questionnaires');
413
407
 
414
- // ## IMPLEMENTATION INSTRUCTIONS ##
415
- // You can query the projection using the ReadModel API:
416
- // - model.getAll() fetch all documents
417
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
418
- // - model.find(filterFn) — filter documents using a predicate
419
- // - model.first(filterFn) — fetch the first document matching a predicate
408
+ // ReadModel API:
409
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
410
+ // - model.findOne(filterFn) T | null returns the first match
420
411
  //
421
- // Example below uses \\\`.find()\\\` to filter
422
- // change the logic for the query as needed to meet the requirements for the current slice.
412
+ // The scaffolded code below uses find() returning an array.
413
+ // If this query should return a single item, switch to findOne().
423
414
 
424
415
  return model.find((item) => {
425
416
  if (participantId !== undefined && item.participantId !== participantId) return false;
@@ -936,15 +927,12 @@ describe('query.resolver.ts.ejs', () => {
936
927
  ): Promise<RecipeMatchesRecipes[]> {
937
928
  const model = new ReadModel<RecipeMatchesRecipes>(ctx.database, 'RecipeMatchesProjection');
938
929
 
939
- // ## IMPLEMENTATION INSTRUCTIONS ##
940
- // You can query the projection using the ReadModel API:
941
- // - model.getAll() fetch all documents
942
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
943
- // - model.find(filterFn) — filter documents using a predicate
944
- // - model.first(filterFn) — fetch the first document matching a predicate
930
+ // ReadModel API:
931
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
932
+ // - model.findOne(filterFn) T | null returns the first match
945
933
  //
946
- // Example below uses \\\`.find()\\\` to filter
947
- // change the logic for the query as needed to meet the requirements for the current slice.
934
+ // The scaffolded code below uses find() returning an array.
935
+ // If this query should return a single item, switch to findOne().
948
936
 
949
937
  return model.find((item) => {
950
938
  if (pantryId !== undefined && item.pantryId !== pantryId) return false;
@@ -1181,15 +1169,12 @@ describe('query.resolver.ts.ejs', () => {
1181
1169
  ): Promise<RecipeMatchesRecipes[]> {
1182
1170
  const model = new ReadModel<RecipeMatchesRecipes>(ctx.database, 'RecipeMatchesProjection');
1183
1171
 
1184
- // ## IMPLEMENTATION INSTRUCTIONS ##
1185
- // You can query the projection using the ReadModel API:
1186
- // - model.getAll() fetch all documents
1187
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
1188
- // - model.find(filterFn) — filter documents using a predicate
1189
- // - model.first(filterFn) — fetch the first document matching a predicate
1172
+ // ReadModel API:
1173
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
1174
+ // - model.findOne(filterFn) T | null returns the first match
1190
1175
  //
1191
- // Example below uses \\\`.find()\\\` to filter
1192
- // change the logic for the query as needed to meet the requirements for the current slice.
1176
+ // The scaffolded code below uses find() returning an array.
1177
+ // If this query should return a single item, switch to findOne().
1193
1178
 
1194
1179
  return model.find((item) => {
1195
1180
  if (pantryId !== undefined && item.pantryId !== pantryId) return false;
@@ -156,15 +156,12 @@ async <%= queryName %>(
156
156
  ): Promise<<%= viewType %>[]> {
157
157
  const model = new ReadModel<<%= viewType %>>(ctx.database, '<%= collectionName %>');
158
158
 
159
- // ## IMPLEMENTATION INSTRUCTIONS ##
160
- // You can query the projection using the ReadModel API:
161
- // - model.getAll() fetch all documents
162
- // - model.getById(id) — fetch a single document by ID (default key: 'id')
163
- // - model.find(filterFn) — filter documents using a predicate
164
- // - model.first(filterFn) — fetch the first document matching a predicate
159
+ // ReadModel API:
160
+ // - model.find(filterFn?) → T[] returns all matches (or all documents if no filter)
161
+ // - model.findOne(filterFn) T | null returns the first match
165
162
  //
166
- // Example below uses \`.find()\` to filter
167
- // change the logic for the query as needed to meet the requirements for the current slice.
163
+ // The scaffolded code below uses find() returning an array.
164
+ // If this query should return a single item, switch to findOne().
168
165
 
169
166
  return model.find((<%= hasArgs ? 'item' : '_item' %>) => {
170
167
  <% if (parsedRequest?.args?.length) {
@@ -7,20 +7,11 @@ export class ReadModel<T extends Record<string, unknown>> {
7
7
  this.collection = database.collection<T>(collectionName);
8
8
  }
9
9
 
10
- async getAll(): Promise<T[]> {
11
- return this.collection.find();
12
- }
13
-
14
- async getById(id: string, idField: keyof T = 'id' as keyof T): Promise<T | null> {
15
- return this.collection.findOne((doc) => doc[idField] === id);
16
- }
17
-
18
- async find(filterFn: (item: T) => boolean): Promise<T[]> {
10
+ async find(filterFn?: (item: T) => boolean): Promise<T[]> {
19
11
  return this.collection.find(filterFn);
20
12
  }
21
13
 
22
- async first(filterFn: (item: T) => boolean): Promise<T | null> {
23
- const all = await this.collection.find(filterFn);
24
- return all[0] ?? null;
14
+ async findOne(filterFn: (item: T) => boolean): Promise<T | null> {
15
+ return this.collection.findOne(filterFn);
25
16
  }
26
17
  }