@cdmbase/wiki-browser 12.0.18-alpha.10

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 (367) hide show
  1. package/LICENSE +21 -0
  2. package/lib/components/Logo.d.ts +4 -0
  3. package/lib/components/Logo.d.ts.map +1 -0
  4. package/lib/components/Logo.js +16 -0
  5. package/lib/components/Logo.js.map +1 -0
  6. package/lib/components/help/SidebarSearch.d.ts +8 -0
  7. package/lib/components/help/SidebarSearch.d.ts.map +1 -0
  8. package/lib/components/help/SidebarSearch.js +111 -0
  9. package/lib/components/help/SidebarSearch.js.map +1 -0
  10. package/lib/components/help/index.d.ts +2 -0
  11. package/lib/components/help/index.d.ts.map +1 -0
  12. package/lib/components/landing/FeatureCard.d.ts +13 -0
  13. package/lib/components/landing/FeatureCard.d.ts.map +1 -0
  14. package/lib/components/landing/FeatureCard.js +85 -0
  15. package/lib/components/landing/FeatureCard.js.map +1 -0
  16. package/lib/components/landing/QuickLinkCard.d.ts +8 -0
  17. package/lib/components/landing/QuickLinkCard.d.ts.map +1 -0
  18. package/lib/components/landing/QuickLinkCard.js +26 -0
  19. package/lib/components/landing/QuickLinkCard.js.map +1 -0
  20. package/lib/components/landing/SearchInput.d.ts +10 -0
  21. package/lib/components/landing/SearchInput.d.ts.map +1 -0
  22. package/lib/components/landing/SearchInput.js +223 -0
  23. package/lib/components/landing/SearchInput.js.map +1 -0
  24. package/lib/components/landing/index.d.ts +4 -0
  25. package/lib/components/landing/index.d.ts.map +1 -0
  26. package/lib/components/welcome.d.ts +3 -0
  27. package/lib/components/welcome.d.ts.map +1 -0
  28. package/lib/compute.d.ts +4 -0
  29. package/lib/compute.d.ts.map +1 -0
  30. package/lib/compute.js +96 -0
  31. package/lib/compute.js.map +1 -0
  32. package/lib/config/env-config.d.ts +4 -0
  33. package/lib/config/env-config.d.ts.map +1 -0
  34. package/lib/config/env-config.js +7 -0
  35. package/lib/config/env-config.js.map +1 -0
  36. package/lib/docs.config.d.ts +48 -0
  37. package/lib/docs.config.d.ts.map +1 -0
  38. package/lib/index.d.ts +4 -0
  39. package/lib/index.d.ts.map +1 -0
  40. package/lib/index.js +2 -0
  41. package/lib/index.js.map +1 -0
  42. package/lib/loaders/search.d.ts +1 -0
  43. package/lib/loaders/search.d.ts.map +1 -0
  44. package/lib/module.d.ts +4 -0
  45. package/lib/module.d.ts.map +1 -0
  46. package/lib/module.js +11 -0
  47. package/lib/module.js.map +1 -0
  48. package/lib/pages/ArticlePage/ArticlePage.d.ts +4 -0
  49. package/lib/pages/ArticlePage/ArticlePage.d.ts.map +1 -0
  50. package/lib/pages/ArticlePage/ArticlePage.js +222 -0
  51. package/lib/pages/ArticlePage/ArticlePage.js.map +1 -0
  52. package/lib/pages/ArticlePage/index.d.ts +3 -0
  53. package/lib/pages/ArticlePage/index.d.ts.map +1 -0
  54. package/lib/pages/ArticlePage/index.js +3 -0
  55. package/lib/pages/ArticlePage/index.js.map +1 -0
  56. package/lib/pages/CategoryCollection/CategoryCollection.d.ts +4 -0
  57. package/lib/pages/CategoryCollection/CategoryCollection.d.ts.map +1 -0
  58. package/lib/pages/CategoryCollection/CategoryCollection.js +103 -0
  59. package/lib/pages/CategoryCollection/CategoryCollection.js.map +1 -0
  60. package/lib/pages/CategoryCollection/index.d.ts +3 -0
  61. package/lib/pages/CategoryCollection/index.d.ts.map +1 -0
  62. package/lib/pages/CategoryCollection/index.js +3 -0
  63. package/lib/pages/CategoryCollection/index.js.map +1 -0
  64. package/lib/pages/Help/HelpIndex.d.ts +4 -0
  65. package/lib/pages/Help/HelpIndex.d.ts.map +1 -0
  66. package/lib/pages/Help/HelpIndex.js +44 -0
  67. package/lib/pages/Help/HelpIndex.js.map +1 -0
  68. package/lib/pages/Help/index.d.ts +4 -0
  69. package/lib/pages/Help/index.d.ts.map +1 -0
  70. package/lib/pages/Help/index.js +226 -0
  71. package/lib/pages/Help/index.js.map +1 -0
  72. package/lib/pages/Landing/index.d.ts +3 -0
  73. package/lib/pages/Landing/index.d.ts.map +1 -0
  74. package/lib/pages/Landing/index.js +281 -0
  75. package/lib/pages/Landing/index.js.map +1 -0
  76. package/lib/routes.json +2533 -0
  77. package/lib/seo.d.ts +22 -0
  78. package/lib/seo.d.ts.map +1 -0
  79. package/lib/slot-fill/FooterFill.d.ts +3 -0
  80. package/lib/slot-fill/FooterFill.d.ts.map +1 -0
  81. package/lib/slot-fill/FooterFill.js +18 -0
  82. package/lib/slot-fill/FooterFill.js.map +1 -0
  83. package/lib/slot-fill/LogoFill.d.ts +5 -0
  84. package/lib/slot-fill/LogoFill.d.ts.map +1 -0
  85. package/lib/slot-fill/LogoFill.js +74 -0
  86. package/lib/slot-fill/LogoFill.js.map +1 -0
  87. package/lib/slot-fill/consts.d.ts +5 -0
  88. package/lib/slot-fill/consts.d.ts.map +1 -0
  89. package/lib/slot-fill/consts.js +1 -0
  90. package/lib/slot-fill/consts.js.map +1 -0
  91. package/lib/slot-fill/index.d.ts +4 -0
  92. package/lib/slot-fill/index.d.ts.map +1 -0
  93. package/lib/templates/assets/images/add-link-frontend.png +0 -0
  94. package/lib/templates/assets/images/add-package-backend.png +0 -0
  95. package/lib/templates/assets/images/add-to-backend-module.png +0 -0
  96. package/lib/templates/assets/images/add-upload-client-frontend.png +0 -0
  97. package/lib/templates/assets/images/additional-parameters.png +0 -0
  98. package/lib/templates/assets/images/aeh-implementation.png +0 -0
  99. package/lib/templates/assets/images/aeh-usage.png +0 -0
  100. package/lib/templates/assets/images/apollo-client/recommendation_cache_mgmt.png +0 -0
  101. package/lib/templates/assets/images/app-deploy-new-version/jenkins1.PNG +0 -0
  102. package/lib/templates/assets/images/app-deploy-new-version/jenkins2.PNG +0 -0
  103. package/lib/templates/assets/images/auth-wrapper-code.png +0 -0
  104. package/lib/templates/assets/images/cdebase.png +0 -0
  105. package/lib/templates/assets/images/cdm-locales-directory.png +0 -0
  106. package/lib/templates/assets/images/client-settings.png +0 -0
  107. package/lib/templates/assets/images/codegen_file_update.png +0 -0
  108. package/lib/templates/assets/images/configuration.png +0 -0
  109. package/lib/templates/assets/images/copy-plugin.png +0 -0
  110. package/lib/templates/assets/images/docusaurus.png +0 -0
  111. package/lib/templates/assets/images/error-link.png +0 -0
  112. package/lib/templates/assets/images/error-sample.png +0 -0
  113. package/lib/templates/assets/images/extension copy.png +0 -0
  114. package/lib/templates/assets/images/extension.png +0 -0
  115. package/lib/templates/assets/images/graphql/graphql-folder-backend.png +0 -0
  116. package/lib/templates/assets/images/graphql/graphql-folder-with-gql.png +0 -0
  117. package/lib/templates/assets/images/i18n-config.png +0 -0
  118. package/lib/templates/assets/images/image.png +0 -0
  119. package/lib/templates/assets/images/logo.svg +10 -0
  120. package/lib/templates/assets/images/logo1.svg +1 -0
  121. package/lib/templates/assets/images/modify-upload-false-server.png +0 -0
  122. package/lib/templates/assets/images/navigation-auth-enabled.png +0 -0
  123. package/lib/templates/assets/images/org-dashboard-navigation.png +0 -0
  124. package/lib/templates/assets/images/org-navigation.png +0 -0
  125. package/lib/templates/assets/images/preferences_graphql_type.png +0 -0
  126. package/lib/templates/assets/images/provider.png +0 -0
  127. package/lib/templates/assets/images/route-config.png +0 -0
  128. package/lib/templates/assets/images/service-accounts.png +0 -0
  129. package/lib/templates/assets/images/source-code/source-code-environments.png +0 -0
  130. package/lib/templates/assets/images/source-code/source-code-organization.png +0 -0
  131. package/lib/templates/assets/images/spin-clone-develop-deployment/jenkins-changes.png +0 -0
  132. package/lib/templates/assets/images/spin-clone-develop-deployment/lerna-changes.png +0 -0
  133. package/lib/templates/assets/images/spin-clone-develop-deployment/root-package-json-changes.png +0 -0
  134. package/lib/templates/assets/images/spin-clone-develop-deployment/values-dev-changes.png +0 -0
  135. package/lib/templates/assets/images/sso-mappers.png +0 -0
  136. package/lib/templates/assets/images/sso-picture-mapper.png +0 -0
  137. package/lib/templates/assets/images/sso-settings.png +0 -0
  138. package/lib/templates/assets/images/timesheet_apollo_cache.png +0 -0
  139. package/lib/templates/assets/images/timesheet_query.png +0 -0
  140. package/lib/templates/assets/images/tutorial/docsVersionDropdown.png +0 -0
  141. package/lib/templates/assets/images/tutorial/localeDropdown.png +0 -0
  142. package/lib/templates/assets/images/unauthenticated.png +0 -0
  143. package/lib/templates/assets/images/undraw_docusaurus_mountain.svg +170 -0
  144. package/lib/templates/assets/images/undraw_docusaurus_react.svg +169 -0
  145. package/lib/templates/assets/images/undraw_docusaurus_tree.svg +1 -0
  146. package/lib/templates/assets/images/vite-plugin-config.png +0 -0
  147. package/lib/templates/content/docs/Generators/Project/generate-fullproject.md +12 -0
  148. package/lib/templates/content/docs/LLM/Logger.llm.md +194 -0
  149. package/lib/templates/content/docs/LLM/backend-proxies-services-llm.md +2687 -0
  150. package/lib/templates/content/docs/LLM/backend-service-llm.md +3384 -0
  151. package/lib/templates/content/docs/LLM/db_migration_llm.md +954 -0
  152. package/lib/templates/content/docs/LLM/frontend/REMIX-15.3-upgrade-llm.md +1245 -0
  153. package/lib/templates/content/docs/LLM/inngest/INNGEST_FUNCTION_DEVELOPMENT_GUIDE_LLM.md +1241 -0
  154. package/lib/templates/content/docs/LLM/inngest/INNGEST_NAMESPACE_LLM.md +384 -0
  155. package/lib/templates/content/docs/LLM/llm_workflow_namespace.md +384 -0
  156. package/lib/templates/content/docs/LLM/organization-components-form-llm.md +1395 -0
  157. package/lib/templates/content/docs/LLM/page-component-llm.md +173 -0
  158. package/lib/templates/content/docs/LLM/preferences-settings-llm.md +2781 -0
  159. package/lib/templates/content/docs/LLM/tailwind-css-llm.md +502 -0
  160. package/lib/templates/content/docs/UI/SchemaBasedUI.md +334 -0
  161. package/lib/templates/content/docs/UI/SlotFillComponent.md +334 -0
  162. package/lib/templates/content/docs/adminide-modules/account/auth0-login.md +31 -0
  163. package/lib/templates/content/docs/adminide-modules/account/index.md +14 -0
  164. package/lib/templates/content/docs/adminide-modules/account/keycloak-remix-setup.md +86 -0
  165. package/lib/templates/content/docs/adminide-modules/account/remix-auth-setup.md +79 -0
  166. package/lib/templates/content/docs/adminide-modules/account/various-auth-qatest.md +157 -0
  167. package/lib/templates/content/docs/adminide-modules/api-builders/graphql.md +906 -0
  168. package/lib/templates/content/docs/adminide-modules/billing/payments/index.md +14 -0
  169. package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/index.md +14 -0
  170. package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/settingup-stripe-locally.md +25 -0
  171. package/lib/templates/content/docs/adminide-modules/billing/tier-config.md +293 -0
  172. package/lib/templates/content/docs/adminide-modules/connectors/Connector.md +207 -0
  173. package/lib/templates/content/docs/adminide-modules/file-upload/index.md +16 -0
  174. package/lib/templates/content/docs/adminide-modules/file-upload/setup.md +435 -0
  175. package/lib/templates/content/docs/adminide-modules/file-upload/upload-file-using-signed-url.md +161 -0
  176. package/lib/templates/content/docs/adminide-modules/preferences/AddAdditionalPermissions.md +151 -0
  177. package/lib/templates/content/docs/adminide-modules/preferences/Configuration.md +241 -0
  178. package/lib/templates/content/docs/adminide-modules/preferences/Policy-Configuration.md +61 -0
  179. package/lib/templates/content/docs/adminide-modules/preferences/UI-components/ResourceSettingsLoader.md +319 -0
  180. package/lib/templates/content/docs/adminide-modules/preferences/contribute_scope_target.md +280 -0
  181. package/lib/templates/content/docs/adminide-modules/preferences/generate-urii.md +94 -0
  182. package/lib/templates/content/docs/adminide-modules/preferences/index.md +28 -0
  183. package/lib/templates/content/docs/adminide-modules/preferences/machine-configuration.md +157 -0
  184. package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/generateCdecodeUri.md +1289 -0
  185. package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/migratingFromUseSettings.md +215 -0
  186. package/lib/templates/content/docs/adminide-modules/preferences/permissions/Roles-Permissions.md +72 -0
  187. package/lib/templates/content/docs/adminide-modules/preferences/permissions/settingUserPermissions.md +139 -0
  188. package/lib/templates/content/docs/adminide-modules/preferences/preference-dependency.md +138 -0
  189. package/lib/templates/content/docs/adminide-modules/preferences/route-based-configuration.md +41 -0
  190. package/lib/templates/content/docs/adminide-modules/preferences/schema-configuration.md +71 -0
  191. package/lib/templates/content/docs/adminide-modules/preferences/supported.md +24 -0
  192. package/lib/templates/content/docs/adminide-modules/preferences/useSettingsLoader.md +248 -0
  193. package/lib/templates/content/docs/adminide-modules/project-tools/auth-providers.md +1317 -0
  194. package/lib/templates/content/docs/adminide-modules/project-tools/keycloak-guide.md +543 -0
  195. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-based-authentication.md +846 -0
  196. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-management.md +708 -0
  197. package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenants.md +1117 -0
  198. package/lib/templates/content/docs/chrome-extension/index.md +14 -0
  199. package/lib/templates/content/docs/chrome-extension/setup.md +30 -0
  200. package/lib/templates/content/docs/contributing/adding-package.md +23 -0
  201. package/lib/templates/content/docs/contributing/adding_new_modules.md +99 -0
  202. package/lib/templates/content/docs/contributing/architecture-updates.md +19 -0
  203. package/lib/templates/content/docs/contributing/avoid-using-promises-ui.md +116 -0
  204. package/lib/templates/content/docs/contributing/coding-guidelines.md +111 -0
  205. package/lib/templates/content/docs/contributing/do-and-dont.md +42 -0
  206. package/lib/templates/content/docs/contributing/faq.md +22 -0
  207. package/lib/templates/content/docs/contributing/folder-setup/browser.md +12 -0
  208. package/lib/templates/content/docs/contributing/folder-setup/config.md +12 -0
  209. package/lib/templates/content/docs/contributing/folder-setup/containers-server.md +12 -0
  210. package/lib/templates/content/docs/contributing/folder-setup/core.md +12 -0
  211. package/lib/templates/content/docs/contributing/folder-setup/graphql.md +12 -0
  212. package/lib/templates/content/docs/contributing/folder-setup/index.md +30 -0
  213. package/lib/templates/content/docs/contributing/folder-setup/module.md +12 -0
  214. package/lib/templates/content/docs/contributing/folder-setup/server.md +12 -0
  215. package/lib/templates/content/docs/contributing/folder-setup/services.md +12 -0
  216. package/lib/templates/content/docs/contributing/folder-setup/store.md +12 -0
  217. package/lib/templates/content/docs/contributing/frontend-coding.md +30 -0
  218. package/lib/templates/content/docs/contributing/git-subtree-sharing.md +73 -0
  219. package/lib/templates/content/docs/contributing/graphql-subscriptions.md +69 -0
  220. package/lib/templates/content/docs/contributing/how-to-contribute.md +30 -0
  221. package/lib/templates/content/docs/contributing/how_to_check_pure_esm.md +29 -0
  222. package/lib/templates/content/docs/contributing/index.md +60 -0
  223. package/lib/templates/content/docs/contributing/installation-issues.md +23 -0
  224. package/lib/templates/content/docs/contributing/keyboard-shortcut.md +131 -0
  225. package/lib/templates/content/docs/contributing/language/locale-support.md +12 -0
  226. package/lib/templates/content/docs/contributing/lerna-build-tools.md +516 -0
  227. package/lib/templates/content/docs/contributing/lerna-yarn-workspaces.md +95 -0
  228. package/lib/templates/content/docs/contributing/lint-and-formatter.md +20 -0
  229. package/lib/templates/content/docs/contributing/mobile-setup.md +16 -0
  230. package/lib/templates/content/docs/contributing/project-setup.md +233 -0
  231. package/lib/templates/content/docs/contributing/react/index.md +14 -0
  232. package/lib/templates/content/docs/contributing/react/lazy-component.md +70 -0
  233. package/lib/templates/content/docs/contributing/run-various-options.md +124 -0
  234. package/lib/templates/content/docs/contributing/schema-first-graphql-types.md +37 -0
  235. package/lib/templates/content/docs/contributing/source-code-organization.md +57 -0
  236. package/lib/templates/content/docs/contributing/staging-docker.md +88 -0
  237. package/lib/templates/content/docs/contributing/third-party/apollo-client-v3-tutorials.md +28 -0
  238. package/lib/templates/content/docs/contributing/third-party/index.md +18 -0
  239. package/lib/templates/content/docs/contributing/typescript-contribution.md +16 -0
  240. package/lib/templates/content/docs/devops/app-deploy-new-version.md +30 -0
  241. package/lib/templates/content/docs/devops/index.md +14 -0
  242. package/lib/templates/content/docs/devops/mobile-jenkins-build.md +40 -0
  243. package/lib/templates/content/docs/devops/versioning-the-project.md +128 -0
  244. package/lib/templates/content/docs/error-handler/application-error-handler.md +40 -0
  245. package/lib/templates/content/docs/error-handler/error-handling.md +26 -0
  246. package/lib/templates/content/docs/error-handler/index.md +16 -0
  247. package/lib/templates/content/docs/error-handler/logging-errors.md +14 -0
  248. package/lib/templates/content/docs/feature-api/copy-operation.md +427 -0
  249. package/lib/templates/content/docs/feature-api/feature-browser/assets.md +46 -0
  250. package/lib/templates/content/docs/feature-api/feature-browser/auth-permissions.md +12 -0
  251. package/lib/templates/content/docs/feature-api/feature-browser/feature.md +131 -0
  252. package/lib/templates/content/docs/feature-api/feature-browser/index.md +22 -0
  253. package/lib/templates/content/docs/feature-api/feature-browser/routes-menu.md +110 -0
  254. package/lib/templates/content/docs/feature-api/feature-browser/routing-convention.md +124 -0
  255. package/lib/templates/content/docs/feature-api/feature-browser/routing.md +338 -0
  256. package/lib/templates/content/docs/feature-api/feature-mobile/auth-permissions.md +20 -0
  257. package/lib/templates/content/docs/feature-api/feature-mobile/feature.md +130 -0
  258. package/lib/templates/content/docs/feature-api/feature-mobile/index.md +18 -0
  259. package/lib/templates/content/docs/feature-api/feature-mobile/navigation.md +187 -0
  260. package/lib/templates/content/docs/feature-api/feature-server/Scheduling.md +44 -0
  261. package/lib/templates/content/docs/feature-api/feature-server/dataloader.md +320 -0
  262. package/lib/templates/content/docs/feature-api/feature-server/dependency-injection.md +81 -0
  263. package/lib/templates/content/docs/feature-api/feature-server/feature.md +65 -0
  264. package/lib/templates/content/docs/feature-api/feature-server/generic-dataloader.md +135 -0
  265. package/lib/templates/content/docs/feature-api/feature-server/index.md +40 -0
  266. package/lib/templates/content/docs/feature-api/feature-server/migration.md +127 -0
  267. package/lib/templates/content/docs/feature-api/feature-server/mongo-model.md +72 -0
  268. package/lib/templates/content/docs/feature-api/feature-server/permissions.md +12 -0
  269. package/lib/templates/content/docs/feature-api/feature-server/policies.md +57 -0
  270. package/lib/templates/content/docs/feature-api/feature-server/preferences.md +57 -0
  271. package/lib/templates/content/docs/feature-api/feature-server/repositories.md +114 -0
  272. package/lib/templates/content/docs/feature-api/feature-server/resolvers.md +126 -0
  273. package/lib/templates/content/docs/feature-api/feature-server/rules.md +132 -0
  274. package/lib/templates/content/docs/feature-api/feature-server/schema.md +12 -0
  275. package/lib/templates/content/docs/feature-api/feature-server/services.md +102 -0
  276. package/lib/templates/content/docs/feature-api/feature-server/setup-resource-crud.md +359 -0
  277. package/lib/templates/content/docs/feature-api/index.md +18 -0
  278. package/lib/templates/content/docs/graphql/apolloClient-mutation.md +94 -0
  279. package/lib/templates/content/docs/graphql/index.md +14 -0
  280. package/lib/templates/content/docs/graphql/scalars.md +15 -0
  281. package/lib/templates/content/docs/help/index.md +14 -0
  282. package/lib/templates/content/docs/help/intro.md +16 -0
  283. package/lib/templates/content/docs/intl/ant-design-menu-translation.md +74 -0
  284. package/lib/templates/content/docs/intl/intl-namespace.md +129 -0
  285. package/lib/templates/content/docs/intl/vite-plugin-intl.md +87 -0
  286. package/lib/templates/content/docs/intl/webpack-plugin-intl.md +12 -0
  287. package/lib/templates/content/docs/intro.md +18 -0
  288. package/lib/templates/content/docs/knowledge/basic-fullstack.md +238 -0
  289. package/lib/templates/content/docs/mailing/index.md +14 -0
  290. package/lib/templates/content/docs/mailing/mailing-template.md +148 -0
  291. package/lib/templates/content/docs/mobile/App-navigation-generator.md +410 -0
  292. package/lib/templates/content/docs/mobile/MobileTestCases.md +264 -0
  293. package/lib/templates/content/docs/mobile/eas-profile-build.md +107 -0
  294. package/lib/templates/content/docs/mobile/expo-push-notification-setup.md +216 -0
  295. package/lib/templates/content/docs/mobile/index.md +14 -0
  296. package/lib/templates/content/docs/mobile/routes.md +83 -0
  297. package/lib/templates/content/docs/organization/adding-account-context.md +116 -0
  298. package/lib/templates/content/docs/organization/adding-org-mobile-navigation.md +22 -0
  299. package/lib/templates/content/docs/organization/adding-org-web-navigation.md +12 -0
  300. package/lib/templates/content/docs/organization/index.md +20 -0
  301. package/lib/templates/content/docs/organization/initialization.md +20 -0
  302. package/lib/templates/content/docs/organization/organization-resource-vs-resource.md +112 -0
  303. package/lib/templates/content/docs/remix/configuration/component-structure-best-practices.md +152 -0
  304. package/lib/templates/content/docs/remix/configuration/configurations.md +218 -0
  305. package/lib/templates/content/docs/remix/configuration/css-import-and-stylesheets.md +142 -0
  306. package/lib/templates/content/docs/remix/configuration/dont-subcomponent-network.md +166 -0
  307. package/lib/templates/content/docs/remix/configuration/generated-data-loaders.md +122 -0
  308. package/lib/templates/content/docs/remix/configuration/generated-resource-loaders.md +257 -0
  309. package/lib/templates/content/docs/remix/configuration/query-params-generator.md +216 -0
  310. package/lib/templates/content/docs/remix/configuration/routes-extra-icons.md +103 -0
  311. package/lib/templates/content/docs/remix/configuration/routes-json-advanced.md +86 -0
  312. package/lib/templates/content/docs/remix/configuration/routes-json-auth.md +113 -0
  313. package/lib/templates/content/docs/remix/configuration/routes-json-best-practices.md +55 -0
  314. package/lib/templates/content/docs/remix/configuration/routes-json-fields.md +79 -0
  315. package/lib/templates/content/docs/remix/configuration/routes-json-graphql.md +79 -0
  316. package/lib/templates/content/docs/remix/configuration/routes-json-index.md +112 -0
  317. package/lib/templates/content/docs/remix/configuration/routes-json-loaders.md +165 -0
  318. package/lib/templates/content/docs/remix/configuration/routes-json-middleware.md +196 -0
  319. package/lib/templates/content/docs/remix/configuration/routes-json-overview.md +53 -0
  320. package/lib/templates/content/docs/remix/data-loaders.md +43 -0
  321. package/lib/templates/content/docs/remix/devtools/remix-devtools.md +58 -0
  322. package/lib/templates/content/docs/remix/examples/changes-using-servercode.md +79 -0
  323. package/lib/templates/content/docs/remix/extra-icons.md +62 -0
  324. package/lib/templates/content/docs/remix/extra-links.md +65 -0
  325. package/lib/templates/content/docs/remix/generated-data-loaders.md +114 -0
  326. package/lib/templates/content/docs/remix/queryParamsGenerator.md +89 -0
  327. package/lib/templates/content/docs/remix/resources.md +16 -0
  328. package/lib/templates/content/docs/remix/styles.md +132 -0
  329. package/lib/templates/content/docs/remix/wiki.md +12 -0
  330. package/lib/templates/content/docs/security/auth-wrapper/auth-wrapper.md +24 -0
  331. package/lib/templates/content/docs/security/index.md +18 -0
  332. package/lib/templates/content/docs/security/secure-button-mobilenative.md +88 -0
  333. package/lib/templates/content/docs/security/secure-button-web.md +89 -0
  334. package/lib/templates/content/docs/server-side/account-customization.md +82 -0
  335. package/lib/templates/content/docs/server-side/apollo/caching.md +164 -0
  336. package/lib/templates/content/docs/server-side/backend-architecture/FINAL-DECISION.md +209 -0
  337. package/lib/templates/content/docs/server-side/backend-architecture/TRUE-FINAL-ARCHITECTURE.md +603 -0
  338. package/lib/templates/content/docs/server-side/backend-architecture/index1.md +0 -0
  339. package/lib/templates/content/docs/server-side/backend-coding.md +839 -0
  340. package/lib/templates/content/docs/server-side/e2b/manageing-template.md +197 -0
  341. package/lib/templates/content/docs/server-side/index.md +14 -0
  342. package/lib/templates/content/docs/server-side/inngest-functions-module.md +309 -0
  343. package/lib/templates/content/docs/server-side/listen-stripe-events.md +43 -0
  344. package/lib/templates/content/docs/server-side/slug-service.md +323 -0
  345. package/lib/templates/content/docs/tests/index.md +18 -0
  346. package/lib/templates/content/docs/tests/jest-test-debug-vscode.md +40 -0
  347. package/lib/templates/content/docs/tests/known-errors.md +116 -0
  348. package/lib/templates/content/docs/tests/service-test-template.md +118 -0
  349. package/lib/templates/content/docs/tests/test-setup.md +93 -0
  350. package/lib/templates/content/docs/xstate.md +23 -0
  351. package/lib/types.d.ts +37 -0
  352. package/lib/types.d.ts.map +1 -0
  353. package/lib/utils/docsNavigation.d.ts +9 -0
  354. package/lib/utils/docsNavigation.d.ts.map +1 -0
  355. package/lib/utils/docsNavigation.js +37 -0
  356. package/lib/utils/docsNavigation.js.map +1 -0
  357. package/lib/utils/helpCenterUtils.d.ts +26 -0
  358. package/lib/utils/helpCenterUtils.d.ts.map +1 -0
  359. package/lib/utils/index.d.ts +3 -0
  360. package/lib/utils/index.d.ts.map +1 -0
  361. package/lib/utils/index.js +3 -0
  362. package/lib/utils/index.js.map +1 -0
  363. package/lib/utils/markdownLoader.d.ts +36 -0
  364. package/lib/utils/markdownLoader.d.ts.map +1 -0
  365. package/lib/utils/markdownLoader.js +2242 -0
  366. package/lib/utils/markdownLoader.js.map +1 -0
  367. package/package.json +71 -0
@@ -0,0 +1,2687 @@
1
+ # LLM Proxy Service Generator Prompt
2
+
3
+ ## Quick Start Prompt
4
+
5
+ Copy and paste this prompt to an LLM to generate a new proxy service:
6
+
7
+ ---
8
+
9
+ ## 🤖 PROMPT START
10
+
11
+ I need you to create a Proxy Service AND Moleculer Service for the AdminIDE Stack following the **modern auto-generation pattern**.
12
+
13
+ ### 🎯 Recommended Approach Summary
14
+
15
+ **ALWAYS use auto-generation for both Moleculer services and Proxy services (Pattern 1):**
16
+
17
+ 1. **Moleculer Service**: Use `Moleculer.generateActionsAndEvents<IService>(service)`
18
+ - 30 lines instead of 200+
19
+ - Auto-detects all methods including parent class methods
20
+ - Auto-registers event handlers from decorators
21
+ - **Auto-derive topic** from `ServiceSchemas.topic` - no enum imports needed!
22
+ - **No configuration needed** - just one line to generate everything
23
+
24
+ 2. **Proxy Service**: Use `generateProxyMethods<IService>(this, ServiceSchemas, broker, logger)`
25
+ - 40 lines instead of 120+
26
+ - Auto-generates all proxy methods
27
+ - Correct parameter ordering guaranteed
28
+ - **No manual `topic` property needed** - extracted automatically from `ServiceSchemas.topic`
29
+
30
+ **Benefits**:
31
+
32
+ - ✅ 90% less code
33
+ - ✅ Zero boilerplate - no configuration needed
34
+ - ✅ Type-safe with full TypeScript inference
35
+ - ✅ Maintainable - add method once, available everywhere
36
+ - ✅ No manual synchronization needed
37
+ - ✅ **Zero dependencies** - topic auto-derived from class name, no enums needed
38
+
39
+ **When to use optional configurations (Patterns 2-4):**
40
+
41
+ - Pattern 2: Custom validation - RARE (~5% of cases)
42
+ - Pattern 3: Manual overrides - VERY RARE (~1% of cases)
43
+ - Pattern 4: Whitelist methods - RARE (~2% of cases)
44
+
45
+ **For 99% of services, use Pattern 1 with zero configuration!**
46
+
47
+ **Topic Convention (Auto-Generated & Minification-Safe)**:
48
+ The topic is **automatically generated** in the service schemas and derived from the service interface name:
49
+
50
+ ```typescript
51
+ // Auto-generated in service-schemas.ts (from IProjectService interface)
52
+ export const ProjectServiceSchemas = {
53
+ /** Moleculer service topic/name - safe for minification */
54
+ topic: 'ProjectService' as const,
55
+ // ... method schemas
56
+ };
57
+
58
+ // In moleculer service - extract topic from schemas
59
+ import { ProjectServiceSchemas } from 'common/server';
60
+ const { topic } = ProjectServiceSchemas; // "ProjectService"
61
+
62
+ // In proxy service - topic is automatically extracted by generateProxyMethods()
63
+ // No manual topic property needed!
64
+ ```
65
+
66
+ **Benefits**:
67
+
68
+ - ✅ **Zero manual configuration** - topic auto-derived from interface name (e.g., `IProjectService` → `ProjectService`)
69
+ - ✅ **Minification-safe** - stored as string constant in generated schemas
70
+ - ✅ **Single source of truth** - schemas object contains both topic and validation
71
+ - ✅ **No enum imports needed** - eliminates `MoleculerTopics` or `MoleculerServiceName` dependencies
72
+ - ✅ **Type-safe** - `as const` provides literal type inference
73
+
74
+ ### Context
75
+
76
+ This codebase uses a microservice architecture with Moleculer message broker. The architecture consists of THREE key components:
77
+
78
+ 1. **Service Interface**: Defines the contract (methods and types)
79
+ 2. **Actual Service Implementation**: Contains business logic
80
+ 3. **Moleculer Service**: Registers actions that delegate to the actual service
81
+ 4. **Proxy Service**: Used by clients to call methods via Moleculer broker
82
+
83
+ **Important**: When creating services, you must create BOTH the Moleculer service AND the proxy service. They work together:
84
+
85
+ **Important**: When creating services, you must create BOTH the Moleculer service AND the proxy service. They work together:
86
+
87
+ - **Moleculer Service**: Lives on the server with business logic, exposes actions
88
+ - **Proxy Service**: Lives on clients, calls Moleculer actions via broker
89
+
90
+ ### Files to Reference
91
+
92
+ 1. **Service Interface**: `packages/common/src/services/[ServiceName].ts`
93
+ - Contains the interface definition with all methods
94
+
95
+ 2. **Actual Service**: `packages-modules/[module-name]/server/src/services/[ServiceName].ts`
96
+ - Contains the actual implementation (for understanding method signatures)
97
+
98
+ 3. **Example Moleculer Services**:
99
+ - **Account Service**: `packages-modules/account-api/server/src/plugins/AccountMoleculerService.ts` (40+ actions)
100
+ - **Project Service**: `packages-modules/account-api/server/src/modules/project/plugins/ProjectMoleculerService.ts` (10+ actions)
101
+
102
+ 4. **Example Proxy Services** (choose based on complexity):
103
+ - Simple: `packages-modules/account-api/core/src/servers/services/ProjectProxyService.ts`
104
+ - Medium: `packages-modules/account-api/core/src/servers/services/TeamMicroservice.ts`
105
+ - Complex: `packages-modules/account-api/core/src/servers/services/AccountProxyService.ts` (40+ methods)
106
+
107
+ 5. **GraphQL Schema**: `packages-modules/[module-name]/server/src/graphql/schema/service.graphql`
108
+ - Contains service action enums
109
+
110
+ ### Task 0: Service Schema Generation (Automatic)
111
+
112
+ **AUTO-GENERATED**: Service schemas with topics are automatically generated by running `yarn generateGraphql`.
113
+
114
+ The schema generator (`@common-stack/server-core/lib/moleculer-generation/generateAllServiceSchemas.cjs`) automatically:
115
+
116
+ - Scans all service interfaces (e.g., `IProjectService`)
117
+ - Generates Zod validation schemas for each method
118
+ - Auto-derives topic from interface name: `IProjectService` → `ProjectService`
119
+ - Outputs to `packages/common/src/generated/service-schemas.ts`
120
+
121
+ ```typescript
122
+ // Auto-generated in service-schemas.ts
123
+ export const ProjectServiceSchemas = {
124
+ /** Moleculer service topic/name - safe for minification */
125
+ topic: 'ProjectService' as const,
126
+ createProject: z.object({
127
+ /* ... */
128
+ }),
129
+ getProject: z.object({
130
+ /* ... */
131
+ }),
132
+ // ... all other methods
133
+ };
134
+ ```
135
+
136
+ **Benefits of auto-generation**:
137
+
138
+ - ✅ **Zero manual work**: Topic and schemas generated from TypeScript interfaces
139
+ - ✅ **Minification-safe**: Topic stored as string constant
140
+ - ✅ **Type-safe**: Full TypeScript inference with `as const`
141
+ - ✅ **Always in sync**: Regenerate after interface changes with `yarn generateGraphql`
142
+ - ✅ **Single source of truth**: Interface defines everything (methods, params, topic)
143
+
144
+ ### Task 1: Update GraphQL Schema
145
+
146
+ Add all missing actions to the `[ServiceName]ServiceAction` enum in `service.graphql`:
147
+
148
+ ```graphql
149
+ enum [ServiceName]ServiceAction {
150
+ # Read operations (get*, find*, search*, etc.)
151
+ getItem
152
+ findItems
153
+
154
+ # Create operations (create*, add*, generate*, etc.)
155
+ createItem
156
+ addItem
157
+
158
+ # Update operations (update*, modify*, change*, set*, etc.)
159
+ updateItem
160
+ changeStatus
161
+
162
+ # Delete operations (delete*, remove*, archive*, etc.)
163
+ deleteItem
164
+ removeItem
165
+
166
+ # Event handlers (on* methods) - MUST start with 'on' prefix
167
+ onItemCreated
168
+ onItemDeleted
169
+ onItemUpdated
170
+ onUserRemoved
171
+ }
172
+ ```
173
+
174
+ **Rules for enum values**:
175
+
176
+ - Use camelCase (first letter lowercase)
177
+ - Match method names from the interface
178
+ - Group by operation type
179
+ - Include all interface methods except lifecycle methods like `dispose()`
180
+ - **Event handlers MUST use `on` prefix** (e.g., `onAccountDeleted`, `onPropertyCreated`)
181
+ - Event names should match the pattern: `OnEventName` → `onEventName`
182
+
183
+ ### Task 2: Create Moleculer Service
184
+
185
+ **CRITICAL**: The Moleculer service must be created FIRST. This is where the actual work happens.
186
+
187
+ **STRICT FILE NAMING CONVENTION:**
188
+
189
+ ✅ **CORRECT**: Use PascalCase matching the class name
190
+
191
+ - File: `AccountMoleculerService.ts` → Class: `AccountMoleculerService`
192
+ - File: `ProjectMoleculerService.ts` → Class: `ProjectMoleculerService`
193
+ - File: `TeamMoleculerService.ts` → Class: `TeamMoleculerService`
194
+
195
+ ❌ **WRONG**: Do NOT use kebab-case or snake-case
196
+
197
+ - ❌ `accounts-moleculer-service.ts` (kebab-case)
198
+ - ❌ `account-moleculer-service.ts` (kebab-case)
199
+ - ❌ `accounts_moleculer_service.ts` (snake-case)
200
+
201
+ **File Location Patterns:**
202
+
203
+ Pattern 1 (Main module):
204
+ `packages-modules/[module-name]/server/src/plugins/[ServiceName]MoleculerService.ts`
205
+
206
+ Examples:
207
+
208
+ - `packages-modules/account-api/server/src/plugins/AccountMoleculerService.ts`
209
+ - `packages-modules/billing-api/server/src/plugins/InvoiceMoleculerService.ts`
210
+
211
+ Pattern 2 (Sub-module):
212
+ `packages-modules/[module-name]/server/src/modules/[service]/plugins/[ServiceName]MoleculerService.ts`
213
+
214
+ Examples:
215
+
216
+ - `packages-modules/account-api/server/src/modules/project/plugins/ProjectMoleculerService.ts`
217
+ - `packages-modules/account-api/server/src/modules/team/plugins/TeamMoleculerService.ts`
218
+
219
+ **Naming Rules:**
220
+
221
+ 1. ✅ File name MUST match class name exactly
222
+ 2. ✅ Use PascalCase (first letter uppercase)
223
+ 3. ✅ Always end with `MoleculerService.ts`
224
+ 4. ✅ Service name comes first: `[ServiceName]MoleculerService`
225
+ 5. ❌ Never use kebab-case (dashes)
226
+ 6. ❌ Never use snake-case (underscores)
227
+ 7. ❌ Never use plural form (e.g., `AccountsMoleculerService` is wrong)
228
+
229
+ ---
230
+
231
+ ## 🎯 RECOMMENDED APPROACH: Auto-Generation
232
+
233
+ **Use `Moleculer.generateActionsAndEvents()` from common package** - eliminates 90% of boilerplate code!
234
+
235
+ **Quick Example:**
236
+
237
+ ```typescript
238
+ import { Service, ServiceBroker } from 'moleculer';
239
+ import { Container } from 'inversify';
240
+ import { I[ServiceName]Service, [ServiceName]ServiceSchemas, SERVER_TYPES } from 'common/server';
241
+ import { Moleculer, zodSchemasToMoleculer } from '@common-stack/codegen-zod';
242
+
243
+ export class [ServiceName]MoleculerService extends Service {
244
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
245
+ super(broker);
246
+ // Get topic from auto-generated schemas
247
+ const { topic } = [ServiceName]ServiceSchemas;
248
+ const service = container.get<I[ServiceName]Service>(SERVER_TYPES.[ServiceName]Service);
249
+
250
+ // Convert Zod schemas to Moleculer param validation
251
+ const paramOverrides = zodSchemasToMoleculer([ServiceName]ServiceSchemas);
252
+
253
+ // ⚡ Auto-generate actions and events with validation
254
+ const { actions, events } = Moleculer.generateActionsAndEvents<I[ServiceName]Service>(service, {
255
+ paramOverrides,
256
+ });
257
+
258
+ this.parseServiceSchema({
259
+ name: topic, // ✅ Auto-derived from interface name
260
+ actions, // ✅ All methods (including parent class) with validation
261
+ events, // ✅ All @Moleculer.EventHandler decorators
262
+ });
263
+ }
264
+ }
265
+ ```
266
+
267
+ **That's it! 30 lines instead of 200+**
268
+
269
+ ### 📊 Auto-Generation vs Manual Comparison
270
+
271
+ | Feature | Auto-Generation | Manual |
272
+ | ------------------------ | --------------------------------- | ------------------------- |
273
+ | **Code Size** | ~30 lines | ~200+ lines |
274
+ | **Parent Class Methods** | ✅ Automatic | ❌ Must copy each one |
275
+ | **Event Handlers** | ✅ Auto-detected from decorators | ❌ Must define each one |
276
+ | **Type Safety** | ✅ Full TypeScript inference | ⚠️ Manual typing required |
277
+ | **Maintenance** | ✅ Add method → auto-available | ❌ Must update 3 places |
278
+ | **Parameter Validation** | ✅ Auto-generated from TypeScript | ✅ Explicit schemas |
279
+ | **Custom Logic** | ⚠️ Requires Pattern 3 override | ✅ Full control |
280
+ | **Best For** | **ALL services (99% of cases)** | Complex custom validation |
281
+
282
+ **Recommendation**: **USE PATTERN 1 FOR ALL NEW SERVICES**. Add manual overrides (Pattern 2/3) only in rare cases where you need custom validation or logic.
283
+
284
+ For detailed patterns, see sections below ⬇️
285
+
286
+ ---
287
+
288
+ ### ⚡ Auto-Generation from Common Package
289
+
290
+ **IMPORTANT**: The common package (`packages/common/src/utils/typed-moleculer-service.ts`) provides powerful utilities to auto-generate actions and events from service classes.
291
+
292
+ #### Primary Function (Use This):
293
+
294
+ **`Moleculer.generateActionsAndEvents<TService>(service, config?)`**
295
+
296
+ - Generates BOTH actions AND events from a single service instance
297
+ - Actions: Generated from regular service methods
298
+ - Events: Generated from methods decorated with `@Moleculer.EventHandler()`
299
+ - Automatically excludes event handler methods from actions
300
+ - **USE THIS FOR ALL SERVICES** (with or without event handlers)
301
+
302
+ #### Alternative Function (Rarely Needed):
303
+
304
+ **`Moleculer.generateAutoInferredActions<TService>(service, config?)`**
305
+
306
+ - Automatically generates Moleculer actions from ALL service methods
307
+ - Infers parameters from TypeScript function signatures
308
+ - Traverses entire prototype chain to include inherited methods from parent classes
309
+ - Excludes lifecycle methods (dispose) and base CRUD methods by default
310
+ - Use this ONLY if you don't have event handlers and want slightly different behavior
311
+
312
+ #### Auto-Generation Configuration (All Optional):
313
+
314
+ ```typescript
315
+ type AutoInferredActionConfig<TService> = {
316
+ // Override param schemas for specific methods (OPTIONAL - Pattern 2)
317
+ paramOverrides?: Partial<{
318
+ [K in ServiceMethods<TService>]: Record<string, unknown>;
319
+ }>;
320
+
321
+ // Only include specific methods - whitelist (OPTIONAL - Pattern 4)
322
+ include?: Array<ServiceMethods<TService>>;
323
+
324
+ // Exclude specific methods - blacklist (OPTIONAL - Pattern 3)
325
+ exclude?: Array<ServiceMethods<TService>>;
326
+
327
+ // Map action names to different method names (OPTIONAL - Advanced)
328
+ actionToMethodMap?: Record<string, string>;
329
+
330
+ // Add custom Moleculer action properties (cache, visibility, etc.)
331
+ actionConfig?: Partial<{
332
+ [K in ServiceMethods<TService>]: {
333
+ cache?: boolean | object;
334
+ visibility?: 'public' | 'protected' | 'private';
335
+ [key: string]: unknown;
336
+ };
337
+ }>;
338
+ };
339
+ ```
340
+
341
+ #### Usage Patterns:
342
+
343
+ **Pattern 1: Full Auto-Generation (USE THIS IN ALL CASES)**
344
+
345
+ ```typescript
346
+ import { Moleculer } from '@common-stack/codegen-zod';
347
+
348
+ export class [ServiceName]MoleculerService extends Service {
349
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
350
+ super(broker);
351
+ const [serviceName]Service = container.get<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service);
352
+
353
+ const { topic } = [ServiceName]ServiceSchemas;
354
+
355
+ // Auto-generate ALL actions and events
356
+ const { actions, events } = Moleculer.generateActionsAndEvents<I[ServiceName]Service>(
357
+ [serviceName]Service
358
+ );
359
+
360
+ this.parseServiceSchema({
361
+ name: topic,
362
+ actions, // All service methods auto-generated
363
+ events, // All @Moleculer.EventHandler methods auto-generated
364
+ });
365
+ }
366
+ }
367
+ ```
368
+
369
+ **Benefits:**
370
+
371
+ - ✅ Simplest implementation - zero configuration needed
372
+ - ✅ All methods automatically included (including parent class methods)
373
+ - ✅ Event handlers automatically detected from `@Moleculer.EventHandler` decorators
374
+ - ✅ Zero maintenance - add method to interface, it's automatically available
375
+ - ✅ Type-safe with full TypeScript inference
376
+
377
+ **When to use:** Use this pattern for **ALL new services** unless you have specific validation requirements (see Pattern 2 below).
378
+
379
+ ---
380
+
381
+ **Pattern 2: Auto-Generation with Custom Validation (OPTIONAL - Only for Special Cases)**
382
+
383
+ Use this pattern ONLY when you need custom Moleculer validation schemas that differ from the auto-generated ones.
384
+
385
+ ```typescript
386
+ export class [ServiceName]MoleculerService extends Service {
387
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
388
+ super(broker);
389
+ const [serviceName]Service = container.get<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service);
390
+
391
+ const { topic } = [ServiceName]ServiceSchemas;
392
+
393
+ // Auto-generate with custom validation overrides
394
+ const { actions, events } = Moleculer.generateActionsAndEvents<I[ServiceName]Service>(
395
+ [serviceName]Service,
396
+ {
397
+ // Override param schemas for specific methods
398
+ paramOverrides: {
399
+ findById: { id: 'string' }, // Add Moleculer validation
400
+ updateItem: { id: 'string', input: 'object' },
401
+ }
402
+ }
403
+ );
404
+
405
+ this.parseServiceSchema({
406
+ name: topic,
407
+ actions,
408
+ events,
409
+ });
410
+ }
411
+ }
412
+ ```
413
+
414
+ **When to use:** Only when you need:
415
+
416
+ - Custom Moleculer validation rules (min, max, positive, etc.)
417
+ - Different validation than TypeScript types provide
418
+ - Backward compatibility with existing validation
419
+
420
+ ---
421
+
422
+ **Pattern 3: Partial Auto-Generation with Manual Overrides (ADVANCED - Rarely Needed)**
423
+
424
+ Use this pattern ONLY when you need complete control over specific actions with custom logic.
425
+
426
+ ```typescript
427
+ export class [ServiceName]MoleculerService extends Service {
428
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
429
+ super(broker);
430
+ const [serviceName]Service = container.get<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service);
431
+
432
+ const { topic } = [ServiceName]ServiceSchemas;
433
+
434
+ // Auto-generate with exclusions for manual override
435
+ const { actions, events } = Moleculer.generateActionsAndEvents<I[ServiceName]Service>(
436
+ [serviceName]Service,
437
+ {
438
+ // Exclude methods that need custom handling
439
+ exclude: ['complexMethod', 'customLogicMethod'],
440
+ }
441
+ );
442
+
443
+ this.parseServiceSchema({
444
+ name: topic,
445
+ actions: {
446
+ ...actions, // All auto-generated actions
447
+
448
+ // Manual overrides for excluded methods
449
+ [[ServiceName]ServiceAction.ComplexMethod]: {
450
+ params: zodSchemasToMoleculer([ServiceName]ServiceSchemas.complexMethod),
451
+ handler: async (ctx: Context<ComplexParams>) => {
452
+ // Custom pre-processing logic
453
+ const processed = await this.preProcess(ctx.params);
454
+
455
+ // Call service method
456
+ const result = await [serviceName]Service.complexMethod(processed);
457
+
458
+ // Custom post-processing
459
+ return this.postProcess(result);
460
+ },
461
+ },
462
+ },
463
+ events,
464
+ });
465
+ }
466
+ }
467
+ ```
468
+
469
+ **When to use:** Only when you need:
470
+
471
+ - Custom pre/post-processing logic in action handlers
472
+ - Different parameter transformation before calling service
473
+ - Special error handling or caching logic
474
+ - **In 99% of cases, Pattern 1 is sufficient**
475
+
476
+ ---
477
+
478
+ **Pattern 4: Include Only Specific Methods (OPTIONAL - For Whitelisting)**
479
+
480
+ Use this ONLY when you want to expose a limited subset of service methods as Moleculer actions.
481
+
482
+ ```typescript
483
+ const { actions, events } = Moleculer.generateActionsAndEvents<I[ServiceName]Service>(
484
+ [serviceName]Service,
485
+ {
486
+ include: ['findById', 'createItem', 'updateItem'], // Only these methods
487
+ }
488
+ );
489
+ ```
490
+
491
+ **When to use:** Only when you need:
492
+
493
+ - Expose only specific methods via Moleculer (security/API design)
494
+ - Create a limited public API from a larger service interface
495
+ - **In 99% of cases, Pattern 1 is sufficient**
496
+
497
+ ---
498
+
499
+ #### Key Benefits of Auto-Generation:
500
+
501
+ ✅ **Automatic inheritance**: Parent class methods automatically included
502
+ ✅ **Type-safe**: Full TypeScript support with generics
503
+ ✅ **Event integration**: Seamlessly handles `@Moleculer.EventHandler` decorators
504
+ ✅ **Zero boilerplate**: No repetitive handler code
505
+ ✅ **Compile-time safety**: TypeScript catches method changes
506
+ ✅ **Flexible**: Override specific methods when needed
507
+
508
+ #### 🔍 How Prototype Chain Traversal Works:
509
+
510
+ The auto-generation uses `getAllMethodNames()` helper that traverses the ENTIRE prototype chain:
511
+
512
+ ```typescript
513
+ function getAllMethodNames(obj: unknown): string[] {
514
+ const methods = new Set<string>();
515
+ let current = obj;
516
+
517
+ // Traverse up the prototype chain
518
+ while (current && current !== Object.prototype) {
519
+ const prototype = Object.getPrototypeOf(current);
520
+ if (prototype && prototype !== Object.prototype) {
521
+ Object.getOwnPropertyNames(prototype).forEach((name) => {
522
+ // Only add functions, not constructors or private methods
523
+ if (name !== 'constructor' && !name.startsWith('_')) {
524
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
525
+ if (descriptor && typeof descriptor.value === 'function') {
526
+ methods.add(name);
527
+ }
528
+ }
529
+ });
530
+ }
531
+ current = prototype;
532
+ }
533
+
534
+ return Array.from(methods);
535
+ }
536
+ ```
537
+
538
+ **Why This Matters:**
539
+
540
+ - **Problem**: `Object.getOwnPropertyNames(Object.getPrototypeOf(service))` only gets immediate class methods
541
+ - **Solution**: `getAllMethodNames()` traverses entire chain to include parent class methods
542
+ - **Example**: `OrganizationService extends BaseOrganizationService`
543
+ - Without traversal: Only ~5 methods from OrganizationService
544
+ - With traversal: All 60+ methods from both classes
545
+ - Result: All inherited CRUD operations automatically available as Moleculer actions
546
+
547
+ **Real-World Impact:**
548
+
549
+ ```typescript
550
+ // Before (missing parent methods):
551
+ OrganizationMoleculerService actions: [
552
+ 'createOrganization', // ✅ From OrganizationService
553
+ 'updateOrganization', // ✅ From OrganizationService
554
+ // ❌ Missing 50+ methods from BaseOrganizationService
555
+ ]
556
+
557
+ // After (with prototype chain traversal):
558
+ OrganizationMoleculerService actions: [
559
+ 'createOrganization', // ✅ From OrganizationService
560
+ 'updateOrganization', // ✅ From OrganizationService
561
+ 'findById', // ✅ From BaseOrganizationService
562
+ 'findAll', // ✅ From BaseOrganizationService
563
+ 'updateStatus', // ✅ From BaseOrganizationService
564
+ // ... 50+ more methods from parent classes
565
+ ]
566
+ ```
567
+
568
+ #### When to Use Each Pattern:
569
+
570
+ **Pattern 1 (Full Auto-Generation) - DEFAULT CHOICE:**
571
+
572
+ ✅ **Use for ALL new services (99% of cases)**
573
+
574
+ - Service has any number of methods (small or large)
575
+ - Standard CRUD operations
576
+ - Event handlers using `@Moleculer.EventHandler` decorator
577
+ - Automatic parent class method inclusion
578
+ - No special validation requirements
579
+
580
+ **Pattern 2 (Custom Validation) - RARE:**
581
+
582
+ ⚠️ **Use ONLY when:**
583
+
584
+ - Need Moleculer-specific validation (min, max, positive, etc.) that differs from TypeScript types
585
+ - Backward compatibility with existing validation rules
586
+ - **Estimate: ~5% of services need this**
587
+
588
+ **Pattern 3 (Manual Overrides) - VERY RARE:**
589
+
590
+ ⚠️ **Use ONLY when:**
591
+
592
+ - Need custom logic before/after service calls (pre/post-processing)
593
+ - Parameters need transformation before passing to service
594
+ - Special error handling or caching logic
595
+ - **Estimate: ~1% of services need this**
596
+
597
+ **Pattern 4 (Whitelist) - RARE:**
598
+
599
+ ⚠️ **Use ONLY when:**
600
+
601
+ - Need to expose limited subset of methods (API security/design)
602
+ - **Estimate: ~2% of services need this**
603
+
604
+ **Manual Implementation - LEGACY:**
605
+
606
+ ❌ **Avoid - use Pattern 1 instead**
607
+
608
+ - Only for backward compatibility with existing services
609
+ - Will be migrated to auto-generation over time
610
+
611
+ ---
612
+
613
+ #### 📡 Event Handler Pattern with Decorators:
614
+
615
+ **Modern Approach**: Use `@Moleculer.EventHandler()` decorator in service classes:
616
+
617
+ **CRITICAL NAMING CONVENTION**: Event handler methods MUST be prefixed with `on` (e.g., `onUserCreated`, `onAccountDeleted`, `onPropertyUpdated`).
618
+
619
+ ```typescript
620
+ import { Moleculer } from '@common-stack/codegen-zod';
621
+
622
+ @injectable()
623
+ export class TeamService extends BaseTeamService {
624
+ // Event handler for cross-service notifications
625
+ // ✅ CORRECT: Method name starts with 'on'
626
+ @Moleculer.EventHandler(OrganizationServiceAction.OnOrgMemberRemoved)
627
+ async onOrgMemberRemoved(event: { orgName: string; userId: string }): Promise<void> {
628
+ await this.changeTeamMemberStatus(event.userId, TeamMemberStatus.Deactivated);
629
+ }
630
+
631
+ // Event handler for cleanup on deletion
632
+ // ✅ CORRECT: Method name starts with 'on'
633
+ @Moleculer.EventHandler(AccountServiceAction.OnAccountDeleted)
634
+ async onAccountDeleted(event: { userId: string }): Promise<void> {
635
+ await this.removeMemberFromTeams(event.userId);
636
+ }
637
+
638
+ // ❌ WRONG: Missing 'on' prefix
639
+ // @Moleculer.EventHandler(AccountServiceAction.OnAccountDeleted)
640
+ // async handleAccountDeleted(event: { userId: string }): Promise<void> { }
641
+ }
642
+ ```
643
+
644
+ **Event Handler Naming Rules:**
645
+
646
+ 1. ✅ **MUST start with `on` prefix** - Makes it clear these are event handlers
647
+ 2. ✅ Use camelCase after the prefix (e.g., `onUserCreated`, not `onusercreated`)
648
+ 3. ✅ Match the event name structure: `OnEventName` → `onEventName`
649
+ 4. ❌ Never use other prefixes (handle, process, react, etc.)
650
+ 5. ❌ Never use snake_case or kebab-case
651
+
652
+ **Examples:**
653
+
654
+ ```typescript
655
+ // Event: AccountServiceAction.OnAccountDeleted
656
+ // ✅ Handler: onAccountDeleted
657
+ @Moleculer.EventHandler(AccountServiceAction.OnAccountDeleted)
658
+ async onAccountDeleted(event: { userId: string }): Promise<void> { }
659
+
660
+ // Event: PropertyMoleculerServiceEvent.OnPropertyCreated
661
+ // ✅ Handler: onPropertyCreated
662
+ @Moleculer.EventHandler(PropertyMoleculerServiceEvent.OnPropertyCreated)
663
+ async onPropertyCreated(property: IProperty): Promise<void> { }
664
+
665
+ // Event: OrganizationServiceAction.OnOrgMemberRemoved
666
+ // ✅ Handler: onOrgMemberRemoved
667
+ @Moleculer.EventHandler(OrganizationServiceAction.OnOrgMemberRemoved)
668
+ async onOrgMemberRemoved(event: { orgName: string; userId: string }): Promise<void> { }
669
+ ```
670
+
671
+ **Auto-Generation Handles:**
672
+
673
+ 1. Detects all `@Moleculer.EventHandler` decorated methods
674
+ 2. Excludes them from actions (they're not callable actions)
675
+ 3. Generates event handlers in Moleculer schema
676
+ 4. Sets up proper event routing and payload handling
677
+
678
+ **Event Handler Metadata:**
679
+
680
+ ```typescript
681
+ // Decorator stores metadata:
682
+ {
683
+ eventName: 'OrganizationServiceAction.OnOrgMemberRemoved',
684
+ methodName: 'onOrgMemberRemoved',
685
+ group?: 'team-service' // Optional event group for load balancing
686
+ }
687
+ ```
688
+
689
+ **What Auto-Generation Does with Event Handlers:**
690
+
691
+ 1. **Detects** all methods decorated with `@Moleculer.EventHandler`
692
+ 2. **Excludes** them from actions list (they're not callable actions, they react to events)
693
+ 3. **Generates** proper Moleculer event handlers in the service schema
694
+ 4. **Validates** that method name starts with `on` prefix (convention enforcement)
695
+ 5. **Sets up** proper event routing and payload handling
696
+
697
+ **Important: Event Handlers vs Regular Methods:**
698
+
699
+ ```typescript
700
+ @injectable()
701
+ export class PropertyService extends BaseService {
702
+ // ✅ Regular method → becomes Moleculer ACTION (can be called directly)
703
+ async updateProperty(id: string, data: any): Promise<IProperty> {
704
+ // Business logic
705
+ return updatedProperty;
706
+ }
707
+
708
+ // ✅ Event handler → becomes Moleculer EVENT HANDLER (reacts to broadcasts)
709
+ // NOT exposed as an action - cannot be called directly
710
+ @Moleculer.EventHandler(AccountServiceAction.OnAccountDeleted)
711
+ async onAccountDeleted(event: { userId: string }): Promise<void> {
712
+ // React to event - find and deactivate user's properties
713
+ await this.updateStatus({ user: event.userId }, PropertyStatusMachineState.Deactivated);
714
+ }
715
+ }
716
+ ```
717
+
718
+ **Event Flow Pattern:**
719
+
720
+ ```
721
+ Service A (creates entity)
722
+
723
+ Direct service call: teamService.createTeam()
724
+
725
+ Broadcast notification: broker.broadcast(OnCreateTeam, { team })
726
+
727
+ Service B (reacts to event)
728
+
729
+ @Moleculer.EventHandler(OnCreateTeam)
730
+ async onCreateTeam(event: { team: ITeam }): Promise<void>
731
+ ```
732
+
733
+ **Important Rules:**
734
+
735
+ - ✅ Broadcasts send result objects (created entity)
736
+ - ✅ Event handlers perform side effects only (logging, notifications, cleanup)
737
+ - ❌ Event handlers should NOT recreate entities (causes duplicates)
738
+ - ✅ Cross-service events use namespace prefixes (OrganizationServiceAction, AccountServiceAction)
739
+
740
+ **Template Structure (Manual - Use when auto-generation doesn't fit):**
741
+
742
+ ```typescript
743
+ import { Context, Service, ServiceBroker } from 'moleculer';
744
+ import { Container } from 'inversify';
745
+ import {
746
+ [ServiceName]ServiceAction,
747
+ MoleculerServiceName,
748
+ I[ServiceName]Service,
749
+ SERVER_TYPES,
750
+ // Import all required types for method parameters
751
+ } from 'common/server';
752
+
753
+ /**
754
+ * Type utility to verify that all I[ServiceName]Service methods have corresponding Moleculer actions.
755
+ * This ensures compile-time checking when the service interface changes.
756
+ *
757
+ * Excluded methods:
758
+ * - dispose: Lifecycle method, not proxied
759
+ * - get/getAll/count/etc: BaseService CRUD methods
760
+ * - bulkDelete/delete: Not supported in proxy services
761
+ */
762
+ type ServiceMethodsToActions<T> = {
763
+ // eslint-disable-next-line @typescript-eslint/ban-types
764
+ [K in keyof T as T[K] extends Function
765
+ ? K extends
766
+ | 'dispose'
767
+ | 'get'
768
+ | 'getAll'
769
+ | 'bulkDelete'
770
+ | 'delete'
771
+ | 'count'
772
+ | 'getByName'
773
+ | 'getByIds'
774
+ | 'getAllWithCount'
775
+ | 'create'
776
+ | 'update'
777
+ | 'bulkCreate'
778
+ | 'insert'
779
+ ? never
780
+ : K
781
+ : never]: K;
782
+ };
783
+
784
+ // This type will show a compile error if any method is missing from the actions
785
+ type Required[ServiceName]Actions = ServiceMethodsToActions<I[ServiceName]Service>;
786
+
787
+ // Compile-time verification helper - causes error if methods don't match actions
788
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
789
+ const _typeCheck: Record<keyof Required[ServiceName]Actions, boolean> = {
790
+ methodName1: true,
791
+ methodName2: true,
792
+ // ... list ALL service methods here (except excluded ones)
793
+ // TypeScript will error if you miss any or add extra ones
794
+ };
795
+
796
+ /**
797
+ * Moleculer Service for [ServiceName] operations.
798
+ * Registers actions that delegate to the actual [ServiceName]Service implementation.
799
+ *
800
+ * This service runs on the server side and handles incoming Moleculer action calls.
801
+ * Each action validates parameters and calls the corresponding service method.
802
+ *
803
+ * @see [ServiceName]Service for business logic implementation
804
+ * @see [ServiceName]ProxyService for client-side proxy
805
+ */
806
+ export class [ServiceName]MoleculerService extends Service {
807
+ constructor(broker: ServiceBroker, { container }: { container: Container; settings?: unknown }) {
808
+ super(broker);
809
+ const topic = MoleculerServiceName.[ServiceName];
810
+ const [serviceName]Service = container.get<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service);
811
+
812
+ this.parseServiceSchema({
813
+ name: topic,
814
+
815
+ // ============================================================================
816
+ // EVENTS (optional - for reacting to other services)
817
+ // ============================================================================
818
+ events: {
819
+ // Example: React to external events
820
+ // [OtherServiceAction.OnSomethingHappened]: {
821
+ // params: {
822
+ // id: 'string',
823
+ // },
824
+ // handler: async (ctx: Context<{ event: any }>) => {
825
+ // // React to event
826
+ // this.logger.debug('Event received');
827
+ // },
828
+ // },
829
+ },
830
+
831
+ // ============================================================================
832
+ // ACTIONS (required - one for each service method)
833
+ // ============================================================================
834
+ actions: {
835
+ // READ OPERATIONS
836
+ [[ServiceName]ServiceAction.GetItem]: {
837
+ params: {
838
+ id: 'string',
839
+ },
840
+ handler: async (ctx: Context<{ id: string }>) =>
841
+ [serviceName]Service.getItem(ctx.params.id),
842
+ },
843
+
844
+ [[ServiceName]ServiceAction.FindItems]: {
845
+ params: {
846
+ where: 'object',
847
+ },
848
+ handler: async (ctx: Context<{ where: IWhereInput }>) =>
849
+ [serviceName]Service.findItems(ctx.params.where),
850
+ },
851
+
852
+ // CREATE OPERATIONS
853
+ [[ServiceName]ServiceAction.CreateItem]: {
854
+ params: {
855
+ input: 'object',
856
+ },
857
+ handler: async (ctx: Context<{ input: ICreateInput }>) =>
858
+ [serviceName]Service.createItem(ctx.params.input),
859
+ },
860
+
861
+ // UPDATE OPERATIONS
862
+ [[ServiceName]ServiceAction.UpdateItem]: {
863
+ params: {
864
+ id: 'string',
865
+ input: 'object',
866
+ },
867
+ handler: async (ctx: Context<{ id: string; input: IUpdateInput }>) =>
868
+ [serviceName]Service.updateItem(ctx.params.id, ctx.params.input),
869
+ },
870
+
871
+ // DELETE OPERATIONS
872
+ [[ServiceName]ServiceAction.DeleteItem]: {
873
+ params: {
874
+ id: 'string',
875
+ },
876
+ handler: async (ctx: Context<{ id: string }>) =>
877
+ [serviceName]Service.deleteItem(ctx.params.id),
878
+ },
879
+
880
+ // For methods with multiple parameters, wrap in params object
881
+ [[ServiceName]ServiceAction.ComplexMethod]: {
882
+ params: {
883
+ param1: 'string',
884
+ param2: 'object',
885
+ param3: { type: 'string', optional: true },
886
+ },
887
+ handler: async (ctx: Context<{ param1: string; param2: IType; param3?: string }>) =>
888
+ [serviceName]Service.complexMethod(ctx.params.param1, ctx.params.param2, ctx.params.param3),
889
+ },
890
+ },
891
+ });
892
+ }
893
+ }
894
+ ```
895
+
896
+ ### Moleculer Service Implementation Rules
897
+
898
+ #### Type Safety with Compile-Time Verification
899
+
900
+ **CRITICAL**: Use the type checking pattern to ensure all service methods have corresponding actions:
901
+
902
+ ```typescript
903
+ /**
904
+ * Type utility to verify that all I[ServiceName]Service methods have corresponding Moleculer actions.
905
+ * This ensures compile-time checking when the service interface changes.
906
+ *
907
+ * Excluded methods:
908
+ * - dispose: Lifecycle method, not proxied
909
+ * - get/getAll/count/etc: BaseService CRUD methods (inherited from BaseService)
910
+ * - bulkDelete/delete: Not supported in proxy services
911
+ */
912
+ type ServiceMethodsToActions<T> = {
913
+ // eslint-disable-next-line @typescript-eslint/ban-types
914
+ [K in keyof T as T[K] extends Function
915
+ ? K extends
916
+ | 'dispose'
917
+ | 'get'
918
+ | 'getAll'
919
+ | 'bulkDelete'
920
+ | 'delete'
921
+ | 'count'
922
+ | 'getByName'
923
+ | 'getByIds'
924
+ | 'getAllWithCount'
925
+ | 'create'
926
+ | 'update'
927
+ | 'bulkCreate'
928
+ | 'insert'
929
+ ? never
930
+ : K
931
+ : never]: K;
932
+ };
933
+
934
+ // This type will show a compile error if any method is missing from the actions
935
+ type Required[ServiceName]Actions = ServiceMethodsToActions<I[ServiceName]Service>;
936
+
937
+ // Compile-time verification helper - causes error if methods don't match actions
938
+ // Add this BEFORE the service class definition
939
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
940
+ const _typeCheck: Record<keyof Required[ServiceName]Actions, boolean> = {
941
+ methodName1: true,
942
+ methodName2: true,
943
+ // ... list ALL service methods here (except excluded ones)
944
+ // TypeScript will error if you:
945
+ // 1. Miss a method that exists in the interface
946
+ // 2. Add a method that doesn't exist in the interface
947
+ // 3. Misspell a method name
948
+ };
949
+ ```
950
+
951
+ **Important Limitation**:
952
+
953
+ ⚠️ **The `_typeCheck` constant only verifies that method names are listed** - it does NOT verify that:
954
+
955
+ 1. Action handlers are actually implemented in the `actions` object
956
+ 2. Action handlers correctly delegate to the service methods
957
+ 3. Actions provided by mixins (like `BaseServiceMixin2`) are working
958
+
959
+ **Why this limitation exists**:
960
+
961
+ - TypeScript cannot verify that a string key in one object (actions) matches a boolean key in another object (\_typeCheck)
962
+ - Moleculer's dynamic action registration happens at runtime, not compile time
963
+ - Mixins add actions dynamically, which TypeScript cannot track
964
+
965
+ **What \_typeCheck DOES catch**:
966
+
967
+ ```typescript
968
+ // ✅ CATCHES: Method added to interface but not listed in _typeCheck
969
+ interface IAccountService {
970
+ newMethod(): void; // Added
971
+ }
972
+ const _typeCheck = {
973
+ // Missing newMethod - COMPILE ERROR
974
+ };
975
+
976
+ // ✅ CATCHES: Method removed from interface but still in _typeCheck
977
+ const _typeCheck = {
978
+ oldMethod: true, // No longer in interface - COMPILE ERROR
979
+ };
980
+
981
+ // ✅ CATCHES: Method name typo in _typeCheck
982
+ const _typeCheck = {
983
+ creeateAccount: true, // Typo - COMPILE ERROR (should be createAccount)
984
+ };
985
+ ```
986
+
987
+ **What \_typeCheck DOES NOT catch**:
988
+
989
+ ```typescript
990
+ // ❌ DOES NOT CATCH: Listed in _typeCheck but action handler not implemented
991
+ const _typeCheck = {
992
+ createAccount: true, // Listed
993
+ };
994
+ actions: {
995
+ // createAccount handler missing - NO COMPILE ERROR!
996
+ };
997
+
998
+ // ❌ DOES NOT CATCH: Action handler exists but doesn't call service method
999
+ actions: {
1000
+ [AccountServiceAction.CreateAccount]: {
1001
+ handler: () => console.log('oops'), // Wrong implementation - NO COMPILE ERROR!
1002
+ },
1003
+ };
1004
+ ```
1005
+
1006
+ **Best Practices to Address Limitations**:
1007
+
1008
+ 1. **Use \_typeCheck as a checklist** - When you add a method to \_typeCheck, immediately implement the action handler
1009
+
1010
+ 2. **Follow naming convention** - Use consistent enum values that match method names:
1011
+
1012
+ ```typescript
1013
+ // Good: Easy to verify visually
1014
+ createAccount: true, // in _typeCheck
1015
+ [ServiceAction.CreateAccount]: { ... } // in actions
1016
+
1017
+ // Bad: Hard to match
1018
+ createAccount: true, // in _typeCheck
1019
+ [ServiceAction.AddNew]: { ... } // in actions - what method does this call?
1020
+ ```
1021
+
1022
+ 3. **Group actions by \_typeCheck order** - List actions in same order as \_typeCheck for easy visual verification
1023
+
1024
+ 4. **Use BaseServiceMixin2 for CRUD operations** - Don't manually implement get/create/update if the mixin provides them:
1025
+
1026
+ ```typescript
1027
+ this.parseServiceSchema({
1028
+ name: topic,
1029
+ mixins: [BaseServiceMixin2(this.serviceInstance)], // Provides CRUD actions
1030
+ actions: {
1031
+ // Only service-specific actions here
1032
+ },
1033
+ });
1034
+ ```
1035
+
1036
+ 5. **Add runtime validation** (optional) - For critical services, add runtime checks:
1037
+
1038
+ ```typescript
1039
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
1040
+ super(broker);
1041
+ this.parseServiceSchema({...});
1042
+
1043
+ // Runtime verification (development only)
1044
+ if (process.env.NODE_ENV !== 'production') {
1045
+ const requiredActions: (keyof RequiredAccountActions)[] = [
1046
+ 'createAccount', 'updateAccount', // ...list all methods
1047
+ ];
1048
+ requiredActions.forEach(method => {
1049
+ if (!this.schema.actions[AccountServiceAction[method]]) {
1050
+ console.warn(`Missing action handler for ${method}`);
1051
+ }
1052
+ });
1053
+ }
1054
+ }
1055
+ ```
1056
+
1057
+ **Benefits**:
1058
+
1059
+ - **Immediate feedback**: TypeScript compiler fails when interface changes but \_typeCheck doesn't
1060
+ - **Prevents runtime errors**: Catches missing methods at compile time (when used as checklist)
1061
+ - **Self-documenting**: Lists all service methods in one place
1062
+ - **Refactoring safety**: Renaming/removing methods triggers errors automatically
1063
+
1064
+ **Example Error Messages**:
1065
+
1066
+ ```
1067
+ Type '{ ... }' is missing the following properties from type 'Record<...>': newMethod, anotherMethod
1068
+ ```
1069
+
1070
+ This error means you added `newMethod` and `anotherMethod` to the interface but forgot to add them to `_typeCheck`.
1071
+
1072
+ #### ✅ DO:
1073
+
1074
+ 1. **Create an action for EVERY service method** (except `dispose()`):
1075
+
1076
+ ```typescript
1077
+ [[ServiceName]ServiceAction.MethodName]: {
1078
+ params: { /* validation schema */ },
1079
+ handler: async (ctx: Context<TypedParams>) => service.methodName(ctx.params.arg1, ctx.params.arg2),
1080
+ },
1081
+ ```
1082
+
1083
+ 2. **Add all method names to \_typeCheck constant**:
1084
+
1085
+ ```typescript
1086
+ const _typeCheck: Record<keyof RequiredAccountActions, boolean> = {
1087
+ createDefaultAccount: true,
1088
+ createUserToken: true,
1089
+ updateUserAccount: true,
1090
+ // ... all other methods
1091
+ };
1092
+ ```
1093
+
1094
+ 3. **Always use strongly typed Context**:
1095
+ 4. **Always use strongly typed Context**:
1096
+
1097
+ ```typescript
1098
+ handler: async (ctx: Context<{ id: string; input: IUpdateInput }>) =>
1099
+ ```
1100
+
1101
+ 5. **Validate parameters using Moleculer params schema**:
1102
+
1103
+ ```typescript
1104
+ params: {
1105
+ id: 'string', // Required string
1106
+ name: { type: 'string', optional: true }, // Optional string
1107
+ items: 'array', // Required array
1108
+ data: 'object', // Required object
1109
+ count: 'number', // Required number
1110
+ active: 'boolean', // Required boolean
1111
+ },
1112
+ ```
1113
+
1114
+ 6. **Extract all parameters from ctx.params**:
1115
+
1116
+ ```typescript
1117
+ handler: async (ctx: Context<{ a: string; b: number; c?: boolean }>) =>
1118
+ service.method(ctx.params.a, ctx.params.b, ctx.params.c),
1119
+ ```
1120
+
1121
+ 7. **Import ALL required types** from 'common/server'
1122
+
1123
+ 8. **Group actions by operation type** with comments
1124
+
1125
+ #### ❌ DON'T:
1126
+
1127
+ 1. **Don't add business logic in handlers**
1128
+ 2. **Don't transform data** (that's the service's job)
1129
+ 3. **Don't use `any` types** - use proper interfaces
1130
+ 4. **Don't forget optional parameter handling**
1131
+ 5. **Don't skip parameter validation schemas**
1132
+
1133
+ ### Special Cases for Moleculer Services
1134
+
1135
+ **Synchronous methods**:
1136
+
1137
+ ```typescript
1138
+ [[ServiceName]ServiceAction.SyncMethod]: {
1139
+ params: { email: 'string', secret: 'string' },
1140
+ handler: (ctx: Context<{ email: string; secret: string }>) =>
1141
+ service.syncMethod(ctx.params.email, ctx.params.secret), // No async
1142
+ },
1143
+ ```
1144
+
1145
+ **Methods with complex nested objects**:
1146
+
1147
+ ```typescript
1148
+ [[ServiceName]ServiceAction.ComplexParams]: {
1149
+ params: { args: 'object' },
1150
+ handler: async (ctx: Context<{
1151
+ args: {
1152
+ details: IDetailsInput;
1153
+ metadata: IMetadata;
1154
+ options?: IOptions;
1155
+ };
1156
+ }>) => service.complexMethod(ctx.params.args),
1157
+ },
1158
+ ```
1159
+
1160
+ **Methods with union types or optional chaining**:
1161
+
1162
+ ```typescript
1163
+ [[ServiceName]ServiceAction.WithOptions]: {
1164
+ params: {
1165
+ id: 'string',
1166
+ options: { type: 'object', optional: true },
1167
+ },
1168
+ handler: async (ctx: Context<{ id: string; options?: IOptions }>) =>
1169
+ service.method(ctx.params.id, ctx.params.options),
1170
+ },
1171
+ ```
1172
+
1173
+ ### Task 3: Create Proxy Service
1174
+
1175
+ **STRICT FILE NAMING CONVENTION:**
1176
+
1177
+ ✅ **CORRECT**: Use PascalCase matching the class name
1178
+
1179
+ - File: `AccountProxyService.ts` → Class: `AccountProxyService`
1180
+ - File: `ProjectProxyService.ts` → Class: `ProjectProxyService`
1181
+ - File: `TeamProxyService.ts` → Class: `TeamProxyService`
1182
+ - File: `PropertyProxyService.ts` → Class: `PropertyProxyService`
1183
+
1184
+ ❌ **WRONG**: Do NOT use kebab-case or other variations
1185
+
1186
+ - ❌ `account-proxy-service.ts` (kebab-case)
1187
+ - ❌ `property-proxy-service.ts` (kebab-case)
1188
+ - ❌ `AccountProxy.ts` (missing Service)
1189
+ - ❌ `AccountMicroservice.ts` (wrong suffix - use ProxyService)
1190
+ - ❌ `account_proxy_service.ts` (snake-case)
1191
+
1192
+ **File Location Patterns:**
1193
+
1194
+ Pattern 1 (Core module - MOST COMMON):
1195
+ `packages-modules/[module-name]/core/src/server-context/proxy-services/[ServiceName]ProxyService.ts`
1196
+
1197
+ Examples:
1198
+
1199
+ - `packages-modules/property/core/src/server-context/proxy-services/PropertyProxyService.ts`
1200
+ - `packages-modules/billing-api/core/src/server-context/proxy-services/InvoiceProxyService.ts`
1201
+ - `packages-modules/calendar-events/core/src/server-context/proxy-services/CalendarEventProxyService.ts`
1202
+
1203
+ Pattern 2 (Servers module - LEGACY):
1204
+ `packages-modules/[module-name]/core/src/servers/services/[ServiceName]ProxyService.ts`
1205
+
1206
+ Examples:
1207
+
1208
+ - `packages-modules/account-api/core/src/servers/services/AccountProxyService.ts`
1209
+ - `packages-modules/account-api/core/src/servers/services/ProjectProxyService.ts`
1210
+
1211
+ **Directory Structure:**
1212
+
1213
+ ```
1214
+ packages-modules/
1215
+ property/ # Module folder
1216
+ core/ # Core package (client-side code)
1217
+ src/
1218
+ server-context/ # Server context (NEW STANDARD)
1219
+ proxy-services/ # Proxy services folder
1220
+ PropertyProxyService.ts # ✅ Proxy service here
1221
+ index.ts # Export from this folder
1222
+ server/ # Server package (server-side code)
1223
+ src/
1224
+ plugins/ # Moleculer services folder
1225
+ PropertyMoleculerService.ts # Moleculer service here
1226
+ services/ # Business logic services
1227
+ property-service.ts # Actual service implementation
1228
+ ```
1229
+
1230
+ **Directory Naming Rules:**
1231
+
1232
+ 1. ✅ Use `server-context/proxy-services/` for NEW proxy services (preferred)
1233
+ 2. ⚠️ `servers/services/` is LEGACY pattern (still valid but being migrated)
1234
+ 3. ✅ Always plural: `proxy-services/` not `proxy-service/`
1235
+ 4. ✅ Always kebab-case for directories: `server-context/` not `serverContext/`
1236
+ 5. ✅ Always PascalCase for files: `PropertyProxyService.ts`
1237
+ 6. ❌ Never mix cases: `ProxyServices/` or `proxy_services/` are wrong
1238
+
1239
+ **File Naming Rules:**
1240
+
1241
+ 1. ✅ File name MUST match class name exactly
1242
+ 2. ✅ Use PascalCase (first letter uppercase)
1243
+ 3. ✅ Always end with `ProxyService.ts`
1244
+ 4. ✅ Service name comes first: `[ServiceName]ProxyService`
1245
+ 5. ❌ Never use kebab-case (dashes)
1246
+ 6. ❌ Never use snake-case (underscores)
1247
+ 7. ❌ Never use `Microservice` suffix (legacy naming)
1248
+ 8. ❌ Never use plural form (e.g., `PropertiesProxyService` is wrong)
1249
+
1250
+ **Index File Pattern:**
1251
+
1252
+ Create an `index.ts` in the proxy-services folder to export all proxies:
1253
+
1254
+ ```typescript
1255
+ // packages-modules/property/core/src/server-context/proxy-services/index.ts
1256
+ export * from './PropertyProxyService';
1257
+ export * from './PropertyTypeProxyService';
1258
+ // ... other proxy services
1259
+ ```
1260
+
1261
+ **Migration Guide:**
1262
+
1263
+ If you find proxy services in the OLD location (`servers/services/`):
1264
+
1265
+ 1. Create new directory structure: `server-context/proxy-services/`
1266
+ 2. Move proxy service files to new location
1267
+ 3. Update imports in container modules
1268
+ 4. Update index.ts exports
1269
+ 5. Keep file names EXACTLY the same (PascalCase)
1270
+
1271
+ ---
1272
+
1273
+ ## 🎯 MANDATORY APPROACH: Auto-Generation with Declaration Merging
1274
+
1275
+ **⚠️ STRICT REQUIREMENT**: ALL new proxy services MUST use this exact pattern with declaration merging.
1276
+
1277
+ **DO NOT use:**
1278
+
1279
+ - ❌ `implements IService` - causes TypeScript errors
1280
+ - ❌ `extends BaseProxyService2` - legacy pattern, deprecated
1281
+ - ❌ Manual method definitions - defeats auto-generation
1282
+ - ❌ Index signatures `[key: string]: any` - unsafe hack
1283
+ - ❌ Manual property declarations (`topic`, `broker`, `callAction`)
1284
+
1285
+ **REQUIRED Pattern - Copy Exactly:**
1286
+
1287
+ ```typescript
1288
+ import { injectable, inject } from 'inversify';
1289
+ import { ServiceBroker } from 'moleculer';
1290
+ import type { CdmLogger } from '@cdm-logger/core';
1291
+ import { CommonType } from '@common-stack/core';
1292
+ import { generateProxyMethods } from '@common-stack/codegen-zod';
1293
+ import type { I[ServiceName]Service } from 'common/server';
1294
+ import { [ServiceName]ServiceSchemas } from 'common/server';
1295
+
1296
+ /**
1297
+ * Client-side proxy for [ServiceName] operations using AUTO-GENERATION.
1298
+ *
1299
+ * 🎉 FULLY AUTOMATIC: All I[ServiceName]Service methods auto-generated!
1300
+ *
1301
+ * ✅ ZERO BOILERPLATE: No manual method definitions
1302
+ * ✅ TYPE-SAFE: Full TypeScript inference from I[ServiceName]Service
1303
+ * ✅ VALIDATED: Zod schemas for parameter validation
1304
+ * ✅ MAINTAINABLE: Add method to interface → automatically available as proxy
1305
+ */
1306
+ @injectable()
1307
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1308
+ export class [ServiceName]ProxyService {
1309
+ constructor(
1310
+ @inject(CommonType.MOLECULER_BROKER)
1311
+ broker: ServiceBroker,
1312
+ @inject(CommonType.LOGGER)
1313
+ logger: CdmLogger.ILogger,
1314
+ ) {
1315
+ const childLogger = logger.child({ className: '[ServiceName]ProxyService' });
1316
+
1317
+ // ⚡ ONE LINE: Auto-generate all proxy methods
1318
+ generateProxyMethods<I[ServiceName]Service>(this, [ServiceName]ServiceSchemas, broker, childLogger);
1319
+ }
1320
+ }
1321
+
1322
+ // Declaration merging for type safety - provides full interface implementation
1323
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1324
+ export interface [ServiceName]ProxyService extends I[ServiceName]Service {}
1325
+ ```
1326
+
1327
+ **CRITICAL RULES - DO NOT DEVIATE:**
1328
+
1329
+ 1. ✅ **MUST use declaration merging** - separate class and interface with same name
1330
+ 2. ✅ **MUST have both eslint-disable comments** for `no-unsafe-declaration-merging`
1331
+ 3. ✅ **MUST import service schemas** - `[ServiceName]ServiceSchemas` (not as type)
1332
+ 4. ✅ **MUST import service interface as type** - `import type { I[ServiceName]Service }`
1333
+ 5. ✅ **MUST use `generateProxyMethods()`** - single call in constructor
1334
+ 6. ✅ **MUST create child logger** - for proper logging context
1335
+ 7. ✅ **NO manual method definitions** - all methods come from generateProxyMethods
1336
+ 8. ✅ **NO implements keyword** - declaration merging handles this
1337
+ 9. ✅ **NO extends BaseProxyService2** - deprecated pattern
1338
+ 10. ✅ **NO manual property declarations** - generateProxyMethods adds them
1339
+
1340
+ **Template Validation Checklist:**
1341
+
1342
+ Before submitting generated code, verify:
1343
+
1344
+ - [ ] Class name ends with `ProxyService`
1345
+ - [ ] Has `@injectable()` decorator
1346
+ - [ ] Has declaration merging comment: `// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging`
1347
+ - [ ] Constructor has exactly 2 parameters: `broker` and `logger`
1348
+ - [ ] Creates child logger with className
1349
+ - [ ] Single `generateProxyMethods()` call with 4 arguments
1350
+ - [ ] Interface declaration after class with same name
1351
+ - [ ] Interface extends service interface
1352
+ - [ ] No method definitions in class body
1353
+ - [ ] No property declarations in class body
1354
+ - [ ] Total file length: ~40 lines
1355
+
1356
+ **Example Output:**
1357
+
1358
+ ```typescript
1359
+ // ✅ CORRECT - Exact pattern to follow
1360
+ @injectable()
1361
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1362
+ export class AccountProxyService {
1363
+ constructor(
1364
+ @inject(CommonType.MOLECULER_BROKER)
1365
+ broker: ServiceBroker,
1366
+ @inject(CommonType.LOGGER)
1367
+ logger: CdmLogger.ILogger,
1368
+ ) {
1369
+ const childLogger = logger.child({ className: 'AccountProxyService' });
1370
+ generateProxyMethods<IAccountService>(this, AccountServiceSchemas, broker, childLogger);
1371
+ }
1372
+ }
1373
+
1374
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1375
+ export interface AccountProxyService extends IAccountService {}
1376
+ ```
1377
+
1378
+ **Common Mistakes to Avoid:**
1379
+
1380
+ ```typescript
1381
+ // ❌ WRONG - Using implements
1382
+ export class ProxyService implements IService {
1383
+ [key: string]: any; // Unsafe hack!
1384
+ }
1385
+
1386
+ // ❌ WRONG - Extending BaseProxyService2
1387
+ export class ProxyService extends BaseProxyService2<IModel> implements IService {
1388
+ }
1389
+
1390
+ // ❌ WRONG - Manual method definitions
1391
+ export class ProxyService {
1392
+ getItem(id: string): Promise<Item> {
1393
+ return this.callAction(...); // Defeats auto-generation!
1394
+ }
1395
+ }
1396
+
1397
+ // ❌ WRONG - Manual property declarations
1398
+ export class ProxyService {
1399
+ protected topic!: string; // Don't declare manually!
1400
+ protected broker!: ServiceBroker;
1401
+ }
1402
+
1403
+ // ❌ WRONG - Missing declaration merging
1404
+ export class ProxyService {
1405
+ // Class only, no interface
1406
+ }
1407
+ ```
1408
+
1409
+ **Why Declaration Merging:**
1410
+
1411
+ 1. TypeScript merges class and interface into single type
1412
+ 2. No need for `implements` - interface provides the type
1413
+ 3. No TypeScript errors about missing methods
1414
+ 4. Full IntelliSense support
1415
+ 5. Runtime methods added by `generateProxyMethods()`
1416
+ 6. Clean, minimal code
1417
+
1418
+ ---
1419
+
1420
+ ## 📋 Manual Proxy Service Template (DEPRECATED - DO NOT USE)
1421
+
1422
+ **⚠️ DEPRECATED**: This pattern is no longer supported. Use auto-generation with declaration merging instead.
1423
+
1424
+ **Only mentioned for reference when maintaining legacy code.**
1425
+
1426
+ **Template Structure (LEGACY - Use Auto-Generation Instead)**:
1427
+
1428
+ ```typescript
1429
+ import { inject, injectable } from 'inversify';
1430
+ import { ServiceBroker } from 'moleculer';
1431
+ import { CommonType } from '@common-stack/core';
1432
+ import type { CdmLogger } from '@cdm-logger/core';
1433
+ import { BaseProxyService2 } from '@common-stack/store-mongo';
1434
+ import {
1435
+ [ServiceName]ServiceAction,
1436
+ MoleculerServiceName,
1437
+ I[ServiceName]Service,
1438
+ AsDomainType,
1439
+ I[ServiceName]Model,
1440
+ // Import other types as needed
1441
+ } from 'common/server';
1442
+
1443
+ /**
1444
+ * Proxy Service for [ServiceName] operations.
1445
+ * Delegates all operations to [ServiceName]Service through Moleculer broker.
1446
+ *
1447
+ * Pattern:
1448
+ * - Extends BaseProxyService2 which provides callAction method
1449
+ * - Implements I[ServiceName]Service interface
1450
+ * - Each method calls this.callAction with appropriate action enum and parameters
1451
+ * - No business logic - pure delegation
1452
+ *
1453
+ * @see [ServiceName]Service for actual implementation
1454
+ * @see BaseProxyService2 for base proxy functionality
1455
+ */
1456
+ @injectable()
1457
+ export class [ServiceName]ProxyService
1458
+ extends BaseProxyService2<I[ServiceName]Model>
1459
+ implements I[ServiceName]Service
1460
+ {
1461
+ protected logger?: CdmLogger.ILogger;
1462
+
1463
+ // ⚠️ CRITICAL: Set the Moleculer service name - REQUIRED for proxy to work
1464
+ protected topic = MoleculerServiceName.[ServiceName];
1465
+
1466
+ constructor(
1467
+ @inject(CommonType.MOLECULER_BROKER)
1468
+ broker: ServiceBroker,
1469
+ @inject(CommonType.LOGGER)
1470
+ logger: CdmLogger.ILogger,
1471
+ ) {
1472
+ super(broker, logger);
1473
+ this.logger = logger.child({ className: '[ServiceName]ProxyService' });
1474
+ }
1475
+
1476
+ // ============================================================================
1477
+ // READ OPERATIONS
1478
+ // ============================================================================
1479
+
1480
+ methodName(param: Type): Promise<ReturnType> {
1481
+ return this.callAction([ServiceName]ServiceAction.MethodName, { param });
1482
+ }
1483
+
1484
+ // ============================================================================
1485
+ // CREATE OPERATIONS
1486
+ // ============================================================================
1487
+
1488
+ // ... implement create methods
1489
+
1490
+ // ============================================================================
1491
+ // UPDATE OPERATIONS
1492
+ // ============================================================================
1493
+
1494
+ // ... implement update methods
1495
+
1496
+ // ============================================================================
1497
+ // DELETE OPERATIONS
1498
+ // ============================================================================
1499
+
1500
+ // ... implement delete methods
1501
+
1502
+ // ============================================================================
1503
+ // LIFECYCLE METHODS
1504
+ // ============================================================================
1505
+
1506
+ dispose(): void {
1507
+ // Dispose is a lifecycle method, not proxied
1508
+ // No-op for proxy service
1509
+ }
1510
+ }
1511
+ ```
1512
+
1513
+ ### Implementation Rules
1514
+
1515
+ #### ✅ DO:
1516
+
1517
+ 1. **For each interface method**, create a corresponding proxy method:
1518
+
1519
+ ```typescript
1520
+ interfaceMethod(param1: Type1, param2?: Type2): Promise<ReturnType> {
1521
+ return this.callAction(ServiceAction.InterfaceMethod, { param1, param2 });
1522
+ }
1523
+ ```
1524
+
1525
+ 2. **Pass ALL parameters as a single object**:
1526
+
1527
+ ```typescript
1528
+ updateItem(id: string, data: UpdateInput, userId: string): Promise<Item> {
1529
+ return this.callAction(ServiceAction.UpdateItem, { id, data, userId });
1530
+ }
1531
+ ```
1532
+
1533
+ 3. **Include optional parameters** in the params object:
1534
+
1535
+ ```typescript
1536
+ getItems(filter?: Filter, limit?: number): Promise<Item[]> {
1537
+ return this.callAction(ServiceAction.GetItems, { filter, limit });
1538
+ }
1539
+ ```
1540
+
1541
+ 4. **Group methods by operation type** with clear section comments
1542
+
1543
+ 5. **Use section dividers** (80-char lines of =)
1544
+
1545
+ 6. **Match parameter names exactly** from the interface
1546
+
1547
+ 7. **Handle void returns** - still use callAction:
1548
+ ```typescript
1549
+ notifyUser(userId: string, message: string): Promise<void> {
1550
+ return this.callAction(ServiceAction.NotifyUser, { userId, message });
1551
+ }
1552
+ ```
1553
+
1554
+ #### ❌ DON'T:
1555
+
1556
+ 1. **Don't add ANY business logic**:
1557
+
1558
+ ```typescript
1559
+ // ❌ BAD
1560
+ createItem(data: Input): Promise<Item> {
1561
+ if (!data.name) throw new Error('Name required');
1562
+ return this.callAction(ServiceAction.CreateItem, { data });
1563
+ }
1564
+
1565
+ // ✅ GOOD
1566
+ createItem(data: Input): Promise<Item> {
1567
+ return this.callAction(ServiceAction.CreateItem, { data });
1568
+ }
1569
+ ```
1570
+
1571
+ 2. **Don't transform or validate data**
1572
+
1573
+ 3. **Don't add logging** (already in callAction)
1574
+
1575
+ 4. **Don't catch errors** (unless re-throwing)
1576
+
1577
+ 5. **Don't add async/await** (return Promise directly):
1578
+
1579
+ ```typescript
1580
+ // ❌ BAD
1581
+ async getItem(id: string): Promise<Item> {
1582
+ return await this.callAction(ServiceAction.GetItem, { id });
1583
+ }
1584
+
1585
+ // ✅ GOOD
1586
+ getItem(id: string): Promise<Item> {
1587
+ return this.callAction(ServiceAction.GetItem, { id });
1588
+ }
1589
+ ```
1590
+
1591
+ ### Special Cases
1592
+
1593
+ **Synchronous methods** that can't be proxied:
1594
+
1595
+ ```typescript
1596
+ createToken(_param1: string, _param2: string): string {
1597
+ throw new Error('createToken should be called directly on [ServiceName]Service, not via proxy.');
1598
+ }
1599
+ ```
1600
+
1601
+ **Methods with Types.ObjectId parameters**:
1602
+
1603
+ ```typescript
1604
+ acceptInvitation(id: string | Types.ObjectId, user: User): Promise<boolean> {
1605
+ return this.callAction(ServiceAction.AcceptInvitation, { id, user });
1606
+ }
1607
+ ```
1608
+
1609
+ **Methods with complex union types** - pass as-is
1610
+
1611
+ ### Task 4: Update Container Module
1612
+
1613
+ Update the DI container module to register the proxy service:
1614
+ `packages-modules/[module-name]/server/src/modules/[service]/containers/module.ts`
1615
+
1616
+ **Pattern for Proxy Module**:
1617
+
1618
+ ```typescript
1619
+ import { ContainerModule, interfaces } from 'inversify';
1620
+ import { SERVER_TYPES, I[ServiceName]Service } from 'common/server';
1621
+ import { [ServiceName]ProxyService } from '../services';
1622
+
1623
+ export const [ServiceName]ProxyModule: (settings: any) => ContainerModule = (setting) =>
1624
+ new ContainerModule((bind: interfaces.Bind) => {
1625
+ // Bind proxy service to interface
1626
+ bind<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service)
1627
+ .to([ServiceName]ProxyService)
1628
+ .inSingletonScope();
1629
+ });
1630
+ ```
1631
+
1632
+ **Complete module file example**:
1633
+
1634
+ ```typescript
1635
+ import { ContainerModule, interfaces } from 'inversify';
1636
+ import {
1637
+ I[ServiceName]Repository,
1638
+ SERVER_TYPES,
1639
+ I[ServiceName]Service,
1640
+ } from 'common/server';
1641
+ import { [ServiceName]Repository } from '../store/repositories';
1642
+ import {
1643
+ [ServiceName]ProxyService,
1644
+ [ServiceName]Service,
1645
+ } from '../services';
1646
+
1647
+ // Database Module (registers actual service + repository)
1648
+ export const [ServiceName]DbModule: (settings: any) => ContainerModule = (setting) =>
1649
+ new ContainerModule((bind: interfaces.Bind) => {
1650
+ bind<I[ServiceName]Repository>(SERVER_TYPES.I[ServiceName]Repository)
1651
+ .to([ServiceName]Repository)
1652
+ .inSingletonScope();
1653
+
1654
+ bind<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service)
1655
+ .to([ServiceName]Service)
1656
+ .inSingletonScope();
1657
+ });
1658
+
1659
+ // Proxy Module (registers proxy service only)
1660
+ export const [ServiceName]ProxyModule: (settings: any) => ContainerModule = (setting) =>
1661
+ new ContainerModule((bind: interfaces.Bind) => {
1662
+ bind<I[ServiceName]Service>(SERVER_TYPES.I[ServiceName]Service)
1663
+ .to([ServiceName]ProxyService)
1664
+ .inSingletonScope();
1665
+ });
1666
+ ```
1667
+
1668
+ **Rules for container modules**:
1669
+
1670
+ - **DbModule**: Binds actual service + repository (used by server that runs business logic)
1671
+ - **ProxyModule**: Binds proxy service only (used by client services that call via Moleculer)
1672
+ - Use same `SERVER_TYPES.I[ServiceName]Service` symbol for both
1673
+ - Both use `.inSingletonScope()` for performance
1674
+ - Keep consistent naming: `[ServiceName]DbModule` and `[ServiceName]ProxyModule`
1675
+
1676
+ ### Output Requirements
1677
+
1678
+ 1. **Complete GraphQL enum** with all actions
1679
+ 2. **Complete Moleculer service** file with:
1680
+ - All imports (including Service, ServiceBroker, Context from 'moleculer')
1681
+ - Container injection for service instance
1682
+ - All actions mapped to service methods
1683
+ - Proper parameter validation schemas
1684
+ - Strongly typed Context handlers
1685
+ 3. **Complete proxy service** file with:
1686
+ - All imports
1687
+ - Proper class structure
1688
+ - All interface methods implemented
1689
+ - Organized by operation type
1690
+ - Section comments
1691
+ - JSDoc on class
1692
+ 4. **Updated container module** with proxy registration
1693
+ 5. **Instructions**: "After creating these files, run: `yarn generateGraphql && yarn build`"
1694
+
1695
+ ### Quality Checklist
1696
+
1697
+ Before outputting, verify:
1698
+
1699
+ #### Moleculer Service (Auto-Generation):
1700
+
1701
+ - [ ] Uses `Moleculer.generateActionsAndEvents<IService>(service)` or `Moleculer.generateAutoInferredActions<IService>(service)`
1702
+ - [ ] Service instance retrieved from DI container
1703
+ - [ ] Correct `name` set to MoleculerServiceName enum value
1704
+ - [ ] Actions and events destructured from generation function
1705
+ - [ ] Optional: paramOverrides specified for methods needing custom validation
1706
+ - [ ] Optional: exclude specified for manually handled methods
1707
+ - [ ] No manual action definitions (unless override needed)
1708
+ - [ ] Event handlers use `@Moleculer.EventHandler` decorator in service class
1709
+
1710
+ #### Moleculer Service (Manual - Only if needed):
1711
+
1712
+ - [ ] All interface methods have corresponding actions
1713
+ - [ ] All actions use strongly typed `Context<TypedParams>`
1714
+ - [ ] Parameter validation schemas are complete
1715
+ - [ ] All parameters extracted from `ctx.params`
1716
+ - [ ] No `any` types used
1717
+ - [ ] Actions grouped by operation type
1718
+ - [ ] Correct `name` set to MoleculerServiceName
1719
+ - [ ] Service instance retrieved from DI container
1720
+
1721
+ #### Proxy Service (Auto-Generation - RECOMMENDED):
1722
+
1723
+ - [ ] Uses `generateProxyMethods<IService>(this, ServiceSchemas, broker, logger)`
1724
+ - [ ] Imports from `@common-stack/server-core`
1725
+ - [ ] Service schemas imported (e.g., `ProjectServiceSchemas`)
1726
+ - [ ] Declaration merging used: `export interface ProxyService extends IService {}`
1727
+ - [ ] Both class and interface have eslint-disable for unsafe-declaration-merging
1728
+ - [ ] No manual method definitions
1729
+ - [ ] No `topic` property needed (derived automatically)
1730
+ - [ ] Class is injectable with proper DI
1731
+ - [ ] Logger passed to generateProxyMethods
1732
+
1733
+ #### Proxy Service (Manual - Legacy):
1734
+
1735
+ - [ ] All interface methods have corresponding proxy methods
1736
+ - [ ] All proxy methods use `this.callAction()`
1737
+ - [ ] All parameters passed as single object
1738
+ - [ ] Parameter names match interface exactly
1739
+ - [ ] Methods grouped by operation type
1740
+ - [ ] No business logic added
1741
+ - [ ] Lifecycle methods (dispose) are no-ops
1742
+ - [ ] ⚠️ **CRITICAL**: `topic` property set to MoleculerServiceName (REQUIRED)
1743
+ - [ ] Extends BaseProxyService2<ModelType>
1744
+ - [ ] Implements IService interface
1745
+
1746
+ #### Container Module:
1747
+
1748
+ - [ ] Container module updated with proxy registration
1749
+ - [ ] Uses same SERVER_TYPES symbol as actual service
1750
+
1751
+ ### Example Output
1752
+
1753
+ See these reference implementations:
1754
+
1755
+ **Moleculer Services**:
1756
+
1757
+ - **Simple (10-15 actions)**: `modules/project/plugins/ProjectMoleculerService.ts`
1758
+ - **Complex (40+ actions)**: `plugins/AccountMoleculerService.ts`
1759
+
1760
+ **Proxy Services**:
1761
+
1762
+ - **Simple (10-15 methods)**: `ProjectProxyService.ts`
1763
+ - **Medium (15-20 methods)**: `TeamMicroservice.ts`
1764
+ - **Complex (40+ methods)**: `AccountProxyService.ts`
1765
+
1766
+ ### Complete Example: Account Module
1767
+
1768
+ **1. Moleculer Service with Auto-Generation** (`plugins/AccountMoleculerService.ts`):
1769
+
1770
+ ```typescript
1771
+ import { Context, Service, ServiceBroker } from 'moleculer';
1772
+ import { Container } from 'inversify';
1773
+ import { Moleculer } from '@common-stack/codegen-zod';
1774
+ import { AccountServiceAction, IAccountService, MoleculerServiceName, SERVER_TYPES } from 'common/server';
1775
+
1776
+ /**
1777
+ * Moleculer Service for Account operations using AUTO-GENERATION.
1778
+ *
1779
+ * This service demonstrates the modern approach:
1780
+ * - Uses Moleculer.generateActionsAndEvents() for automatic action/event generation
1781
+ * - All service methods become actions automatically
1782
+ * - All @Moleculer.EventHandler decorated methods become event handlers
1783
+ * - No manual action definitions needed
1784
+ * - Parent class methods automatically included
1785
+ *
1786
+ * @see AccountService for business logic and event handlers
1787
+ * @see AccountProxyService for client-side proxy
1788
+ */
1789
+ export class AccountMoleculerService extends Service {
1790
+ constructor(broker: ServiceBroker, { container }: { container: Container; settings?: unknown }) {
1791
+ super(broker);
1792
+ const topic = MoleculerServiceName.Account;
1793
+ const accountService = container.get<IAccountService>(SERVER_TYPES.IAccountService);
1794
+
1795
+ // ⚡ AUTO-GENERATE both actions and events
1796
+ const { actions, events } = Moleculer.generateActionsAndEvents<IAccountService>(accountService);
1797
+
1798
+ this.parseServiceSchema({
1799
+ name: topic,
1800
+ actions, // ✅ All 60+ methods auto-generated (including parent class methods)
1801
+ events, // ✅ All @Moleculer.EventHandler methods auto-generated
1802
+ });
1803
+ }
1804
+ }
1805
+ ```
1806
+
1807
+ **Benefits of Auto-Generation:**
1808
+
1809
+ - **30 lines** instead of 200+ lines of manual action definitions
1810
+ - **Automatic inheritance**: All parent class methods included
1811
+ - **Type-safe**: Full TypeScript inference
1812
+ - **Maintainable**: Add method to service → automatically available as action
1813
+ - **Event integration**: Decorators handled automatically
1814
+
1815
+ **2. Service with Event Handlers** (showing what auto-generation detects):
1816
+
1817
+ ```typescript
1818
+ import { injectable } from 'inversify';
1819
+ import { Moleculer } from '@common-stack/codegen-zod';
1820
+ import { UserBroadcasterAction, AuthStrategy } from 'common/server';
1821
+
1822
+ @injectable()
1823
+ export class AccountService extends BaseAccountService {
1824
+ // Regular method → becomes Moleculer action
1825
+ async findAccountById(id: string): Promise<IAccount> {
1826
+ return this.repository.findById(id);
1827
+ }
1828
+
1829
+ // Regular method → becomes Moleculer action
1830
+ async createAccount(account: IAccountInput): Promise<IAccount> {
1831
+ return this.repository.create(account);
1832
+ }
1833
+
1834
+ // Decorated method → becomes Moleculer event handler
1835
+ @Moleculer.EventHandler(UserBroadcasterAction.OnUserCreated)
1836
+ async onUserCreated(event: IUserProfile & { authStrategy: AuthStrategy }): Promise<void> {
1837
+ await this.createDefaultAccount(event, { authStrategy: event.authStrategy });
1838
+ }
1839
+
1840
+ // Decorated method → becomes Moleculer event handler
1841
+ @Moleculer.EventHandler(UserBroadcasterAction.OnAccountLinked)
1842
+ async onAccountLinked(event: { email: string; aliases: string[] }): Promise<void> {
1843
+ await this.updateUserAccountAliases({
1844
+ email: event?.email,
1845
+ aliasesToAdd: event?.aliases,
1846
+ });
1847
+ }
1848
+ }
1849
+ ```
1850
+
1851
+ **Result of Auto-Generation:**
1852
+
1853
+ - `findAccountById` → action: `AccountServiceAction.FindAccountById`
1854
+ - `createAccount` → action: `AccountServiceAction.CreateAccount`
1855
+ - `onUserCreated` → event: `UserBroadcasterAction.OnUserCreated` (excluded from actions)
1856
+ - `onAccountLinked` → event: `UserBroadcasterAction.OnAccountLinked` (excluded from actions)
1857
+
1858
+ **1. Moleculer Service (MANUAL - Legacy Pattern)** (`plugins/AccountMoleculerService.ts`):
1859
+
1860
+ ```typescript
1861
+ import { Context, Service, ServiceBroker } from 'moleculer';
1862
+ import { Container } from 'inversify';
1863
+ import {
1864
+ AccountServiceAction,
1865
+ IAccountService,
1866
+ IPhoneNumberInput,
1867
+ IUserToken,
1868
+ SERVER_TYPES,
1869
+ TokenTypesEnum,
1870
+ } from 'common/server';
1871
+
1872
+ export class AccountMoleculerService extends Service {
1873
+ constructor(broker: ServiceBroker, { container }: { container: Container; settings?: unknown }) {
1874
+ super(broker);
1875
+ const accountService = container.get<IAccountService>(SERVER_TYPES.IAccountService);
1876
+
1877
+ this.parseServiceSchema({
1878
+ name: 'accountUser',
1879
+ actions: {
1880
+ // READ OPERATIONS
1881
+ [AccountServiceAction.FindAccountById]: {
1882
+ params: { id: 'string' },
1883
+ handler: async (ctx: Context<{ id: string }>) => accountService.findAccountById(ctx.params.id),
1884
+ },
1885
+
1886
+ // CREATE OPERATIONS
1887
+ [AccountServiceAction.CreateAccount]: {
1888
+ handler: async (ctx: Context<{ account: any }>) => accountService.createAccount(ctx.params.account),
1889
+ },
1890
+
1891
+ // Synchronous method
1892
+ [AccountServiceAction.CreateUserToken]: {
1893
+ params: {
1894
+ email: 'string',
1895
+ secret: 'string',
1896
+ expiresIn: { type: 'string', optional: true },
1897
+ },
1898
+ handler: (ctx: Context<{ email: string; secret: string; expiresIn?: string }>) =>
1899
+ accountService.createUserToken(ctx.params.email, ctx.params.secret, ctx.params.expiresIn),
1900
+ },
1901
+
1902
+ // With complex parameters
1903
+ [AccountServiceAction.ValidateAndFetchUserToken]: {
1904
+ params: { userId: 'string', tokens: 'array', type: 'string' },
1905
+ handler: async (ctx: Context<{ userId: string; tokens: IUserToken[]; type: TokenTypesEnum }>) =>
1906
+ accountService.validateAndFetchUserToken(ctx.params.userId, ctx.params.tokens, ctx.params.type),
1907
+ },
1908
+ },
1909
+ });
1910
+ }
1911
+ }
1912
+ ```
1913
+
1914
+ **2a. Proxy Service (AUTO-GENERATION - RECOMMENDED)** (`ProjectProxyService.ts`):
1915
+
1916
+ ```typescript
1917
+ import { injectable, inject } from 'inversify';
1918
+ import { ServiceBroker } from 'moleculer';
1919
+ import type { CdmLogger } from '@cdm-logger/core';
1920
+ import { CommonType } from '@common-stack/core';
1921
+ import { generateProxyMethods } from '@common-stack/codegen-zod';
1922
+ import { IProjectService, ProjectServiceSchemas } from 'common/server';
1923
+
1924
+ /**
1925
+ * Client-side proxy for Project operations using AUTO-GENERATION.
1926
+ *
1927
+ * 🎉 FULLY AUTOMATIC: All IProjectService methods auto-generated!
1928
+ *
1929
+ * Uses generateProxyMethods() to automatically create all proxy methods:
1930
+ * • getProjects(), addProject(), updateProject(), deleteProject(), etc.
1931
+ *
1932
+ * ✅ ZERO BOILERPLATE: No manual method definitions (~100 lines eliminated)
1933
+ * ✅ TYPE-SAFE: Full TypeScript inference from IProjectService
1934
+ * ✅ VALIDATED: Zod schemas for parameter validation
1935
+ * ✅ MAINTAINABLE: Add method to interface → automatically available as proxy
1936
+ * ✅ CORRECT ORDERING: Parameters passed in correct order
1937
+ */
1938
+ @injectable()
1939
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1940
+ export class ProjectProxyService {
1941
+ constructor(
1942
+ @inject(CommonType.MOLECULER_BROKER)
1943
+ broker: ServiceBroker,
1944
+ @inject('Logger')
1945
+ logger: CdmLogger.ILogger,
1946
+ ) {
1947
+ const childLogger = logger.child({ className: 'ProjectProxyService' });
1948
+ generateProxyMethods<IProjectService>(this, ProjectServiceSchemas, broker, childLogger);
1949
+ }
1950
+ }
1951
+
1952
+ // Declaration merging for type safety - provides full interface implementation
1953
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1954
+ export interface ProjectProxyService extends IProjectService {}
1955
+ ```
1956
+
1957
+ **2b. Proxy Service (MANUAL - LEGACY)** (`AccountProxyService.ts`):
1958
+
1959
+ ```typescript
1960
+ import { inject, injectable } from 'inversify';
1961
+ import { ServiceBroker } from 'moleculer';
1962
+ import { BaseProxyService2 } from '@common-stack/store-mongo';
1963
+ import {
1964
+ AccountServiceAction,
1965
+ IAccountService,
1966
+ IPhoneNumberInput,
1967
+ IUserAccountModel,
1968
+ IUserToken,
1969
+ TokenTypesEnum,
1970
+ } from 'common/server';
1971
+
1972
+ @injectable()
1973
+ export class AccountProxyService extends BaseProxyService2<IUserAccountModel> implements IAccountService {
1974
+ // ⚠️ CRITICAL: topic is REQUIRED for manual proxy services
1975
+ protected topic = 'accountUser';
1976
+
1977
+ constructor(broker: ServiceBroker, logger: any) {
1978
+ super(broker, logger);
1979
+ }
1980
+
1981
+ // READ OPERATIONS
1982
+ findAccountById(id: string): Promise<any> {
1983
+ return this.callAction(AccountServiceAction.FindAccountById, { id });
1984
+ }
1985
+
1986
+ // CREATE OPERATIONS
1987
+ createAccount(account: any): Promise<any> {
1988
+ return this.callAction(AccountServiceAction.CreateAccount, { account });
1989
+ }
1990
+
1991
+ // Synchronous method - throws error (cannot be proxied)
1992
+ createUserToken(email: string, secret: string, expiresIn?: string): string {
1993
+ throw new Error('createUserToken should be called directly on AccountService, not via proxy.');
1994
+ }
1995
+
1996
+ // With complex parameters
1997
+ validateAndFetchUserToken(userId: string, tokens: IUserToken[], type: TokenTypesEnum): Promise<IUserToken> {
1998
+ return this.callAction(AccountServiceAction.ValidateAndFetchUserToken, { userId, tokens, type });
1999
+ }
2000
+
2001
+ // ... other methods (~40+ manual method definitions)
2002
+ }
2003
+ ```
2004
+
2005
+ **3. Container Module** (`modules/account/containers/module.ts`):
2006
+
2007
+ **3. Container Module** (`modules/account/containers/module.ts`):
2008
+
2009
+ ```typescript
2010
+ import { ContainerModule, interfaces } from 'inversify';
2011
+ import { IAccountRepository, SERVER_TYPES, IAccountService } from 'common/server';
2012
+ import { AccountRepository } from '../store/repositories';
2013
+ import { AccountProxyService, AccountService } from '../services';
2014
+
2015
+ // Database Module - Registers actual service + repository (for server)
2016
+ export const AccountDbModule: (settings: any) => ContainerModule = (setting) =>
2017
+ new ContainerModule((bind: interfaces.Bind) => {
2018
+ bind<IAccountRepository>(SERVER_TYPES.IAccountRepository).to(AccountRepository).inSingletonScope();
2019
+ bind<IAccountService>(SERVER_TYPES.IAccountService).to(AccountService).inSingletonScope();
2020
+ });
2021
+
2022
+ // Proxy Module - Registers proxy service only (for clients)
2023
+ export const AccountProxyModule: (settings: any) => ContainerModule = (setting) =>
2024
+ new ContainerModule((bind: interfaces.Bind) => {
2025
+ bind<IAccountService>(SERVER_TYPES.IAccountService).to(AccountProxyService).inSingletonScope();
2026
+ });
2027
+ ```
2028
+
2029
+ ### Complete Example: Project Module
2030
+
2031
+ **1. Moleculer Service** (`modules/project/plugins/project-moleculer-service.ts`):
2032
+
2033
+ ```typescript
2034
+ import { Context, Service, ServiceBroker } from 'moleculer';
2035
+ import { MoleculerTopics, IProjectService, ProjectCommand, SERVER_TYPES } from 'common/server';
2036
+ import { Container } from 'inversify';
2037
+
2038
+ export class ProjectMolecularService extends Service {
2039
+ private projectService: IProjectService;
2040
+
2041
+ constructor(broker: ServiceBroker, { container }: { container: Container }) {
2042
+ super(broker);
2043
+ this.projectService = container.get<IProjectService>(SERVER_TYPES.IProjectService);
2044
+
2045
+ this.parseServiceSchema({
2046
+ name: MoleculerTopics.Project,
2047
+ actions: {
2048
+ [ProjectCommand.GetProjects]: {
2049
+ handler: async (ctx: Context<{ orgName: string; offset?: number; limit?: number }>) =>
2050
+ this.projectService.getProjects(ctx.params.orgName, ctx.params.offset, ctx.params.limit),
2051
+ },
2052
+ [ProjectCommand.AddProject]: {
2053
+ handler: async (ctx: Context<{ project: any; orgId: string; orgName: string }>) =>
2054
+ this.projectService.addProject(ctx.params.project, ctx.params.orgId, ctx.params.orgName),
2055
+ },
2056
+ [ProjectCommand.UpdateProject]: {
2057
+ handler: async (ctx: Context<{ where: any; project: any; orgName: string }>) =>
2058
+ this.projectService.updateProject(ctx.params.where, ctx.params.project, ctx.params.orgName),
2059
+ },
2060
+ [ProjectCommand.DeleteProject]: {
2061
+ handler: async (ctx: Context<{ where: any; tenantId: string }>) =>
2062
+ this.projectService.deleteProject(ctx.params.where, ctx.params.tenantId),
2063
+ },
2064
+ },
2065
+ });
2066
+ }
2067
+ }
2068
+ ```
2069
+
2070
+ **2. Container Module** (`modules/project/containers/module.ts`):
2071
+
2072
+ **2. Container Module** (`modules/project/containers/module.ts`):
2073
+
2074
+ ```typescript
2075
+ import { ContainerModule, interfaces } from 'inversify';
2076
+ import { IProjectRepository, SERVER_TYPES, IProjectService } from 'common/server';
2077
+ import { ProjectRepository } from '../store/repositories';
2078
+ import { ProjectProxyService, ProjectService } from '../services';
2079
+
2080
+ // Database Module - Registers actual service
2081
+ export const ProjectDbModule: (settings: any) => ContainerModule = (setting) =>
2082
+ new ContainerModule((bind: interfaces.Bind) => {
2083
+ bind<IProjectRepository>(SERVER_TYPES.IProjectRepository).to(ProjectRepository).inSingletonScope();
2084
+ bind<IProjectService>(SERVER_TYPES.IProjectService).to(ProjectService).inSingletonScope();
2085
+ });
2086
+
2087
+ // Proxy Module - Registers proxy service
2088
+ export const ProjectProxyModule: (settings: any) => ContainerModule = (setting) =>
2089
+ new ContainerModule((bind: interfaces.Bind) => {
2090
+ bind<IProjectService>(SERVER_TYPES.IProjectService).to(ProjectProxyService).inSingletonScope();
2091
+ });
2092
+ ```
2093
+
2094
+ **Key Points**:
2095
+
2096
+ - **Both modules use same interface** (`IProjectService`)
2097
+ - **Both use same DI symbol** (`SERVER_TYPES.IProjectService`)
2098
+ - DbModule includes repository + actual service
2099
+ - ProxyModule includes only proxy service
2100
+ - Consumer code doesn't know if using proxy or actual service (polymorphism)
2101
+ - **Moleculer service** must be registered separately in server bootstrap
2102
+
2103
+ ---
2104
+
2105
+ ## 🤖 PROMPT END
2106
+
2107
+ ---
2108
+
2109
+ ## Usage Instructions
2110
+
2111
+ 1. **Copy the prompt above** (from "PROMPT START" to "PROMPT END")
2112
+
2113
+ 2. **Customize the placeholders**:
2114
+ - Replace `[ServiceName]` with your service name (e.g., "Project", "User", "Invoice")
2115
+ - Replace `[module-name]` with your module name (e.g., "account-api", "project-api")
2116
+ - Replace `[service]` with lowercase service name (e.g., "project", "user", "invoice")
2117
+
2118
+ 3. **Provide to LLM** with the following files:
2119
+
2120
+ ```
2121
+ Attached files:
2122
+ 1. packages/common/src/services/[ServiceName].ts
2123
+ 2. packages-modules/[module]/server/src/graphql/schema/service.graphql
2124
+ 3. packages-modules/[module]/server/src/modules/[service]/containers/module.ts
2125
+ 4. (Optional) packages-modules/[module]/server/src/services/[ServiceName].ts
2126
+ ```
2127
+
2128
+ 4. **Review the output** and verify against the checklist
2129
+
2130
+ 5. **Run the generation command**:
2131
+
2132
+ ```bash
2133
+ yarn generateGraphql
2134
+ ```
2135
+
2136
+ 6. **Update the container module** with the generated proxy registration
2137
+
2138
+ 7. **Verify compilation**:
2139
+ ```bash
2140
+ # Check for TypeScript errors
2141
+ cd packages-modules/[module]/core
2142
+ npx tsc --noEmit
2143
+ ```
2144
+
2145
+ ---
2146
+
2147
+ ## Example Conversation
2148
+
2149
+ **You**: "I need to create a proxy service for UserService"
2150
+
2151
+ **Attach**:
2152
+
2153
+ - `packages/common/src/services/UserService.ts`
2154
+ - `packages-modules/user-api/server/src/graphql/schema/service.graphql`
2155
+ - `packages-modules/user-api/server/src/modules/user/containers/module.ts`
2156
+
2157
+ **Paste**: [The full prompt from above with [ServiceName] replaced with "User"]
2158
+
2159
+ **LLM Output**:
2160
+
2161
+ 1. Complete proxy service implementation
2162
+ 2. GraphQL enum updates
2163
+ 3. Container module registration code
2164
+
2165
+ **You Run**:
2166
+
2167
+ ```bash
2168
+ yarn generateGraphql
2169
+ ```
2170
+
2171
+ **You Update**: Apply the container module changes
2172
+
2173
+ **Done**: Proxy service ready to use!
2174
+
2175
+ ---
2176
+
2177
+ ## Troubleshooting
2178
+
2179
+ ### Issue: Generated proxy has wrong method signatures
2180
+
2181
+ **Fix**: Ensure you attached the correct interface file. The LLM must see the exact method signatures.
2182
+
2183
+ ### Issue: Missing imports
2184
+
2185
+ **Fix**: Check that `MoleculerServiceName` enum includes your service. Add if missing:
2186
+
2187
+ ```graphql
2188
+ extend enum MoleculerServiceName {
2189
+ YourService
2190
+ }
2191
+ ```
2192
+
2193
+ ### Issue: callAction type errors
2194
+
2195
+ **Fix**: After running `yarn generateGraphql`, restart your TypeScript server (VS Code: Cmd+Shift+P → "Restart TS Server")
2196
+
2197
+ ### Issue: DI container can't resolve service
2198
+
2199
+ **Error**: `No matching bindings found for serviceIdentifier: Symbol(IYourService)`
2200
+
2201
+ **Fix**: Ensure you're loading the correct module:
2202
+
2203
+ - **For server (business logic)**: Load `YourServiceDbModule`
2204
+ - **For client (via Moleculer)**: Load `YourServiceProxyModule`
2205
+ - Never load both in same container
2206
+
2207
+ ### Issue: Service methods not being called / "Service not found" errors
2208
+
2209
+ **Symptoms**:
2210
+
2211
+ - Moleculer throws "Service '[ServiceName]' not found" errors
2212
+ - Proxy methods timeout or fail silently
2213
+ - Actions not reaching the moleculer service
2214
+
2215
+ **Root Cause**: Missing or incorrect `topic` property in manual proxy service
2216
+
2217
+ **Fix for Manual Proxy Services**:
2218
+
2219
+ ⚠️ **CRITICAL**: The `topic` property is **REQUIRED** for manual proxy services extending BaseProxyService2
2220
+
2221
+ ```typescript
2222
+ // ❌ BAD - Missing topic
2223
+ @injectable()
2224
+ export class YourProxyService extends BaseProxyService2<IYourModel> implements IYourService {
2225
+ constructor(broker: ServiceBroker, logger: CdmLogger.ILogger) {
2226
+ super(broker, logger);
2227
+ }
2228
+ // Methods won't work - no topic set!
2229
+ }
2230
+
2231
+ // ✅ GOOD - Topic properly set
2232
+ @injectable()
2233
+ export class YourProxyService extends BaseProxyService2<IYourModel> implements IYourService {
2234
+ protected topic = MoleculerServiceName.YourService; // REQUIRED!
2235
+
2236
+ constructor(broker: ServiceBroker, logger: CdmLogger.ILogger) {
2237
+ super(broker, logger);
2238
+ }
2239
+ }
2240
+
2241
+ // ✅ BEST - Use auto-generation (topic handled automatically)
2242
+ @injectable()
2243
+ export class YourProxyService {
2244
+ constructor(broker: ServiceBroker, logger: CdmLogger.ILogger) {
2245
+ const childLogger = logger.child({ className: 'YourProxyService' });
2246
+ generateProxyMethods<IYourService>(this, YourServiceSchemas, broker, childLogger);
2247
+ }
2248
+ }
2249
+ export interface YourProxyService extends IYourService {}
2250
+ ```
2251
+
2252
+ **Verify topic matches Moleculer service registration**:
2253
+
2254
+ ```typescript
2255
+ // In proxy service
2256
+ protected topic = MoleculerServiceName.YourService;
2257
+
2258
+ // Must match in moleculer service
2259
+ this.parseServiceSchema({
2260
+ name: MoleculerServiceName.YourService, // Must match!
2261
+ actions,
2262
+ events,
2263
+ });
2264
+ ```
2265
+
2266
+ ### Issue: Multiple bindings for same service
2267
+
2268
+ **Error**: Ambiguous binding resolution
2269
+
2270
+ **Fix**:
2271
+
2272
+ 1. Check only ONE service module is loaded per container
2273
+ 2. Don't bind same service in multiple modules
2274
+ 3. Use conditional binding if needed:
2275
+ ```typescript
2276
+ if (useMicroservices) {
2277
+ container.load(YourServiceProxyModule(settings));
2278
+ } else {
2279
+ container.load(YourServiceDbModule(settings));
2280
+ }
2281
+ ```
2282
+
2283
+ ---
2284
+
2285
+ ## Tips for Best Results
2286
+
2287
+ 1. **Always attach the interface file** - this is the source of truth
2288
+ 2. **Provide the actual service file** if methods have complex signatures
2289
+ 3. **Reference similar complexity** - mention which example to follow
2290
+ 4. **Be specific about module name** - helps LLM determine correct paths
2291
+ 5. **Review section organization** - ensure methods are grouped logically
2292
+
2293
+ ---
2294
+
2295
+ ## Advanced: Batch Generation
2296
+
2297
+ To generate multiple proxy services:
2298
+
2299
+ ```bash
2300
+ # Create a list file
2301
+ cat > services-to-generate.txt << EOF
2302
+ UserService user-api
2303
+ InvoiceService billing-api
2304
+ NotificationService notification-api
2305
+ EOF
2306
+
2307
+ # Use with your favorite LLM tool
2308
+ # Each line: ServiceName module-name
2309
+ ```
2310
+
2311
+ ---
2312
+
2313
+ ## Configuration & Code Generation
2314
+
2315
+ ### Prerequisites
2316
+
2317
+ **Required Package Version**:
2318
+
2319
+ ```json
2320
+ {
2321
+ "devDependencies": {
2322
+ "@common-stack/graphql-codegen-zod-schemas": "^7.2.1-alpha.21"
2323
+ }
2324
+ }
2325
+ ```
2326
+
2327
+ **Minimum Version**: `7.2.1-alpha.21` or higher
2328
+
2329
+ This version includes:
2330
+
2331
+ - Support for `constEnums` configuration
2332
+ - Proper handling of `zodImportPath`
2333
+ - Export as `@common-stack` scoped package
2334
+ - GraphQL and Service schema generation plugins
2335
+
2336
+ **Installation**:
2337
+
2338
+ ```bash
2339
+ yarn add -D @common-stack/graphql-codegen-zod-schemas@^7.2.1-alpha.21
2340
+ ```
2341
+
2342
+ ### GraphQL Codegen Plugin Configuration
2343
+
2344
+ The project uses `@common-stack/graphql-codegen-zod-schemas` for generating Zod validation schemas from GraphQL schemas. The configuration is centralized in `cdecode-config.json`.
2345
+
2346
+ **Configuration File**: `cdecode-config.json` (root level)
2347
+
2348
+ This file contains ALL project code generation and automation configuration. Key sections:
2349
+
2350
+ 1. **`servers`**: Frontend and backend server config paths
2351
+ 2. **`codegen`**: GraphQL code generation configuration (including Zod schemas)
2352
+ 3. **`serviceSchemas`**: TypeScript service interface Zod schema generation
2353
+ 4. **`updateDependencies`**: Dependency synchronization rules
2354
+ 5. **`updateDependencyVersion`**: Version management across packages
2355
+ 6. **`sortPackageJson`**: Package.json formatting rules
2356
+ 7. **`deployVersionUpdate`**: Deployment version tracking
2357
+ 8. **`projectPaths`**: Project structure paths
2358
+
2359
+ **Complete Configuration Structure** (`cdecode-config.json`):
2360
+
2361
+ ```json
2362
+ {
2363
+ "servers": ["servers/frontend-server/config.json", "servers/backend-server/config.json"],
2364
+ "codegen": {
2365
+ "outputFile": "codegen.ts",
2366
+ "rootSchema": "node_modules/@common-stack/graphql-api/root-schema.graphqls",
2367
+ "fullConfig": {
2368
+ "overwrite": true,
2369
+ "schema": ["$PRIMARY_SCHEMA_PLACEHOLDER$"],
2370
+ "hooks": {
2371
+ "afterAllFileWrite": [
2372
+ "node scripts/fix-enum-references.js",
2373
+ "node scripts/generate-all-service-schemas.js"
2374
+ ]
2375
+ },
2376
+ "generates": {
2377
+ "packages/common/src/generated/generated-zod-schemas.ts": {
2378
+ "schema": "%discoveredSchemas%",
2379
+ "config": {
2380
+ "enumsAsTypes": true,
2381
+ "enumValues": {
2382
+ "ConfigurationScope": "@workbench-stack/core/lib/interfaces/configuration/configuration.js#ConfigurationScope",
2383
+ "ConfigurationTarget": "../configuration#ConfigurationTarget"
2384
+ },
2385
+ "constEnums": {
2386
+ "ConfigurationScope": [1, 2, 3, 4],
2387
+ "ConfigurationTarget": [1, 2, 3, 4, 5, 6, 7]
2388
+ },
2389
+ "zodImportPath": "zod"
2390
+ },
2391
+ "plugins": ["@common-stack/codegen-zod/graphql"]
2392
+ }
2393
+ }
2394
+ }
2395
+ },
2396
+ "serviceSchemas": {
2397
+ "servicesDir": "packages/common/src/services",
2398
+ "outputFile": "packages/common/src/generated/service-schemas.ts",
2399
+ "skipServices": [
2400
+ "AuthBackendClient",
2401
+ "PubSub",
2402
+ "RedisCacheManager",
2403
+ "InngestClient",
2404
+ "JSONContributionRegistry",
2405
+ "PageStore",
2406
+ "PublisherEventService"
2407
+ ],
2408
+ "knownEnums": [],
2409
+ "constEnumSchemas": ["ConfigurationTarget", "ConfigurationScope"],
2410
+ "graphqlSchemasPath": "packages/common/src/generated/generated-zod-schemas.ts"
2411
+ }
2412
+ }
2413
+ ```
2414
+
2415
+ **Key Configuration Options**:
2416
+
2417
+ - **`enumsAsTypes`**: Generates TypeScript enums as union types for better Zod compatibility
2418
+ - **`enumValues`**: Maps GraphQL enums to TypeScript module imports for shared enum definitions
2419
+ - **`constEnums`**: Defines numeric values for const enums (used for runtime validation)
2420
+ - **`zodImportPath`**: Specifies the Zod import path (defaults to "zod")
2421
+ - **`hooks.afterAllFileWrite`**: Scripts that run after code generation completes
2422
+ - **`plugins`**: Must reference `@common-stack/codegen-zod/graphql` (version ^7.2.1-alpha.21 or higher)
2423
+
2424
+ ### Service Schema Generation Configuration
2425
+
2426
+ The project automatically generates Zod schemas for TypeScript service interfaces using the centralized schema generator from `@common-stack/server-core`. Configuration is in the `serviceSchemas` section of `cdecode-config.json` (shown in the complete configuration above).
2427
+
2428
+ **Schema Generator**: `@common-stack/server-core/lib/moleculer-generation/generateAllServiceSchemas.cjs`
2429
+
2430
+ This CJS script is published as part of the `@common-stack/server-core` package and shared across all projects.
2431
+
2432
+ **Service Schema Configuration Properties**:
2433
+
2434
+ - **`servicesDir`**: Directory containing service interface TypeScript files
2435
+ - **`outputFile`**: Where to generate the service schemas file
2436
+ - **`skipServices`**: Services to exclude from schema generation (external dependencies, special cases)
2437
+ - **`knownEnums`**: Additional enums to recognize during schema generation
2438
+ - **`constEnumSchemas`**: Enums that should use const enum schemas (numeric values)
2439
+ - **`graphqlSchemasPath`**: Path to GraphQL Zod schemas file (for importing shared schemas)
2440
+
2441
+ **Automatic Relative Path Calculation**:
2442
+
2443
+ The service schema generator automatically calculates the correct relative import path from `outputFile` to `graphqlSchemasPath`. You don't need to specify a separate import path - it's derived automatically.
2444
+
2445
+ **Example**:
2446
+
2447
+ ```typescript
2448
+ // Configuration
2449
+ {
2450
+ "outputFile": "packages/common/src/generated/service-schemas.ts",
2451
+ "graphqlSchemasPath": "packages/common/src/generated/generated-zod-schemas.ts"
2452
+ }
2453
+
2454
+ // Generated import (automatically calculated as same directory)
2455
+ import { ConfigurationScopeSchema, ConfigurationTargetSchema } from './generated-zod-schemas';
2456
+ ```
2457
+
2458
+ ### Running Code Generation
2459
+
2460
+ **Generate GraphQL schemas and service schemas**:
2461
+
2462
+ ```bash
2463
+ yarn generateGraphql
2464
+ ```
2465
+
2466
+ This command:
2467
+
2468
+ 1. Runs GraphQL Codegen to generate TypeScript types and Zod schemas from GraphQL schemas
2469
+ 2. Fixes enum references in generated files (via `scripts/fix-enum-references.js`)
2470
+ 3. Generates Zod schemas for all service interfaces (via `scripts/generate-all-service-schemas.js`)
2471
+ 4. Rebuilds the common package with updated schemas
2472
+
2473
+ **Generation happens automatically via hooks** defined in `cdecode-config.json`:
2474
+
2475
+ ```json
2476
+ {
2477
+ "hooks": {
2478
+ "afterAllFileWrite": [
2479
+ "node scripts/fix-enum-references.js",
2480
+ "node node node_modules/@common-stack/codegen-zod/dist/service/generateAllServiceSchemas.js"
2481
+ ]
2482
+ }
2483
+ }
2484
+ ```
2485
+
2486
+ ### Schema Generation Script
2487
+
2488
+ The service schema generator (`@common-stack/server-core/lib/moleculer-generation/generateAllServiceSchemas.cjs`) uses the configuration from `cdecode-config.json` to:
2489
+
2490
+ 1. **Discover all service interfaces** in the configured services directory
2491
+ 2. **Parse TypeScript** to extract method signatures and parameter types
2492
+ 3. **Auto-generate topic** from interface name (e.g., `IProjectService` → `ProjectService`)
2493
+ 4. **Generate Zod schemas** for each method's parameters
2494
+ 5. **Import shared schemas** from GraphQL Zod schemas (enums, input types)
2495
+ 6. **Skip configured services** that shouldn't have schemas generated
2496
+ 7. **Use const enum schemas** for numeric enums where configured
2497
+ 8. **Calculate relative import paths** automatically based on file locations
2498
+
2499
+ **Script Location**: `node node_modules/@common-stack/codegen-zod/dist/service/generateAllServiceSchemas.js`
2500
+
2501
+ **How it works**:
2502
+
2503
+ ```javascript
2504
+ // 1. Load configuration from cdecode-config.json
2505
+ const configPath = path.join(__dirname, '../cdecode-config.json');
2506
+ const fullConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
2507
+ const serviceConfig = fullConfig.serviceSchemas || {};
2508
+
2509
+ // 2. Calculate relative import path automatically
2510
+ function calculateRelativeImportPath() {
2511
+ if (!serviceConfig.outputFile || !serviceConfig.graphqlSchemasPath) {
2512
+ return './generated-zod-schemas';
2513
+ }
2514
+
2515
+ const outputDir = path.dirname(serviceConfig.outputFile);
2516
+ const graphqlSchemaPath = serviceConfig.graphqlSchemasPath;
2517
+
2518
+ // Calculate relative path from output file to GraphQL schemas
2519
+ const relativePath = path.relative(outputDir, graphqlSchemaPath);
2520
+
2521
+ // Remove .ts extension and ensure it starts with ./
2522
+ const withoutExt = relativePath.replace(/\.ts$/, '');
2523
+ return withoutExt.startsWith('.') ? withoutExt : `./${withoutExt}`;
2524
+ }
2525
+
2526
+ const GRAPHQL_SCHEMAS_IMPORT_PATH = calculateRelativeImportPath();
2527
+
2528
+ // 3. Discover GraphQL Zod types from generated file
2529
+ function discoverGraphQLZodTypes() {
2530
+ const graphqlSchemaFile = path.join(__dirname, '..', serviceConfig.graphqlSchemasPath);
2531
+ const content = fs.readFileSync(graphqlSchemaFile, 'utf8');
2532
+ const graphqlTypes = new Set();
2533
+
2534
+ // Find all exported schema functions like: export function UserInputSchema()
2535
+ const schemaFunctionPattern = /export function ([A-Z][a-zA-Z0-9]+)Schema\(\)/g;
2536
+ let match;
2537
+
2538
+ while ((match = schemaFunctionPattern.exec(content)) !== null) {
2539
+ const schemaName = match[1];
2540
+ // Convert schema name to interface name (add 'I' prefix)
2541
+ const interfaceName = 'I' + schemaName;
2542
+ graphqlTypes.add(interfaceName);
2543
+ }
2544
+
2545
+ return graphqlTypes;
2546
+ }
2547
+
2548
+ // 4. Find all service interfaces (excluding skipServices)
2549
+ function findServiceInterfaces() {
2550
+ const files = fs.readdirSync(SERVICES_DIR).filter((f) => f.endsWith('.ts'));
2551
+ const services = [];
2552
+
2553
+ files.forEach((file) => {
2554
+ const content = fs.readFileSync(path.join(SERVICES_DIR, file), 'utf8');
2555
+ const interfaceMatch = content.match(/export interface (I[A-Z][a-zA-Z0-9]*Service)/);
2556
+
2557
+ if (interfaceMatch) {
2558
+ const serviceName = interfaceMatch[1];
2559
+ if (!SKIP_SERVICES.includes(serviceName.replace(/^I/, ''))) {
2560
+ services.push({ name: serviceName, file, path: filePath });
2561
+ }
2562
+ }
2563
+ });
2564
+
2565
+ return services;
2566
+ }
2567
+
2568
+ // 5. Parse TypeScript to extract method signatures
2569
+ function parseServiceInterface(filePath, interfaceName) {
2570
+ const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true);
2571
+
2572
+ // Visit AST nodes to find interface and extract methods
2573
+ // Returns: { methods: [...], usedEnums: [...] }
2574
+ }
2575
+
2576
+ // 6. Generate Zod schemas for each parameter type
2577
+ function generateZodType(paramType, isOptional, paramName) {
2578
+ // Handle arrays: Type[] -> z.array(...)
2579
+ // Handle primitives: string -> z.string()
2580
+ // Handle GraphQL types: IUserInput -> UserInputSchema()
2581
+ // Handle enums: TokenType -> z.nativeEnum(TokenType)
2582
+ // Handle const enums: ConfigurationScope -> ConfigurationScopeSchema()
2583
+ // Default: z.object({}).passthrough()
2584
+ }
2585
+ ```
2586
+
2587
+ **Configuration Properties Used**:
2588
+
2589
+ - `serviceSchemas.servicesDir`: Where to find service interface files
2590
+ - `serviceSchemas.outputFile`: Where to write generated schemas
2591
+ - `serviceSchemas.skipServices`: Services to exclude from generation
2592
+ - `serviceSchemas.knownEnums`: Regular enums to import
2593
+ - `serviceSchemas.constEnumSchemas`: Const enums to use schema functions for
2594
+ - `serviceSchemas.graphqlSchemasPath`: Source of GraphQL Zod schemas to import
2595
+
2596
+ **What gets generated**:
2597
+
2598
+ ```typescript
2599
+ // Example generated service schema (from IAccountService interface)
2600
+ export const AccountServiceSchemas = {
2601
+ /** Moleculer service topic/name - safe for minification */
2602
+ topic: 'AccountService' as const, // Auto-derived from IAccountService
2603
+
2604
+ findAccountById: z.object({
2605
+ id: z.string(),
2606
+ }),
2607
+ createAccount: z.object({
2608
+ account: AccountInputSchema, // From GraphQL schemas
2609
+ }),
2610
+ updateUserAccount: z.object({
2611
+ userId: z.string(),
2612
+ input: UserAccountUpdateInputSchema, // From GraphQL schemas
2613
+ }),
2614
+ };
2615
+ ```
2616
+
2617
+ ### Benefits of Centralized Configuration
2618
+
2619
+ 1. **Single Source of Truth**: All code generation config in one file
2620
+ 2. **Easy Customization**: Change paths, add services, modify schemas without editing scripts
2621
+ 3. **Automatic Path Resolution**: No manual relative path calculations needed
2622
+ 4. **Type Safety**: Generated schemas provide runtime validation for Moleculer actions
2623
+ 5. **Consistency**: Same configuration used across all code generation tools
2624
+ 6. **Plugin Publishing Ready**: Clean separation of plugin code and project configuration
2625
+
2626
+ ### Configuration Migration Notes
2627
+
2628
+ **Recent Changes** (October 2025):
2629
+
2630
+ 1. **Plugin renamed**: `@adminide-stack/graphql-codegen-zod-schemas` → `@common-stack/graphql-codegen-zod-schemas`
2631
+ 2. **Version requirement**: Must use `^7.2.1-alpha.21` or higher
2632
+ 3. **Plugin path changed**: `./packages/graphql-codegen-zod-schemas/dist/graphql.js` → `@common-stack/codegen-zod/graphql`
2633
+ 4. **Service schema config moved**: Separate `service-schemas.config.js` → `cdecode-config.json` (serviceSchemas section)
2634
+ 5. **Automatic path calculation**: Import paths now derived from file paths (no separate `graphqlSchemasImportPath` needed)
2635
+
2636
+ **If updating from older configuration**:
2637
+
2638
+ 1. **Install/upgrade the plugin**:
2639
+
2640
+ ```bash
2641
+ yarn add -D @common-stack/graphql-codegen-zod-schemas@^7.2.1-alpha.21
2642
+ ```
2643
+
2644
+ 2. **Update plugin reference** in `cdecode-config.json`:
2645
+
2646
+ ```json
2647
+ {
2648
+ "plugins": ["@common-stack/codegen-zod/graphql"]
2649
+ }
2650
+ ```
2651
+
2652
+ 3. **Move service schema config** to `serviceSchemas` section of `cdecode-config.json`:
2653
+
2654
+ ```json
2655
+ {
2656
+ "serviceSchemas": {
2657
+ "servicesDir": "packages/common/src/services",
2658
+ "outputFile": "packages/common/src/generated/service-schemas.ts",
2659
+ "graphqlSchemasPath": "packages/common/src/generated/generated-zod-schemas.ts",
2660
+ ...
2661
+ }
2662
+ }
2663
+ ```
2664
+
2665
+ 4. **Remove deprecated properties**:
2666
+ - Delete `graphqlSchemasImportPath` from serviceSchemas (now calculated automatically)
2667
+ - Delete `service-schemas.config.js` file if it exists
2668
+
2669
+ 5. **Verify the setup**:
2670
+ ```bash
2671
+ yarn generateGraphql
2672
+ yarn build
2673
+ ```
2674
+
2675
+ **Breaking Changes**:
2676
+
2677
+ - Old plugin path `./packages/graphql-codegen-zod-schemas/dist/graphql.js` will no longer work
2678
+ - Service schema generation now requires configuration in `cdecode-config.json`
2679
+ - Minimum version requirement: `@common-stack/graphql-codegen-zod-schemas@^7.2.1-alpha.21`
2680
+
2681
+ ---
2682
+
2683
+ ## Version
2684
+
2685
+ - **v1.2.0** (2025-10-26): Added configuration and code generation documentation, plugin rename updates
2686
+ - **v1.1.0** (2024-10-24): Added container module pattern and DI registration guidance
2687
+ - **v1.0.0** (2024-10-24): Initial LLM prompt template based on 4 implemented examples