@cdmbase/wiki-browser 12.0.18-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Secure Button Mobile
|
|
4
|
+
description: Secure Button Mobile
|
|
5
|
+
date: '2023-06-02T00:00:00'
|
|
6
|
+
updated: '2024-06-02T00:00:00'
|
|
7
|
+
excerpt: Secure Button Mobile...
|
|
8
|
+
headers:
|
|
9
|
+
Cache-Control: no-cache
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Documentation for SecureButton Component (Mobile)
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
The `SecureButton` component is a higher-order component that wraps another component and adds a security layer to ensure that the action defined in the button is executed only if the user is authenticated. If the user is not authenticated, it navigates them to the login screen.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
To use the `SecureButton` component, you need to import it and pass a child component (such as a button) as an argument. The child component should accept certain props that are common in most button components.
|
|
21
|
+
|
|
22
|
+
### Example Usage:
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
import React from 'react';
|
|
26
|
+
import { Button } from 'native-base';
|
|
27
|
+
import { SecureButton } from './SecureButton';
|
|
28
|
+
|
|
29
|
+
const SecureMyButton = SecureButton(Button);
|
|
30
|
+
|
|
31
|
+
function MyButton(props) {
|
|
32
|
+
// Your button component code
|
|
33
|
+
return <SecureMyButton onPress={props.onPress}>{props.children}</SecureMyButton>;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
In this example, `MyButton` is a custom button component. We wrap it using the `SecureButton` to create a `SecureMyButton`. The `SecureMyButton` will ensure that the action passed to the `onPress` prop is only executed if the user is authenticated.
|
|
38
|
+
|
|
39
|
+
## Props
|
|
40
|
+
|
|
41
|
+
The `SecureButton` component accepts the following props:
|
|
42
|
+
|
|
43
|
+
- `Component`: The child component that you want to wrap with the security layer. This component should accept certain props, including `onPress`, `children`, `borderRadius`, `backgroundColor`, `rightIcon`, and `isDisabled`.
|
|
44
|
+
|
|
45
|
+
## Behavior
|
|
46
|
+
|
|
47
|
+
When a user interacts with the `SecureButton`, it will perform the following actions based on the user's authentication status:
|
|
48
|
+
|
|
49
|
+
- If the user is authenticated:
|
|
50
|
+
- It will execute the action specified in the `onPress` prop.
|
|
51
|
+
- If the user is not authenticated:
|
|
52
|
+
- It will navigate the user to the login screen using `navigationRef.navigate`.
|
|
53
|
+
- It passes the `redirect` parameter as `'back'` to indicate that after successful login, the user should be redirected back to the previous screen.
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import React, { useCallback } from 'react';
|
|
59
|
+
import { navigationRef } from '@common-stack/client-react';
|
|
60
|
+
import { isUserAuthenticated } from '@adminide-stack/user-auth0-client';
|
|
61
|
+
|
|
62
|
+
export function SecureButton<P extends { onPress; children; borderRadius; backgroundColor; rightIcon; isDisabled }>(
|
|
63
|
+
Component: React.ComponentType<P>,
|
|
64
|
+
) {
|
|
65
|
+
return (props: P) => {
|
|
66
|
+
const { authenticated } = isUserAuthenticated();
|
|
67
|
+
const handleOnClick = useCallback(() => {
|
|
68
|
+
if (authenticated) {
|
|
69
|
+
return props.onPress();
|
|
70
|
+
} else {
|
|
71
|
+
navigationRef.navigate('MainStack.Login', {
|
|
72
|
+
redirect: 'back',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}, [authenticated, props]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<>
|
|
79
|
+
<Component {...props} onPress={handleOnClick} />
|
|
80
|
+
</>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
In this example, the `SecureButton` component is defined, and it wraps a child component specified in the `Component` prop. If the user is authenticated, it allows the action to be executed; otherwise, it navigates the user to the login screen.
|
|
87
|
+
|
|
88
|
+
Make sure that the child component (`Component`) accepts the required props, including `onPress`, `children`, `borderRadius`, `backgroundColor`, `rightIcon`, and `isDisabled`, to work seamlessly with the `SecureButton`.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Secure Button Web
|
|
4
|
+
description: Secure Button Web
|
|
5
|
+
date: '2023-06-02T00:00:00'
|
|
6
|
+
updated: '2024-06-02T00:00:00'
|
|
7
|
+
excerpt: Secure Button Web...
|
|
8
|
+
headers:
|
|
9
|
+
Cache-Control: no-cache
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Documentation for SecureButton Component (Web Version)
|
|
13
|
+
|
|
14
|
+
The `SecureButton` component for the web is an extension of the SecureButton component. It is designed for use on web applications and provides additional functionality, including the ability to display a login modal when the user is not authenticated. This component ensures that the action specified in the `onClick` prop is executed only if the user is authenticated. If the user is not authenticated, it can show a login modal for the user to log in.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
To use the `SecureButton` component for the web, you need to import it and pass a child component (e.g., a button) as an argument. The child component should accept an `onClick` prop, which is a function that defines the action to be executed when the button is clicked.
|
|
19
|
+
|
|
20
|
+
### Example Usage:
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import React from 'react';
|
|
24
|
+
import { SecureButton } from './SecureButton';
|
|
25
|
+
|
|
26
|
+
function MyButton(props) {
|
|
27
|
+
// Your button component code
|
|
28
|
+
return <button onClick={props.onClick}>{props.children}</button>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const SecureMyButton = SecureButton(MyButton);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
In this example, `MyButton` is a custom button component. We wrap it using the `SecureButton` to create a `SecureMyButton`. The `SecureMyButton` will ensure that the action specified in the `onClick` prop is only executed if the user is authenticated. If the user is not authenticated, it can display a login modal for the user to log in.
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
|
|
38
|
+
The `SecureButton` component for the web accepts the following props:
|
|
39
|
+
|
|
40
|
+
- `Component`: The child component that you want to wrap with the security layer. This component should accept the `onClick` prop, which is a function that defines the action to be executed when the button is clicked.
|
|
41
|
+
|
|
42
|
+
## Behavior
|
|
43
|
+
|
|
44
|
+
When a user interacts with the `SecureButton`, it will perform the following actions based on the user's authentication status:
|
|
45
|
+
|
|
46
|
+
- If the user is authenticated:
|
|
47
|
+
- It will execute the action specified in the `onClick` prop.
|
|
48
|
+
- If the user is not authenticated:
|
|
49
|
+
- It will set `renderProtectedComponent` to `true`, which can trigger the display of a login modal.
|
|
50
|
+
- It passes control to the `onClick` function with the event object.
|
|
51
|
+
- The login modal should be displayed conditionally based on the value of `renderProtectedComponent`.
|
|
52
|
+
- The login modal should provide a way for the user to log in.
|
|
53
|
+
- The login modal should also have a mechanism to close it, which can be achieved by invoking `onLoginModalClose`.
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import React, { useState, useCallback } from 'react';
|
|
59
|
+
import { LoginModal } from './LoginModal'; // Import your login modal component
|
|
60
|
+
import { isUserAuthenticated } from '@adminide-stack/user-auth0-client';
|
|
61
|
+
|
|
62
|
+
export function SecureButton<P extends { onClick: (e?: React.MouseEvent<HTMLButtonElement>) => {} }>(
|
|
63
|
+
Component: React.ComponentType<P>,
|
|
64
|
+
) {
|
|
65
|
+
return (props: P) => {
|
|
66
|
+
const [renderProtectedComponent, setRenderProtectedComponent] = useState(false);
|
|
67
|
+
const { authenticated } = isUserAuthenticated();
|
|
68
|
+
const handleOnClick = useCallback((e) => {
|
|
69
|
+
if (authenticated) {
|
|
70
|
+
return props.onClick(e);
|
|
71
|
+
}
|
|
72
|
+
setRenderProtectedComponent(true);
|
|
73
|
+
}, [authenticated, props, setRenderProtectedComponent]);
|
|
74
|
+
|
|
75
|
+
const onLoginModalClose = useCallback(() => {
|
|
76
|
+
setRenderProtectedComponent(false);
|
|
77
|
+
}, [setRenderProtectedComponent]);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<>
|
|
81
|
+
{renderProtectedComponent && <LoginModal onClose={onLoginModalClose} />}
|
|
82
|
+
<Component {...props} onClick={handleOnClick} />
|
|
83
|
+
</>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
In this example, the `SecureButton` component for the web is defined. It wraps a child component specified in the `Component` prop. If the user is not authenticated, it sets `renderProtectedComponent` to `true`, which can trigger the display of a login modal. The login modal can be your custom modal component, and it provides a way for the user to log in. The `onLoginModalClose` function allows closing the login modal when needed.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Account Customization
|
|
4
|
+
description: Account Customization
|
|
5
|
+
date: '2023-06-02T00:00:00'
|
|
6
|
+
updated: '2024-06-02T00:00:00'
|
|
7
|
+
excerpt: Account Customization...
|
|
8
|
+
headers:
|
|
9
|
+
Cache-Control: no-cache
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Backend
|
|
13
|
+
|
|
14
|
+
Accounts are now customized to add multiple fields.
|
|
15
|
+
|
|
16
|
+
1. Accounts module is imported from `adminide-stack/accounts-api-server` the module has basic fields like `email, phone number, etc` and those are added to graphql schema and mongo schema like below.
|
|
17
|
+
|
|
18
|
+
Mongo Schema
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
Graphql Schema
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
2. We can inject the default mongo schema through the module.
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
3. But if we need to customize accounts to add more fields, we can skip the default module.
|
|
33
|
+
|
|
34
|
+
a) Add extended fields in mongo scheme like below.
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
b) As well graphql extension. Make sure to add the directives `@isAuthenticated @addAccountContext` at the end.
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
Generate graphql types by running `yarn generateGraphql` and all the new files generated need to be compiled in those specific packages.
|
|
43
|
+
|
|
44
|
+
c) Write service
|
|
45
|
+
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+
d) Add necessary types to refer in the Container
|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
e) Bind to the `IAccountMongoExtSchema` in Container for extending Account's Mongo Schema. Also bind `ExtendedAccountServce` for accessing in the resolvers.
|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
d) Write the resolver to get the specific field data
|
|
57
|
+
|
|
58
|
+

|
|
59
|
+
|
|
60
|
+
f) Include it in the modules
|
|
61
|
+
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
# Frontend
|
|
65
|
+
|
|
66
|
+
On frontend you can write queries how you want.
|
|
67
|
+
|
|
68
|
+
For example if you need to get Composite Account data including the basic account field + exntended account fields, you can query in one gql
|
|
69
|
+
|
|
70
|
+
Fragment
|
|
71
|
+
|
|
72
|
+

|
|
73
|
+
|
|
74
|
+
Query
|
|
75
|
+
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
Also you can call individual queries
|
|
79
|
+
|
|
80
|
+

|
|
81
|
+
|
|
82
|
+
After any changes to `.gql` or `.graphql` make sure to run `yarn generateGraphql` to generate types.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
meta:
|
|
3
|
+
title: Caching with Apollo Server
|
|
4
|
+
description: Caching with Apollo Server
|
|
5
|
+
date: '2023-06-02T00:00:00'
|
|
6
|
+
updated: '2024-06-02T00:00:00'
|
|
7
|
+
excerpt: Caching with Apollo Server...
|
|
8
|
+
headers:
|
|
9
|
+
Cache-Control: no-cache
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Caching with Apollo Server
|
|
13
|
+
|
|
14
|
+
## A Guide to Using `ApolloServerPluginCacheControl` and Redis
|
|
15
|
+
|
|
16
|
+
Apollo Server provides multiple ways to implement caching, helping reduce server load and improve response times for frequently requested data. This document outlines how caching works in Apollo Server and how to use the `ApolloServerPluginCacheControl` and `responseCachePlugin` to store cache in Redis.
|
|
17
|
+
|
|
18
|
+
### 1. **How Caching Works in Apollo Server**
|
|
19
|
+
|
|
20
|
+
Apollo Server supports two types of caching:
|
|
21
|
+
|
|
22
|
+
- **In-memory cache**: Data is temporarily stored on the server to avoid recomputation on subsequent identical queries.
|
|
23
|
+
- **External cache (e.g., Redis)**: Data is stored in external caching layers, such as Redis, allowing caching across multiple servers.
|
|
24
|
+
|
|
25
|
+
To enable caching, Apollo Server relies on two key plugins:
|
|
26
|
+
|
|
27
|
+
- `ApolloServerPluginCacheControl`: Controls caching at the field level using cache directives and provides metadata like `maxAge` (TTL) for each field or query.
|
|
28
|
+
- `responseCachePlugin`: Caches full query responses based on the operation (i.e., the entire query and its result).
|
|
29
|
+
|
|
30
|
+
### 2. **Caching with `ApolloServerPluginCacheControl`**
|
|
31
|
+
|
|
32
|
+
`ApolloServerPluginCacheControl` allows you to define cache control settings directly in your GraphQL schema using the `@cacheControl` directive or globally through server settings.
|
|
33
|
+
|
|
34
|
+
#### Key Features:
|
|
35
|
+
|
|
36
|
+
- **`maxAge`**: Sets the time (in seconds) for which a response or field can be cached.
|
|
37
|
+
- **`scope`**: Defines if the cache is shared (`public`) or user-specific (`private`).
|
|
38
|
+
|
|
39
|
+
#### Example:
|
|
40
|
+
|
|
41
|
+
```graphql
|
|
42
|
+
type Query {
|
|
43
|
+
favouriteBooks: [Book] @cacheControl(maxAge: 60, scope: Private)
|
|
44
|
+
books: [Book] @cacheControl(maxAge: 60)
|
|
45
|
+
bookByTitle(title: String!): Book @cacheControl(maxAge: 30)
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
In this example, the `books` query response is cached for 60 seconds, while `bookByTitle` is cached for 30 seconds, both of them will be cached
|
|
50
|
+
once whereas the `favouriteBooks` due to its private scope will be cached differently against each user request.
|
|
51
|
+
|
|
52
|
+
#### Default Cache Control:
|
|
53
|
+
|
|
54
|
+
If no `@cacheControl` directive is used, you can specify a default `maxAge` globally.
|
|
55
|
+
PS: We do not use Global Max Age
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
const server = new ApolloServer({
|
|
59
|
+
typeDefs,
|
|
60
|
+
resolvers,
|
|
61
|
+
plugins: [
|
|
62
|
+
ApolloServerPluginCacheControl({
|
|
63
|
+
defaultMaxAge: 10, // Default cache duration of 10 seconds
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### 3. **Using the `responseCachePlugin` with Redis**
|
|
72
|
+
|
|
73
|
+
The `responseCachePlugin` is designed to cache entire query responses (not just field-level caching). By integrating Redis as the cache storage, responses can be cached externally and shared across multiple instances of Apollo Server.
|
|
74
|
+
|
|
75
|
+
#### Steps to Enable Response Caching in Redis:
|
|
76
|
+
|
|
77
|
+
1. **Install Redis and Required Packages**:
|
|
78
|
+
Install Redis and its Node.js client (`ioredis`) to interact with the Redis server.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install ioredis @apollo/server-plugin-response-cache
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. **Setup Redis Client**:
|
|
85
|
+
Initialize a Redis client using `ioredis` and configure the cache storage.
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
const Redis = require('ioredis');
|
|
89
|
+
const redis = new Redis();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
3. **Configure the `responseCachePlugin`**:
|
|
93
|
+
Use the `responseCachePlugin` to store query results in Redis.
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const { ApolloServer } = require('@apollo/server');
|
|
97
|
+
const { responseCachePlugin } = require('@apollo/server-plugin-response-cache');
|
|
98
|
+
|
|
99
|
+
const server = new ApolloServer({
|
|
100
|
+
typeDefs,
|
|
101
|
+
resolvers,
|
|
102
|
+
cache: redisCache,
|
|
103
|
+
plugins: [
|
|
104
|
+
responseCachePlugin({
|
|
105
|
+
shouldReadFromCache: async (requestContext) => {
|
|
106
|
+
const { maxAge } = requestContext.overallCachePolicy || {};
|
|
107
|
+
return maxAge > 0; // Cache only if maxAge is set
|
|
108
|
+
},
|
|
109
|
+
shouldWriteToCache: async (requestContext) => {
|
|
110
|
+
const { maxAge } = requestContext.overallCachePolicy || {};
|
|
111
|
+
return maxAge > 0; // Write to cache only if maxAge is set
|
|
112
|
+
},
|
|
113
|
+
}),
|
|
114
|
+
],
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
4. **Server Configuration**:
|
|
119
|
+
Add both `ApolloServerPluginCacheControl` (for defining cache policies) and `responseCachePlugin` (for full-response caching) to your Apollo Server configuration.
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
const { ApolloServerPluginCacheControl } = require('@apollo/server-plugin-cache-control');
|
|
123
|
+
|
|
124
|
+
const server = new ApolloServer({
|
|
125
|
+
typeDefs,
|
|
126
|
+
resolvers,
|
|
127
|
+
plugins: [
|
|
128
|
+
ApolloServerPluginCacheControl({}),
|
|
129
|
+
responseCachePlugin({
|
|
130
|
+
...pluginOptions,
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 4. **How the Caching Workflow Operates**
|
|
137
|
+
|
|
138
|
+
- **Field-level Cache Control**: The `ApolloServerPluginCacheControl` checks for `@cacheControl` directives or uses the default `maxAge` to define TTLs for each query/field.
|
|
139
|
+
- **Full Response Caching**: The `responseCachePlugin` caches the full result of a query if the request is cacheable (i.e., if `maxAge` is set).
|
|
140
|
+
- **Redis as Cache Store**: Query responses are stored in Redis, and when a cached query is requested again, the response is served from Redis, avoiding the need for computation.
|
|
141
|
+
|
|
142
|
+
### 5. **Cache Invalidation**
|
|
143
|
+
|
|
144
|
+
As we know, Redis stores cached data with a TTL (Max Age) value, and it automatically expires once that time limit is reached. However, in scenarios where the actual data changes before the cache expires, we need a way to **invalidate the cache on demand** to ensure the application always returns up-to-date information.
|
|
145
|
+
|
|
146
|
+
To address this, we’ve developed a custom plugin called `invalidateCachePlugin`. This plugin introduces a custom directive that can be applied to mutations. With this directive, you can specify a list of queries to invalidate. Whenever the mutation runs successfully, the cache for all the listed queries is automatically cleared, ensuring the application serves fresh data.
|
|
147
|
+
|
|
148
|
+
#### Example:
|
|
149
|
+
|
|
150
|
+
```graphql
|
|
151
|
+
type Mutation {
|
|
152
|
+
addToFavourites(id: ID!): Boolean @invalidateCache(queries: ["favouriteBooks"])
|
|
153
|
+
addBook(book: BookInput!): [Book] @invalidateCache(queries: ["books"])
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 6 . **Caveats**
|
|
158
|
+
|
|
159
|
+
There is one weird issue happening with `@cacheControl` directive, as it fails to set `maxAge` for some queries.
|
|
160
|
+
To overcome that we've written a custom resolver for `cacheController` to make sure that value is always there
|
|
161
|
+
|
|
162
|
+
### Conclusion:
|
|
163
|
+
|
|
164
|
+
By using `ApolloServerPluginCacheControl` for cache control metadata and `responseCachePlugin` to cache full responses, you can significantly improve the performance of your Apollo Server application. Storing the cache in Redis ensures a scalable, centralized cache that works across multiple instances, making it ideal for distributed systems.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# FINAL ARCHITECTURE DECISION ✅
|
|
2
|
+
|
|
3
|
+
**Date:** October 31, 2025
|
|
4
|
+
**Status:** APPROVED - This is the correct pattern
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🎯 The Winning Pattern (Simple!)
|
|
9
|
+
|
|
10
|
+
### What You Store in Database
|
|
11
|
+
|
|
12
|
+
```javascript
|
|
13
|
+
{
|
|
14
|
+
_id: ObjectId("507f..."), // MongoDB internal
|
|
15
|
+
appId: "f47ac10b-...", // External UUID
|
|
16
|
+
|
|
17
|
+
project: ObjectId("507f..."), // ObjectId reference
|
|
18
|
+
tenant: ObjectId("507f..."), // ObjectId reference
|
|
19
|
+
organization: ObjectId("507f..."), // ObjectId reference
|
|
20
|
+
|
|
21
|
+
name: "My Application"
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**One field per reference!** No duplication!
|
|
26
|
+
|
|
27
|
+
### What Client Sees via GraphQL
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"id": "f47ac10b-...",
|
|
32
|
+
"name": "My Application",
|
|
33
|
+
"project": {
|
|
34
|
+
"id": "a1b2c3d4-...",
|
|
35
|
+
"name": "My Project"
|
|
36
|
+
},
|
|
37
|
+
"tenant": {
|
|
38
|
+
"id": "e5f6a7b8-...",
|
|
39
|
+
"name": "Production"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Only UUIDs!** ObjectIds never exposed!
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🔑 Key Principles
|
|
49
|
+
|
|
50
|
+
1. **Store ObjectId references** - Fast MongoDB joins
|
|
51
|
+
2. **Store UUID for each entity** - appId, projectId, tenantId
|
|
52
|
+
3. **Query by UUID** - application(id: "uuid")
|
|
53
|
+
4. **Populate via ObjectId** - .populate('project')
|
|
54
|
+
5. **Expose UUIDs via GraphQL** - Resolvers transform ObjectId → UUID
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 📋 Naming Convention (Final)
|
|
59
|
+
|
|
60
|
+
| Field | Type | Example | Exposed to Client? |
|
|
61
|
+
| --------- | ------------- | --------------------- | --------------------------- |
|
|
62
|
+
| `_id` | ObjectId | `ObjectId('507f...')` | ❌ Never |
|
|
63
|
+
| `appId` | String (UUID) | `'f47ac10b-...'` | ✅ Yes (as `id`) |
|
|
64
|
+
| `project` | ObjectId | `ObjectId('507f...')` | ❌ Never (GraphQL resolves) |
|
|
65
|
+
| `tenant` | ObjectId | `ObjectId('507f...')` | ❌ Never (GraphQL resolves) |
|
|
66
|
+
|
|
67
|
+
**When GraphQL resolves `project`, it returns the populated Project document which has `projectId` exposed as `id`.**
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 🎨 GraphQL Flow
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Client: application(id: "uuid-app") { id, project { id, name } }
|
|
75
|
+
↓
|
|
76
|
+
Resolver: Application.findOne({ appId: "uuid-app" }).populate('project')
|
|
77
|
+
↓
|
|
78
|
+
MongoDB: Fast join using ObjectId reference
|
|
79
|
+
↓
|
|
80
|
+
Response: { id: "uuid-app", project: { id: "uuid-project", name: "..." } }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## ✅ Why This Works Perfectly
|
|
86
|
+
|
|
87
|
+
| Benefit | How |
|
|
88
|
+
| ------------------ | ------------------------------ |
|
|
89
|
+
| **Fast Joins** | ObjectId references + populate |
|
|
90
|
+
| **Clean API** | GraphQL exposes only UUIDs |
|
|
91
|
+
| **No Duplication** | One field per reference |
|
|
92
|
+
| **Simple** | Straightforward schema |
|
|
93
|
+
| **Secure** | No internal structure leaked |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 📊 Schema Template
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const ApplicationSchema = new Schema(
|
|
101
|
+
{
|
|
102
|
+
// External UUID (query entry point)
|
|
103
|
+
appId: {
|
|
104
|
+
type: String,
|
|
105
|
+
default: () => uuidv4(),
|
|
106
|
+
unique: true,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// ObjectId references (fast joins, never exposed)
|
|
110
|
+
project: {
|
|
111
|
+
type: Schema.Types.ObjectId,
|
|
112
|
+
ref: 'Project',
|
|
113
|
+
required: true,
|
|
114
|
+
},
|
|
115
|
+
tenant: {
|
|
116
|
+
type: Schema.Types.ObjectId,
|
|
117
|
+
ref: 'Tenant',
|
|
118
|
+
required: true,
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Business fields
|
|
122
|
+
name: String,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
toJSON: {
|
|
126
|
+
virtuals: true,
|
|
127
|
+
transform: (doc, ret) => {
|
|
128
|
+
delete ret._id; // Hide MongoDB ID
|
|
129
|
+
delete ret.project; // Hide ObjectId refs
|
|
130
|
+
delete ret.tenant; // GraphQL will resolve these
|
|
131
|
+
return ret;
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
ApplicationSchema.virtual('id').get(function () {
|
|
138
|
+
return this.appId;
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 🚀 Implementation Checklist
|
|
145
|
+
|
|
146
|
+
For each collection:
|
|
147
|
+
|
|
148
|
+
- [ ] Has `<entity>Id` UUID field (appId, projectId, etc.)
|
|
149
|
+
- [ ] Virtual `id` maps to `<entity>Id`
|
|
150
|
+
- [ ] References are ObjectId (project, tenant, organization)
|
|
151
|
+
- [ ] `toJSON` hides `_id` and ObjectId references
|
|
152
|
+
- [ ] GraphQL resolvers populate and expose nested UUIDs
|
|
153
|
+
- [ ] No duplicate reference fields
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 📄 Document Priority
|
|
158
|
+
|
|
159
|
+
1. **[TRUE-FINAL-ARCHITECTURE.md](./TRUE-FINAL-ARCHITECTURE.md)** ⭐ **START HERE**
|
|
160
|
+
- Complete implementation guide
|
|
161
|
+
- 20 minutes
|
|
162
|
+
|
|
163
|
+
2. **[FINAL-NAMING-CONVENTION.md](./FINAL-NAMING-CONVENTION.md)** 📋
|
|
164
|
+
- Quick reference
|
|
165
|
+
- 10 minutes
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 💡 The Bottom Line
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
INTERNAL: ObjectId references (fast)
|
|
173
|
+
EXTERNAL: UUIDs via GraphQL (clean)
|
|
174
|
+
NO DUPLICATION: One field per reference
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Simple, fast, and clean!** 🎉
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
**Approved by:** Architecture Team
|
|
182
|
+
**Date:** October 31, 2025
|
|
183
|
+
**Ready for:** Implementation
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 🎓 Quick Example
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Create
|
|
191
|
+
const project = await Project.findOne({ projectId: input.projectId });
|
|
192
|
+
await Application.create({
|
|
193
|
+
appId: uuidv4(),
|
|
194
|
+
project: project._id, // Store ObjectId
|
|
195
|
+
name: input.name
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Query
|
|
199
|
+
const app = await Application.findOne({ appId: 'uuid' })
|
|
200
|
+
.populate('project'); // Fast ObjectId join
|
|
201
|
+
|
|
202
|
+
// GraphQL returns
|
|
203
|
+
{
|
|
204
|
+
id: "uuid-app",
|
|
205
|
+
project: { id: "uuid-project", name: "..." } // UUIDs only!
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Perfect!** ✅
|