@izara_project/izara-core-generate-service-code 1.0.87 → 1.0.89

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.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/src/compile/flowValidator.js +25 -0
  3. package/src/compile/loadSchemas.js +199 -10
  4. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +3 -7
  5. package/src/emit/crud/crudActionPlan.js +105 -6
  6. package/src/emit/crud/emitCrudApplicationArtifacts.js +63 -3
  7. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +15 -32
  8. package/src/emit/crud/templates/CreateAfterHookCallback_Main.ejs +121 -0
  9. package/src/emit/crud/templates/CreateBeforeHookCallback_Main.ejs +108 -0
  10. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +140 -340
  11. package/src/emit/crud/templates/CreateLogicalLib.ejs +338 -82
  12. package/src/emit/crud/templates/CreateNodeCallback_Main.ejs +90 -0
  13. package/src/emit/crud/templates/DeleteAfterHookCallback_Main.ejs +118 -0
  14. package/src/emit/crud/templates/DeleteBeforeHookCallback_Main.ejs +99 -0
  15. package/src/emit/crud/templates/DeleteComplete_Main.ejs +124 -10
  16. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +151 -179
  17. package/src/emit/crud/templates/DeleteLogicalLib.ejs +244 -27
  18. package/src/emit/crud/templates/UpdateAfterHookCallback_Main.ejs +120 -0
  19. package/src/emit/crud/templates/UpdateBeforeHookCallback_Main.ejs +112 -0
  20. package/src/emit/crud/templates/UpdateComplete_Main.ejs +104 -10
  21. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +166 -185
  22. package/src/emit/crud/templates/UpdateLogicalLib.ejs +123 -3
  23. package/src/emit/custom/customFlows.js +3 -1
  24. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +8 -2
  25. package/src/emit/rbac/templates/CancelUsage_Main.ejs +34 -14
  26. package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +34 -14
  27. package/src/emit/resource/emitResourceArtifacts.js +119 -59
  28. package/test/crudApplicationArtifacts.test.js +876 -0
  29. package/test/dynamicCrudFlowSchemas.test.js +10 -5
  30. package/test/dynamicRbacFlowSchemas.test.js +24 -2
  31. package/test/graphDrivenFlowSchema.test.js +36 -0
  32. package/test/resourceArtifacts.test.js +271 -12
@@ -41,237 +41,16 @@ import {
41
41
  } from '@izara_project/izara-core-library-service-schemas';
42
42
  import snsSharedLib from '@izara_project/izara-core-library-sns';
43
43
 
44
- import { <%- flowTag %>LogicalLib } from './<%- upperCaseFlowTag %>LogicalLib.js';
44
+ import {
45
+ <%- flowTag %>LogicalLib,
46
+ resolveSchemaAndIdentity,
47
+ resolveAndGenerateIdentifiers,
48
+ validateFieldNames
49
+ } from './<%- upperCaseFlowTag %>LogicalLib.js';
45
50
 
46
51
  //(<optionalRequire>)
47
52
  //(</optionalRequire>)
48
53
 
49
- const { createObjType, firstLetterUpperCase } = utils;
50
- const { createDataDetailsLib } = dataDetailsLib;
51
- const { createIdentifiersByUseCase } = identifiersObject;
52
-
53
- // ── Helper Functions ──────────────────────────────────────────────────────────
54
-
55
- /**
56
- * Loads Schema and resolves submittedByUserId and targetIdentifiers
57
- * @param {Object} _izContext - Izara context object
58
- * @param {Object} requestParams - Request parameters
59
- * @param {Array<string>} errorsFound - Error list
60
- * @returns {Promise<{ objType: Object, objectSchema: Object, targetIdentifiers?: Object }>}
61
- */
62
- async function resolveSchemaAndIdentity(_izContext, requestParams, errorsFound) {
63
- const objType = createObjType(requestParams.objectType);
64
- const objectSchema = await getObjectSchema.getObjSchemaS3WithHierarchy(
65
- _izContext,
66
- objType
67
- );
68
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchema:`, objectSchema);
69
-
70
- let submittedByUserId, targetIdentifiers;
71
- if (
72
- objectSchema.generatedBy === 'user' ||
73
- objectSchema.generatedBy === 'systemWithUser'
74
- ) {
75
- submittedByUserId =
76
- requestParams.submittedByUserId ||
77
- _izContext.correlationIds.get(coreConsts.SUBMITTED_BY_USER_ID);
78
-
79
- targetIdentifiers = requestParams.targetIdentifiers;
80
-
81
- if (!targetIdentifiers && submittedByUserId) {
82
- targetIdentifiers = { submittedByUserId };
83
- }
84
-
85
- if (!submittedByUserId) errorsFound.push('Not have submittedByUserId');
86
- if (objectSchema.hasOwnProperty('belongTo') && !targetIdentifiers)
87
- errorsFound.push('not have targetIdentifiers');
88
-
89
- if (targetIdentifiers) {
90
- if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
91
- targetIdentifiers.submittedByUserId = submittedByUserId;
92
- }
93
-
94
- if (Array.isArray(objectSchema.identifiers)) {
95
- for (const identifier of objectSchema.identifiers) {
96
- if (identifier.fieldName) {
97
- if (targetIdentifiers[identifier.fieldName] === undefined) {
98
- targetIdentifiers[identifier.fieldName] = null;
99
- }
100
- } else if (Array.isArray(identifier.fieldNames)) {
101
- for (const fn of identifier.fieldNames) {
102
- if (targetIdentifiers[fn] === undefined) {
103
- targetIdentifiers[fn] = null;
104
- }
105
- }
106
- } else if (identifier.name) {
107
- if (targetIdentifiers[identifier.name] === undefined) {
108
- targetIdentifiers[identifier.name] = null;
109
- }
110
- }
111
- }
112
- }
113
-
114
- requestParams.targetIdentifiers = targetIdentifiers;
115
- }
116
-
117
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
118
- submittedByUserId: requestParams.submittedByUserId,
119
- targetIdentifiers: requestParams.targetIdentifiers,
120
- belongTo: objectSchema.belongTo,
121
- generatedBy: objectSchema.generatedBy
122
- });
123
- } else if (objectSchema.generatedBy === 'searchResultGenerated') {
124
- throw new NoRetryError(
125
- 'error searchResultGenerated should not happen here'
126
- );
127
- }
128
-
129
- return { objType, objectSchema, targetIdentifiers };
130
- }
131
-
132
- /**
133
- * Resolves fromRequiredOnCreate fields and generates identifiers
134
- * @param {Object} _izContext - Izara context object
135
- * @param {Object} requestParams - Request parameters
136
- * @param {Object} objectSchema - Base object schema
137
- * @param {Object} objType - Object type
138
- * @param {Object} targetIdentifiers - Target identifiers
139
- * @param {Array<string>} errorsFound - Error list
140
- * @returns {Promise<{ objectSchemas: Object, createDataDetails: Object }>}
141
- */
142
- async function resolveAndGenerateIdentifiers(
143
- _izContext,
144
- requestParams,
145
- objectSchema,
146
- objType,
147
- targetIdentifiers,
148
- errorsFound
149
- ) {
150
- const objectSchemas =
151
- uploadUseCase.generateObjectSchemaForCombineFieldNames(
152
- _izContext,
153
- objectSchema
154
- );
155
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchemas:`, objectSchemas);
156
-
157
- const createDataDetails = await createDataDetailsLib(
158
- _izContext,
159
- objectSchemas
160
- );
161
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] createDataDetails:`, createDataDetails);
162
-
163
- if (requestParams.relationships?.length > 0) {
164
- //(<beforeValidateRelationships>)
165
- //(</beforeValidateRelationships>)
166
- }
167
-
168
- errorsFound.push(
169
- ...(await createNodeLib.validateRequiredOnCreateLinks(
170
- _izContext,
171
- objType,
172
- requestParams.relationships
173
- ))
174
- );
175
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] errorsFound:`, errorsFound);
176
-
177
- // ── Resolve fromRequiredOnCreate fields ──
178
- if (objectSchemas.fieldNames) {
179
- if (!requestParams.fieldNames) requestParams.fieldNames = {};
180
- for (const [fieldName, val] of Object.entries(objectSchemas.fieldNames)) {
181
- if (val.fromRequiredOnCreate && requestParams.fieldNames[fieldName] === undefined) {
182
- const fromConfig = val.fromRequiredOnCreate;
183
- const sourceField = fromConfig.fieldName || fieldName;
184
- if (fromConfig.belongToObjType === true && targetIdentifiers) {
185
- const targetValue =
186
- targetIdentifiers[sourceField] !== undefined
187
- ? targetIdentifiers[sourceField]
188
- : Object.values(targetIdentifiers)[0];
189
- requestParams.fieldNames[fieldName] = targetValue;
190
- } else if (fromConfig.relType && requestParams.relationships?.length > 0) {
191
- const matchedRel = requestParams.relationships.find(
192
- (rel) =>
193
- rel.relType?.serviceTag === fromConfig.relType.serviceTag &&
194
- rel.relType?.relationshipTag === fromConfig.relType.relationshipTag
195
- );
196
- if (matchedRel?.targetIdentifiers?.[sourceField] !== undefined) {
197
- requestParams.fieldNames[fieldName] = matchedRel.targetIdentifiers[sourceField];
198
- }
199
- }
200
- }
201
- }
202
- }
203
-
204
- // ── Resolve identifiers ──
205
- let errors;
206
- const identifiers = objectSchemas.identifiers;
207
- let optionalOnCreateIdentifiers;
208
-
209
- if (
210
- identifiers.length === 1 &&
211
- !identifiers[0].hasOwnProperty('fieldNames')
212
- ) {
213
- [requestParams, errors] = await createIdentifiersByUseCase(
214
- _izContext,
215
- requestParams,
216
- objectSchemas,
217
- identifiers[0],
218
- optionalOnCreateIdentifiers
219
- );
220
- errorsFound.push(...errors);
221
- } else if (identifiers.length > 1) {
222
- for (const identifier of identifiers) {
223
- [requestParams, errors] = await createIdentifiersByUseCase(
224
- _izContext,
225
- requestParams,
226
- objectSchemas,
227
- identifier,
228
- optionalOnCreateIdentifiers
229
- );
230
- errorsFound.push(...errors);
231
- }
232
- }
233
-
234
- return { objectSchemas, createDataDetails };
235
- }
236
-
237
- /**
238
- * Validates request field names against schema
239
- * @param {Object} requestParams - Request parameters
240
- * @param {Object} objectSchemas - Combined schema
241
- * @param {Array<string>} errorsFound - Error list
242
- */
243
- function validateFieldNames(requestParams, objectSchemas, errorsFound) {
244
- const listOfRequiredOnCreate = [];
245
- const listOfOptionalOnCreate = [];
246
-
247
- for (const [key, val] of Object.entries(objectSchemas.fieldNames)) {
248
- if (
249
- val.randomOnCreate === true ||
250
- val.requiredOnCreate === true ||
251
- val.fromRequiredOnCreate ||
252
- val.hashOnCreate?.length
253
- ) {
254
- listOfRequiredOnCreate.push(key);
255
- }
256
- if (val.requiredOnCreate === false && val.optionalOnCreate === true) {
257
- listOfOptionalOnCreate.push(key);
258
- }
259
- }
260
-
261
- for (const fieldName of Object.keys(requestParams.fieldNames)) {
262
- if (
263
- !listOfRequiredOnCreate.includes(fieldName) &&
264
- !listOfOptionalOnCreate.includes(fieldName)
265
- ) {
266
- errorsFound.push('[invalid] over fieldNames create object');
267
- }
268
- if (errorsFound.length > 0) {
269
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] HaveError:`, errorsFound);
270
- break;
271
- }
272
- }
273
- }
274
-
275
54
  // ── Main Entry Function ───────────────────────────────────────────────────────
276
55
 
277
56
  /**
@@ -284,20 +63,23 @@ function validateFieldNames(requestParams, objectSchemas, errorsFound) {
284
63
  export default async function <%- flowTag %>(
285
64
  _izContext,
286
65
  requestParams,
287
- callingFlowConfig = {},
66
+ callingFlowConfig = {}
288
67
  //(<additionalParams>)
289
68
  //(</additionalParams>)
290
69
  ) {
291
70
  try {
292
- _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] createMain:`, {
293
- requestParams,
294
- callingFlowConfig
295
- });
71
+ _izContext.logger.debug(
72
+ `[${process.env.iz_serviceTag}:<%- flowTag %>] createMain:`,
73
+ {
74
+ requestParams,
75
+ callingFlowConfig
76
+ }
77
+ );
296
78
 
297
79
  const errorsFound = [];
298
80
 
299
81
  // Step 1: Resolve Schema & Identity
300
- const { objType, objectSchema, targetIdentifiers } =
82
+ const { objType, objectSchema } =
301
83
  await resolveSchemaAndIdentity(_izContext, requestParams, errorsFound);
302
84
 
303
85
  //(<beforeQuery>)
@@ -308,8 +90,6 @@ export default async function <%- flowTag %>(
308
90
  _izContext,
309
91
  requestParams,
310
92
  objectSchema,
311
- objType,
312
- targetIdentifiers,
313
93
  errorsFound
314
94
  );
315
95
 
@@ -323,7 +103,7 @@ export default async function <%- flowTag %>(
323
103
  }
324
104
 
325
105
  // Step 3: Validate FieldNames
326
- validateFieldNames(requestParams, objectSchemas, errorsFound);
106
+ validateFieldNames(_izContext, requestParams, objectSchemas, errorsFound);
327
107
 
328
108
  if (errorsFound.length > 0) {
329
109
  return await <%- flowTag %>LogicalLib(
@@ -381,7 +161,9 @@ export default async function <%- flowTag %>(
381
161
  },
382
162
  parameterGroups,
383
163
  {
384
- targetIdentifiers,
164
+ targetIdentifiers:
165
+ requestParams.rbacTargetIdentifiers ||
166
+ requestParams.targetIdentifiers,
385
167
  rbacObjType: {
386
168
  serviceTag: <%- rbacServiceTags.length === 1 ? rbacServiceTags[0] : `{ ${Object.entries(rbacServiceTagMap).map(([k, v]) => `'${k}': ${v}`).join(', ')} }[requestParams.objectType] || process.env.iz_serviceTag` %>
387
169
  },
@@ -412,111 +194,122 @@ export default async function <%- flowTag %>(
412
194
 
413
195
  // ── Optional phase extension point ────────────────────────────────────────
414
196
  <%_
415
- const groupedByObjType = [];
197
+ const allCrudObjectTypes = (objects || []).filter(isCrudObject).map(o => o.objectType);
198
+ const beforeHooksByObjType = (plan?.beforeHooks || []).reduce((acc, hook) => {
199
+ const targets = (hook?.targetObjectTypes && hook.targetObjectTypes.length > 0)
200
+ ? hook.targetObjectTypes
201
+ : allCrudObjectTypes;
202
+ for (const key of targets) {
203
+ if (!acc[key]) acc[key] = [];
204
+ acc[key].push(hook);
205
+ }
206
+ return acc;
207
+ }, {});
416
208
  _%>
417
- <%_ Object.entries(groupedByObjType).forEach(([objectType, configs]) => { _%>
209
+ <%_ Object.entries(beforeHooksByObjType).forEach(([objectType, configs]) => { _%>
418
210
  <%_
419
- const hasOwnTopic = configs.some(c => c.invocationType === 'ownTopic');
420
- const hasLambdaSyncInv = configs.some(c => c.invocationType === 'lambdaSyncInv');
421
- _%>
211
+ const hasOwnTopic = configs.some(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic'));
212
+ const hasLambdaSyncInv = configs.some(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'));
213
+ _%>
422
214
  if (requestParams.objectType === '<%= objectType %>') {
423
215
  <%_ if (hasLambdaSyncInv) { _%>
424
- const lambdaSyncInvResults = await Promise.all([
425
- <%_ configs.filter(c => c.invocationType === 'lambdaSyncInv').forEach((config, index, arr) => { _%>
426
- // lambdaSyncInv <%= config.flowTag %>
427
- lambda
428
- .invokeSync(
216
+ const lambdaSyncInvResults = [];
217
+ <%_ for (const config of configs.filter(c => c?.generatedCodeConfig?.invocationType === 'lambdaSyncInv' || c?.event?.includes('lambdaSyncInv'))) { _%>
218
+ try {
219
+ let hookPayload_<%= config.flowTag %> = {
220
+ objType,
221
+ fieldNames: requestParams.fieldNames,
222
+ relationships: requestParams.relationships || [],
223
+ targetIdentifiers: requestParams.targetIdentifiers,
224
+ submittedByUserId: requestParams.submittedByUserId
225
+ };
226
+ //(<beforeSendHook_<%= config.flowTag %>>)
227
+ //(</beforeSendHook_<%= config.flowTag %>>)
228
+ const returnValue = await lambda.invokeSync(
229
+ _izContext,
230
+ await lambdaSharedLib.lambdaFunctionName(
429
231
  _izContext,
430
- await lambdaSharedLib.lambdaFunctionName(
431
- _izContext,
432
- 'Process<%= config.flowTag %>HdrInv'
433
- ),
434
- { requestParams, callingFlowConfig }
435
- )
436
- .then((returnValue) => ({
437
- flowTag: '<%= config.flowTag %>',
438
- returnValue
439
- })) /*__EJS_COMMA_14__*/
440
- // lambdaSyncInv <%= config.flowTag %>
441
- <%_ }) _%>
442
- ]);
232
+ '<%= config.flowTag %>'
233
+ ),
234
+ {
235
+ requestParams: hookPayload_<%= config.flowTag %>,
236
+ callingFlowConfig
237
+ }
238
+ );
239
+ lambdaSyncInvResults.push({
240
+ flowTag: '<%= config.flowTag %>',
241
+ returnValue
242
+ });
243
+ if (returnValue?.errorsFound?.length > 0) {
244
+ errorsFound.push(...returnValue.errorsFound);
245
+ } else if (returnValue?.status === 'error') {
246
+ errorsFound.push('Error from <%= config.flowTag %>');
247
+ } else {
248
+ if (returnValue?.fieldNames && requestParams?.fieldNames) {
249
+ Object.assign(requestParams.fieldNames, returnValue.fieldNames);
250
+ }
251
+ if (returnValue?.relationships && requestParams) {
252
+ requestParams.relationships = returnValue.relationships;
253
+ }
254
+ }
255
+ } catch (hookErr) {
256
+ _izContext.logger.error(
257
+ '[<%- flowTag %>] Sync hook <%= config.flowTag %> error:',
258
+ hookErr
259
+ );
260
+ errorsFound.push(hookErr.message || 'Hook <%= config.flowTag %> failed');
261
+ }
262
+ <%_ } _%>
443
263
 
264
+ if (errorsFound.length > 0) {
265
+ return await <%- flowTag %>LogicalLib(
266
+ _izContext,
267
+ requestParams,
268
+ callingFlowConfig,
269
+ errorsFound
270
+ );
271
+ }
444
272
  <%_ } _%>
445
273
 
446
274
  //(<afterBeforeLogical_<%= objectType %>>)
447
275
  //(</afterBeforeLogical_<%= objectType %>>)
448
276
 
449
277
  <%_ if (hasOwnTopic) { _%>
450
- // ── ownTopic (async — create awaitingSteps and then publish) ──────────────
451
- const awaitingMultipleStepIds = [];
452
- const recordMsgs = [];
453
-
454
- <%_ configs.filter(c => c.invocationType === 'ownTopic').forEach(config => { _%>
455
- // ownTopic <%= config.flowTag %>
456
- awaitingMultipleStepIds.push({
457
- awaitingStepId: await asyncFlowSharedLib.createAwaitingStepId(
458
- hash(objInstanceFull.identifiers),
459
- 'logical_<%= objectType %>_<%= config.flowTag.charAt(0).toUpperCase() + config.flowTag.slice(1) %>'
460
- ),
461
- additionalAttributes: {}
462
- });
463
-
464
- recordMsgs.push({
465
- msg: callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
466
- requestParams,
278
+ // ── ownTopic (async — dispatch to before-hook and await callback) ──────────
279
+ <%_ configs.filter(c => c?.generatedCodeConfig?.invocationType === 'ownTopic' || c?.event?.includes('ownTopic')).forEach(config => { _%>
280
+ let hookPayload_<%= config.flowTag %> = {
281
+ objType,
282
+ fieldNames: requestParams.fieldNames,
283
+ relationships: requestParams.relationships || [],
284
+ targetIdentifiers: requestParams.targetIdentifiers,
285
+ submittedByUserId: requestParams.submittedByUserId
286
+ };
287
+ //(<beforeSendHook_<%= config.flowTag %>>)
288
+ //(</beforeSendHook_<%= config.flowTag %>>)
289
+ const hookMsg_<%= config.flowTag %> =
290
+ callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
291
+ hookPayload_<%= config.flowTag %>,
467
292
  callingFlowSharedLib.addParentCallingFlowConfig(
468
293
  callingFlowConfig,
469
294
  callingFlowSharedLib.createCallingFlowConfig(
470
- //(<callingFlowProperties_<%= config.flowTag %>>)
471
295
  await lambdaSharedLib.lambdaFunctionName(
472
296
  _izContext,
473
- '<%= flowTag.toLowerCase() %>Complete'
297
+ '<%- flowTag %>BeforeHookCallbackHdrSqs'
474
298
  ),
475
- {}
476
- //(</callingFlowProperties_<%= config.flowTag %>>)
299
+ {
300
+ originalRequestParams: {
301
+ ...requestParams,
302
+ objType,
303
+ targetIdentifiers: requestParams.targetIdentifiers
304
+ },
305
+ callingFlowConfig
306
+ }
477
307
  )
478
308
  )
479
- ),
480
- flowTag: '<%= config.flowTag.charAt(0).toUpperCase() + config.flowTag.slice(1) %>'
481
- });
482
- <%_ }) _%>
483
-
484
- <%_ if (hasLambdaSyncInv) { _%>
485
- // ── Add lambdaSyncInv results to awaitingSteps ────────────────────────
486
- for (const syncResult of lambdaSyncInvResults) {
487
- awaitingMultipleStepIds.push({
488
- awaitingStepId: await asyncFlowSharedLib.createAwaitingStepId(
489
- hash(objInstanceFull.identifiers),
490
- 'logical_<%= objectType %>_' + syncResult.flowTag
491
- ),
492
- additionalAttributes: {
493
- complete: true,
494
- errorsFound: [],
495
- returnValue: syncResult.returnValue
496
- }
497
- });
498
- }
499
- <%_ } _%>
500
-
501
- await asyncFlowSharedLib.createAwaitingMultipleSteps(
502
- _izContext,
503
- asyncFlowSharedLib.createPendingStepId(
504
- _izContext.uniqueRequestId,
505
- 'logical_<%= objectType %>'
506
- ),
507
- awaitingMultipleStepIds,
508
- {
509
- additionalAttributes: {
510
- callingFlowConfig
511
- }
512
- }
513
- );
514
-
515
- //(<beforePublish_<%= objectType %>>)
516
- //(</beforePublish_<%= objectType %>>)
309
+ );
517
310
 
518
- for (const recordMsg of recordMsgs) {
519
- const messageAttributes = sns.createStringMessageAttributes(
311
+ const messageAttributes_<%= config.flowTag %> =
312
+ sns.createStringMessageAttributes(
520
313
  _izContext,
521
314
  callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(
522
315
  callingFlowConfig,
@@ -524,32 +317,36 @@ export default async function <%- flowTag %>(
524
317
  )
525
318
  );
526
319
 
527
- const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
528
- _izContext,
529
- `${recordMsg.flowTag}_In`
530
- );
320
+ const topicArn_<%= config.flowTag %> = snsSharedLib.snsTopicArnByFlowSchema(
321
+ _izContext,
322
+ '<%= config.flowTag %>_In'
323
+ );
531
324
 
532
- await sns.publishAsync(_izContext, {
533
- Message: JSON.stringify(recordMsg.msg),
534
- MessageAttributes: messageAttributes,
535
- TopicArn: topicArn
536
- });
537
- }
325
+ _izContext.logger.debug(
326
+ `[${process.env.iz_serviceTag}:<%- flowTag %>] Dispatching to BeforeHook:`,
327
+ {
328
+ topicArn: topicArn_<%= config.flowTag %>,
329
+ flowTag: '<%= config.flowTag %>'
330
+ }
331
+ );
538
332
 
539
- return 'complete logical <%= objectType %>';
333
+ await sns.publishAsync(_izContext, {
334
+ Message: JSON.stringify(hookMsg_<%= config.flowTag %>),
335
+ MessageAttributes: messageAttributes_<%= config.flowTag %>,
336
+ TopicArn: topicArn_<%= config.flowTag %>
337
+ });
338
+ <%_ }) _%>
540
339
 
340
+ return {
341
+ status: 'pending',
342
+ message: 'Dispatched to BeforeHook'
343
+ };
541
344
  <%_ } else { _%>
542
- // ── lambdaSyncInv only — collect results and proceed to createLogicalLib ────────────
543
- const phaseResults = Object.fromEntries(
544
- lambdaSyncInvResults.map(({ flowTag: tag, returnValue }) => [tag, returnValue])
545
- );
546
-
547
345
  return await <%- flowTag %>LogicalLib(
548
346
  _izContext,
549
347
  requestParams,
550
348
  callingFlowConfig,
551
- errorsFound,
552
- phaseResults
349
+ errorsFound
553
350
  );
554
351
  <%_ } _%>
555
352
  }
@@ -565,7 +362,10 @@ export default async function <%- flowTag %>(
565
362
  errorsFound
566
363
  );
567
364
  } catch (err) {
568
- _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>] error:`, err);
365
+ _izContext.logger.error(
366
+ `[${process.env.iz_serviceTag}:<%- flowTag %>] error:`,
367
+ err
368
+ );
569
369
  throw err;
570
370
  }
571
371
  }