@cdmbase/wiki-browser 12.0.18-alpha.5

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,1117 @@
1
+ # Tenant Management System - Comprehensive Documentation
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Overview](#overview)
6
+ 2. [What This Functionality Is About](#what-this-functionality-is-about)
7
+ 3. [How to Execute the Functionality](#how-to-execute-the-functionality)
8
+ 4. [Implementation Details](#implementation-details)
9
+ 5. [Component Architecture](#component-architecture)
10
+ 6. [State Management](#state-management)
11
+ 7. [GraphQL Integration](#graphql-integration)
12
+ 8. [Backend Architecture & Inngest Integration](#backend-architecture--inngest-integration)
13
+ 9. [Important Notes and Best Practices](#important-notes-and-best-practices)
14
+
15
+ ---
16
+
17
+ ## Overview
18
+
19
+ The Tenant Management System is a comprehensive multi-tenant management solution built with React, TypeScript, XState, and GraphQL. It provides a complete CRUD interface for managing tenants within an organization, including tenant creation, editing, deletion, secret key management, and lifecycle operations.
20
+
21
+ **Primary Entry Point:** `TenantDashboard.tsx`
22
+
23
+ ---
24
+
25
+ ## What This Functionality Is About
26
+
27
+ ### Core Purpose
28
+
29
+ The Tenant Management System enables organizations to:
30
+
31
+ 1. **Manage Multiple Tenants**: Create, view, update, and delete tenant configurations within an organization
32
+ 2. **Environment-Based Organization**: Associate tenants with specific environments (development, staging, production) and projects
33
+ 3. **Secret Key Management**: Generate, view, and revoke API secret keys for tenant authentication
34
+ 4. **Lifecycle Management**: Handle tenant creation workflows, retry failed operations, and monitor tenant status
35
+ 5. **Multi-Project Support**: Link tenants to specific projects within an organization
36
+
37
+ ### Key Features
38
+
39
+ - ✅ **Full CRUD Operations**: Create, Read, Update, Delete tenants
40
+ - ✅ **Secret API Key Management**: Generate and manage client configurations with secret keys
41
+ - ✅ **Status Tracking**: Monitor tenant status (active, pending, error, disabled, completed)
42
+ - ✅ **Error Handling**: Retry failed tenant creation operations
43
+ - ✅ **Project Integration**: Associate tenants with projects and environment tags
44
+ - ✅ **Real-time Updates**: Automatic refetching and cache management
45
+ - ✅ **Toast Notifications**: User-friendly success/error feedback
46
+ - ✅ **State Machine Management**: Predictable state transitions using XState
47
+
48
+ ---
49
+
50
+ ## How to Execute the Functionality
51
+
52
+ ### Accessing the Tenant Dashboard
53
+
54
+ 1. **Navigate to the Route**: The Tenant Dashboard is accessible via a route that includes the organization name parameter (`orgName`)
55
+
56
+ ```typescript
57
+ // Route pattern: /organizations/:orgName/tenants
58
+ ```
59
+
60
+ 2. **Prerequisites**:
61
+ - User must be authenticated
62
+ - User must have appropriate permissions for the organization
63
+ - Organization must exist and be accessible
64
+
65
+ ### Creating a New Tenant
66
+
67
+ 1. **Click "Create Tenant" Button**: Located in the header of the tenant list or in the empty state
68
+ 2. **Fill Required Fields**:
69
+ - **Name**: Tenant name (minimum 3 characters)
70
+ - **Description**: Detailed description of the tenant
71
+ - **Project**: Select a project from the dropdown (optional)
72
+ - **Environment**: Select an environment tag (automatically populated based on selected project)
73
+ - **Secret API Keys**: Add at least one secret key with name and optional description
74
+ 3. **Submit**: Click "Create Tenant" button
75
+ 4. **Result**:
76
+ - Success: Tenant is created, modal closes, list refreshes, toast notification appears
77
+ - Error: Error message displayed in the form, toast notification shows error details
78
+
79
+ ### Viewing Tenant Details
80
+
81
+ 1. **Click Tenant Name**: Click on any tenant name in the list to view details
82
+ 2. **Actions Menu**: Click "Actions" dropdown and select "View Details"
83
+ 3. **Details Modal Shows**:
84
+ - Basic information (name, description, app name, environment, status, auth type)
85
+ - Creation and update timestamps
86
+ - Error messages (if any)
87
+ - Secret API Keys section with reveal/revoke functionality
88
+
89
+ ### Editing a Tenant
90
+
91
+ 1. **Open Actions Menu**: Click "Actions" button next to the tenant
92
+ 2. **Select "Edit"**: Opens the edit modal
93
+ 3. **Modify Fields**: Update name, description, environment, or project
94
+ 4. **Add New Secret Keys**: Add additional secret API keys (existing keys are preserved)
95
+ 5. **Submit**: Click "Update Tenant" button
96
+ 6. **Result**: Tenant is updated, modal closes, list refreshes, selected tenant is cleared
97
+
98
+ ### Deleting a Tenant
99
+
100
+ 1. **Open Actions Menu**: Click "Actions" button next to the tenant
101
+ 2. **Select "Delete"**: Confirmation dialog appears
102
+ 3. **Confirm**: Tenant is permanently deleted
103
+ 4. **Result**: Tenant removed from list, toast notification confirms deletion
104
+
105
+ ### Managing Secret API Keys
106
+
107
+ #### Viewing Secret Keys
108
+
109
+ - **In Tenant Details**: All secret keys are listed with their metadata
110
+ - **Reveal Key**: Click "Reveal" button to view the actual secret value
111
+ - **Copy Key**: After revealing, click "Copy" to copy to clipboard
112
+ - **Hide Key**: Click "Hide" to conceal the secret value again
113
+
114
+ #### Revoking Secret Keys
115
+
116
+ 1. **In Tenant Details**: Click "Revoke" button next to a secret key
117
+ 2. **Confirm**: Confirm the revocation in the modal
118
+ 3. **Result**: Key is permanently revoked and removed from the list
119
+
120
+ #### Adding New Secret Keys
121
+
122
+ - **During Creation**: Add keys in the create tenant form
123
+ - **During Edit**: Add new keys in the edit form (existing keys remain unchanged)
124
+
125
+ ### Retrying Failed Tenant Creation
126
+
127
+ 1. **Identify Failed Tenant**: Look for tenants with status "error" (red badge)
128
+ 2. **Open Actions Menu**: Click "Actions" button
129
+ 3. **Select "Retry Creation"**: Only visible for tenants with error status
130
+ 4. **Result**: Retry process initiated, status updates accordingly
131
+
132
+ ### Regenerating Tenant Secret
133
+
134
+ **Note**: This feature is currently commented out in the UI but available in the backend.
135
+
136
+ ---
137
+
138
+ ## Implementation Details
139
+
140
+ ### Component Hierarchy
141
+
142
+ ```
143
+ TenantDashboard (Main Container)
144
+ ├── TenantList (Table View)
145
+ │ └── Action Dropdown Menu
146
+ ├── TenantDetails (Modal - View Only)
147
+ │ └── SecretKeyList (Secret Key Management)
148
+ ├── CreateTenantModal (Modal)
149
+ │ └── TenantForm
150
+ │ ├── SecretKeyModal (Add New Keys)
151
+ │ └── SecretKeyList (Preview New Keys)
152
+ ├── EditTenantModal (Modal)
153
+ │ └── TenantForm
154
+ │ ├── SecretKeyList (Existing Keys)
155
+ │ ├── SecretKeyList (New Keys to Add)
156
+ │ └── SecretKeyModal (Add New Keys)
157
+ └── Toast (Notifications)
158
+ ```
159
+
160
+ ### Key Components
161
+
162
+ #### 1. TenantDashboard (`TenantDashboard.tsx`)
163
+
164
+ **Purpose**: Main orchestrator component that manages the entire tenant management workflow.
165
+
166
+ **Responsibilities**:
167
+
168
+ - State machine initialization and management
169
+ - GraphQL query/mutation orchestration
170
+ - Event handling and state synchronization
171
+ - Modal visibility management
172
+ - Toast notification management
173
+
174
+ **Key Features**:
175
+
176
+ - Uses XState machine (`tenantMachine`) for predictable state management
177
+ - Integrates with Apollo Client for GraphQL operations
178
+ - Manages multiple modals (create, edit, details) with proper state isolation
179
+ - Handles organization context via URL parameter (`orgName`)
180
+
181
+ **State Management Flow**:
182
+
183
+ ```typescript
184
+ // Initial load
185
+ useEffect(() => {
186
+ send({ type: 'LOAD_TENANTS' });
187
+ await loadTenants({ variables: { orgName } });
188
+ }, []);
189
+
190
+ // State updates via machine events
191
+ send({ type: 'SUCCESS', data: tenants });
192
+ send({ type: 'ERROR', error: errorMessage });
193
+ send({ type: 'SELECT_TENANT', tenant });
194
+ ```
195
+
196
+ #### 2. TenantList (`TenantList.tsx`)
197
+
198
+ **Purpose**: Displays tenants in a tabular format with action capabilities.
199
+
200
+ **Features**:
201
+
202
+ - Responsive table layout
203
+ - Status badges with color coding
204
+ - Environment tag badges
205
+ - Action dropdown menu per tenant
206
+ - Empty state with call-to-action
207
+ - Loading state with spinner
208
+
209
+ **Status Colors**:
210
+
211
+ - `active`: Green
212
+ - `pending`: Yellow
213
+ - `error`: Red
214
+ - `disabled`: Gray
215
+ - `completed`: Blue
216
+
217
+ **Environment Colors**:
218
+
219
+ - `development`: Cyan
220
+ - `staging`: Orange
221
+ - `production`: Red
222
+
223
+ **Action Menu Options**:
224
+
225
+ - View Details
226
+ - Edit
227
+ - Retry Creation (only for error status)
228
+ - Delete
229
+
230
+ #### 3. TenantDetails (`TenantDetails.tsx`)
231
+
232
+ **Purpose**: Modal component displaying comprehensive tenant information.
233
+
234
+ **Displays**:
235
+
236
+ - Basic information (name, description, app name)
237
+ - Environment tag
238
+ - Status badge
239
+ - Auth type
240
+ - Timestamps (created/updated)
241
+ - Error messages (if applicable)
242
+ - Secret API Keys section
243
+
244
+ **Secret Key Integration**:
245
+
246
+ - Embeds `SecretKeyList` component
247
+ - Passes `send` function for state machine updates
248
+ - Enables reveal/revoke actions
249
+
250
+ #### 4. CreateTenantModal (`CreateTenantModal.tsx`)
251
+
252
+ **Purpose**: Modal wrapper for tenant creation form.
253
+
254
+ **Features**:
255
+
256
+ - Full-screen overlay modal
257
+ - Click-outside-to-close functionality
258
+ - Responsive design (max-width: 4xl)
259
+ - Integrates with `TenantForm` component
260
+
261
+ #### 5. EditTenantModal (`EditTenantModal.tsx`)
262
+
263
+ **Purpose**: Modal wrapper for tenant editing form.
264
+
265
+ **Features**:
266
+
267
+ - Similar to CreateTenantModal
268
+ - Pre-populates form with existing tenant data
269
+ - Handles update-specific logic
270
+
271
+ #### 6. TenantForm (`TenantForm/TenantForm.tsx`)
272
+
273
+ **Purpose**: Reusable form component for both create and edit operations.
274
+
275
+ **Form Fields**:
276
+
277
+ 1. **Name** (required, min 3 chars)
278
+ 2. **Description** (required)
279
+ 3. **Project** (optional dropdown)
280
+ 4. **Environment** (required, auto-populated from project)
281
+ 5. **Secret API Keys** (required for creation, optional for edit)
282
+
283
+ **Key Behaviors**:
284
+
285
+ - **Project Selection**: Automatically fetches environment tags when project is selected
286
+ - **Environment Auto-selection**: Sets first environment tag as default
287
+ - **Validation**: Real-time validation with error messages
288
+ - **Secret Key Management**:
289
+ - Create mode: Requires at least one key
290
+ - Edit mode: Shows existing keys separately from new keys
291
+ - New keys can be added via modal
292
+ - Existing keys cannot be modified (only revoked via details view)
293
+
294
+ **State Synchronization**:
295
+
296
+ - Updates XState machine on field changes
297
+ - Validates form before submission
298
+ - Handles loading and error states
299
+
300
+ #### 7. SecretKeyList (`SecretKeyList/SecretKeyList.tsx`)
301
+
302
+ **Purpose**: Displays and manages secret API keys.
303
+
304
+ **Features**:
305
+
306
+ - Table view of secret keys
307
+ - Reveal/Hide functionality for secret values
308
+ - Copy to clipboard
309
+ - Revoke functionality with confirmation
310
+ - Security warning banner
311
+ - Loading states for async operations
312
+
313
+ **Key Operations**:
314
+
315
+ - `revealKey(keyId)`: Fetches and displays secret value
316
+ - `revokeKey(keyId)`: Permanently deletes secret key
317
+ - Uses `useSecretKeys` hook for API operations
318
+
319
+ **Security Considerations**:
320
+
321
+ - Secrets are hidden by default
322
+ - One-time reveal (must click reveal for each key)
323
+ - Confirmation required for revocation
324
+ - Security best practices displayed in warning banner
325
+
326
+ #### 8. Toast (`Toast/Toast.tsx`)
327
+
328
+ **Purpose**: User notification system.
329
+
330
+ **Types**:
331
+
332
+ - `success`: Green background
333
+ - `error`: Red background
334
+ - `info`: Blue background
335
+ - `warning`: Yellow background
336
+
337
+ **Features**:
338
+
339
+ - Auto-dismiss after 5 seconds (configurable)
340
+ - Manual close button
341
+ - Icon indicators per type
342
+ - Fixed position (top-right)
343
+
344
+ ---
345
+
346
+ ---
347
+
348
+ ## State Management
349
+
350
+ ### XState Machine (`tenantMachine.ts`)
351
+
352
+ The tenant management system uses XState for predictable state management.
353
+
354
+ #### Machine Context
355
+
356
+ ```typescript
357
+ interface TenantMachineContext {
358
+ tenant: Partial<ITenant>;
359
+ tenants: ITenant[];
360
+ selectedTenant?: ITenant;
361
+ formData: TenantFormData;
362
+ loading: boolean;
363
+ error?: string;
364
+ success?: string;
365
+ validationErrors: Record<string, string>;
366
+ }
367
+ ```
368
+
369
+ #### Machine States
370
+
371
+ 1. **idle**: Initial state, ready for actions
372
+ 2. **loadingTenants**: Fetching tenant list
373
+ 3. **loadingTenant**: Fetching single tenant details
374
+ 4. **creatingTenant**: Creating new tenant
375
+ 5. **updatingTenant**: Updating existing tenant
376
+ 6. **deletingTenant**: Deleting tenant
377
+ 7. **regeneratingSecret**: Regenerating tenant secret
378
+ 8. **retryingCreation**: Retrying failed tenant creation
379
+
380
+ #### Key Events
381
+
382
+ - `LOAD_TENANTS`: Initialize tenant list loading
383
+ - `SELECT_TENANT`: Select a tenant for viewing/editing
384
+ - `CREATE_TENANT`: Initiate tenant creation
385
+ - `UPDATE_TENANT`: Initiate tenant update
386
+ - `DELETE_TENANT`: Initiate tenant deletion
387
+ - `SUCCESS`: Handle successful operation
388
+ - `ERROR`: Handle error condition
389
+ - `RESET`: Clear selected tenant and errors
390
+ - `UPDATE_FORM`: Update form field in context
391
+ - `REVOKE_SECRET_KEY`: Revoke a secret key
392
+
393
+ #### Actions
394
+
395
+ - `setTenants`: Update tenants array
396
+ - `setSelectedTenant`: Update selected tenant
397
+ - `addTenant`: Add new tenant to list
398
+ - `updateTenantInList`: Update tenant in list
399
+ - `removeTenant`: Remove tenant from list
400
+ - `updateForm`: Update form data
401
+ - `validateForm`: Validate form fields
402
+ - `resetForm`: Clear form data
403
+ - `setError`: Set error message
404
+ - `setSuccess`: Set success message
405
+
406
+ ---
407
+
408
+ ## GraphQL Integration
409
+
410
+ ### Queries
411
+
412
+ #### GetTenants
413
+
414
+ ```graphql
415
+ query GetTenants($orgName: String!) {
416
+ tenants(orgName: $orgName) {
417
+ id
418
+ tenantId
419
+ name
420
+ description
421
+ appName
422
+ status
423
+ environmentTag {
424
+ id
425
+ name
426
+ }
427
+ project {
428
+ id
429
+ name
430
+ }
431
+ clientConfigurations {
432
+ id
433
+ name
434
+ description
435
+ createdAt
436
+ }
437
+ errorMessage
438
+ createdAt
439
+ updatedAt
440
+ }
441
+ }
442
+ ```
443
+
444
+ #### GetTenant
445
+
446
+ ```graphql
447
+ query GetTenant($id: ID!) {
448
+ tenant(id: $id) {
449
+ # Same fields as GetTenants
450
+ }
451
+ }
452
+ ```
453
+
454
+ #### GetProjectsNameAndId
455
+
456
+ ```graphql
457
+ query GetProjectsNameAndId($orgName: String!) {
458
+ getProjects(orgName: $orgName) {
459
+ data {
460
+ id
461
+ name
462
+ }
463
+ }
464
+ }
465
+ ```
466
+
467
+ #### GetEnvironmentTags
468
+
469
+ ```graphql
470
+ query GetEnvironmentTags($projectId: ID!) {
471
+ getEnvironmentTags(projectId: $projectId) {
472
+ id
473
+ name
474
+ }
475
+ }
476
+ ```
477
+
478
+ ### Mutations
479
+
480
+ #### CreateTenant
481
+
482
+ ```graphql
483
+ mutation CreateTenant($input: TenantInput!) {
484
+ createTenant(input: $input) {
485
+ tenant {
486
+ id
487
+ tenantId
488
+ name
489
+ # ... other fields
490
+ }
491
+ message
492
+ }
493
+ }
494
+ ```
495
+
496
+ **Input Structure**:
497
+
498
+ ```typescript
499
+ {
500
+ name: string;
501
+ description: string;
502
+ environmentTag: string; // Environment tag ID
503
+ authType: AuthType.ClientSecret;
504
+ clientConfigurations: Array<{
505
+ name: string;
506
+ description?: string;
507
+ }>;
508
+ vault: string; // Project ID
509
+ organization: string; // Organization name/slug
510
+ }
511
+ ```
512
+
513
+ #### UpdateTenant
514
+
515
+ ```graphql
516
+ mutation UpdateTenant($id: ID!, $input: TenantUpdateInput!) {
517
+ updateTenant(id: $id, input: $input) {
518
+ id
519
+ tenantId
520
+ name
521
+ # ... updated fields
522
+ }
523
+ }
524
+ ```
525
+
526
+ **Update Input**: Only includes changed fields (partial update)
527
+
528
+ #### DeleteTenant
529
+
530
+ ```graphql
531
+ mutation DeleteTenant($id: ID!) {
532
+ deleteTenant(id: $id)
533
+ }
534
+ ```
535
+
536
+ #### RegenerateTenantSecret
537
+
538
+ ```graphql
539
+ mutation RegenerateTenantSecret($id: ID!) {
540
+ regenerateTenantSecret(id: $id) {
541
+ id
542
+ # ... tenant fields
543
+ }
544
+ }
545
+ ```
546
+
547
+ #### RetryTenantCreation
548
+
549
+ ```graphql
550
+ mutation RetryTenantCreation($tenantId: ID!) {
551
+ retryTenantCreation(tenantId: $tenantId)
552
+ }
553
+ ```
554
+
555
+ ### Apollo Client Configuration
556
+
557
+ - **Fetch Policy**: `cache-and-network` for queries (ensures fresh data)
558
+ - **Fetch Policy**: `network-only` for tenant details (always fetch latest)
559
+ - **Refetch Queries**: Automatic refetch after mutations
560
+ - **Error Handling**: Centralized via `onError` callbacks
561
+ - **Loading States**: Managed via Apollo hooks
562
+
563
+ ---
564
+
565
+ ## Backend Architecture & Inngest Integration
566
+
567
+ ### Overview
568
+
569
+ The Tenant Management System uses an **event-driven architecture** with **Inngest** for asynchronous background processing. The backend service handles immediate database operations, while Inngest functions handle external integrations (primarily Keycloak client management) and long-running workflows.
570
+
571
+ ### Architecture Pattern
572
+
573
+ The system follows a **separation of concerns** pattern:
574
+
575
+ 1. **Service Layer** (`TenantService`): Handles immediate database operations and triggers Inngest events
576
+ 2. **Inngest Functions**: Handle external integrations (Keycloak) and async workflows
577
+ 3. **No Infinite Loops**: Inngest functions perform different operations than the service methods that trigger them
578
+
579
+ ### Backend Service Layer
580
+
581
+ #### TenantService (`tenant-service.ts`)
582
+
583
+ **Purpose**: Core service for tenant CRUD operations and business logic.
584
+
585
+ **Key Responsibilities**:
586
+
587
+ - Database operations (create, read, update, delete)
588
+ - Tenant ID resolution and mapping
589
+ - Secret key generation and management
590
+ - Inngest event triggering for async operations
591
+ - Status management (pending → active → error)
592
+
593
+ **Key Methods**:
594
+
595
+ ##### `createTenant(input: ITenantInput)`
596
+
597
+ **Flow**:
598
+
599
+ 1. Generates unique `jobId` for tracking
600
+ 2. Creates tenant record in MongoDB with status `Pending`
601
+ 3. Generates `connectionId` (secret for tenant connection)
602
+ 4. Creates `appName` from tenant name (lowercase, hyphenated)
603
+ 5. Maps `vault` input to `project` (MongoDB ObjectId)
604
+ 6. Maps `organization` input to ObjectId
605
+ 7. **Triggers Inngest Event**: `TENANT_MGMT_CREATE_CLIENT_EVENT` for Keycloak client creation
606
+ 8. Returns tenant with `jobId` and success message
607
+
608
+ **Inngest Event Payload**:
609
+
610
+ ```typescript
611
+ {
612
+ name: WorkflowNamespace.TENANT_MGMT_CREATE_CLIENT_EVENT,
613
+ data: {
614
+ tenantId: tenant.id,
615
+ id: tenant._id, // MongoDB ObjectId
616
+ clientConfigurations: input.clientConfigurations
617
+ }
618
+ }
619
+ ```
620
+
621
+ ##### `updateTenant(id: string, input: Partial<ITenantInput>)`
622
+
623
+ **Flow**:
624
+
625
+ 1. Finds existing tenant by `tenantId`
626
+ 2. Updates basic fields (name, description, environmentTag, project)
627
+ 3. **Preserves existing client configurations**
628
+ 4. Merges new configurations with existing ones
629
+ 5. **Triggers Inngest Event**: `TENANT_MGMT_CREATE_CLIENT_EVENT` if new keys are added
630
+ 6. Returns updated tenant
631
+
632
+ **Important**: Only new client configurations trigger Inngest events. Existing keys remain unchanged.
633
+
634
+ ##### `deleteTenant(id: string)`
635
+
636
+ **Flow**:
637
+
638
+ 1. Finds tenant by `tenantId`
639
+ 2. Deletes tenant from MongoDB
640
+ 3. **Triggers Inngest Event**: `TENANT_MGMT_DELETE_TENANT_EVENT` with client configurations
641
+ 4. Returns success boolean
642
+
643
+ **Inngest Event Payload**:
644
+
645
+ ```typescript
646
+ {
647
+ name: WorkflowNamespace.TENANT_MGMT_DELETE_TENANT_EVENT,
648
+ data: {
649
+ clientConfiguraiton: tenant.clientConfigurations // Note: typo in original code
650
+ }
651
+ }
652
+ ```
653
+
654
+ ##### `getSecretKeyValue(tenantId: string, keyId: string)`
655
+
656
+ **Purpose**: Reveals secret key value on-demand (deterministic generation).
657
+
658
+ **Flow**:
659
+
660
+ 1. Finds tenant by `tenantId`
661
+ 2. Locates client configuration by `keyId`
662
+ 3. **Generates secret deterministically** using `generateSecretFromName()`
663
+ 4. Creates base64-encoded secret: `clientId:secret`
664
+ 5. Returns secret value
665
+
666
+ **Security**: Secrets are not stored; they are regenerated deterministically when needed.
667
+
668
+ ##### `revokeSecretKey(tenantId: string, keyId: string)`
669
+
670
+ **Flow**:
671
+
672
+ 1. Finds tenant and secret key
673
+ 2. Removes key from `clientConfigurations` array
674
+ 3. Updates tenant in database
675
+ 4. **Triggers Inngest Event**: `TENANT_MGMT_DELETE_TENANT_EVENT` to delete Keycloak client
676
+ 5. Returns revoked key ID
677
+
678
+ ##### `retryTenantCreation(tenantId: string)`
679
+
680
+ **Flow**:
681
+
682
+ 1. Validates tenant exists and has `error` status
683
+ 2. Increments retry count
684
+ 3. Resets status to `Pending`
685
+ 4. Generates new `jobId`
686
+ 5. Updates tenant in database
687
+ 6. Returns success boolean
688
+
689
+ **Note**: This only resets the status. The actual retry is handled by background processes monitoring pending tenants.
690
+
691
+ #### Tenant ID Resolution
692
+
693
+ **Method**: `resolveTenantId(tenantId: string)`
694
+
695
+ **Purpose**: Maps special tenant IDs to actual IDs.
696
+
697
+ **Implementation**:
698
+
699
+ ```typescript
700
+ private resolveTenantId(tenantId: string): string {
701
+ return defaultTenantIdMapper(tenantId);
702
+ }
703
+ ```
704
+
705
+ **Mapping Logic**:
706
+
707
+ - `'default'` → `config.STATIC_TENANT_ID` (from environment)
708
+ - All other IDs → Returned as-is
709
+
710
+ **Usage**: All tenant lookups use this method to ensure consistent ID resolution.
711
+
712
+ ### Inngest Event-Driven Workflow
713
+
714
+ #### Event Namespace
715
+
716
+ All tenant management events use the `WorkflowNamespace` constants:
717
+
718
+ **Trigger Events** (what functions listen for):
719
+
720
+ - `TENANT_MGMT_CREATE_CLIENT_EVENT`: Create Keycloak clients
721
+ - `TENANT_MGMT_DELETE_TENANT_EVENT`: Delete Keycloak clients
722
+
723
+ **Function IDs**:
724
+
725
+ - `TENANT_MGMT_CREATE_CLIENT`: Function that creates clients
726
+ - `TENANT_MGMT_DELETE_TENANT`: Function that deletes clients
727
+
728
+ #### Inngest Functions
729
+
730
+ ##### 1. `createTenantClientFunction`
731
+
732
+ **Purpose**: Creates Keycloak clients for tenant secret keys.
733
+
734
+ **Trigger**: `TENANT_MGMT_CREATE_CLIENT_EVENT`
735
+
736
+ **Event Data**:
737
+
738
+ ```typescript
739
+ {
740
+ tenantId: string;
741
+ id: string; // MongoDB ObjectId
742
+ clientConfigurations: Array<{
743
+ name: string;
744
+ description?: string;
745
+ }>;
746
+ }
747
+ ```
748
+
749
+ **Workflow Steps**:
750
+
751
+ 1. **Step: `create-secret-keys`**
752
+ - Iterates through `clientConfigurations`
753
+ - For each key without `clientId`:
754
+ - Generates deterministic secret using `generateSecretFromName(keyName, tenantId)`
755
+ - Creates unique `clientId`: `tenant-${tenantId}-key-${timestamp}`
756
+ - Calls `KeycloakInternalAdminService.Instance.createClientWithClientSecretAuthType(clientId, clientSecret)`
757
+ - Creates key object with metadata
758
+ - Returns array of created keys with `clientId` and metadata
759
+
760
+ 2. **Step: `update-tenant-with-keys`**
761
+ - Calls `tenantService.update()` with:
762
+ - Updated `clientConfigurations` array (with `clientId` values)
763
+ - Status set to `Active`
764
+ - Returns success confirmation
765
+
766
+ **Result**: Tenant status changes from `Pending` → `Active`, and Keycloak clients are created.
767
+
768
+ **Error Handling**: If Keycloak client creation fails, tenant status remains `Pending` or changes to `Error`.
769
+
770
+ ##### 2. `deleteTenantClientFunction`
771
+
772
+ **Purpose**: Deletes Keycloak clients when tenant or secret keys are revoked.
773
+
774
+ **Trigger**: `TENANT_MGMT_DELETE_TENANT_EVENT`
775
+
776
+ **Event Data**:
777
+
778
+ ```typescript
779
+ {
780
+ clientConfiguration: IClientConfigurations[] // Array of client configs to delete
781
+ }
782
+ ```
783
+
784
+ **Workflow Steps**:
785
+
786
+ 1. **Step: `delete-tenant`**
787
+ - Iterates through `clientConfiguration` array
788
+ - For each config with `clientId`:
789
+ - Calls `keycloakAdminService.deleteClient(clientId)`
790
+ - Continues even if individual deletions fail
791
+ - Returns success
792
+
793
+ **Error Handling**: Individual client deletion failures are logged but don't stop the process.
794
+
795
+ ##### 3. `createTenantFunction` (Legacy/Alternative)
796
+
797
+ **Purpose**: Alternative tenant creation workflow (used in some contexts).
798
+
799
+ **Trigger**: `TENANT_MGMT_CREATE_TENANT_EVENT`
800
+
801
+ **Note**: This function creates a tenant from project data, typically used in project creation workflows rather than direct tenant creation.
802
+
803
+ ### Secret Key Generation
804
+
805
+ #### Deterministic Secret Generation
806
+
807
+ **Function**: `generateSecretFromName(keyName: string, tenantId: string)`
808
+
809
+ **Purpose**: Generate reproducible secrets for API keys.
810
+
811
+ **Algorithm**:
812
+
813
+ 1. Uses salt from environment: `process.env.SECRET_KEY_SALT` or default
814
+ 2. Creates data string: `${keyName}:${tenantId}:${salt}`
815
+ 3. Generates SHA-256 hash
816
+ 4. Encodes as base64
817
+ 5. Removes non-alphanumeric characters
818
+ 6. Limits to 32 characters (Keycloak requirement)
819
+
820
+ **Benefits**:
821
+
822
+ - Secrets can be regenerated on-demand
823
+ - No need to store secrets in database
824
+ - Consistent across regenerations
825
+
826
+ **Usage**:
827
+
828
+ - When revealing secret keys (on-demand generation)
829
+ - When creating new Keycloak clients
830
+
831
+ #### Secret Format
832
+
833
+ **For API Usage**: Secrets are base64-encoded as `clientId:secret`
834
+
835
+ **Example**:
836
+
837
+ ```typescript
838
+ const secret = generateSecretFromName('ACCESS_KEY', 'tenant-123');
839
+ const clientSecret = Buffer.from(`${clientId}:${secret}`).toString('base64');
840
+ // Returns: "Y2xpZW50SWQ6c2VjcmV0VmFsdWU="
841
+ ```
842
+
843
+ ### Complete Data Flow
844
+
845
+ #### Creating a Tenant
846
+
847
+ ```
848
+ 1. Frontend: User submits create tenant form
849
+
850
+ 2. GraphQL Mutation: createTenant(input)
851
+
852
+ 3. TenantService.createTenant()
853
+ ├── Creates tenant in MongoDB (status: Pending)
854
+ ├── Generates jobId, connectionId, appName
855
+ └── Triggers Inngest Event: TENANT_MGMT_CREATE_CLIENT_EVENT
856
+
857
+ 4. Returns tenant to frontend (status: Pending)
858
+
859
+ 5. Inngest Function: createTenantClientFunction
860
+ ├── Step 1: Create Keycloak clients
861
+ │ ├── Generate secrets deterministically
862
+ │ ├── Create clientId for each key
863
+ │ └── Call Keycloak API to create clients
864
+ └── Step 2: Update tenant
865
+ ├── Add clientId to each configuration
866
+ └── Set status: Active
867
+
868
+ 6. Tenant status: Pending → Active
869
+ ```
870
+
871
+ #### Updating a Tenant (Adding New Keys)
872
+
873
+ ```
874
+ 1. Frontend: User adds new secret keys in edit form
875
+
876
+ 2. GraphQL Mutation: updateTenant(id, input)
877
+
878
+ 3. TenantService.updateTenant()
879
+ ├── Preserves existing clientConfigurations
880
+ ├── Merges new configurations
881
+ └── Triggers Inngest Event: TENANT_MGMT_CREATE_CLIENT_EVENT
882
+
883
+ 4. Returns updated tenant to frontend
884
+
885
+ 5. Inngest Function: createTenantClientFunction
886
+ ├── Step 1: Create Keycloak clients for NEW keys only
887
+ └── Step 2: Update tenant with all keys (existing + new)
888
+ ```
889
+
890
+ #### Revoking a Secret Key
891
+
892
+ ```
893
+ 1. Frontend: User clicks "Revoke" on a secret key
894
+
895
+ 2. GraphQL Mutation: revokeSecretKey(tenantId, keyId)
896
+
897
+ 3. TenantService.revokeSecretKey()
898
+ ├── Removes key from clientConfigurations array
899
+ ├── Updates tenant in database
900
+ └── Triggers Inngest Event: TENANT_MGMT_DELETE_TENANT_EVENT
901
+
902
+ 4. Returns success to frontend
903
+
904
+ 5. Inngest Function: deleteTenantClientFunction
905
+ └── Step: Delete Keycloak client by clientId
906
+ ```
907
+
908
+ #### Deleting a Tenant
909
+
910
+ ```
911
+ 1. Frontend: User confirms tenant deletion
912
+
913
+ 2. GraphQL Mutation: deleteTenant(id)
914
+
915
+ 3. TenantService.deleteTenant()
916
+ ├── Deletes tenant from MongoDB
917
+ └── Triggers Inngest Event: TENANT_MGMT_DELETE_TENANT_EVENT
918
+
919
+ 4. Returns success to frontend
920
+
921
+ 5. Inngest Function: deleteTenantClientFunction
922
+ └── Step: Delete all Keycloak clients for tenant
923
+ ```
924
+
925
+ ### Keycloak Integration
926
+
927
+ #### Client Creation
928
+
929
+ **Service**: `KeycloakInternalAdminService.Instance.createClientWithClientSecretAuthType()`
930
+
931
+ **Parameters**:
932
+
933
+ - `clientId`: Unique identifier (format: `tenant-{tenantId}-key-{timestamp}`)
934
+ - `clientSecret`: Deterministically generated secret (32 chars, alphanumeric)
935
+
936
+ **Configuration**:
937
+
938
+ - Authentication type: Client Secret
939
+ - Client credentials flow enabled
940
+ - Scopes and permissions configured per tenant requirements
941
+
942
+ #### Client Deletion
943
+
944
+ **Service**: `keycloakAdminService.deleteClient(clientId)`
945
+
946
+ **Behavior**:
947
+
948
+ - Permanently removes client from Keycloak
949
+ - All associated tokens become invalid
950
+ - Cannot be undone
951
+
952
+ ### Status Lifecycle
953
+
954
+ ```
955
+ Pending → Active (when Keycloak clients created successfully)
956
+ Pending → Error (when Keycloak client creation fails)
957
+ Error → Pending (when retry is initiated)
958
+ ```
959
+
960
+ **Status Transitions**:
961
+
962
+ - **Pending**: Initial state, waiting for Keycloak client creation
963
+ - **Active**: All Keycloak clients created successfully
964
+ - **Error**: Keycloak client creation failed (error message stored)
965
+ - **Disabled**: Manually disabled (not used in current flow)
966
+ - **Completed**: Legacy status (not commonly used)
967
+
968
+ ### Error Handling
969
+
970
+ #### Service Layer Errors
971
+
972
+ - **Database Errors**: Thrown immediately, caught by GraphQL resolver
973
+ - **Validation Errors**: Thrown before database operations
974
+ - **Inngest Trigger Errors**: Logged but don't fail the operation (event is queued)
975
+
976
+ #### Inngest Function Errors
977
+
978
+ - **Keycloak API Errors**: Logged, tenant status may remain `Pending` or change to `Error`
979
+ - **Partial Failures**: Individual client creation failures don't stop the entire process
980
+ - **Retry Mechanism**: Failed operations can be retried via `retryTenantCreation()`
981
+
982
+ ### Performance Considerations
983
+
984
+ #### Async Processing
985
+
986
+ - **Immediate Response**: Service methods return immediately after triggering Inngest events
987
+ - **Background Processing**: Keycloak operations happen asynchronously
988
+ - **Status Updates**: Frontend can poll or use subscriptions to track status changes
989
+
990
+ #### Database Operations
991
+
992
+ - **Optimistic Updates**: Frontend updates immediately, backend confirms asynchronously
993
+ - **Idempotency**: Inngest functions are designed to be safely retried
994
+ - **Transaction Safety**: Database updates are atomic, but Keycloak operations are separate
995
+
996
+ ### Monitoring & Debugging
997
+
998
+ #### Logging
999
+
1000
+ - **Service Layer**: Uses structured logging with tenant context
1001
+ - **Inngest Functions**: Console logs for debugging (can be enhanced with proper logging)
1002
+ - **Keycloak Operations**: Errors logged with clientId and tenantId
1003
+
1004
+ #### Tracking
1005
+
1006
+ - **Job IDs**: Each tenant creation gets a unique `jobId` for tracking
1007
+ - **Retry Count**: Failed operations track retry attempts
1008
+ - **Error Messages**: Stored in `tenant.errorMessage` for debugging
1009
+
1010
+ ### Best Practices
1011
+
1012
+ 1. **Always Check Status**: Before operations, verify tenant status
1013
+ 2. **Handle Async Nature**: Keycloak operations are async; don't expect immediate completion
1014
+ 3. **Idempotent Operations**: Inngest functions can be safely retried
1015
+ 4. **Error Recovery**: Use `retryTenantCreation()` for failed operations
1016
+ 5. **Secret Security**: Never log or expose secret values
1017
+ 6. **Client ID Uniqueness**: Ensure clientIds are unique across all tenants
1018
+
1019
+ ---
1020
+
1021
+ ## Important Notes and Best Practices
1022
+
1023
+ ### 1. Tenant ID vs ID
1024
+
1025
+ **Critical Distinction**:
1026
+
1027
+ - `id`: MongoDB ObjectId (used internally)
1028
+ - `tenantId`: String identifier (used in API calls and display)
1029
+
1030
+ **Usage**:
1031
+
1032
+ ```typescript
1033
+ // For GraphQL mutations/queries
1034
+ variables: {
1035
+ id: tenant.tenantId;
1036
+ }
1037
+
1038
+ // For display and internal references
1039
+ tenant.id; // MongoDB ID
1040
+ tenant.tenantId; // Tenant identifier
1041
+ ```
1042
+
1043
+ ### 2. Secret Key Management
1044
+
1045
+ **Important Behaviors**:
1046
+
1047
+ - **Creation**: At least one secret key is required when creating a tenant
1048
+ - **Editing**: Existing keys are preserved; only new keys can be added
1049
+ - **Revealing**: Secret values are fetched on-demand (not stored in state)
1050
+ - **Revocation**: Permanent action; cannot be undone
1051
+ - **Security**: Secrets are hidden by default; must explicitly reveal
1052
+
1053
+ **Best Practices**:
1054
+
1055
+ - Never log secret values
1056
+ - Use one-time reveal pattern
1057
+ - Always confirm before revocation
1058
+ - Rotate keys regularly
1059
+
1060
+ ### 3. Form State Management
1061
+
1062
+ **Key Points**:
1063
+
1064
+ - Form state is managed in XState machine context
1065
+ - Field updates trigger machine events
1066
+ - Validation happens before submission
1067
+ - Form resets after successful operations
1068
+
1069
+ **Form Data Structure**:
1070
+
1071
+ ```typescript
1072
+ {
1073
+ name: string;
1074
+ description: string;
1075
+ environment: string | undefined; // Environment tag ID
1076
+ projectId?: string; // Project ID
1077
+ clientConfigurations: Array<{
1078
+ name: string;
1079
+ description?: string;
1080
+ }>;
1081
+ }
1082
+ ```
1083
+
1084
+ ### 4. Project and Environment Relationship
1085
+
1086
+ **Workflow**:
1087
+
1088
+ 1. User selects a project
1089
+ 2. System automatically fetches environment tags for that project
1090
+ 3. First environment tag is auto-selected
1091
+ 4. User can change environment if needed
1092
+
1093
+ **Important**: Environment tags are project-specific. If no project is selected, environment selection may be limited.
1094
+
1095
+ ## Summary
1096
+
1097
+ The Tenant Management System provides a comprehensive, user-friendly interface for managing multi-tenant configurations. It leverages modern React patterns, state management with XState, GraphQL for efficient data operations, and Inngest for asynchronous background processing. The system is designed with type safety, error handling, and user experience as top priorities.
1098
+
1099
+ **Key Takeaways**:
1100
+
1101
+ **Frontend**:
1102
+
1103
+ - ✅ Full CRUD operations with proper state management
1104
+ - ✅ Secret key management with security best practices
1105
+ - ✅ Project and environment integration
1106
+ - ✅ Comprehensive error handling and user feedback
1107
+ - ✅ Type-safe implementation with TypeScript
1108
+ - ✅ Scalable architecture with XState and GraphQL
1109
+
1110
+ **Backend**:
1111
+
1112
+ - ✅ Event-driven architecture with Inngest for async operations
1113
+ - ✅ Keycloak integration for client management
1114
+ - ✅ Deterministic secret generation (no secret storage)
1115
+ - ✅ Status lifecycle management (Pending → Active/Error)
1116
+ - ✅ Retry mechanism for failed operations
1117
+ - ✅ Separation of concerns (Service handles DB, Inngest handles external APIs)