@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.
- package/LICENSE +21 -0
- package/lib/components/Logo.d.ts +4 -0
- package/lib/components/Logo.d.ts.map +1 -0
- package/lib/components/Logo.js +16 -0
- package/lib/components/Logo.js.map +1 -0
- package/lib/components/help/SidebarSearch.d.ts +8 -0
- package/lib/components/help/SidebarSearch.d.ts.map +1 -0
- package/lib/components/help/SidebarSearch.js +111 -0
- package/lib/components/help/SidebarSearch.js.map +1 -0
- package/lib/components/help/index.d.ts +2 -0
- package/lib/components/help/index.d.ts.map +1 -0
- package/lib/components/landing/FeatureCard.d.ts +13 -0
- package/lib/components/landing/FeatureCard.d.ts.map +1 -0
- package/lib/components/landing/FeatureCard.js +85 -0
- package/lib/components/landing/FeatureCard.js.map +1 -0
- package/lib/components/landing/QuickLinkCard.d.ts +8 -0
- package/lib/components/landing/QuickLinkCard.d.ts.map +1 -0
- package/lib/components/landing/QuickLinkCard.js +26 -0
- package/lib/components/landing/QuickLinkCard.js.map +1 -0
- package/lib/components/landing/SearchInput.d.ts +10 -0
- package/lib/components/landing/SearchInput.d.ts.map +1 -0
- package/lib/components/landing/SearchInput.js +223 -0
- package/lib/components/landing/SearchInput.js.map +1 -0
- package/lib/components/landing/index.d.ts +4 -0
- package/lib/components/landing/index.d.ts.map +1 -0
- package/lib/components/welcome.d.ts +3 -0
- package/lib/components/welcome.d.ts.map +1 -0
- package/lib/compute.d.ts +4 -0
- package/lib/compute.d.ts.map +1 -0
- package/lib/compute.js +96 -0
- package/lib/compute.js.map +1 -0
- package/lib/config/env-config.d.ts +4 -0
- package/lib/config/env-config.d.ts.map +1 -0
- package/lib/config/env-config.js +7 -0
- package/lib/config/env-config.js.map +1 -0
- package/lib/docs.config.d.ts +48 -0
- package/lib/docs.config.d.ts.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/lib/loaders/search.d.ts +1 -0
- package/lib/loaders/search.d.ts.map +1 -0
- package/lib/module.d.ts +4 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +11 -0
- package/lib/module.js.map +1 -0
- package/lib/pages/ArticlePage/ArticlePage.d.ts +4 -0
- package/lib/pages/ArticlePage/ArticlePage.d.ts.map +1 -0
- package/lib/pages/ArticlePage/ArticlePage.js +222 -0
- package/lib/pages/ArticlePage/ArticlePage.js.map +1 -0
- package/lib/pages/ArticlePage/index.d.ts +3 -0
- package/lib/pages/ArticlePage/index.d.ts.map +1 -0
- package/lib/pages/ArticlePage/index.js +3 -0
- package/lib/pages/ArticlePage/index.js.map +1 -0
- package/lib/pages/CategoryCollection/CategoryCollection.d.ts +4 -0
- package/lib/pages/CategoryCollection/CategoryCollection.d.ts.map +1 -0
- package/lib/pages/CategoryCollection/CategoryCollection.js +103 -0
- package/lib/pages/CategoryCollection/CategoryCollection.js.map +1 -0
- package/lib/pages/CategoryCollection/index.d.ts +3 -0
- package/lib/pages/CategoryCollection/index.d.ts.map +1 -0
- package/lib/pages/CategoryCollection/index.js +3 -0
- package/lib/pages/CategoryCollection/index.js.map +1 -0
- package/lib/pages/Help/HelpIndex.d.ts +4 -0
- package/lib/pages/Help/HelpIndex.d.ts.map +1 -0
- package/lib/pages/Help/HelpIndex.js +44 -0
- package/lib/pages/Help/HelpIndex.js.map +1 -0
- package/lib/pages/Help/index.d.ts +4 -0
- package/lib/pages/Help/index.d.ts.map +1 -0
- package/lib/pages/Help/index.js +226 -0
- package/lib/pages/Help/index.js.map +1 -0
- package/lib/pages/Landing/index.d.ts +3 -0
- package/lib/pages/Landing/index.d.ts.map +1 -0
- package/lib/pages/Landing/index.js +281 -0
- package/lib/pages/Landing/index.js.map +1 -0
- package/lib/routes.json +2533 -0
- package/lib/seo.d.ts +22 -0
- package/lib/seo.d.ts.map +1 -0
- package/lib/slot-fill/FooterFill.d.ts +3 -0
- package/lib/slot-fill/FooterFill.d.ts.map +1 -0
- package/lib/slot-fill/FooterFill.js +18 -0
- package/lib/slot-fill/FooterFill.js.map +1 -0
- package/lib/slot-fill/LogoFill.d.ts +5 -0
- package/lib/slot-fill/LogoFill.d.ts.map +1 -0
- package/lib/slot-fill/LogoFill.js +74 -0
- package/lib/slot-fill/LogoFill.js.map +1 -0
- package/lib/slot-fill/consts.d.ts +5 -0
- package/lib/slot-fill/consts.d.ts.map +1 -0
- package/lib/slot-fill/consts.js +1 -0
- package/lib/slot-fill/consts.js.map +1 -0
- package/lib/slot-fill/index.d.ts +4 -0
- package/lib/slot-fill/index.d.ts.map +1 -0
- package/lib/templates/assets/images/add-link-frontend.png +0 -0
- package/lib/templates/assets/images/add-package-backend.png +0 -0
- package/lib/templates/assets/images/add-to-backend-module.png +0 -0
- package/lib/templates/assets/images/add-upload-client-frontend.png +0 -0
- package/lib/templates/assets/images/additional-parameters.png +0 -0
- package/lib/templates/assets/images/aeh-implementation.png +0 -0
- package/lib/templates/assets/images/aeh-usage.png +0 -0
- package/lib/templates/assets/images/apollo-client/recommendation_cache_mgmt.png +0 -0
- package/lib/templates/assets/images/app-deploy-new-version/jenkins1.PNG +0 -0
- package/lib/templates/assets/images/app-deploy-new-version/jenkins2.PNG +0 -0
- package/lib/templates/assets/images/auth-wrapper-code.png +0 -0
- package/lib/templates/assets/images/cdebase.png +0 -0
- package/lib/templates/assets/images/cdm-locales-directory.png +0 -0
- package/lib/templates/assets/images/client-settings.png +0 -0
- package/lib/templates/assets/images/codegen_file_update.png +0 -0
- package/lib/templates/assets/images/configuration.png +0 -0
- package/lib/templates/assets/images/copy-plugin.png +0 -0
- package/lib/templates/assets/images/docusaurus.png +0 -0
- package/lib/templates/assets/images/error-link.png +0 -0
- package/lib/templates/assets/images/error-sample.png +0 -0
- package/lib/templates/assets/images/extension copy.png +0 -0
- package/lib/templates/assets/images/extension.png +0 -0
- package/lib/templates/assets/images/graphql/graphql-folder-backend.png +0 -0
- package/lib/templates/assets/images/graphql/graphql-folder-with-gql.png +0 -0
- package/lib/templates/assets/images/i18n-config.png +0 -0
- package/lib/templates/assets/images/image.png +0 -0
- package/lib/templates/assets/images/logo.svg +10 -0
- package/lib/templates/assets/images/logo1.svg +1 -0
- package/lib/templates/assets/images/modify-upload-false-server.png +0 -0
- package/lib/templates/assets/images/navigation-auth-enabled.png +0 -0
- package/lib/templates/assets/images/org-dashboard-navigation.png +0 -0
- package/lib/templates/assets/images/org-navigation.png +0 -0
- package/lib/templates/assets/images/preferences_graphql_type.png +0 -0
- package/lib/templates/assets/images/provider.png +0 -0
- package/lib/templates/assets/images/route-config.png +0 -0
- package/lib/templates/assets/images/service-accounts.png +0 -0
- package/lib/templates/assets/images/source-code/source-code-environments.png +0 -0
- package/lib/templates/assets/images/source-code/source-code-organization.png +0 -0
- package/lib/templates/assets/images/spin-clone-develop-deployment/jenkins-changes.png +0 -0
- package/lib/templates/assets/images/spin-clone-develop-deployment/lerna-changes.png +0 -0
- package/lib/templates/assets/images/spin-clone-develop-deployment/root-package-json-changes.png +0 -0
- package/lib/templates/assets/images/spin-clone-develop-deployment/values-dev-changes.png +0 -0
- package/lib/templates/assets/images/sso-mappers.png +0 -0
- package/lib/templates/assets/images/sso-picture-mapper.png +0 -0
- package/lib/templates/assets/images/sso-settings.png +0 -0
- package/lib/templates/assets/images/timesheet_apollo_cache.png +0 -0
- package/lib/templates/assets/images/timesheet_query.png +0 -0
- package/lib/templates/assets/images/tutorial/docsVersionDropdown.png +0 -0
- package/lib/templates/assets/images/tutorial/localeDropdown.png +0 -0
- package/lib/templates/assets/images/unauthenticated.png +0 -0
- package/lib/templates/assets/images/undraw_docusaurus_mountain.svg +170 -0
- package/lib/templates/assets/images/undraw_docusaurus_react.svg +169 -0
- package/lib/templates/assets/images/undraw_docusaurus_tree.svg +1 -0
- package/lib/templates/assets/images/vite-plugin-config.png +0 -0
- package/lib/templates/content/docs/Generators/Project/generate-fullproject.md +12 -0
- package/lib/templates/content/docs/LLM/Logger.llm.md +194 -0
- package/lib/templates/content/docs/LLM/backend-proxies-services-llm.md +2687 -0
- package/lib/templates/content/docs/LLM/backend-service-llm.md +3384 -0
- package/lib/templates/content/docs/LLM/db_migration_llm.md +954 -0
- package/lib/templates/content/docs/LLM/frontend/REMIX-15.3-upgrade-llm.md +1245 -0
- package/lib/templates/content/docs/LLM/inngest/INNGEST_FUNCTION_DEVELOPMENT_GUIDE_LLM.md +1241 -0
- package/lib/templates/content/docs/LLM/inngest/INNGEST_NAMESPACE_LLM.md +384 -0
- package/lib/templates/content/docs/LLM/llm_workflow_namespace.md +384 -0
- package/lib/templates/content/docs/LLM/organization-components-form-llm.md +1395 -0
- package/lib/templates/content/docs/LLM/page-component-llm.md +173 -0
- package/lib/templates/content/docs/LLM/preferences-settings-llm.md +2781 -0
- package/lib/templates/content/docs/LLM/tailwind-css-llm.md +502 -0
- package/lib/templates/content/docs/UI/SchemaBasedUI.md +334 -0
- package/lib/templates/content/docs/UI/SlotFillComponent.md +334 -0
- package/lib/templates/content/docs/adminide-modules/account/auth0-login.md +31 -0
- package/lib/templates/content/docs/adminide-modules/account/index.md +14 -0
- package/lib/templates/content/docs/adminide-modules/account/keycloak-remix-setup.md +86 -0
- package/lib/templates/content/docs/adminide-modules/account/remix-auth-setup.md +79 -0
- package/lib/templates/content/docs/adminide-modules/account/various-auth-qatest.md +157 -0
- package/lib/templates/content/docs/adminide-modules/api-builders/graphql.md +906 -0
- package/lib/templates/content/docs/adminide-modules/billing/payments/index.md +14 -0
- package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/index.md +14 -0
- package/lib/templates/content/docs/adminide-modules/billing/payments/stripe/settingup-stripe-locally.md +25 -0
- package/lib/templates/content/docs/adminide-modules/billing/tier-config.md +293 -0
- package/lib/templates/content/docs/adminide-modules/connectors/Connector.md +207 -0
- package/lib/templates/content/docs/adminide-modules/file-upload/index.md +16 -0
- package/lib/templates/content/docs/adminide-modules/file-upload/setup.md +435 -0
- package/lib/templates/content/docs/adminide-modules/file-upload/upload-file-using-signed-url.md +161 -0
- package/lib/templates/content/docs/adminide-modules/preferences/AddAdditionalPermissions.md +151 -0
- package/lib/templates/content/docs/adminide-modules/preferences/Configuration.md +241 -0
- package/lib/templates/content/docs/adminide-modules/preferences/Policy-Configuration.md +61 -0
- package/lib/templates/content/docs/adminide-modules/preferences/UI-components/ResourceSettingsLoader.md +319 -0
- package/lib/templates/content/docs/adminide-modules/preferences/contribute_scope_target.md +280 -0
- package/lib/templates/content/docs/adminide-modules/preferences/generate-urii.md +94 -0
- package/lib/templates/content/docs/adminide-modules/preferences/index.md +28 -0
- package/lib/templates/content/docs/adminide-modules/preferences/machine-configuration.md +157 -0
- package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/generateCdecodeUri.md +1289 -0
- package/lib/templates/content/docs/adminide-modules/preferences/pageSettings/migratingFromUseSettings.md +215 -0
- package/lib/templates/content/docs/adminide-modules/preferences/permissions/Roles-Permissions.md +72 -0
- package/lib/templates/content/docs/adminide-modules/preferences/permissions/settingUserPermissions.md +139 -0
- package/lib/templates/content/docs/adminide-modules/preferences/preference-dependency.md +138 -0
- package/lib/templates/content/docs/adminide-modules/preferences/route-based-configuration.md +41 -0
- package/lib/templates/content/docs/adminide-modules/preferences/schema-configuration.md +71 -0
- package/lib/templates/content/docs/adminide-modules/preferences/supported.md +24 -0
- package/lib/templates/content/docs/adminide-modules/preferences/useSettingsLoader.md +248 -0
- package/lib/templates/content/docs/adminide-modules/project-tools/auth-providers.md +1317 -0
- package/lib/templates/content/docs/adminide-modules/project-tools/keycloak-guide.md +543 -0
- package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-based-authentication.md +846 -0
- package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenant-management.md +708 -0
- package/lib/templates/content/docs/adminide-modules/project-tools/tenant-management/tenants.md +1117 -0
- package/lib/templates/content/docs/chrome-extension/index.md +14 -0
- package/lib/templates/content/docs/chrome-extension/setup.md +30 -0
- package/lib/templates/content/docs/contributing/adding-package.md +23 -0
- package/lib/templates/content/docs/contributing/adding_new_modules.md +99 -0
- package/lib/templates/content/docs/contributing/architecture-updates.md +19 -0
- package/lib/templates/content/docs/contributing/avoid-using-promises-ui.md +116 -0
- package/lib/templates/content/docs/contributing/coding-guidelines.md +111 -0
- package/lib/templates/content/docs/contributing/do-and-dont.md +42 -0
- package/lib/templates/content/docs/contributing/faq.md +22 -0
- package/lib/templates/content/docs/contributing/folder-setup/browser.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/config.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/containers-server.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/core.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/graphql.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/index.md +30 -0
- package/lib/templates/content/docs/contributing/folder-setup/module.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/server.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/services.md +12 -0
- package/lib/templates/content/docs/contributing/folder-setup/store.md +12 -0
- package/lib/templates/content/docs/contributing/frontend-coding.md +30 -0
- package/lib/templates/content/docs/contributing/git-subtree-sharing.md +73 -0
- package/lib/templates/content/docs/contributing/graphql-subscriptions.md +69 -0
- package/lib/templates/content/docs/contributing/how-to-contribute.md +30 -0
- package/lib/templates/content/docs/contributing/how_to_check_pure_esm.md +29 -0
- package/lib/templates/content/docs/contributing/index.md +60 -0
- package/lib/templates/content/docs/contributing/installation-issues.md +23 -0
- package/lib/templates/content/docs/contributing/keyboard-shortcut.md +131 -0
- package/lib/templates/content/docs/contributing/language/locale-support.md +12 -0
- package/lib/templates/content/docs/contributing/lerna-build-tools.md +516 -0
- package/lib/templates/content/docs/contributing/lerna-yarn-workspaces.md +95 -0
- package/lib/templates/content/docs/contributing/lint-and-formatter.md +20 -0
- package/lib/templates/content/docs/contributing/mobile-setup.md +16 -0
- package/lib/templates/content/docs/contributing/project-setup.md +233 -0
- package/lib/templates/content/docs/contributing/react/index.md +14 -0
- package/lib/templates/content/docs/contributing/react/lazy-component.md +70 -0
- package/lib/templates/content/docs/contributing/run-various-options.md +124 -0
- package/lib/templates/content/docs/contributing/schema-first-graphql-types.md +37 -0
- package/lib/templates/content/docs/contributing/source-code-organization.md +57 -0
- package/lib/templates/content/docs/contributing/staging-docker.md +88 -0
- package/lib/templates/content/docs/contributing/third-party/apollo-client-v3-tutorials.md +28 -0
- package/lib/templates/content/docs/contributing/third-party/index.md +18 -0
- package/lib/templates/content/docs/contributing/typescript-contribution.md +16 -0
- package/lib/templates/content/docs/devops/app-deploy-new-version.md +30 -0
- package/lib/templates/content/docs/devops/index.md +14 -0
- package/lib/templates/content/docs/devops/mobile-jenkins-build.md +40 -0
- package/lib/templates/content/docs/devops/versioning-the-project.md +128 -0
- package/lib/templates/content/docs/error-handler/application-error-handler.md +40 -0
- package/lib/templates/content/docs/error-handler/error-handling.md +26 -0
- package/lib/templates/content/docs/error-handler/index.md +16 -0
- package/lib/templates/content/docs/error-handler/logging-errors.md +14 -0
- package/lib/templates/content/docs/feature-api/copy-operation.md +427 -0
- package/lib/templates/content/docs/feature-api/feature-browser/assets.md +46 -0
- package/lib/templates/content/docs/feature-api/feature-browser/auth-permissions.md +12 -0
- package/lib/templates/content/docs/feature-api/feature-browser/feature.md +131 -0
- package/lib/templates/content/docs/feature-api/feature-browser/index.md +22 -0
- package/lib/templates/content/docs/feature-api/feature-browser/routes-menu.md +110 -0
- package/lib/templates/content/docs/feature-api/feature-browser/routing-convention.md +124 -0
- package/lib/templates/content/docs/feature-api/feature-browser/routing.md +338 -0
- package/lib/templates/content/docs/feature-api/feature-mobile/auth-permissions.md +20 -0
- package/lib/templates/content/docs/feature-api/feature-mobile/feature.md +130 -0
- package/lib/templates/content/docs/feature-api/feature-mobile/index.md +18 -0
- package/lib/templates/content/docs/feature-api/feature-mobile/navigation.md +187 -0
- package/lib/templates/content/docs/feature-api/feature-server/Scheduling.md +44 -0
- package/lib/templates/content/docs/feature-api/feature-server/dataloader.md +320 -0
- package/lib/templates/content/docs/feature-api/feature-server/dependency-injection.md +81 -0
- package/lib/templates/content/docs/feature-api/feature-server/feature.md +65 -0
- package/lib/templates/content/docs/feature-api/feature-server/generic-dataloader.md +135 -0
- package/lib/templates/content/docs/feature-api/feature-server/index.md +40 -0
- package/lib/templates/content/docs/feature-api/feature-server/migration.md +127 -0
- package/lib/templates/content/docs/feature-api/feature-server/mongo-model.md +72 -0
- package/lib/templates/content/docs/feature-api/feature-server/permissions.md +12 -0
- package/lib/templates/content/docs/feature-api/feature-server/policies.md +57 -0
- package/lib/templates/content/docs/feature-api/feature-server/preferences.md +57 -0
- package/lib/templates/content/docs/feature-api/feature-server/repositories.md +114 -0
- package/lib/templates/content/docs/feature-api/feature-server/resolvers.md +126 -0
- package/lib/templates/content/docs/feature-api/feature-server/rules.md +132 -0
- package/lib/templates/content/docs/feature-api/feature-server/schema.md +12 -0
- package/lib/templates/content/docs/feature-api/feature-server/services.md +102 -0
- package/lib/templates/content/docs/feature-api/feature-server/setup-resource-crud.md +359 -0
- package/lib/templates/content/docs/feature-api/index.md +18 -0
- package/lib/templates/content/docs/graphql/apolloClient-mutation.md +94 -0
- package/lib/templates/content/docs/graphql/index.md +14 -0
- package/lib/templates/content/docs/graphql/scalars.md +15 -0
- package/lib/templates/content/docs/help/index.md +14 -0
- package/lib/templates/content/docs/help/intro.md +16 -0
- package/lib/templates/content/docs/intl/ant-design-menu-translation.md +74 -0
- package/lib/templates/content/docs/intl/intl-namespace.md +129 -0
- package/lib/templates/content/docs/intl/vite-plugin-intl.md +87 -0
- package/lib/templates/content/docs/intl/webpack-plugin-intl.md +12 -0
- package/lib/templates/content/docs/intro.md +18 -0
- package/lib/templates/content/docs/knowledge/basic-fullstack.md +238 -0
- package/lib/templates/content/docs/mailing/index.md +14 -0
- package/lib/templates/content/docs/mailing/mailing-template.md +148 -0
- package/lib/templates/content/docs/mobile/App-navigation-generator.md +410 -0
- package/lib/templates/content/docs/mobile/MobileTestCases.md +264 -0
- package/lib/templates/content/docs/mobile/eas-profile-build.md +107 -0
- package/lib/templates/content/docs/mobile/expo-push-notification-setup.md +216 -0
- package/lib/templates/content/docs/mobile/index.md +14 -0
- package/lib/templates/content/docs/mobile/routes.md +83 -0
- package/lib/templates/content/docs/organization/adding-account-context.md +116 -0
- package/lib/templates/content/docs/organization/adding-org-mobile-navigation.md +22 -0
- package/lib/templates/content/docs/organization/adding-org-web-navigation.md +12 -0
- package/lib/templates/content/docs/organization/index.md +20 -0
- package/lib/templates/content/docs/organization/initialization.md +20 -0
- package/lib/templates/content/docs/organization/organization-resource-vs-resource.md +112 -0
- package/lib/templates/content/docs/remix/configuration/component-structure-best-practices.md +152 -0
- package/lib/templates/content/docs/remix/configuration/configurations.md +218 -0
- package/lib/templates/content/docs/remix/configuration/css-import-and-stylesheets.md +142 -0
- package/lib/templates/content/docs/remix/configuration/dont-subcomponent-network.md +166 -0
- package/lib/templates/content/docs/remix/configuration/generated-data-loaders.md +122 -0
- package/lib/templates/content/docs/remix/configuration/generated-resource-loaders.md +257 -0
- package/lib/templates/content/docs/remix/configuration/query-params-generator.md +216 -0
- package/lib/templates/content/docs/remix/configuration/routes-extra-icons.md +103 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-advanced.md +86 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-auth.md +113 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-best-practices.md +55 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-fields.md +79 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-graphql.md +79 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-index.md +112 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-loaders.md +165 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-middleware.md +196 -0
- package/lib/templates/content/docs/remix/configuration/routes-json-overview.md +53 -0
- package/lib/templates/content/docs/remix/data-loaders.md +43 -0
- package/lib/templates/content/docs/remix/devtools/remix-devtools.md +58 -0
- package/lib/templates/content/docs/remix/examples/changes-using-servercode.md +79 -0
- package/lib/templates/content/docs/remix/extra-icons.md +62 -0
- package/lib/templates/content/docs/remix/extra-links.md +65 -0
- package/lib/templates/content/docs/remix/generated-data-loaders.md +114 -0
- package/lib/templates/content/docs/remix/queryParamsGenerator.md +89 -0
- package/lib/templates/content/docs/remix/resources.md +16 -0
- package/lib/templates/content/docs/remix/styles.md +132 -0
- package/lib/templates/content/docs/remix/wiki.md +12 -0
- package/lib/templates/content/docs/security/auth-wrapper/auth-wrapper.md +24 -0
- package/lib/templates/content/docs/security/index.md +18 -0
- package/lib/templates/content/docs/security/secure-button-mobilenative.md +88 -0
- package/lib/templates/content/docs/security/secure-button-web.md +89 -0
- package/lib/templates/content/docs/server-side/account-customization.md +82 -0
- package/lib/templates/content/docs/server-side/apollo/caching.md +164 -0
- package/lib/templates/content/docs/server-side/backend-architecture/FINAL-DECISION.md +209 -0
- package/lib/templates/content/docs/server-side/backend-architecture/TRUE-FINAL-ARCHITECTURE.md +603 -0
- package/lib/templates/content/docs/server-side/backend-architecture/index1.md +0 -0
- package/lib/templates/content/docs/server-side/backend-coding.md +839 -0
- package/lib/templates/content/docs/server-side/e2b/manageing-template.md +197 -0
- package/lib/templates/content/docs/server-side/index.md +14 -0
- package/lib/templates/content/docs/server-side/inngest-functions-module.md +309 -0
- package/lib/templates/content/docs/server-side/listen-stripe-events.md +43 -0
- package/lib/templates/content/docs/server-side/slug-service.md +323 -0
- package/lib/templates/content/docs/tests/index.md +18 -0
- package/lib/templates/content/docs/tests/jest-test-debug-vscode.md +40 -0
- package/lib/templates/content/docs/tests/known-errors.md +116 -0
- package/lib/templates/content/docs/tests/service-test-template.md +118 -0
- package/lib/templates/content/docs/tests/test-setup.md +93 -0
- package/lib/templates/content/docs/xstate.md +23 -0
- package/lib/types.d.ts +37 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/utils/docsNavigation.d.ts +9 -0
- package/lib/utils/docsNavigation.d.ts.map +1 -0
- package/lib/utils/docsNavigation.js +37 -0
- package/lib/utils/docsNavigation.js.map +1 -0
- package/lib/utils/helpCenterUtils.d.ts +26 -0
- package/lib/utils/helpCenterUtils.d.ts.map +1 -0
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +3 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/markdownLoader.d.ts +36 -0
- package/lib/utils/markdownLoader.d.ts.map +1 -0
- package/lib/utils/markdownLoader.js +2242 -0
- package/lib/utils/markdownLoader.js.map +1 -0
- package/package.json +71 -0
package/lib/templates/content/docs/server-side/backend-architecture/TRUE-FINAL-ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
# THE TRUE OPTIMAL ARCHITECTURE ✅
|
|
2
|
+
|
|
3
|
+
**Crystal Clear Now!** Store ObjectId references internally, expose UUIDs only through GraphQL resolution.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎯 The Actual Pattern
|
|
8
|
+
|
|
9
|
+
### Database Storage (MongoDB)
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
// Application Document
|
|
13
|
+
{
|
|
14
|
+
_id: ObjectId("507f1f77bcf86cd799439011"), // Internal (never expose)
|
|
15
|
+
appId: "f47ac10b-58cc-4372-a567-0e02b2c3d479", // External UUID
|
|
16
|
+
|
|
17
|
+
// ObjectId references (MongoDB-optimized)
|
|
18
|
+
project: ObjectId("507f1f77bcf86cd799439012"),
|
|
19
|
+
tenant: ObjectId("507f1f77bcf86cd799439013"),
|
|
20
|
+
organization: ObjectId("507f1f77bcf86cd799439014"),
|
|
21
|
+
|
|
22
|
+
// Business data
|
|
23
|
+
name: "My Application",
|
|
24
|
+
status: "production",
|
|
25
|
+
createdAt: ISODate("2025-10-31T10:00:00Z"),
|
|
26
|
+
updatedAt: ISODate("2025-10-31T10:00:00Z")
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Key Points:**
|
|
31
|
+
|
|
32
|
+
- ✅ Only ONE reference field per relationship (`project`, not `project` + `projectId`)
|
|
33
|
+
- ✅ References are ObjectId (MongoDB-optimized)
|
|
34
|
+
- ✅ UUIDs exposed ONLY through GraphQL resolution
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 📋 Complete Schema
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// models/Application.ts
|
|
42
|
+
import { Schema, model, Document } from 'mongoose';
|
|
43
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
44
|
+
|
|
45
|
+
export interface IApplication extends Document {
|
|
46
|
+
_id: Schema.Types.ObjectId; // MongoDB internal
|
|
47
|
+
id: string; // Virtual → appId
|
|
48
|
+
appId: string; // External UUID
|
|
49
|
+
|
|
50
|
+
// ObjectId references (internal only)
|
|
51
|
+
project: Schema.Types.ObjectId;
|
|
52
|
+
tenant: Schema.Types.ObjectId;
|
|
53
|
+
organization: Schema.Types.ObjectId;
|
|
54
|
+
|
|
55
|
+
name: string;
|
|
56
|
+
status: string;
|
|
57
|
+
createdAt: Date;
|
|
58
|
+
updatedAt: Date;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const ApplicationSchema = new Schema<IApplication>(
|
|
62
|
+
{
|
|
63
|
+
// External UUID (only way to query from outside)
|
|
64
|
+
appId: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: () => uuidv4(),
|
|
67
|
+
unique: true,
|
|
68
|
+
required: true,
|
|
69
|
+
index: true,
|
|
70
|
+
immutable: true,
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// ObjectId references (internal, never exposed directly)
|
|
74
|
+
project: {
|
|
75
|
+
type: Schema.Types.ObjectId,
|
|
76
|
+
ref: 'Project',
|
|
77
|
+
required: true,
|
|
78
|
+
index: true,
|
|
79
|
+
},
|
|
80
|
+
tenant: {
|
|
81
|
+
type: Schema.Types.ObjectId,
|
|
82
|
+
ref: 'Tenant',
|
|
83
|
+
required: true,
|
|
84
|
+
index: true,
|
|
85
|
+
},
|
|
86
|
+
organization: {
|
|
87
|
+
type: Schema.Types.ObjectId,
|
|
88
|
+
ref: 'Organization',
|
|
89
|
+
required: true,
|
|
90
|
+
index: true,
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// Business fields
|
|
94
|
+
name: {
|
|
95
|
+
type: String,
|
|
96
|
+
required: true,
|
|
97
|
+
trim: true,
|
|
98
|
+
},
|
|
99
|
+
status: {
|
|
100
|
+
type: String,
|
|
101
|
+
enum: ['development', 'staging', 'production', 'archived'],
|
|
102
|
+
default: 'development',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
timestamps: true,
|
|
107
|
+
toJSON: {
|
|
108
|
+
virtuals: true,
|
|
109
|
+
transform: (doc, ret) => {
|
|
110
|
+
// Remove internal MongoDB fields
|
|
111
|
+
delete ret._id;
|
|
112
|
+
delete ret.__v;
|
|
113
|
+
// Remove ObjectId references (GraphQL will resolve these)
|
|
114
|
+
delete ret.project;
|
|
115
|
+
delete ret.tenant;
|
|
116
|
+
delete ret.organization;
|
|
117
|
+
return ret;
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
toObject: { virtuals: true },
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Virtual 'id' field
|
|
125
|
+
ApplicationSchema.virtual('id').get(function () {
|
|
126
|
+
return this.appId;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Indexes
|
|
130
|
+
ApplicationSchema.index({ project: 1, status: 1 });
|
|
131
|
+
ApplicationSchema.index({ tenant: 1 });
|
|
132
|
+
|
|
133
|
+
export const Application = model<IApplication>('Application', ApplicationSchema);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 🎨 GraphQL Pattern
|
|
139
|
+
|
|
140
|
+
### Type Definitions
|
|
141
|
+
|
|
142
|
+
```graphql
|
|
143
|
+
type Application {
|
|
144
|
+
id: ID! # appId (UUID)
|
|
145
|
+
name: String!
|
|
146
|
+
status: ApplicationStatus!
|
|
147
|
+
|
|
148
|
+
# These are RESOLVED via populate, exposing nested UUIDs
|
|
149
|
+
project: Project! # Resolves to { id, name, ... }
|
|
150
|
+
tenant: Tenant! # Resolves to { id, name, ... }
|
|
151
|
+
organization: Organization!
|
|
152
|
+
|
|
153
|
+
createdAt: DateTime!
|
|
154
|
+
updatedAt: DateTime!
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
type Project {
|
|
158
|
+
id: ID! # projectId (UUID)
|
|
159
|
+
name: String!
|
|
160
|
+
organization: Organization!
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
type Query {
|
|
164
|
+
# Query by UUID only
|
|
165
|
+
application(id: ID!): Application
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
input CreateApplicationInput {
|
|
169
|
+
# Client provides UUIDs
|
|
170
|
+
projectId: ID!
|
|
171
|
+
tenantId: ID!
|
|
172
|
+
name: String!
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### How Client Queries
|
|
177
|
+
|
|
178
|
+
```graphql
|
|
179
|
+
# Client queries by UUID (appId)
|
|
180
|
+
query GetApplication {
|
|
181
|
+
application(id: "f47ac10b-58cc-4372-a567-0e02b2c3d479") {
|
|
182
|
+
id # Returns appId (UUID)
|
|
183
|
+
name
|
|
184
|
+
project {
|
|
185
|
+
id # Returns projectId (UUID)
|
|
186
|
+
name
|
|
187
|
+
}
|
|
188
|
+
tenant {
|
|
189
|
+
id # Returns tenantId (UUID)
|
|
190
|
+
name
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Response (all UUIDs, no ObjectIds!)
|
|
196
|
+
{
|
|
197
|
+
"data": {
|
|
198
|
+
"application": {
|
|
199
|
+
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
200
|
+
"name": "My Application",
|
|
201
|
+
"project": {
|
|
202
|
+
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
203
|
+
"name": "My Project"
|
|
204
|
+
},
|
|
205
|
+
"tenant": {
|
|
206
|
+
"id": "e5f6a7b8-c9d0-1234-5678-9abcdef01234",
|
|
207
|
+
"name": "Production Tenant"
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 💻 GraphQL Resolvers
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// resolvers/application.ts
|
|
220
|
+
import { Application } from '../models/Application';
|
|
221
|
+
import { Project } from '../models/Project';
|
|
222
|
+
|
|
223
|
+
export const applicationResolvers = {
|
|
224
|
+
Query: {
|
|
225
|
+
application: async (_, { id }: { id: string }) => {
|
|
226
|
+
// Query by UUID (appId)
|
|
227
|
+
return Application.findOne({ appId: id })
|
|
228
|
+
.populate('project') // Populate ObjectId reference
|
|
229
|
+
.populate('tenant') // Populate ObjectId reference
|
|
230
|
+
.populate('organization'); // Populate ObjectId reference
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
Mutation: {
|
|
235
|
+
createApplication: async (_, { input }, context) => {
|
|
236
|
+
// Step 1: Resolve input UUIDs to ObjectIds
|
|
237
|
+
const project = await Project.findOne({ projectId: input.projectId });
|
|
238
|
+
if (!project) throw new Error('Project not found');
|
|
239
|
+
|
|
240
|
+
const tenant = await Tenant.findOne({ tenantId: input.tenantId });
|
|
241
|
+
if (!tenant) throw new Error('Tenant not found');
|
|
242
|
+
|
|
243
|
+
// Step 2: Create with ObjectId references
|
|
244
|
+
const application = await Application.create({
|
|
245
|
+
appId: uuidv4(),
|
|
246
|
+
project: project._id, // Store ObjectId
|
|
247
|
+
tenant: tenant._id, // Store ObjectId
|
|
248
|
+
organization: project.organization, // Store ObjectId
|
|
249
|
+
name: input.name,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Step 3: Return with populated refs
|
|
253
|
+
return Application.findById(application._id)
|
|
254
|
+
.populate('project')
|
|
255
|
+
.populate('tenant')
|
|
256
|
+
.populate('organization');
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
Application: {
|
|
261
|
+
// These resolvers expose UUIDs from populated documents
|
|
262
|
+
project: (parent) => {
|
|
263
|
+
// If already populated, it has projectId
|
|
264
|
+
// toJSON will expose only the projectId as 'id'
|
|
265
|
+
return parent.project; // Returns populated Project with projectId
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
tenant: (parent) => {
|
|
269
|
+
return parent.tenant; // Returns populated Tenant with tenantId
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
organization: (parent) => {
|
|
273
|
+
return parent.organization; // Returns populated Org with organizationId
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 🔄 The Data Flow
|
|
282
|
+
|
|
283
|
+
### 1. Client Queries Application
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
Client Request (GraphQL):
|
|
287
|
+
application(id: "uuid-app")
|
|
288
|
+
|
|
289
|
+
↓
|
|
290
|
+
|
|
291
|
+
GraphQL Resolver:
|
|
292
|
+
Application.findOne({ appId: "uuid-app" })
|
|
293
|
+
.populate('project')
|
|
294
|
+
.populate('tenant')
|
|
295
|
+
|
|
296
|
+
↓
|
|
297
|
+
|
|
298
|
+
MongoDB Query:
|
|
299
|
+
1. Find application by appId (UUID)
|
|
300
|
+
2. Populate project using ObjectId reference (fast!)
|
|
301
|
+
3. Populate tenant using ObjectId reference (fast!)
|
|
302
|
+
|
|
303
|
+
↓
|
|
304
|
+
|
|
305
|
+
Response to Client (all UUIDs):
|
|
306
|
+
{
|
|
307
|
+
id: "uuid-app",
|
|
308
|
+
project: { id: "uuid-project", name: "..." },
|
|
309
|
+
tenant: { id: "uuid-tenant", name: "..." }
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 2. Client Creates Application
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
Client Request (GraphQL):
|
|
317
|
+
createApplication(input: {
|
|
318
|
+
projectId: "uuid-project",
|
|
319
|
+
tenantId: "uuid-tenant",
|
|
320
|
+
name: "My App"
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
↓
|
|
324
|
+
|
|
325
|
+
GraphQL Resolver:
|
|
326
|
+
1. Find Project by projectId (UUID)
|
|
327
|
+
2. Find Tenant by tenantId (UUID)
|
|
328
|
+
3. Create Application with ObjectId references
|
|
329
|
+
|
|
330
|
+
↓
|
|
331
|
+
|
|
332
|
+
MongoDB:
|
|
333
|
+
Application.create({
|
|
334
|
+
appId: uuidv4(),
|
|
335
|
+
project: ObjectId('507f...'), // ObjectId reference
|
|
336
|
+
tenant: ObjectId('507f...'), // ObjectId reference
|
|
337
|
+
organization: ObjectId('507f...'),
|
|
338
|
+
name: "My App"
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
↓
|
|
342
|
+
|
|
343
|
+
Response to Client:
|
|
344
|
+
{
|
|
345
|
+
id: "uuid-app",
|
|
346
|
+
project: { id: "uuid-project", name: "..." },
|
|
347
|
+
tenant: { id: "uuid-tenant", name: "..." }
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## 📊 Project Collection Schema
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
const ProjectSchema = new Schema(
|
|
357
|
+
{
|
|
358
|
+
// External UUID (only way to query from outside)
|
|
359
|
+
projectId: {
|
|
360
|
+
type: String,
|
|
361
|
+
default: () => uuidv4(),
|
|
362
|
+
unique: true,
|
|
363
|
+
required: true,
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
// ObjectId reference (internal)
|
|
367
|
+
organization: {
|
|
368
|
+
type: Schema.Types.ObjectId,
|
|
369
|
+
ref: 'Organization',
|
|
370
|
+
required: true,
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
name: String,
|
|
374
|
+
status: String,
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
toJSON: {
|
|
378
|
+
virtuals: true,
|
|
379
|
+
transform: (doc, ret) => {
|
|
380
|
+
delete ret._id;
|
|
381
|
+
delete ret.organization; // Hide ObjectId reference
|
|
382
|
+
return ret;
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
ProjectSchema.virtual('id').get(function () {
|
|
389
|
+
return this.projectId;
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## 🎯 Key Principles
|
|
396
|
+
|
|
397
|
+
### ✅ What We Store
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
{
|
|
401
|
+
appId: String (UUID), // External identifier
|
|
402
|
+
project: ObjectId, // Internal reference (MongoDB-optimized)
|
|
403
|
+
tenant: ObjectId, // Internal reference (MongoDB-optimized)
|
|
404
|
+
organization: ObjectId // Internal reference (MongoDB-optimized)
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### ✅ What Client Sees
|
|
409
|
+
|
|
410
|
+
```graphql
|
|
411
|
+
{
|
|
412
|
+
id: "uuid-app" # appId
|
|
413
|
+
project {
|
|
414
|
+
id: "uuid-project" # projectId (from populated doc)
|
|
415
|
+
name: "..."
|
|
416
|
+
}
|
|
417
|
+
tenant {
|
|
418
|
+
id: "uuid-tenant" # tenantId (from populated doc)
|
|
419
|
+
name: "..."
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### ✅ The Magic
|
|
425
|
+
|
|
426
|
+
- **Storage:** ObjectId references (MongoDB-optimized, fast joins)
|
|
427
|
+
- **Exposure:** UUIDs only (via GraphQL resolution)
|
|
428
|
+
- **No duplication:** Single source of truth per reference
|
|
429
|
+
- **Fast queries:** ObjectId populate is native and fast
|
|
430
|
+
- **Clean APIs:** Client never sees ObjectIds
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## 💡 Why This is Perfect
|
|
435
|
+
|
|
436
|
+
| Benefit | How |
|
|
437
|
+
| ---------------------- | ----------------------------------- |
|
|
438
|
+
| **Fast MongoDB Joins** | ObjectId references + populate |
|
|
439
|
+
| **Clean API** | UUIDs exposed via GraphQL |
|
|
440
|
+
| **No Duplication** | One field per reference |
|
|
441
|
+
| **Simple Schema** | Straightforward document structure |
|
|
442
|
+
| **GraphQL Native** | Resolvers handle the transformation |
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## ⚠️ What About Database Migration?
|
|
447
|
+
|
|
448
|
+
When migrating to PostgreSQL:
|
|
449
|
+
|
|
450
|
+
### MongoDB
|
|
451
|
+
|
|
452
|
+
```javascript
|
|
453
|
+
{
|
|
454
|
+
_id: ObjectId('507f...'),
|
|
455
|
+
appId: 'uuid',
|
|
456
|
+
project: ObjectId('507f...'), // MongoDB reference
|
|
457
|
+
name: 'My App'
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### PostgreSQL
|
|
462
|
+
|
|
463
|
+
```sql
|
|
464
|
+
CREATE TABLE applications (
|
|
465
|
+
_id SERIAL PRIMARY KEY,
|
|
466
|
+
app_id UUID UNIQUE,
|
|
467
|
+
project INTEGER REFERENCES projects(_id), -- PostgreSQL reference
|
|
468
|
+
name VARCHAR(200)
|
|
469
|
+
);
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Migration Steps:**
|
|
473
|
+
|
|
474
|
+
1. ObjectId references → Integer references
|
|
475
|
+
2. Keep the same GraphQL resolvers
|
|
476
|
+
3. Update queries to use integer joins instead of ObjectId
|
|
477
|
+
4. UUIDs (appId, projectId) stay exactly the same!
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## 🚀 Service Layer
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
export class ApplicationService {
|
|
485
|
+
async create(input: CreateApplicationInput): Promise<IApplication> {
|
|
486
|
+
// Resolve UUID to ObjectId
|
|
487
|
+
const project = await Project.findOne({ projectId: input.projectId });
|
|
488
|
+
if (!project) throw new NotFoundError('Project not found');
|
|
489
|
+
|
|
490
|
+
const tenant = await Tenant.findOne({ tenantId: input.tenantId });
|
|
491
|
+
if (!tenant) throw new NotFoundError('Tenant not found');
|
|
492
|
+
|
|
493
|
+
// Create with ObjectId references
|
|
494
|
+
return Application.create({
|
|
495
|
+
appId: uuidv4(),
|
|
496
|
+
project: project._id, // ObjectId
|
|
497
|
+
tenant: tenant._id, // ObjectId
|
|
498
|
+
organization: project.organization, // ObjectId
|
|
499
|
+
name: input.name,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async findById(appId: string): Promise<IApplication | null> {
|
|
504
|
+
return Application.findOne({ appId }).populate('project').populate('tenant').populate('organization');
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## 📋 Complete Example
|
|
512
|
+
|
|
513
|
+
### MongoDB Collections
|
|
514
|
+
|
|
515
|
+
```javascript
|
|
516
|
+
// Organizations
|
|
517
|
+
{
|
|
518
|
+
_id: ObjectId('org1'),
|
|
519
|
+
organizationId: 'uuid-org-1',
|
|
520
|
+
name: 'Acme Corp'
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Projects
|
|
524
|
+
{
|
|
525
|
+
_id: ObjectId('proj1'),
|
|
526
|
+
projectId: 'uuid-proj-1',
|
|
527
|
+
organization: ObjectId('org1'), // ObjectId reference
|
|
528
|
+
name: 'Mobile App'
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Applications
|
|
532
|
+
{
|
|
533
|
+
_id: ObjectId('app1'),
|
|
534
|
+
appId: 'uuid-app-1',
|
|
535
|
+
project: ObjectId('proj1'), // ObjectId reference
|
|
536
|
+
tenant: ObjectId('tenant1'), // ObjectId reference
|
|
537
|
+
organization: ObjectId('org1'), // ObjectId reference
|
|
538
|
+
name: 'Production App'
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### GraphQL Query
|
|
543
|
+
|
|
544
|
+
```graphql
|
|
545
|
+
query {
|
|
546
|
+
application(id: "uuid-app-1") {
|
|
547
|
+
id # uuid-app-1
|
|
548
|
+
name # Production App
|
|
549
|
+
project {
|
|
550
|
+
id # uuid-proj-1 (from populated project)
|
|
551
|
+
name # Mobile App
|
|
552
|
+
organization {
|
|
553
|
+
id # uuid-org-1 (from populated org)
|
|
554
|
+
name # Acme Corp
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## ✅ Final Summary
|
|
564
|
+
|
|
565
|
+
### Storage Strategy
|
|
566
|
+
|
|
567
|
+
- `_id`: Database-native (ObjectId in MongoDB)
|
|
568
|
+
- `<entity>Id`: External UUID (appId, projectId, tenantId)
|
|
569
|
+
- References: ObjectId (fast, MongoDB-optimized)
|
|
570
|
+
|
|
571
|
+
### Exposure Strategy
|
|
572
|
+
|
|
573
|
+
- Entry point: Query by UUID (`appId`, `projectId`, etc.)
|
|
574
|
+
- References: Populated via GraphQL, expose nested UUIDs
|
|
575
|
+
- Client sees: Only UUIDs, never ObjectIds
|
|
576
|
+
|
|
577
|
+
### Benefits
|
|
578
|
+
|
|
579
|
+
1. ✅ **Fast MongoDB joins** (ObjectId populate)
|
|
580
|
+
2. ✅ **No data duplication** (one field per reference)
|
|
581
|
+
3. ✅ **Clean APIs** (UUIDs only via GraphQL)
|
|
582
|
+
4. ✅ **Simple schemas** (straightforward structure)
|
|
583
|
+
5. ✅ **GraphQL-native** (resolvers handle transformation)
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
## 🎯 The Rule
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
STORE: ObjectId references (database-optimized)
|
|
591
|
+
EXPOSE: UUIDs via GraphQL resolution (API-friendly)
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Perfect balance of performance and clean APIs!** 🎉
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
**This is the true optimal architecture!**
|
|
599
|
+
|
|
600
|
+
- Internal: Fast ObjectId references
|
|
601
|
+
- External: Clean UUID exposure
|
|
602
|
+
- No duplication
|
|
603
|
+
- GraphQL handles the magic ✨
|
|
File without changes
|