@aifabrix/builder 2.52.1 → 2.53.1

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 (225) hide show
  1. package/lib/app/deploy-config.js +3 -2
  2. package/lib/channels/add-channel.js +11 -41
  3. package/lib/channels/approval-guides/index.js +3 -0
  4. package/lib/channels/approval-guides/microsoft-copilot.js +26 -17
  5. package/lib/channels/channel-add-existing.js +72 -0
  6. package/lib/channels/channel-runtime-resolver.js +5 -1
  7. package/lib/channels/channel-status-display.js +30 -3
  8. package/lib/channels/microsoft-copilot-entra-sso-form.js +73 -2
  9. package/lib/channels/microsoft-copilot-entra-sso.js +26 -5
  10. package/lib/channels/microsoft-copilot-limits.js +22 -3
  11. package/lib/channels/microsoft-copilot-package.js +59 -14
  12. package/lib/channels/microsoft-copilot-validate.js +40 -10
  13. package/lib/cli/attach-default-help-examples.js +102 -0
  14. package/lib/cli/index.js +2 -0
  15. package/lib/cli/setup-credential-deployment.js +7 -5
  16. package/lib/cli/setup-utility-validate.js +1 -0
  17. package/lib/commands/credential-push.js +37 -5
  18. package/lib/commands/package-score.js +72 -0
  19. package/lib/commands/role-assistant.js +46 -8
  20. package/lib/deployment/deployer-poll-run.js +2 -2
  21. package/lib/deployment/deployer.js +1 -1
  22. package/lib/deployment/environment.js +2 -2
  23. package/lib/external-system/deploy.js +11 -21
  24. package/lib/integration-definition/apply.js +12 -14
  25. package/lib/integration-definition/enrich-openapi-operations.js +9 -10
  26. package/lib/lab/package-parity-score.js +417 -0
  27. package/lib/programmatic/capability-registry.js +1 -0
  28. package/lib/programmatic/help-content/channel-onboarding.md +35 -0
  29. package/lib/programmatic/help-content/cip-overview.md +27 -0
  30. package/lib/programmatic/help-content/connected-system-ui.md +70 -0
  31. package/lib/programmatic/help-content/dimensions-guide.md +23 -0
  32. package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
  33. package/lib/programmatic/help-content/overview.md +25 -0
  34. package/lib/programmatic/help-content/subscription-guide.md +27 -0
  35. package/lib/programmatic/help-content/workflow.md +50 -0
  36. package/lib/programmatic/openapi-component-schemas.js +1 -0
  37. package/lib/programmatic/openapi-descriptions.js +6 -0
  38. package/lib/programmatic/openapi-envelope-examples.js +11 -0
  39. package/lib/programmatic/openapi-operation-bindings.js +5 -0
  40. package/lib/programmatic/openapi-request-schemas.js +39 -13
  41. package/lib/programmatic/openapi-result-schemas.js +30 -0
  42. package/lib/programmatic/openapi-schema-descriptions-core.js +18 -0
  43. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  44. package/lib/programmatic/persist-supplied-openapi.js +180 -0
  45. package/lib/programmatic/route-handler-map.js +6 -0
  46. package/lib/programmatic/run-integration-definition.js +13 -5
  47. package/lib/role-assistant/evidence-sync.js +55 -7
  48. package/lib/role-assistant/test-runner-attachments.js +118 -0
  49. package/lib/role-assistant/test-runner-bid-apply.js +100 -21
  50. package/lib/role-assistant/test-runner-bid-document.js +1 -1
  51. package/lib/role-assistant/test-runner-start-payload.js +96 -0
  52. package/lib/role-assistant/test-runner-workhub-answers.js +11 -7
  53. package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
  54. package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
  55. package/lib/role-assistant/test-runner-workhub.js +68 -105
  56. package/lib/role-assistant/test-runner.js +5 -63
  57. package/lib/role-assistant/test-suite.js +33 -40
  58. package/lib/schema/external-datasource.schema.json +13 -4
  59. package/lib/utils/compose-generator.js +10 -1
  60. package/lib/utils/compose-traefik-extra-routes.js +107 -0
  61. package/lib/utils/docker-build.js +2 -2
  62. package/lib/utils/help-builder.js +2 -1
  63. package/lib/utils/promote-dev-docker-image.js +15 -10
  64. package/package.json +14 -16
  65. package/templates/README.md +12 -1
  66. package/templates/applications/dataplane/application.yaml +8 -1
  67. package/templates/applications/dataplane/env.template +1 -1
  68. package/templates/applications/miso-controller/application.yaml +2 -1
  69. package/templates/applications/miso-controller/rbac.yaml +1 -0
  70. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +6 -2
  71. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +8 -5
  72. package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
  73. package/templates/channels/microsoft-copilot/install.template.md.hbs +74 -22
  74. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +29 -14
  75. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +6 -2
  76. package/templates/python/docker-compose.hbs +36 -0
  77. package/templates/typescript/docker-compose.hbs +36 -0
  78. package/.cursor/plans/Archive/157.1-security-quality-violations-by-type.csv +0 -374
  79. package/.cursor/process/README.md +0 -9
  80. package/.cursor/rules/anchor-docs.mdc +0 -15
  81. package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
  82. package/.cursor/rules/cli-layout.mdc +0 -81
  83. package/.cursor/rules/cli-product-neutral.mdc +0 -43
  84. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
  85. package/.cursor/rules/docs-rules.mdc +0 -32
  86. package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
  87. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
  88. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
  89. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
  90. package/.cursor/rules/project-rules.mdc +0 -913
  91. package/.cursor/skills/README.md +0 -15
  92. package/.dockerignore +0 -52
  93. package/.eslintignore +0 -22
  94. package/.markdownlint.json +0 -14
  95. package/anchor-docs/README.md +0 -10
  96. package/anchor-docs/_TEMPLATE +0 -24
  97. package/babel.config.js +0 -6
  98. package/bin/builder-api-cleanup.js +0 -26
  99. package/bin/builder-api-nest.js +0 -10
  100. package/bin/builder-api-spike.js +0 -19
  101. package/enterprise-knowledge/README.md +0 -50
  102. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
  103. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
  104. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
  105. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
  106. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
  107. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
  108. package/integration/README.md +0 -81
  109. package/integration/github/README.md +0 -53
  110. package/integration/github/application.json +0 -21
  111. package/integration/github/deploy.js +0 -72
  112. package/integration/github/env.template +0 -11
  113. package/integration/github/github-datasource-issue-comments.json +0 -239
  114. package/integration/github/github-datasource-issues.json +0 -399
  115. package/integration/github/github-datasource-repository.json +0 -354
  116. package/integration/github/github-deploy.json +0 -1202
  117. package/integration/github/github-system.json +0 -82
  118. package/integration/hubspot-test/README.md +0 -159
  119. package/integration/hubspot-test/application.json +0 -54
  120. package/integration/hubspot-test/companies.json +0 -2048
  121. package/integration/hubspot-test/create-hubspot.js +0 -523
  122. package/integration/hubspot-test/env.template +0 -4
  123. package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
  124. package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
  125. package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
  126. package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
  127. package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
  128. package/integration/hubspot-test/hubspot-test-system.json +0 -74
  129. package/integration/hubspot-test/rbac.json +0 -166
  130. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
  131. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
  132. package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
  133. package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
  134. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
  135. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
  136. package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
  137. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
  138. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  139. package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
  140. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
  141. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
  142. package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
  143. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
  144. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  145. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  146. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
  147. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
  148. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
  149. package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
  150. package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
  151. package/integration/hubspot-test/test-dataplane-down.js +0 -209
  152. package/integration/hubspot-test/test.js +0 -1588
  153. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
  154. package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
  155. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
  156. package/integration/roundtrip-test-local/README.md +0 -143
  157. package/integration/roundtrip-test-local/application.yaml +0 -13
  158. package/integration/roundtrip-test-local/env.template +0 -15
  159. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
  160. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
  161. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
  162. package/integration/roundtrip-test-local2/README.md +0 -143
  163. package/integration/roundtrip-test-local2/application.yaml +0 -13
  164. package/integration/roundtrip-test-local2/env.template +0 -15
  165. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
  166. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
  167. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
  168. package/integration/test/wizard.yaml +0 -8
  169. package/jest.config.coverage.js +0 -37
  170. package/jest.config.default.js +0 -11
  171. package/jest.config.integration.fixtures.js +0 -22
  172. package/jest.config.integration.js +0 -33
  173. package/jest.config.isolated.js +0 -11
  174. package/jest.config.manual.js +0 -30
  175. package/jest.global-live-fabrix-hooks.js +0 -36
  176. package/jest.isolated-projects.js +0 -283
  177. package/jest.projects.js +0 -79
  178. package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +0 -205
  179. package/packages/builder-api/README.md +0 -120
  180. package/packages/builder-api/package.json +0 -30
  181. package/packages/builder-api/src/app.module.ts +0 -7
  182. package/packages/builder-api/src/auth/auth.module.ts +0 -5
  183. package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
  184. package/packages/builder-api/src/main.ts +0 -16
  185. package/packages/builder-api/tsconfig.json +0 -15
  186. package/scripts/check-builder-api-architecture-grep.js +0 -79
  187. package/scripts/check-datasource-test-run-schema-sync.js +0 -34
  188. package/scripts/ci-fix.sh +0 -19
  189. package/scripts/ci-simulate.sh +0 -19
  190. package/scripts/diagnose-cli.js +0 -150
  191. package/scripts/docker_image_content_gate.js +0 -47
  192. package/scripts/docker_image_content_gate.sh +0 -5
  193. package/scripts/export-builder-api-evidence.js +0 -262
  194. package/scripts/install-local.js +0 -490
  195. package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
  196. package/scripts/lib/builder-api-docker-staging-core.js +0 -183
  197. package/scripts/lib/docker-image-content-gate-core.js +0 -166
  198. package/scripts/lib/plan-actor.js +0 -109
  199. package/scripts/lib/plan-config.js +0 -20
  200. package/scripts/lib/plan-gates.js +0 -154
  201. package/scripts/lib/plan-meta.js +0 -104
  202. package/scripts/lib/plan-parse.js +0 -162
  203. package/scripts/lib/plan-prevalidate-gates.js +0 -337
  204. package/scripts/lib/plan-run-core.js +0 -125
  205. package/scripts/lib/plan-run-report.js +0 -119
  206. package/scripts/plan-approve.js +0 -24
  207. package/scripts/plan-archive.js +0 -49
  208. package/scripts/plan-run.js +0 -13
  209. package/scripts/plan-set-actor.js +0 -21
  210. package/scripts/plan-validate.js +0 -80
  211. package/scripts/pnpm/af.mjs +0 -125
  212. package/scripts/pnpm/check-quiet.mjs +0 -32
  213. package/scripts/pnpm/dev-install.mjs +0 -29
  214. package/scripts/pnpm/dev-reload.mjs +0 -18
  215. package/scripts/pnpm/help.mjs +0 -55
  216. package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
  217. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
  218. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
  219. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
  220. package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
  221. package/scripts/pnpm/lib/spinner.mjs +0 -42
  222. package/scripts/pnpm-global-remove.js +0 -48
  223. package/scripts/stage_builder_api_for_docker.js +0 -65
  224. package/scripts/sync-builder-api-template.js +0 -44
  225. package/scripts/test-dataplane-bootstrap.js +0 -331
@@ -1,913 +0,0 @@
1
- ---
2
- alwaysApply: true
3
- ---
4
- # AI Fabrix Builder - Cursor Rules - ISO 27001 Compliant Development Standards
5
-
6
- ## Project Overview
7
-
8
- This is the AI Fabrix Builder - a CLI tool for local development infrastructure and Azure deployment. The builder provides:
9
- - **Local Infrastructure** - Postgres + Redis via Docker Compose
10
- - **Application Scaffolding** - Generate configuration files for apps
11
- - **Docker Generation** - Auto-detect runtime and generate Dockerfiles
12
- - **Template System** - Handlebars-based templates for TypeScript and Python
13
- - **Azure Deployment** - Push to ACR and deploy via Miso Controller
14
- - **Configuration Management** - YAML-based config with schema validation
15
-
16
- Technologies:
17
- - Node.js/JavaScript (CommonJS modules)
18
- - Commander.js for CLI
19
- - Handlebars for template generation
20
- - js-yaml for YAML parsing
21
- - AJV for JSON schema validation
22
- - Jest for testing
23
- - Docker for containerization
24
-
25
- ## CLI layout and output
26
-
27
- When adding or changing CLI commands, subcommands, flags, help text, or terminal output (`lib/cli.js`, `lib/cli/**`, `lib/commands/**`, shared `lib/utils/cli-*layout*.js`), you must follow the CLI layout rule and its referenced source-of-truth docs:
28
-
29
- - **Rule**: `.cursor/rules/cli-layout.mdc`
30
- - **Visual/layout spec**: `.cursor/rules/layout.md`
31
- - **Per-command output profiles**: `.cursor/rules/cli-output-command-matrix.md` (update for every new leaf command; see matrix **Layout compliance** for `cli-test-layout-chalk` adoption status)
32
-
33
- ## Architecture Patterns
34
-
35
- > **Visual Documentation**: When documenting architecture, workflows, or command flows, use the canonical Mermaid diagram templates from [flows-and-visuals.md](flows-and-visuals.md). These templates ensure consistent styling and accurate representation of Builder architecture.
36
-
37
- ### Module Structure
38
- - All modules use CommonJS (`require`/`module.exports`)
39
- - Main entry point: `bin/aifabrix.js`
40
- - Core logic in `lib/` directory
41
- - Commands in `lib/cli.js` and `lib/commands/`
42
- - Utilities in `lib/utils/`
43
- - Schemas in `lib/schema/`
44
- - Templates in `templates/` directory
45
-
46
- ### File Organization
47
- ```yaml
48
- lib/
49
- ├── cli.js # CLI command definitions (Commander.js)
50
- ├── commands/ # Command implementations
51
- ├── app.js # App creation and management
52
- ├── generator.js # Deployment JSON generation
53
- ├── validator.js # Schema validation
54
- ├── build.js # Docker build logic
55
- ├── infra.js # Infrastructure management
56
- ├── deployer.js # Azure deployment
57
- ├── templates.js # Template rendering
58
- ├── secrets.js # Secret resolution (kv://)
59
- ├── config.js # Configuration management
60
- ├── api/ # Centralized API client structure
61
- │ ├── index.js # Main API client class
62
- │ ├── types/ # JSDoc type definitions
63
- │ │ ├── auth.types.js
64
- │ │ ├── applications.types.js
65
- │ │ ├── deployments.types.js
66
- │ │ ├── environments.types.js
67
- │ │ ├── datasources.types.js
68
- │ │ ├── external-systems.types.js
69
- │ │ └── pipeline.types.js
70
- │ ├── auth.api.js # Authentication API functions
71
- │ ├── applications.api.js
72
- │ ├── deployments.api.js
73
- │ ├── environments.api.js
74
- │ ├── datasources.api.js
75
- │ ├── external-systems.api.js
76
- │ └── pipeline.api.js
77
- ├── utils/ # Utility functions
78
- └── schema/ # JSON schemas
79
- ```
80
-
81
- ### Generated Output (integration/ and builder/)
82
-
83
- Files under **integration/** and **builder/** are **auto-generated** by the CLI. When fixing bugs or changing behavior, validate **where** each file is produced so fixes go into the generator, not only into the generated artifact.
84
-
85
- - **integration/** – External system / wizard output:
86
- - Path: `integration/<appName>/` (see `lib/utils/paths.js` → `getIntegrationPath`).
87
- - Generated by: `lib/generator/wizard.js` (`generateWizardFiles`, `generateConfigFilesForWizard`), `lib/external-system/download.js`, wizard commands in `lib/commands/wizard-core.js` and `lib/commands/wizard.js`.
88
- - Typical outputs: `application.yaml`, `env.template`, `README.md`, `*-system.json`, `*-datasource*.json`, `*-deploy.json`, deploy script (`deploy.js`), and optionally `wizard.yaml`, `error.log`.
89
- - **builder/** – Application (non-external) output:
90
- - Path: `builder/<appName>/` or custom root via `AIFABRIX_BUILDER_DIR` (see `lib/utils/paths.js` → `getBuilderPath`).
91
- - Generated by: app create/register flow, `lib/generator/index.js`, `lib/commands/up-common.js`, `lib/core/secrets.js`, and related app/deploy logic.
92
- - Typical outputs: `application.yaml`, `env.template`, deploy JSON, `.env` (from secrets), and app-specific config.
93
-
94
- **Editable vs generated:**
95
- - Some generated files are **intended to be edited** (e.g. `application.yaml`, `env.template`, `README.md`, `wizard.yaml`). Improvements to defaults or structure still belong in the generator/templates.
96
- - **When debugging:** First identify the **source of generation** (which module and function write the file). Fix bugs in that generator or template; avoid treating a one-off edit in integration/ or builder/ as the permanent fix unless it’s a deliberate local override.
97
-
98
- ### CLI Command Pattern
99
- Commands are defined in `lib/cli.js` using Commander.js:
100
- ```javascript
101
- program.command('command-name')
102
- .description('Command description')
103
- .option('-f, --flag <value>', 'Option description', defaultValue)
104
- .action(async (options) => {
105
- try {
106
- // Command implementation
107
- await commandFunction(options);
108
- } catch (error) {
109
- console.error(chalk.red(`Error: ${error.message}`));
110
- process.exit(1);
111
- }
112
- });
113
- ```
114
-
115
- ### Module Export Pattern
116
- - Use named exports for multiple functions
117
- - Use default exports for single-purpose modules
118
- - Pattern:
119
- ```javascript
120
- /**
121
- * Module description
122
- * @fileoverview Brief description
123
- * @author AI Fabrix Team
124
- * @version 2.0.0
125
- */
126
-
127
- const dependency = require('./dependency');
128
-
129
- /**
130
- * Function description
131
- * @async
132
- * @function functionName
133
- * @param {string} param - Parameter description
134
- * @returns {Promise<Type>} Return description
135
- * @throws {Error} Error description
136
- */
137
- async function functionName(param) {
138
- // Implementation
139
- }
140
-
141
- module.exports = { functionName };
142
- ```
143
-
144
- ### Template Generation Pattern
145
- Templates use Handlebars and are stored in `templates/`:
146
- ```javascript
147
- const Handlebars = require('handlebars');
148
- const fs = require('fs');
149
-
150
- const templateContent = fs.readFileSync(templatePath, 'utf8');
151
- const template = Handlebars.compile(templateContent);
152
- const rendered = template(context);
153
- fs.writeFileSync(outputPath, rendered, 'utf8');
154
- ```
155
-
156
- ### YAML Processing Pattern
157
- All YAML files use js-yaml with proper error handling:
158
- ```javascript
159
- const yaml = require('js-yaml');
160
- const fs = require('fs');
161
-
162
- try {
163
- const content = fs.readFileSync(yamlPath, 'utf8');
164
- const parsed = yaml.load(content);
165
- // Process parsed YAML
166
- } catch (error) {
167
- throw new Error(`Invalid YAML syntax: ${error.message}`);
168
- }
169
- ```
170
-
171
- ### Schema Validation Pattern
172
- Use AJV for JSON schema validation:
173
- ```javascript
174
- const Ajv = require('ajv');
175
- const schema = require('./schema/application-schema.json');
176
-
177
- const ajv = new Ajv({ allErrors: true, strict: false });
178
- const validate = ajv.compile(schema);
179
- const valid = validate(data);
180
-
181
- if (!valid) {
182
- const errors = formatValidationErrors(validate.errors);
183
- throw new Error(`Validation failed: ${errors.join(', ')}`);
184
- }
185
- ```
186
-
187
- ### API Client Structure Pattern
188
- Use the centralized API client structure in `lib/api/` for all API calls. This provides typed interfaces, domain separation, and consistent error handling.
189
-
190
- **Structure**:
191
- - Base client (`lib/api/index.js`) - Main HTTP client with authentication and error handling
192
- - Type definitions (`lib/api/types/`) - JSDoc type definitions for request/response types
193
- - Domain modules (`lib/api/*.api.js`) - Domain-specific API functions
194
-
195
- **Type Definitions Pattern**:
196
- Use JSDoc `@typedef` for all request/response types in `lib/api/types/`:
197
- ```javascript
198
- /**
199
- * @fileoverview Authentication API type definitions
200
- * @author AI Fabrix Team
201
- * @version 2.0.0
202
- */
203
-
204
- /**
205
- * Token request payload
206
- * @typedef {Object} TokenRequest
207
- * @property {string} clientId - Client ID
208
- * @property {string} clientSecret - Client secret
209
- */
210
-
211
- /**
212
- * Token response payload
213
- * @typedef {Object} TokenResponse
214
- * @property {boolean} success - Request success flag
215
- * @property {string} token - Authentication token
216
- * @property {number} expiresIn - Token expiration time in seconds
217
- * @property {string} expiresAt - Token expiration timestamp
218
- */
219
- ```
220
-
221
- **API Module Pattern**:
222
- Each domain module exports typed API functions:
223
- ```javascript
224
- /**
225
- * @fileoverview Authentication API functions
226
- * @author AI Fabrix Team
227
- * @version 2.0.0
228
- */
229
-
230
- const { ApiClient } = require('./index');
231
- const { TokenRequest, TokenResponse } = require('./types/auth.types');
232
-
233
- /**
234
- * Get authentication token using client credentials
235
- * @async
236
- * @function getToken
237
- * @param {string} clientId - Client ID
238
- * @param {string} clientSecret - Client secret
239
- * @param {string} controllerUrl - Controller base URL
240
- * @returns {Promise<TokenResponse>} Token response with access token
241
- * @throws {Error} If authentication fails
242
- */
243
- async function getToken(clientId, clientSecret, controllerUrl) {
244
- const client = new ApiClient(controllerUrl);
245
- return await client.post('/api/v1/auth/token', {
246
- headers: {
247
- 'x-client-id': clientId,
248
- 'x-client-secret': clientSecret
249
- }
250
- });
251
- }
252
-
253
- module.exports = { getToken };
254
- ```
255
-
256
- **Usage Pattern**:
257
- Import and use domain-specific API modules:
258
- ```javascript
259
- const { getToken } = require('../api/auth.api');
260
- const { registerApplication } = require('../api/applications.api');
261
-
262
- // Use typed API functions
263
- const tokenResponse = await getToken(clientId, clientSecret, controllerUrl);
264
- const appResponse = await registerApplication(controllerUrl, environment, data, token);
265
- ```
266
-
267
- **Migration Strategy**:
268
- - New code should use `lib/api/` modules
269
- - Existing code can continue using `lib/utils/api.js` (backward compatible)
270
- - Gradually migrate modules to use centralized API client
271
- - Eventually deprecate direct usage of `lib/utils/api.js`
272
-
273
- **API Permissions**: When adding or changing `lib/api` functions that call Controller or Dataplane, document required permissions. See [permissions-guide.md](permissions-guide.md) for how to update `@requiresPermission` JSDoc and [docs/commands/permissions.md](../docs/commands/permissions.md).
274
-
275
- ## Code Style
276
-
277
- ### JavaScript Conventions
278
- - Use strict mode where applicable
279
- - Use async/await for asynchronous operations
280
- - Use try-catch for error handling
281
- - Prefer const over let, avoid var
282
- - Use template literals for string interpolation
283
- - Use object destructuring where appropriate
284
-
285
- ### Naming Conventions
286
- - **Files**: kebab-case (`app-deploy.js`, `env-reader.js`)
287
- - **Functions**: camelCase (`createApp`, `validateVariables`)
288
- - **Constants**: UPPER_SNAKE_CASE (`MAX_FILE_SIZE`, `DEFAULT_PORT`)
289
- - **Classes**: PascalCase (not common in this project, but if used)
290
- - **Private functions**: prefix with underscore if needed (rare in CommonJS)
291
-
292
- ### Error Handling
293
- - Always wrap async operations in try-catch
294
- - Provide meaningful error messages
295
- - Include context in error messages (file path, app name, etc.)
296
- - Use chalk for colored error output
297
- - Pattern:
298
- ```javascript
299
- try {
300
- await operation();
301
- } catch (error) {
302
- console.error(chalk.red(`Error: ${error.message}`));
303
- throw new Error(`Operation failed: ${error.message}`);
304
- }
305
- ```
306
-
307
- ### Input Validation
308
- - Validate all function parameters
309
- - Check for null/undefined values
310
- - Validate file paths and existence
311
- - Validate app names (alphanumeric, hyphens, underscores)
312
- - Pattern:
313
- ```javascript
314
- function validateAppName(appName) {
315
- if (!appName || typeof appName !== 'string') {
316
- throw new Error('App name is required and must be a string');
317
- }
318
- if (!/^[a-z0-9-_]+$/.test(appName)) {
319
- throw new Error('App name must contain only lowercase letters, numbers, hyphens, and underscores');
320
- }
321
- }
322
- ```
323
-
324
- ### Async/Await
325
- - Always use async/await, never raw promises
326
- - Always use try-catch with async operations
327
- - Return appropriate default values on error (empty arrays, null, etc.)
328
- - Pattern:
329
- ```javascript
330
- async function getItems() {
331
- try {
332
- const items = await fetchItems();
333
- return items || [];
334
- } catch (error) {
335
- console.error('Failed to get items:', error);
336
- return [];
337
- }
338
- }
339
- ```
340
-
341
- ### File Operations
342
- - Use `fs.promises` for async file operations
343
- - Use `fs.existsSync` for synchronous checks when needed
344
- - Always handle file not found errors
345
- - Use `path.join()` for cross-platform path construction
346
- - Pattern:
347
- ```javascript
348
- const fs = require('fs').promises;
349
- const path = require('path');
350
-
351
- const filePath = path.join(process.cwd(), 'builder', appName, 'application.yaml');
352
- try {
353
- const content = await fs.readFileSync(filePath, 'utf8');
354
- // Process content
355
- } catch (error) {
356
- if (error.code === 'ENOENT') {
357
- throw new Error(`File not found: ${filePath}`);
358
- }
359
- throw error;
360
- }
361
- ```
362
-
363
- ## Testing Conventions
364
-
365
- ### Test File Structure
366
- - Test files mirror source structure: `tests/lib/app.test.js`
367
- - Use Jest for testing framework
368
- - Mock all external dependencies (fs, axios, child_process)
369
- - Test both success and error paths
370
- - Test edge cases (missing files, invalid YAML, etc.)
371
-
372
- ### Test Organization
373
- ```yaml
374
- tests/
375
- ├── lib/
376
- │ ├── app.test.js
377
- │ ├── validator.test.js
378
- │ ├── cli.test.js
379
- │ └── generator.test.js
380
- ├── bin/
381
- │ └── aifabrix.test.js
382
- └── integration/
383
- ├── build.test.js
384
- └── deploy.test.js
385
- ```
386
-
387
- ### Mock Patterns
388
- - Mock fs operations: `jest.mock('fs')` or `jest.mock('fs').promises`
389
- - Mock axios: `jest.mock('axios')` or use `makeApiCall` mock
390
- - Mock API client: `jest.mock('../lib/api')` or mock individual API modules
391
- - Mock child_process: `jest.mock('child_process')`
392
- - Mock templates: provide test templates in `tests/fixtures/`
393
- - Pattern:
394
- ```javascript
395
- jest.mock('fs');
396
- jest.mock('fs').promises;
397
- jest.mock('../lib/api/auth.api');
398
-
399
- const fs = require('fs');
400
- const fsp = require('fs').promises;
401
- const { getToken } = require('../lib/api/auth.api');
402
-
403
- describe('ModuleName', () => {
404
- beforeEach(() => {
405
- jest.clearAllMocks();
406
- });
407
-
408
- it('should handle success case', async () => {
409
- fsp.readFile = jest.fn().resolves('content');
410
- getToken = jest.fn().resolves({ success: true, token: 'test-token' });
411
- // Test implementation
412
- });
413
-
414
- it('should handle error case', async () => {
415
- fsp.readFile = jest.fn().rejects(new Error('File not found'));
416
- getToken = jest.fn().resolves({ success: false, error: 'Auth failed' });
417
- // Test error handling
418
- });
419
- });
420
- ```
421
-
422
- ### API Client Testing Pattern
423
- Test API modules by mocking the base client:
424
- ```javascript
425
- jest.mock('../lib/api/index');
426
-
427
- const { ApiClient } = require('../lib/api/index');
428
- const { getToken } = require('../lib/api/auth.api');
429
-
430
- describe('auth.api', () => {
431
- beforeEach(() => {
432
- jest.clearAllMocks();
433
- });
434
-
435
- it('should get token successfully', async () => {
436
- const mockResponse = { success: true, token: 'test-token' };
437
- ApiClient.prototype.post = jest.fn().resolves(mockResponse);
438
-
439
- const result = await getToken('client-id', 'secret', 'https://controller');
440
- expect(result).toEqual(mockResponse);
441
- expect(ApiClient.prototype.post).toHaveBeenCalledWith(
442
- '/api/v1/auth/token',
443
- expect.objectContaining({
444
- headers: expect.objectContaining({
445
- 'x-client-id': 'client-id',
446
- 'x-client-secret': 'secret'
447
- })
448
- })
449
- );
450
- });
451
- });
452
- ```
453
-
454
- ### Test Coverage
455
- - Aim for 80%+ branch coverage
456
- - Test edge cases (null tokens, empty arrays, file errors)
457
- - Test validation failures
458
- - Test template rendering
459
- - Test Docker operations (mocked)
460
-
461
- ## Security & Compliance (ISO 27001)
462
-
463
- ### Information Security Management
464
- - All code must follow ISO 27001 information security standards
465
- - Implement proper access controls and authentication mechanisms
466
- - Ensure data confidentiality, integrity, and availability
467
- - Document all security-related decisions and implementations
468
- - Regular security reviews and vulnerability assessments required
469
-
470
- ### Data Protection
471
- - **No hardcoded secrets, passwords, or sensitive data in code**
472
- - Use environment variables and secure configuration management
473
- - Implement proper input validation and sanitization
474
- - Follow principle of least privilege for all operations
475
- - Encrypt sensitive data at rest and in transit
476
- - Never log sensitive information (passwords, tokens, secrets)
477
-
478
- ### Secret Management
479
- - Use `kv://` references in env.template for secrets
480
- - Resolve secrets via `lib/secrets.js` before deployment
481
- - Never expose secrets in generated files
482
- - Mask secrets in logs and error messages
483
- - Pattern:
484
- ```javascript
485
- // In env.template
486
- DATABASE_PASSWORD=kv://secrets/database/password
487
-
488
- // In secrets.js
489
- function resolveSecret(key) {
490
- // Resolve from secure key store
491
- // Never log the actual value
492
- }
493
- ```
494
-
495
- ### Audit & Compliance
496
- - All actions must be logged and auditable
497
- - Use `lib/audit-logger.js` for audit logging
498
- - Maintain comprehensive documentation for compliance
499
- - Regular code reviews and security assessments
500
- - Version control all changes with proper commit messages
501
- - Document all dependencies and their security implications
502
-
503
- ### Input Validation
504
- - Sanitize all user inputs (app names, file paths, URLs)
505
- - Validate YAML syntax before processing
506
- - Validate JSON schemas before deployment
507
- - Prevent path traversal attacks
508
- - Validate URLs and endpoints
509
-
510
- ### Infrastructure Security
511
- - Use secure container configurations
512
- - Implement proper network security
513
- - Follow Docker security best practices
514
- - Use secure base images and dependencies
515
- - Validate Dockerfile security before generation
516
-
517
- ## Code Quality Standards
518
-
519
- ### File Size Limits
520
- - **Maximum 500 lines per file** - Split large files into smaller, focused modules
521
- - **Maximum 50 lines per function/method** - Break down complex functions
522
- - Use composition over inheritance to reduce complexity
523
- - Extract reusable components and utilities
524
-
525
- ### Code Organization
526
- - Follow single responsibility principle
527
- - Use meaningful, descriptive names for variables and functions
528
- - Implement proper error handling and logging
529
- - Write self-documenting code with clear comments
530
- - Use JSDoc for all public functions
531
-
532
- ### Documentation Requirements
533
- - **JSDoc comments for all public functions**
534
- - Include parameter types and return types
535
- - Document error conditions
536
- - Add examples in comments for complex methods
537
- - Document security considerations
538
- - **Visual Documentation**: Use canonical Mermaid diagram templates from [flows-and-visuals.md](flows-and-visuals.md) for architecture diagrams and workflow visualizations
539
- - Use Template 1 for overall Builder architecture
540
- - Use Template 2 for application creation flows
541
- - Use Template 3 for development lifecycle workflows
542
- - Use Template 4 for wizard/external system flows
543
- - Follow strict styling guidelines (colors, fonts, spacing) defined in flows-and-visuals.md
544
-
545
- ### Code Comments
546
- - Use JSDoc format for function documentation
547
- - Include `@fileoverview` at top of each file
548
- - Include `@author` and `@version` tags
549
- - Use inline comments for complex logic
550
- - Pattern:
551
- ```javascript
552
- /**
553
- * Function description
554
- * @async
555
- * @function functionName
556
- * @param {string} appName - Application name
557
- * @param {Object} options - Configuration options
558
- * @param {number} [options.port] - Application port (optional)
559
- * @returns {Promise<void>} Resolves when operation completes
560
- * @throws {Error} If app name is invalid or operation fails
561
- *
562
- * @example
563
- * await functionName('myapp', { port: 3000 });
564
- */
565
- ```
566
-
567
- ## Development Workflow
568
-
569
- ### Pre-Development
570
- 1. Analyze requirements and create detailed specifications
571
- 2. Design architecture following security best practices
572
- 3. Plan test cases before writing implementation
573
- 4. Review existing code for potential security vulnerabilities
574
-
575
- ### During Development
576
- 1. Write tests first (TDD approach)
577
- 2. Implement functionality with security in mind
578
- 3. Follow coding standards and file size limits
579
- 4. Document all security-related decisions
580
- 5. Use proper error handling and logging
581
- 6. Validate all inputs
582
- 7. Use JSDoc for documentation
583
-
584
- ### Post-Development
585
- 1. **Build project** - Run `npm run build` (lint + test)
586
- 2. **Validate linting** - Run `npm run lint` and fix all issues
587
- 3. **Run tests** - Execute `npm test` and ensure 100% pass rate
588
- 4. **Check coverage** - Ensure 80%+ coverage for new code
589
- 5. **Security review** - Check for vulnerabilities and compliance
590
- 6. **Code review** - Peer review for quality and security
591
-
592
- ## CLI Command Development
593
-
594
- ### Adding New Commands
595
- 1. Add command definition in `lib/cli.js`
596
- 2. Implement command logic in `lib/commands/` or appropriate module
597
- 3. Add input validation
598
- 4. Add error handling with user-friendly messages
599
- 5. Use chalk for colored output
600
- 6. Write tests for the command
601
-
602
- ### Command Pattern
603
- ```javascript
604
- program.command('new-command')
605
- .description('Clear description of what the command does')
606
- .option('-f, --flag <value>', 'Option description', defaultValue)
607
- .action(async (options) => {
608
- try {
609
- // Validate inputs
610
- if (!options.required) {
611
- throw new Error('Required option missing');
612
- }
613
-
614
- // Execute command
615
- const result = await executeCommand(options);
616
-
617
- // Success message
618
- console.log(chalk.green(`✓ Success: ${result}`));
619
- } catch (error) {
620
- console.error(chalk.red(`✗ Error: ${error.message}`));
621
- process.exit(1);
622
- }
623
- });
624
- ```
625
-
626
- ### User Experience
627
- - Provide clear, actionable error messages
628
- - Use emoji/icons for visual feedback (✓, ✗, ⚠️, 🔐, etc.)
629
- - Show progress for long-running operations (use ora spinner)
630
- - Provide helpful hints in error messages
631
- - Use consistent formatting across commands
632
-
633
- ## Template Development
634
-
635
- ### Template Location
636
- - Templates in `templates/` directory
637
- - Organize by type: `templates/typescript/`, `templates/python/`, `templates/github/`
638
- - Use `.hbs` extension for Handlebars templates
639
-
640
- ### Template Patterns
641
- - Use Handlebars helpers for conditionals: `{{#if condition}}`
642
- - Use Handlebars loops: `{{#each items}}`
643
- - Use context variables: `{{variableName}}`
644
- - Provide default values: `{{variableName default="value"}}`
645
- - Pattern:
646
- ```handlebars
647
- # {{appName}} Dockerfile
648
- FROM {{baseImage}}
649
- {{#if hasDatabase}}
650
- ENV DATABASE_URL={{databaseUrl}}
651
- {{/if}}
652
- ```
653
-
654
- ### Template Context
655
- - Build context object with all necessary variables
656
- - Validate context before rendering
657
- - Provide sensible defaults for optional values
658
- - Document required context variables
659
-
660
- ## Validation Patterns
661
-
662
- ### Schema Validation
663
- - Define schemas in `lib/schema/` directory
664
- - Use JSON Schema format
665
- - Validate before deployment
666
- - Provide developer-friendly error messages
667
- - Pattern:
668
- ```javascript
669
- const schema = require('./schema/application-schema.json');
670
- const ajv = new Ajv({ allErrors: true });
671
- const validate = ajv.compile(schema);
672
-
673
- if (!validate(data)) {
674
- const errors = validate.errors.map(err =>
675
- `${err.instancePath} ${err.message}`
676
- ).join(', ');
677
- throw new Error(`Validation failed: ${errors}`);
678
- }
679
- ```
680
-
681
- ### YAML Validation
682
- - Validate YAML syntax before parsing
683
- - Validate against schemas after parsing
684
- - Provide line numbers in error messages when possible
685
- - Pattern:
686
- ```javascript
687
- try {
688
- const parsed = yaml.load(content);
689
- await validateAgainstSchema(parsed);
690
- } catch (error) {
691
- if (error.message.includes('YAML')) {
692
- throw new Error(`Invalid YAML syntax: ${error.message}`);
693
- }
694
- throw error;
695
- }
696
- ```
697
-
698
- ## Docker & Infrastructure
699
-
700
- ### Dockerfile Generation
701
- - Auto-detect runtime (TypeScript/Python)
702
- - Use appropriate base images
703
- - Follow security best practices
704
- - Minimize image size
705
- - Pattern in `lib/app-dockerfile.js`:
706
- ```javascript
707
- function detectRuntime(appPath) {
708
- // Check for package.json (Node.js/TypeScript)
709
- // Check for requirements.txt (Python)
710
- // Return appropriate template
711
- }
712
- ```
713
-
714
- ### Docker Compose
715
- - Infrastructure templates in `templates/infra/`
716
- - Use environment variables for configuration
717
- - Follow Docker security best practices
718
- - Validate compose files before deployment
719
-
720
- ## Common Patterns
721
-
722
- ### App Name Validation
723
- ```javascript
724
- function validateAppName(appName) {
725
- if (!appName || typeof appName !== 'string') {
726
- throw new Error('App name is required and must be a string');
727
- }
728
- if (!/^[a-z0-9-_]+$/.test(appName)) {
729
- throw new Error('App name must contain only lowercase letters, numbers, hyphens, and underscores');
730
- }
731
- }
732
- ```
733
-
734
- ### File Path Construction
735
- ```javascript
736
- const path = require('path');
737
-
738
- const appPath = path.join(process.cwd(), 'builder', appName);
739
- const configPath = path.join(appPath, 'application.yaml');
740
- ```
741
-
742
- ### Configuration Loading
743
- ```javascript
744
- async function loadConfig(appName) {
745
- const configPath = path.join(process.cwd(), 'builder', appName, 'application.yaml');
746
- const content = await fs.readFile(configPath, 'utf8');
747
- return yaml.load(content);
748
- }
749
- ```
750
-
751
- ### Template Rendering
752
- ```javascript
753
- const Handlebars = require('handlebars');
754
- const fs = require('fs');
755
-
756
- const templatePath = path.join(__dirname, '../templates/typescript/Dockerfile.hbs');
757
- const templateContent = fs.readFileSync(templatePath, 'utf8');
758
- const template = Handlebars.compile(templateContent);
759
- const rendered = template(context);
760
- await fs.writeFile(outputPath, rendered, 'utf8');
761
- ```
762
-
763
- ### API Client Usage
764
- Use the centralized API client for all API calls:
765
- ```javascript
766
- const { getToken } = require('../api/auth.api');
767
- const { registerApplication } = require('../api/applications.api');
768
-
769
- // Typed API calls with automatic error handling
770
- try {
771
- const tokenResponse = await getToken(clientId, clientSecret, controllerUrl);
772
- if (!tokenResponse.success) {
773
- throw new Error(tokenResponse.formattedError || 'Authentication failed');
774
- }
775
-
776
- const appResponse = await registerApplication(
777
- controllerUrl,
778
- environment,
779
- registrationData,
780
- tokenResponse.token
781
- );
782
- } catch (error) {
783
- console.error(chalk.red(`Error: ${error.message}`));
784
- throw error;
785
- }
786
- ```
787
-
788
- ### Type Definition Pattern
789
- Define request/response types using JSDoc `@typedef`:
790
- ```javascript
791
- /**
792
- * Application registration request
793
- * @typedef {Object} RegisterApplicationRequest
794
- * @property {string} appKey - Application key
795
- * @property {string} name - Application name
796
- * @property {string} [description] - Application description (optional)
797
- * @property {string[]} [tags] - Application tags (optional)
798
- */
799
-
800
- /**
801
- * Application registration response
802
- * @typedef {Object} RegisterApplicationResponse
803
- * @property {boolean} success - Request success flag
804
- * @property {Object} data - Response data
805
- * @property {string} data.appKey - Registered application key
806
- * @property {string} data.clientId - Generated client ID
807
- * @property {string} data.clientSecret - Generated client secret
808
- */
809
- ```
810
-
811
- ## Quality Gates
812
-
813
- ### Mandatory Checks Before Commit
814
- 1. ✅ File size limits respected (≤500 lines, ≤50 lines per function)
815
- 2. ✅ All functions have corresponding tests
816
- 3. ✅ Tests are in `tests/` folder (not in code directories)
817
- 4. ✅ Build process completes successfully (`npm run build`)
818
- 5. ✅ Linting passes with no errors (`npm run lint`)
819
- 6. ✅ All tests pass (100% success rate)
820
- 7. ✅ Test coverage ≥80% for new code
821
- 8. ✅ Security review completed
822
- 9. ✅ Documentation updated (JSDoc comments)
823
- 10. ✅ No hardcoded secrets or sensitive data
824
-
825
- ### Continuous Integration
826
- - Automated testing on all pull requests
827
- - Security scanning and vulnerability assessment
828
- - Code quality metrics and coverage reporting
829
- - Automated deployment validation
830
- - Linting enforcement
831
-
832
- ## Error Handling & Logging
833
-
834
- ### Error Handling
835
- - Implement comprehensive error handling
836
- - Use structured error messages with context
837
- - Log all errors with appropriate context
838
- - Never expose sensitive information in error messages
839
- - Use chalk for colored error output
840
- - Provide actionable error messages
841
-
842
- ### Logging Standards
843
- - Use console.log for normal output (with chalk coloring)
844
- - Use console.error for errors
845
- - Use console.warn for warnings
846
- - Use ora spinner for progress indication
847
- - Never log secrets, passwords, or tokens
848
- - Use structured logging for audit trail
849
-
850
- ## Dependencies & Security
851
-
852
- ### Dependency Management
853
- - Regularly update dependencies for security patches
854
- - Use only trusted and well-maintained packages
855
- - Implement dependency scanning and vulnerability assessment
856
- - Document all dependencies and their purposes
857
- - Review security advisories regularly
858
-
859
- ### Security Scanning
860
- - Regular security scans of dependencies
861
- - Vulnerability assessment and remediation
862
- - Security testing in CI/CD pipeline
863
- - Regular security audits and reviews
864
- - Use `npm audit` regularly
865
-
866
- ## When Adding New Features
867
-
868
- 1. **Plan** - Analyze requirements and design architecture
869
- 2. **Test First** - Write tests before implementation (TDD)
870
- 3. **Implement** - Write code following all patterns and standards
871
- 4. **Validate** - Run build, lint, and tests
872
- 5. **Document** - Add JSDoc comments and update README if needed
873
- 6. **Security Review** - Check for vulnerabilities and compliance
874
- 7. **Code Review** - Peer review for quality and security
875
-
876
- ## Critical Rules
877
-
878
- ### Must Do (✅)
879
- - ✅ Validate all inputs (app names, file paths, URLs)
880
- - ✅ When fixing bugs in integration/ or builder/ output: identify the generator that produces the file and fix the source (lib/generator, lib/commands, templates), not only the generated artifact
881
- - ✅ Use try-catch for all async operations
882
- - ✅ Provide meaningful error messages with context
883
- - ✅ Use JSDoc for all public functions
884
- - ✅ Write tests for all functions
885
- - ✅ Keep files ≤500 lines and functions ≤50 lines
886
- - ✅ Use chalk for colored output in CLI
887
- - ✅ Use path.join() for cross-platform paths
888
- - ✅ Validate YAML syntax before parsing
889
- - ✅ Never log secrets or sensitive data
890
- - ✅ Use centralized API client (`lib/api/`) for new API calls
891
- - ✅ Define request/response types using JSDoc `@typedef` in `lib/api/types/`
892
- - ✅ Use domain-specific API modules (`lib/api/*.api.js`) instead of direct `makeApiCall`
893
- - ✅ When adding lib/api functions that call Controller/Dataplane, add `@requiresPermission` JSDoc per [permissions-guide.md](permissions-guide.md)
894
-
895
- ### Must Not Do (❌)
896
- - ❌ Never hardcode secrets, passwords, or tokens
897
- - ❌ Never hardcode lab/training integration names, vendor names, or internal plan IDs in generic CLI/helpers (`lib/commands/**`, `lib/cli/**`, shared `lib/utils/*-error*.js`); use dynamic keys from user input, manifests, and secrets — see [cli-product-neutral.mdc](cli-product-neutral.mdc)
898
- - ❌ Never expose sensitive data in error messages
899
- - ❌ Never use synchronous file operations in async functions (unless necessary)
900
- - ❌ Never ignore errors or use empty catch blocks
901
- - ❌ Never commit files with secrets or sensitive data
902
- - ❌ Never skip input validation
903
- - ❌ Never skip tests for new functionality
904
- - ❌ Never use `eval()` or `Function()` constructor
905
- - ❌ Never use raw paths (always use path.join)
906
- - ❌ Never make direct API calls using `makeApiCall` in new code (use `lib/api/` modules)
907
- - ❌ Never treat one-off edits in integration/ or builder/ as the permanent fix for a bug—update the generator or template that produces the file
908
- - ❌ Never skip type definitions for API request/response types
909
- - ❌ Never log authentication tokens or secrets in API calls
910
-
911
- ---
912
-
913
- **Remember**: Security is not optional. Every line of code must be written with security and compliance in mind. When in doubt, choose the more secure option and document the decision.