@izara_project/izara-core-generate-service-code 1.0.83 → 1.0.84

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 (59) hide show
  1. package/package.json +4 -4
  2. package/src/compile/flowValidator.js +13 -2
  3. package/src/compile/loadSchemas.js +116 -7
  4. package/src/emit/attributeTree/emitAttributeTreeSchemas.js +388 -0
  5. package/src/emit/coreFunction/emitCoreFunctionArtifacts.js +29 -1
  6. package/src/emit/coreFunction/templates/InitialSetupConfig.ejs +16 -3
  7. package/src/emit/crud/crudActionPlan.js +38 -5
  8. package/src/emit/crud/emitCrudApplicationArtifacts.js +19 -4
  9. package/src/emit/crud/emitDynamicCrudFlowSchemas.js +27 -6
  10. package/src/emit/crud/generateCrudApplicationArtifacts.js +3 -2
  11. package/src/emit/crud/generateDynamicCrudFlowSchemas.js +3 -2
  12. package/src/emit/crud/loadLocalSchemaArrays.js +3 -3
  13. package/src/emit/crud/templates/CreateComplete_Main.ejs +1 -1
  14. package/src/emit/crud/templates/CreateEndpoint_Main.ejs +50 -19
  15. package/src/emit/crud/templates/CreateLogicalLib.ejs +73 -8
  16. package/src/emit/crud/templates/DeleteComplete_Main.ejs +1 -1
  17. package/src/emit/crud/templates/DeleteEndpoint_Main.ejs +33 -8
  18. package/src/emit/crud/templates/DeleteLogicalLib.ejs +6 -3
  19. package/src/emit/crud/templates/FlowEndpointRbacCallback_Main.ejs +2 -2
  20. package/src/emit/crud/templates/FlowEndpoint_HdrWbs.ejs +7 -0
  21. package/src/emit/crud/templates/FlowMain_Wbs.ejs +1 -1
  22. package/src/emit/crud/templates/GetEndpoint_Main.ejs +13 -0
  23. package/src/emit/crud/templates/UpdateComplete_Main.ejs +1 -1
  24. package/src/emit/crud/templates/UpdateEndpoint_Main.ejs +52 -3
  25. package/src/emit/crud/templates/UpdateLogicalLib.ejs +4 -3
  26. package/src/emit/custom/customFlows.js +47 -0
  27. package/src/emit/custom/emitCustomFlowApplicationArtifacts.js +168 -49
  28. package/src/emit/custom/generateCustomFlowApplicationArtifacts.js +1 -1
  29. package/src/emit/custom/templates/FlowEndpointRbacCallback_Main.ejs +194 -0
  30. package/src/emit/custom/templates/FlowEndpoint_Main.ejs +14 -22
  31. package/src/emit/custom/templates/FlowStep_Main.ejs +1 -1
  32. package/src/emit/function/templates/WbsFunction_Yaml.ejs +0 -2
  33. package/src/emit/rbac/emitDynamicRbacFlowSchemas.js +33 -8
  34. package/src/emit/rbac/emitRbacApplicationArtifacts.js +204 -7
  35. package/src/emit/rbac/templates/CancelUsage_Main.ejs +103 -0
  36. package/src/emit/rbac/templates/ConfirmUsage_Main.ejs +71 -0
  37. package/src/emit/rbac/templates/CreateTargetRole_Main.ejs +49 -6
  38. package/src/emit/rbac/templates/ListRbac_Main.ejs +9 -3
  39. package/src/emit/rbac/templates/RbacMutation_Main.ejs +1 -1
  40. package/src/emit/rbac/templates/ReservedDynamicUsage_Main.ejs +147 -0
  41. package/src/emit/rbac/templates/UserRbacFlow_Main.ejs +59 -23
  42. package/src/emit/rbac/templates/UserRoleMutation_Main.ejs +1 -1
  43. package/src/emit/relationship/emitDynamicRelationshipFlowSchemas.js +1 -1
  44. package/src/emit/relationship/templates/ChangeRelationship_Main.ejs +4 -4
  45. package/src/emit/resource/emitResourceArtifacts.js +342 -108
  46. package/src/emit/resource/templates/SystemDynamoDB_Yaml.ejs +53 -2
  47. package/src/emit/system/emitSystemWebSocketArtifacts.js +6 -5
  48. package/src/emit/system/templates/WebSocketConnect.ejs +71 -12
  49. package/src/emit/system/templates/WebSocketConnect_Yaml.ejs +7 -0
  50. package/src/emit/systemText/emitSystemTextSchemas.js +1 -1
  51. package/src/generate.js +41 -10
  52. package/test/attributeTreeSchemas.test.js +219 -0
  53. package/test/createTargetRoleHandler.test.js +59 -4
  54. package/test/crudApplicationArtifacts.test.js +20 -3
  55. package/test/customFlowApplicationArtifacts.test.js +5 -5
  56. package/test/dynamicCrudFlowSchemas.test.js +91 -4
  57. package/test/dynamicRbacFlowSchemas.test.js +15 -2
  58. package/test/publicApi.test.js +6 -6
  59. package/test/resourceArtifacts.test.js +68 -27
@@ -56,7 +56,7 @@ export default async function <%- flowTag %>(
56
56
  //(</additionalParams>)
57
57
  ) {
58
58
  try {
59
- _izContext.logger.debug('[<%- flowTag %>]', {
59
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] deleteMain:`, {
60
60
  requestParams,
61
61
  callingFlowConfig
62
62
  });
@@ -72,18 +72,42 @@ export default async function <%- flowTag %>(
72
72
  _izContext,
73
73
  objType
74
74
  );
75
- _izContext.logger.debug('objectSchema', objectSchema);
75
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchema:`, objectSchema);
76
76
 
77
- // ── Resolve userId / targetId ─────────────────────────────────────────────
77
+ // ── Resolve submittedByUserId / targetIdentifiers ─────────────────────────
78
+ let submittedByUserId, targetIdentifiers;
78
79
  if (
79
80
  objectSchema.generatedBy === 'user' ||
80
81
  objectSchema.generatedBy === 'systemWithUser'
81
82
  ) {
82
- const userId = _izContext.correlationIds.get(coreConsts.BASE_USER_ID);
83
- const targetId = _izContext.correlationIds.get(coreConsts.TARGET_ID);
84
- if (!userId) errorsFound.push('Not have userId');
85
- if (objectSchema.hasOwnProperty('belongTo') && !targetId)
86
- errorsFound.push('not have targetId');
83
+ submittedByUserId =
84
+ requestParams.submittedByUserId ||
85
+ _izContext.correlationIds.get(coreConsts.SUBMITTED_BY_USER_ID);
86
+
87
+ targetIdentifiers = requestParams.targetIdentifiers;
88
+
89
+ if (!targetIdentifiers && objectSchema.belongTo?.objectType === 'user' && submittedByUserId) {
90
+ targetIdentifiers = { submittedByUserId };
91
+ }
92
+
93
+ if (!submittedByUserId) errorsFound.push('Not have submittedByUserId');
94
+ if (objectSchema.hasOwnProperty('belongTo') && !targetIdentifiers)
95
+ errorsFound.push('not have targetIdentifiers');
96
+
97
+ requestParams.submittedByUserId = submittedByUserId;
98
+ if (targetIdentifiers) {
99
+ if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
100
+ targetIdentifiers.submittedByUserId = submittedByUserId;
101
+ }
102
+ requestParams.targetIdentifiers = targetIdentifiers;
103
+ }
104
+
105
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
106
+ submittedByUserId: requestParams.submittedByUserId,
107
+ targetIdentifiers: requestParams.targetIdentifiers,
108
+ belongTo: objectSchema.belongTo,
109
+ generatedBy: objectSchema.generatedBy
110
+ });
87
111
  }
88
112
 
89
113
  //(<beforeQuery>)
@@ -315,6 +339,7 @@ export default async function <%- flowTag %>(
315
339
  errorsFound
316
340
  );
317
341
  } catch (err) {
342
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>] error:`, err);
318
343
  throw err;
319
344
  }
320
345
  }
@@ -62,7 +62,7 @@ export async function <%- flowTag %>LogicalLib(
62
62
  phaseResults = {}
63
63
  ) {
64
64
  try {
65
- _izContext.logger.debug('[<%- flowTag %>LogicalLib] started', {
65
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] started`, {
66
66
  requestParams,
67
67
  callingFlowConfig,
68
68
  phaseResults
@@ -78,14 +78,14 @@ export async function <%- flowTag %>LogicalLib(
78
78
  _izContext,
79
79
  objType
80
80
  );
81
- _izContext.logger.debug('objectSchema', objectSchema);
81
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] objectSchema:`, objectSchema);
82
82
 
83
83
  // ── Build deleteDataDetails ───────────────────────────────────────────────
84
84
  const deleteDataDetails = await createDeleteDataDetail(
85
85
  _izContext,
86
86
  objectSchema
87
87
  );
88
- _izContext.logger.debug('deleteDataDetails', deleteDataDetails);
88
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] deleteDataDetails:`, deleteDataDetails);
89
89
 
90
90
  if (objectSchema.canDelete === false || objectSchema.canDelete == null) {
91
91
  errorsFound.push("this objectSchema can't delete");
@@ -119,6 +119,7 @@ export async function <%- flowTag %>LogicalLib(
119
119
  return {
120
120
  objType,
121
121
  identifiers: requestParams.identifiers,
122
+ targetIdentifiers: requestParams.targetIdentifiers,
122
123
  status: 'error',
123
124
  errorsFound
124
125
  };
@@ -201,10 +202,12 @@ export async function <%- flowTag %>LogicalLib(
201
202
  return {
202
203
  objType,
203
204
  identifiers: requestParams.identifiers,
205
+ targetIdentifiers: requestParams.targetIdentifiers,
204
206
  status: 'complete',
205
207
  errorsFound
206
208
  };
207
209
  } catch (err) {
210
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] error:`, err);
208
211
  throw err;
209
212
  }
210
213
  }
@@ -49,7 +49,7 @@ export default async function <%- flowTag %>RbacCallbackMain(
49
49
  callingFlowConfig = {}
50
50
  ) {
51
51
  try {
52
- _izContext.logger.debug('[<%- flowTag %>RbacCallbackMain] Started with params:', {
52
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>RbacCallback] Started with params:`, {
53
53
  requestParams,
54
54
  flowTag,
55
55
  callingFlowConfig
@@ -209,7 +209,7 @@ export default async function <%- flowTag %>RbacCallbackMain(
209
209
 
210
210
  return logicalResult;
211
211
  } catch (err) {
212
- _izContext.logger.error('[<%- flowTag %>RbacCallbackMain] Error caught:', {
212
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>RbacCallback] Error caught:`, {
213
213
  error: err
214
214
  });
215
215
  throw err;
@@ -100,6 +100,13 @@ export const main = middleware.wrap(async (event, context) => {
100
100
  );
101
101
  }
102
102
 
103
+ if (!eventParams.submittedByUserId) {
104
+ const contextUserId = event._izContext.correlationIds?.get(consts.SUBMITTED_BY_USER_ID);
105
+ if (contextUserId) {
106
+ eventParams.submittedByUserId = contextUserId;
107
+ }
108
+ }
109
+
103
110
  let callingFlow = eventParams?.callingFlow
104
111
  ? eventParams.callingFlow
105
112
  : {};
@@ -120,7 +120,7 @@ export default async function <%- typeof functionName !== 'undefined' ? function
120
120
  _izContext.logger.debug('sendMessageToEndpoint', sendMessageToEndpoint);
121
121
  await sns.publishAsync(_izContext, sendMessageToEndpoint);
122
122
  } catch (err) {
123
- _izContext.logger.error('error WebSocketInvoke: ', err);
123
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- typeof functionName !== undefined ? functionName : upperCaseFlowTag %>Wbs] error:`, err);
124
124
  throw err;
125
125
  }
126
126
  }
@@ -68,6 +68,19 @@ export default async function <%- flowTag %>(
68
68
  callingFlowConfig
69
69
  });
70
70
 
71
+ // ── Resolve submittedByUserId / targetIdentifiers ─────────────────────────
72
+ const submittedByUserId =
73
+ requestParams.submittedByUserId ||
74
+ _izContext.correlationIds?.get(coreConsts.SUBMITTED_BY_USER_ID);
75
+ if (submittedByUserId) {
76
+ requestParams.submittedByUserId = submittedByUserId;
77
+ }
78
+
79
+ const targetIdentifiers = requestParams.targetIdentifiers;
80
+ if (targetIdentifiers) {
81
+ requestParams.targetIdentifiers = targetIdentifiers;
82
+ }
83
+
71
84
  // ── Settings ──────────────────────────────────────────────────────────────
72
85
  const settings = requestParams.additionalParams?.settings ?? {};
73
86
  const returnSystemFieldsName = settings.returnSystemFieldsName === true;
@@ -52,7 +52,7 @@ export default async function UpdateComplete(
52
52
  //(</additionalParams>)
53
53
  ) {
54
54
  try {
55
- _izContext.logger.debug('[UpdateComplete] started', {
55
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:UpdateComplete] started`, {
56
56
  requestParams
57
57
  });
58
58
  const {
@@ -78,9 +78,58 @@ export default async function <%- flowTag %>(
78
78
  callingFlowConfig
79
79
  });
80
80
 
81
+ const errorsFound = [];
82
+ const objType = createObjType(requestParams.objectType);
83
+
84
+ // ── Load schema ───────────────────────────────────────────────────────────
85
+ const objectSchema = await getObjectSchema.getObjSchemaS3WithHierarchy(
86
+ _izContext,
87
+ objType
88
+ );
89
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] objectSchema:`, objectSchema);
90
+
91
+ // ── Resolve submittedByUserId / targetIdentifiers ─────────────────────────
92
+ let submittedByUserId, targetIdentifiers;
93
+ if (
94
+ objectSchema.generatedBy === 'user' ||
95
+ objectSchema.generatedBy === 'systemWithUser'
96
+ ) {
97
+ submittedByUserId =
98
+ requestParams.submittedByUserId ||
99
+ _izContext.correlationIds?.get(coreConsts.SUBMITTED_BY_USER_ID);
100
+
101
+ targetIdentifiers = requestParams.targetIdentifiers;
102
+
103
+ if (!targetIdentifiers && objectSchema.belongTo?.objectType === 'user' && submittedByUserId) {
104
+ targetIdentifiers = { submittedByUserId };
105
+ }
106
+
107
+ if (!submittedByUserId) errorsFound.push('Not have submittedByUserId');
108
+ if (objectSchema.hasOwnProperty('belongTo') && !targetIdentifiers)
109
+ errorsFound.push('not have targetIdentifiers');
110
+
111
+ requestParams.submittedByUserId = submittedByUserId;
112
+ if (targetIdentifiers) {
113
+ if (!targetIdentifiers.submittedByUserId && submittedByUserId) {
114
+ targetIdentifiers.submittedByUserId = submittedByUserId;
115
+ }
116
+ requestParams.targetIdentifiers = targetIdentifiers;
117
+ }
118
+
119
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>] Identity & Target Context Resolved:`, {
120
+ submittedByUserId: requestParams.submittedByUserId,
121
+ targetIdentifiers: requestParams.targetIdentifiers,
122
+ belongTo: objectSchema.belongTo,
123
+ generatedBy: objectSchema.generatedBy
124
+ });
125
+ } else if (objectSchema.generatedBy === 'searchResultGenerated') {
126
+ throw new NoRetryError(
127
+ 'error searchResultGenerated should not happen here'
128
+ );
129
+ }
130
+
81
131
  // ── Build identifiers used by asynchronous processing ────────────────────
82
132
  const identifiers = requestParams.objInstanceFull.identifiers;
83
- const errorsFound = [];
84
133
 
85
134
  //(<validateBeforeUpdate>)
86
135
  //(</validateBeforeUpdate>)
@@ -142,7 +191,7 @@ export default async function <%- flowTag %>(
142
191
  );
143
192
 
144
193
  _izContext.logger.debug(
145
- '[lib:auth:checkRbacPermission] resultPermissionCheck:',
194
+ `[${process.env.iz_serviceTag}:<%- flowTag %>] checkRbacPermission result:`,
146
195
  resultPermissionCheck
147
196
  );
148
197
 
@@ -308,7 +357,7 @@ export default async function <%- flowTag %>(
308
357
  errorsFound
309
358
  );
310
359
  } catch (err) {
311
- _izContext.logger.error('[<%- flowTag %>] error:', err);
360
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>] error:`, err);
312
361
  throw err;
313
362
  }
314
363
  }
@@ -72,7 +72,7 @@ export async function <%- flowTag %>LogicalLib(
72
72
  phaseResults = {}
73
73
  ) {
74
74
  try {
75
- _izContext.logger.debug('[<%- flowTag %>LogicalLib] started', {
75
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] started`, {
76
76
  requestParams,
77
77
  callingFlowConfig,
78
78
  phaseResults
@@ -96,7 +96,7 @@ export async function <%- flowTag %>LogicalLib(
96
96
  _izContext,
97
97
  objType
98
98
  );
99
- _izContext.logger.debug('objectSchema', objectSchema);
99
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] objectSchema:`, objectSchema);
100
100
 
101
101
  const objectSchemas =
102
102
  await uploadUseCase.generateObjectSchemaForCombineFieldNames(
@@ -110,7 +110,7 @@ export async function <%- flowTag %>LogicalLib(
110
110
  _izContext,
111
111
  objectSchemas
112
112
  );
113
- _izContext.logger.debug('updateDataDetails', updateDataDetails);
113
+ _izContext.logger.debug(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] updateDataDetails:`, updateDataDetails);
114
114
 
115
115
  const originTimestamp = Date.now();
116
116
 
@@ -468,6 +468,7 @@ export async function <%- flowTag %>LogicalLib(
468
468
  errorsFound
469
469
  };
470
470
  } catch (err) {
471
+ _izContext.logger.error(`[${process.env.iz_serviceTag}:<%- flowTag %>LogicalLib] error:`, err);
471
472
  _izContext.logger.error('[<%- flowTag %>LogicalLib] error:', err);
472
473
  throw err;
473
474
  }
@@ -49,6 +49,7 @@ export function flowExtTopicSteps(flows) {
49
49
  typeof step?.stepName !== 'string' ||
50
50
  step.stepName === '' ||
51
51
  step.stepName.toLowerCase() === 'start' ||
52
+ step.stepName.toLowerCase() === 'rbaccallback' ||
52
53
  !Array.isArray(step.event) ||
53
54
  !step.event.includes('extTopic')
54
55
  ) {
@@ -242,3 +243,49 @@ export function customFlowNextSteps(flows) {
242
243
  }
243
244
  return results;
244
245
  }
246
+
247
+ export function flowHasRbac(flow, objects = []) {
248
+ if (!flow || !flow.objType || typeof flow.objType !== "object") return false;
249
+ const candidates = objects.filter(
250
+ (o) => o.objectType === flow.objType.objectType
251
+ );
252
+ const object = flow.objType.serviceTag
253
+ ? (candidates.find((o) => o.serviceTag === flow.objType.serviceTag) ??
254
+ candidates.find((o) => o.serviceTag === undefined) ??
255
+ candidates[0])
256
+ : candidates[0];
257
+ if (!object) return false;
258
+ return hasRbacObject(object, objects);
259
+ }
260
+
261
+ function hasRbacObject(object, objects = []) {
262
+ return (
263
+ hasSelfRbac(object) ||
264
+ (Array.isArray(object?.belongToSchema?.addOnDataStructure) &&
265
+ object.belongToSchema.addOnDataStructure.some(
266
+ (addOn) => addOn?.type === "rbac"
267
+ )) ||
268
+ normalizeBelongTo(object).some((target) => {
269
+ if (target?.serviceTag === "UserAccount") return true;
270
+ const matched = objects.find(
271
+ (candidate) =>
272
+ candidate?.serviceTag === target?.serviceTag &&
273
+ candidate?.objectType === target?.objectType
274
+ );
275
+ return hasSelfRbac(matched);
276
+ })
277
+ );
278
+ }
279
+
280
+ function hasSelfRbac(object) {
281
+ return (
282
+ Array.isArray(object?.addOnDataStructure) &&
283
+ object.addOnDataStructure.some((addOn) => addOn?.type === "rbac")
284
+ );
285
+ }
286
+
287
+ function normalizeBelongTo(object) {
288
+ const belongTo = object?.belongTo;
289
+ if (!belongTo) return [];
290
+ return Array.isArray(belongTo) ? belongTo : [belongTo];
291
+ }
@@ -16,7 +16,8 @@ import {
16
16
  generatedDsqFlows,
17
17
  generatedOwnTopicFlows,
18
18
  supportedCustomFlows,
19
- upperFirst
19
+ upperFirst,
20
+ flowHasRbac
20
21
  } from './customFlows.js';
21
22
 
22
23
  const YAML_PATH = 'app/sls_yaml/generatedCode/source/flow-schema.yml';
@@ -67,10 +68,10 @@ export async function emitCustomFlowApplicationArtifacts(
67
68
  ];
68
69
  }
69
70
 
70
- export function customFlowApplicationManagedPaths(flows) {
71
+ export function customFlowApplicationManagedPaths(flows, { objects = [] } = {}) {
71
72
  return [
72
- ...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow)),
73
- ...generatedOwnTopicFlows(flows).flatMap(ownTopicRootPaths),
73
+ ...supportedCustomFlows(flows).flatMap((flow) => flowPaths(flow, objects)),
74
+ ...generatedOwnTopicFlows(flows).flatMap((flow) => ownTopicRootPaths(flow, objects)),
74
75
  ...flowExtTopicSteps(flows).flatMap(({ flowTag, stepName }) => {
75
76
  const source = `app/src/generatedCode/FlowSchemas/${flowTag}/source`;
76
77
  return [
@@ -122,6 +123,45 @@ async function emitFlow(flow, objects) {
122
123
  : [];
123
124
  const functions = [];
124
125
 
126
+ const isRbac = flowHasRbac(flow, objects);
127
+ if (isRbac && !flow.event.includes('ownTopic')) {
128
+ const rbacStep = (flow.flowSteps || []).find(
129
+ (s) => typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'rbaccallback'
130
+ );
131
+ const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
132
+ artifacts.push(
133
+ {
134
+ path: `${source}/${tag}RbacCallback_Main.js`,
135
+ content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
136
+ flowTag: flow.flowTag,
137
+ upperCaseFlowTag: tag,
138
+ functionName: `${tag}RbacCallbackMain`
139
+ })
140
+ },
141
+ {
142
+ path: `${source}/${tag}RbacCallback_HdrSqs.js`,
143
+ content: await renderShared('FlowHandler_HdrSqs.ejs', {
144
+ flowTag: flow.flowTag,
145
+ flowStepName: 'RbacCallback',
146
+ mainFileName: `${tag}RbacCallback_Main`,
147
+ functionName: `${tag}RbacCallbackMain`,
148
+ queueName: `${tag}RbacCallbackHdrSqs`,
149
+ startConfig: rbacConfig
150
+ })
151
+ }
152
+ );
153
+ functions.push(
154
+ renderSqsFunctionYaml({
155
+ functionName: `${tag}RbacCallbackHdrSqs`,
156
+ handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
157
+ roleName: customFlowRoleName(flow.flowTag),
158
+ queueName: `${tag}RbacCallbackHdrSqs`,
159
+ flowTag: flow.flowTag,
160
+ flowStepName: 'RbacCallback'
161
+ })
162
+ );
163
+ }
164
+
125
165
  if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
126
166
  artifacts.push({
127
167
  path: `${source}/${process}_HdrSqs.js`,
@@ -219,7 +259,7 @@ async function emitFlow(flow, objects) {
219
259
  return { artifacts, functions };
220
260
  }
221
261
 
222
- function flowPaths(flow) {
262
+ function flowPaths(flow, objects = []) {
223
263
  const tag = upperFirst(flow.flowTag);
224
264
  const process = tag;
225
265
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
@@ -227,6 +267,12 @@ function flowPaths(flow) {
227
267
  if (needsProcessMain(flow)) {
228
268
  paths.push(`${source}/${process}_Main.js`);
229
269
  }
270
+ if (flowHasRbac(flow, objects)) {
271
+ paths.push(
272
+ `${source}/${tag}RbacCallback_Main.js`,
273
+ `${source}/${tag}RbacCallback_HdrSqs.js`
274
+ );
275
+ }
230
276
  if (flow.event.includes('extTopic') && !flow.event.includes('ownTopic')) {
231
277
  paths.push(`${source}/${process}_HdrSqs.js`);
232
278
  }
@@ -418,68 +464,118 @@ async function emitOwnTopicRoot(flow, objects) {
418
464
  upperCaseFlowTag: tag,
419
465
  startConfig: _startConfig(flow)
420
466
  };
421
- return {
422
- artifacts: [
423
- {
424
- path: `${source}/${mainFileName}.js`,
425
- content: await renderEndpointMain(flow, mainFileName, objects)
426
- },
427
- {
428
- path: `${source}/${tag}_HdrSqs.js`,
429
- content: await renderShared('FlowHandler_HdrSqs.ejs', {
430
- ...shared,
431
- functionName: mainFileName,
432
- mainFileName,
433
- queueName: `${tag}HdrSqs`
434
- })
435
- },
467
+ const isRbac = flowHasRbac(flow, objects);
468
+ const ownArtifacts = [
469
+ {
470
+ path: `${source}/${mainFileName}.js`,
471
+ content: await renderEndpointMain(flow, mainFileName, objects)
472
+ },
473
+ {
474
+ path: `${source}/${tag}_HdrSqs.js`,
475
+ content: await renderShared('FlowHandler_HdrSqs.ejs', {
476
+ ...shared,
477
+ functionName: mainFileName,
478
+ mainFileName,
479
+ queueName: `${tag}HdrSqs`
480
+ })
481
+ },
482
+ {
483
+ path: `${source}/${wbsMainFileName}.js`,
484
+ content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
485
+ ...shared,
486
+ functionName: wbsMainFileName
487
+ })
488
+ },
489
+ {
490
+ path: `${source}/${tag}_HdrWbs.js`,
491
+ content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
492
+ ...shared,
493
+ functionName: tag,
494
+ mainFileName: wbsMainFileName,
495
+ route: tag
496
+ })
497
+ }
498
+ ];
499
+
500
+ const ownFunctions = [
501
+ renderWbsFunctionYaml({
502
+ functionName: `${tag}HdrWbs`,
503
+ handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
504
+ roleName: customFlowRoleName(flow.flowTag),
505
+ routeName: tag,
506
+ flowTag: flow.flowTag,
507
+ flowStepName: ''
508
+ }),
509
+ renderSqsFunctionYaml({
510
+ functionName: `${tag}HdrSqs`,
511
+ handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
512
+ roleName: customFlowRoleName(flow.flowTag),
513
+ queueName: `${tag}HdrSqs`,
514
+ flowTag: flow.flowTag,
515
+ flowStepName: ''
516
+ })
517
+ ];
518
+
519
+ if (isRbac) {
520
+ const rbacStep = (flow.flowSteps || []).find(
521
+ (s) => typeof s?.stepName === 'string' && s.stepName.toLowerCase() === 'rbaccallback'
522
+ );
523
+ const rbacConfig = rbacStep ? stepConfig(flow, rbacStep) : null;
524
+ ownArtifacts.push(
436
525
  {
437
- path: `${source}/${wbsMainFileName}.js`,
438
- content: await renderCrudTemplate('FlowMain_Wbs.ejs', {
439
- ...shared,
440
- functionName: wbsMainFileName
526
+ path: `${source}/${tag}RbacCallback_Main.js`,
527
+ content: await renderCustom('FlowEndpointRbacCallback_Main.ejs', {
528
+ flowTag: flow.flowTag,
529
+ upperCaseFlowTag: tag,
530
+ functionName: `${tag}RbacCallbackMain`
441
531
  })
442
532
  },
443
533
  {
444
- path: `${source}/${tag}_HdrWbs.js`,
445
- content: await renderCrudTemplate('FlowEndpoint_HdrWbs.ejs', {
446
- ...shared,
447
- functionName: tag,
448
- mainFileName: wbsMainFileName,
449
- route: tag
534
+ path: `${source}/${tag}RbacCallback_HdrSqs.js`,
535
+ content: await renderShared('FlowHandler_HdrSqs.ejs', {
536
+ flowTag: flow.flowTag,
537
+ flowStepName: 'RbacCallback',
538
+ mainFileName: `${tag}RbacCallback_Main`,
539
+ functionName: `${tag}RbacCallbackMain`,
540
+ queueName: `${tag}RbacCallbackHdrSqs`,
541
+ startConfig: rbacConfig
450
542
  })
451
543
  }
452
- ],
453
- functions: [
454
- renderWbsFunctionYaml({
455
- functionName: `${tag}HdrWbs`,
456
- handlerPath: `${handlerRoot}/${tag}_HdrWbs.main`,
457
- roleName: customFlowRoleName(flow.flowTag),
458
- routeName: tag,
459
- flowTag: flow.flowTag,
460
- flowStepName: ''
461
- }),
544
+ );
545
+ ownFunctions.push(
462
546
  renderSqsFunctionYaml({
463
- functionName: `${tag}HdrSqs`,
464
- handlerPath: `${handlerRoot}/${tag}_HdrSqs.main`,
547
+ functionName: `${tag}RbacCallbackHdrSqs`,
548
+ handlerPath: `${handlerRoot}/${tag}RbacCallback_HdrSqs.main`,
465
549
  roleName: customFlowRoleName(flow.flowTag),
466
- queueName: `${tag}HdrSqs`,
550
+ queueName: `${tag}RbacCallbackHdrSqs`,
467
551
  flowTag: flow.flowTag,
468
- flowStepName: ''
552
+ flowStepName: 'RbacCallback'
469
553
  })
470
- ]
554
+ );
555
+ }
556
+
557
+ return {
558
+ artifacts: ownArtifacts,
559
+ functions: ownFunctions
471
560
  };
472
561
  }
473
562
 
474
- function ownTopicRootPaths(flow) {
563
+ function ownTopicRootPaths(flow, objects = []) {
475
564
  const tag = upperFirst(flow.flowTag);
476
565
  const source = `app/src/generatedCode/FlowSchemas/${tag}/source`;
477
- return [
566
+ const paths = [
478
567
  `${source}/${tag}_Main.js`,
479
568
  `${source}/${tag}_HdrSqs.js`,
480
569
  `${source}/${tag}_WbsMain.js`,
481
570
  `${source}/${tag}_HdrWbs.js`
482
571
  ];
572
+ if (flowHasRbac(flow, objects)) {
573
+ paths.push(
574
+ `${source}/${tag}RbacCallback_Main.js`,
575
+ `${source}/${tag}RbacCallback_HdrSqs.js`
576
+ );
577
+ }
578
+ return paths;
483
579
  }
484
580
 
485
581
  function needsProcessMain(flow) {
@@ -694,12 +790,35 @@ function isS3Only(flow) {
694
790
  return flow.event.length === 1 && flow.event[0] === 's3';
695
791
  }
696
792
 
697
- async function renderEndpointMain(flow, functionName, objects) {
793
+ async function renderEndpointMain(flow, functionName, objects = []) {
794
+ const isRbac = flowHasRbac(flow, objects);
795
+ const matchedObject = objects.find(
796
+ (o) => o.objectType === flow.objType?.objectType
797
+ );
798
+ let rbacServiceTag = null;
799
+ if (matchedObject) {
800
+ const belongTo = matchedObject.belongTo;
801
+ if (belongTo) {
802
+ rbacServiceTag = Array.isArray(belongTo)
803
+ ? belongTo[0]?.serviceTag
804
+ : belongTo?.serviceTag;
805
+ }
806
+ }
807
+ if (!rbacServiceTag) {
808
+ rbacServiceTag = flow.objType?.serviceTag || flow.serviceTag || 'Rbac';
809
+ }
810
+
811
+ const enrichedFlow = {
812
+ ...flow,
813
+ isRbac
814
+ };
815
+
698
816
  return renderCustom('FlowEndpoint_Main.ejs', {
699
- flow,
817
+ flow: enrichedFlow,
700
818
  flowTag: flow.flowTag,
701
819
  upperCaseFlowTag: upperFirst(flow.flowTag),
702
820
  functionName,
821
+ rbacServiceTag,
703
822
  tableName: storedCacheTableName(flow, objects),
704
823
  startConfig: _startConfig(flow)
705
824
  });
@@ -32,7 +32,7 @@ export async function generateCustomFlowApplicationArtifacts(
32
32
  managedPaths: [
33
33
  ...systemWebSocketManagedPaths(),
34
34
  ...customFlowApplicationManagedPaths(flows, {
35
- includeYaml: hasSystemWebSocket(flows)
35
+ includeYaml: hasSystemWebSocket(flows), objects
36
36
  })
37
37
  ],
38
38
  managedScope: 'custom-flow-application'