vybekiit 0.4.0 → 0.6.0
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/dist/bin.js +840 -296
- package/dist/global-skills/add-ai/SKILL.md +53 -0
- package/dist/global-skills/add-analytics/SKILL.md +65 -0
- package/dist/global-skills/add-app-clip/SKILL.md +280 -0
- package/dist/global-skills/add-app-clip/agents/openai.yaml +4 -0
- package/dist/global-skills/add-app-clip/references/native-module.md +96 -0
- package/dist/global-skills/add-blog/SKILL.md +49 -0
- package/dist/global-skills/add-crud/SKILL.md +28 -0
- package/dist/global-skills/add-files/SKILL.md +65 -0
- package/dist/global-skills/add-images/SKILL.md +64 -0
- package/dist/global-skills/add-language/SKILL.md +44 -0
- package/dist/global-skills/add-notifications/SKILL.md +61 -0
- package/dist/global-skills/add-realtime/SKILL.md +49 -0
- package/dist/global-skills/add-route/SKILL.md +28 -0
- package/dist/global-skills/add-search/SKILL.md +43 -0
- package/dist/global-skills/add-signin/SKILL.md +78 -0
- package/dist/global-skills/add-teams/SKILL.md +64 -0
- package/dist/global-skills/add-upload/SKILL.md +27 -0
- package/dist/global-skills/aws-cdk/SKILL.md +72 -0
- package/dist/global-skills/aws-cdk/references/bootstrap-and-project-setup.md +257 -0
- package/dist/global-skills/aws-cdk/references/compliance-and-drift.md +193 -0
- package/dist/global-skills/aws-cdk/references/construct-patterns.md +315 -0
- package/dist/global-skills/aws-cdk/references/import-and-migrate.md +184 -0
- package/dist/global-skills/aws-cdk/references/refactor-and-prevent-replacement.md +198 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-credentials.md +183 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +293 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-synth.md +274 -0
- package/dist/global-skills/aws-cdk/references/v1-to-v2-migration.md +119 -0
- package/dist/global-skills/aws-cloudformation/SKILL.md +88 -0
- package/dist/global-skills/aws-cloudformation/references/author-cloudformation-best-practices.script.md +179 -0
- package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +159 -0
- package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +217 -0
- package/dist/global-skills/aws-cloudformation/references/deploy-with-express-mode.script.md +271 -0
- package/dist/global-skills/aws-cloudformation/references/lookup-resource-properties.script.md +130 -0
- package/dist/global-skills/aws-cloudformation/references/troubleshoot-deployment.script.md +200 -0
- package/dist/global-skills/aws-cloudformation/references/validate-cloudformation-template.script.md +135 -0
- package/dist/global-skills/aws-serverless/SKILL.md +51 -0
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +49 -0
- package/dist/global-skills/aws-serverless/references/api-gateway.md +553 -0
- package/dist/global-skills/aws-serverless/references/architecture.md +262 -0
- package/dist/global-skills/aws-serverless/references/concurrency.md +200 -0
- package/dist/global-skills/aws-serverless/references/deployment.md +94 -0
- package/dist/global-skills/aws-serverless/references/event-sources.md +484 -0
- package/dist/global-skills/aws-serverless/references/lambda.md +548 -0
- package/dist/global-skills/aws-serverless/references/orchestration.md +449 -0
- package/dist/global-skills/aws-serverless/references/production.md +493 -0
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +711 -0
- package/dist/global-skills/back-up-my-code/SKILL.md +48 -0
- package/dist/global-skills/better-auth-best-practices/SKILL.md +182 -0
- package/dist/global-skills/better-auth-security-best-practices/SKILL.md +432 -0
- package/dist/global-skills/building-native-ui/SKILL.md +377 -0
- package/dist/global-skills/building-native-ui/agents/openai.yaml +4 -0
- package/dist/global-skills/building-native-ui/references/animations.md +220 -0
- package/dist/global-skills/building-native-ui/references/controls.md +270 -0
- package/dist/global-skills/building-native-ui/references/form-sheet.md +253 -0
- package/dist/global-skills/building-native-ui/references/gradients.md +106 -0
- package/dist/global-skills/building-native-ui/references/icons.md +213 -0
- package/dist/global-skills/building-native-ui/references/media.md +198 -0
- package/dist/global-skills/building-native-ui/references/route-structure.md +229 -0
- package/dist/global-skills/building-native-ui/references/search.md +248 -0
- package/dist/global-skills/building-native-ui/references/storage.md +121 -0
- package/dist/global-skills/building-native-ui/references/tabs.md +433 -0
- package/dist/global-skills/building-native-ui/references/toolbar-and-headers.md +284 -0
- package/dist/global-skills/building-native-ui/references/visual-effects.md +197 -0
- package/dist/global-skills/building-native-ui/references/webgpu-three.md +605 -0
- package/dist/global-skills/building-native-ui/references/zoom-transitions.md +158 -0
- package/dist/global-skills/buy-domain/SKILL.md +64 -0
- package/dist/global-skills/check-safety/SKILL.md +94 -0
- package/dist/global-skills/claimable-postgres/SKILL.md +249 -0
- package/dist/global-skills/configure-capabilities/SKILL.md +38 -0
- package/dist/global-skills/connect-account/SKILL.md +64 -0
- package/dist/global-skills/connect-account-backend/SKILL.md +41 -0
- package/dist/global-skills/create-auth-skill/SKILL.md +321 -0
- package/dist/global-skills/design-my-data/SKILL.md +48 -0
- package/dist/global-skills/doctor/SKILL.md +84 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +152 -0
- package/dist/global-skills/eas-app-stores/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-app-stores/references/app-store-metadata.md +497 -0
- package/dist/global-skills/eas-app-stores/references/ios-app-store.md +371 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +246 -0
- package/dist/global-skills/eas-app-stores/references/testflight.md +58 -0
- package/dist/global-skills/eas-app-stores/references/workflows.md +120 -0
- package/dist/global-skills/eas-hosting/SKILL.md +423 -0
- package/dist/global-skills/eas-hosting/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-observe/SKILL.md +32 -0
- package/dist/global-skills/eas-observe/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-observe/references/metrics.md +47 -0
- package/dist/global-skills/eas-observe/references/queries.md +342 -0
- package/dist/global-skills/eas-observe/references/setup.md +317 -0
- package/dist/global-skills/eas-simulator/SKILL.md +156 -0
- package/dist/global-skills/eas-simulator/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-simulator/references/controllers.md +67 -0
- package/dist/global-skills/eas-simulator/references/run-your-app.md +185 -0
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +38 -0
- package/dist/global-skills/eas-update-insights/SKILL.md +230 -0
- package/dist/global-skills/eas-update-insights/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/dist/global-skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/dist/global-skills/eas-workflows/SKILL.md +94 -0
- package/dist/global-skills/eas-workflows/agents/openai.yaml +4 -0
- package/dist/global-skills/eas-workflows/scripts/fetch.js +109 -0
- package/dist/global-skills/eas-workflows/scripts/package.json +11 -0
- package/dist/global-skills/eas-workflows/scripts/validate.js +84 -0
- package/dist/global-skills/email-best-practices/SKILL.md +73 -0
- package/dist/global-skills/expo-api-routes/SKILL.md +368 -0
- package/dist/global-skills/expo-api-routes/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +282 -0
- package/dist/global-skills/expo-app-clip/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/references/native-module.md +96 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +54 -0
- package/dist/global-skills/expo-brownfield/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +526 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +402 -0
- package/dist/global-skills/expo-brownfield/references/comparison.md +63 -0
- package/dist/global-skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/dist/global-skills/expo-cicd-workflows/SKILL.md +92 -0
- package/dist/global-skills/expo-cicd-workflows/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-cicd-workflows/scripts/fetch.js +109 -0
- package/dist/global-skills/expo-cicd-workflows/scripts/package.json +11 -0
- package/dist/global-skills/expo-cicd-workflows/scripts/validate.js +84 -0
- package/dist/global-skills/expo-data-fetching/SKILL.md +449 -0
- package/dist/global-skills/expo-data-fetching/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
- package/dist/global-skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
- package/dist/global-skills/expo-deployment/SKILL.md +167 -0
- package/dist/global-skills/expo-deployment/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-deployment/references/app-store-metadata.md +497 -0
- package/dist/global-skills/expo-deployment/references/ios-app-store.md +371 -0
- package/dist/global-skills/expo-deployment/references/play-store.md +246 -0
- package/dist/global-skills/expo-deployment/references/testflight.md +58 -0
- package/dist/global-skills/expo-deployment/references/workflows.md +160 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +174 -0
- package/dist/global-skills/expo-dev-client/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-dom/SKILL.md +417 -0
- package/dist/global-skills/expo-dom/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-examples/SKILL.md +99 -0
- package/dist/global-skills/expo-examples/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-examples/references/catalog.md +105 -0
- package/dist/global-skills/expo-module/SKILL.md +141 -0
- package/dist/global-skills/expo-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-module/references/config-plugin.md +90 -0
- package/dist/global-skills/expo-module/references/create-expo-module.md +206 -0
- package/dist/global-skills/expo-module/references/lifecycle.md +127 -0
- package/dist/global-skills/expo-module/references/module-config.md +48 -0
- package/dist/global-skills/expo-module/references/native-module.md +286 -0
- package/dist/global-skills/expo-module/references/native-view.md +171 -0
- package/dist/global-skills/expo-native-ui/SKILL.md +181 -0
- package/dist/global-skills/expo-native-ui/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-native-ui/references/animations.md +220 -0
- package/dist/global-skills/expo-native-ui/references/controls.md +270 -0
- package/dist/global-skills/expo-native-ui/references/gradients.md +106 -0
- package/dist/global-skills/expo-native-ui/references/icons.md +213 -0
- package/dist/global-skills/expo-native-ui/references/media.md +198 -0
- package/dist/global-skills/expo-native-ui/references/storage.md +121 -0
- package/dist/global-skills/expo-native-ui/references/visual-effects.md +197 -0
- package/dist/global-skills/expo-native-ui/references/webgpu-three.md +605 -0
- package/dist/global-skills/expo-observe/SKILL.md +30 -0
- package/dist/global-skills/expo-observe/references/metrics.md +47 -0
- package/dist/global-skills/expo-observe/references/queries.md +342 -0
- package/dist/global-skills/expo-observe/references/setup.md +317 -0
- package/dist/global-skills/expo-router/SKILL.md +230 -0
- package/dist/global-skills/expo-router/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/references/form-sheet.md +253 -0
- package/dist/global-skills/expo-router/references/route-structure.md +229 -0
- package/dist/global-skills/expo-router/references/search.md +248 -0
- package/dist/global-skills/expo-router/references/tabs.md +433 -0
- package/dist/global-skills/expo-router/references/toolbar-and-headers.md +284 -0
- package/dist/global-skills/expo-router/references/zoom-transitions.md +158 -0
- package/dist/global-skills/expo-skill-eval/SKILL.md +314 -0
- package/dist/global-skills/expo-skill-eval/agents/visual-grader.md +52 -0
- package/dist/global-skills/expo-skill-eval/references/design-rubric.md +45 -0
- package/dist/global-skills/expo-skill-eval/references/runtime-matrix.md +34 -0
- package/dist/global-skills/expo-skill-eval/scripts/check-static.sh +64 -0
- package/dist/global-skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
- package/dist/global-skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
- package/dist/global-skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
- package/dist/global-skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
- package/dist/global-skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
- package/dist/global-skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
- package/dist/global-skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
- package/dist/global-skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +54 -0
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-skill-feedback/scripts/skill-event.cjs +180 -0
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +118 -0
- package/dist/global-skills/expo-skill-feedback/scripts/telemetry.cjs +65 -0
- package/dist/global-skills/expo-skill-feedback/scripts/telemetry_common.cjs +171 -0
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +480 -0
- package/dist/global-skills/expo-tailwind-setup/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-ui/SKILL.md +47 -0
- package/dist/global-skills/expo-ui/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-ui/references/drop-in-replacements.md +27 -0
- package/dist/global-skills/expo-ui/references/jetpack-compose.md +73 -0
- package/dist/global-skills/expo-ui/references/swift-ui.md +73 -0
- package/dist/global-skills/expo-ui/references/universal.md +73 -0
- package/dist/global-skills/expo-ui/scripts/list-components.js +193 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +134 -0
- package/dist/global-skills/expo-upgrade/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
- package/dist/global-skills/expo-upgrade/references/expo-av-to-video.md +160 -0
- package/dist/global-skills/expo-upgrade/references/native-tabs.md +124 -0
- package/dist/global-skills/expo-upgrade/references/new-architecture.md +79 -0
- package/dist/global-skills/expo-upgrade/references/react-19.md +79 -0
- package/dist/global-skills/expo-upgrade/references/react-compiler.md +59 -0
- package/dist/global-skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
- package/dist/global-skills/expo-web-to-native/SKILL.md +83 -0
- package/dist/global-skills/expo-web-to-native/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-web-to-native/references/false-friends.md +119 -0
- package/dist/global-skills/expo-web-to-native/references/native-patterns.md +39 -0
- package/dist/global-skills/expo-web-to-native/references/run-as-goal.md +48 -0
- package/dist/global-skills/expo-web-to-native/references/verify-on-device.md +45 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +165 -0
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +95 -0
- package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +156 -0
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +157 -0
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +186 -0
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +73 -0
- package/dist/global-skills/firebase-app-hosting-basics/references/cli_commands.md +85 -0
- package/dist/global-skills/firebase-app-hosting-basics/references/configuration.md +59 -0
- package/dist/global-skills/firebase-app-hosting-basics/references/emulation.md +59 -0
- package/dist/global-skills/firebase-auth-basics/SKILL.md +118 -0
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +160 -0
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +301 -0
- package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +149 -0
- package/dist/global-skills/firebase-auth-basics/references/ios_setup.md +87 -0
- package/dist/global-skills/firebase-auth-basics/references/security_rules.md +49 -0
- package/dist/global-skills/firebase-basics/SKILL.md +148 -0
- package/dist/global-skills/firebase-basics/references/android_setup.md +41 -0
- package/dist/global-skills/firebase-basics/references/firebase-cli-guide.md +18 -0
- package/dist/global-skills/firebase-basics/references/firebase-service-init.md +20 -0
- package/dist/global-skills/firebase-basics/references/flutter_setup.md +143 -0
- package/dist/global-skills/firebase-basics/references/ios_setup.md +113 -0
- package/dist/global-skills/firebase-basics/references/local-env-setup.md +80 -0
- package/dist/global-skills/firebase-basics/references/refresh/android_studio.md +41 -0
- package/dist/global-skills/firebase-basics/references/refresh/antigravity.md +64 -0
- package/dist/global-skills/firebase-basics/references/refresh/claude.md +12 -0
- package/dist/global-skills/firebase-basics/references/refresh/gemini-cli.md +13 -0
- package/dist/global-skills/firebase-basics/references/refresh/other-agents.md +67 -0
- package/dist/global-skills/firebase-basics/references/setup/android_studio.md +23 -0
- package/dist/global-skills/firebase-basics/references/setup/antigravity.md +98 -0
- package/dist/global-skills/firebase-basics/references/setup/claude_code.md +45 -0
- package/dist/global-skills/firebase-basics/references/setup/cursor.md +93 -0
- package/dist/global-skills/firebase-basics/references/setup/gemini_cli.md +53 -0
- package/dist/global-skills/firebase-basics/references/setup/github_copilot.md +104 -0
- package/dist/global-skills/firebase-basics/references/setup/other_agents.md +99 -0
- package/dist/global-skills/firebase-basics/references/web_setup.md +77 -0
- package/dist/global-skills/firebase-crashlytics/SKILL.md +42 -0
- package/dist/global-skills/firebase-crashlytics/references/android_setup.md +152 -0
- package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +115 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +191 -0
- package/dist/global-skills/firebase-data-connect/examples.md +638 -0
- package/dist/global-skills/firebase-data-connect/reference/cloud_functions.md +184 -0
- package/dist/global-skills/firebase-data-connect/reference/config.md +271 -0
- package/dist/global-skills/firebase-data-connect/reference/data_seeding.md +185 -0
- package/dist/global-skills/firebase-data-connect/reference/native_sql.md +170 -0
- package/dist/global-skills/firebase-data-connect/reference/operations.md +385 -0
- package/dist/global-skills/firebase-data-connect/reference/realtime.md +210 -0
- package/dist/global-skills/firebase-data-connect/reference/schema.md +290 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_admin_node.md +141 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_android.md +126 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +134 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +157 -0
- package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +146 -0
- package/dist/global-skills/firebase-data-connect/reference/search.md +264 -0
- package/dist/global-skills/firebase-data-connect/reference/security.md +295 -0
- package/dist/global-skills/firebase-data-connect/templates.md +318 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +89 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +230 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +66 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/flutter_setup.md +180 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +135 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/ios_setup.md +189 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +118 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +138 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +577 -0
- package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +127 -0
- package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +193 -0
- package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +176 -0
- package/dist/global-skills/firebase-firestore/references/standard/indexes.md +113 -0
- package/dist/global-skills/firebase-firestore/references/standard/ios_setup.md +174 -0
- package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +110 -0
- package/dist/global-skills/firebase-firestore/references/standard/security_rules.md +577 -0
- package/dist/global-skills/firebase-firestore/references/standard/web_sdk_usage.md +192 -0
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +64 -0
- package/dist/global-skills/firebase-hosting-basics/references/configuration.md +115 -0
- package/dist/global-skills/firebase-hosting-basics/references/deploying.md +48 -0
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +124 -0
- package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +91 -0
- package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +89 -0
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +70 -0
- package/dist/global-skills/go-live/SKILL.md +90 -0
- package/dist/global-skills/harden/SKILL.md +101 -0
- package/dist/global-skills/instrument-feature-flags/SKILL.md +88 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +3578 -0
- package/dist/global-skills/instrument-feature-flags/references/android.md +146 -0
- package/dist/global-skills/instrument-feature-flags/references/api.md +194 -0
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +231 -0
- package/dist/global-skills/instrument-feature-flags/references/django.md +263 -0
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +763 -0
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +47 -0
- package/dist/global-skills/instrument-feature-flags/references/flask.md +131 -0
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +212 -0
- package/dist/global-skills/instrument-feature-flags/references/go.md +208 -0
- package/dist/global-skills/instrument-feature-flags/references/ios.md +146 -0
- package/dist/global-skills/instrument-feature-flags/references/java.md +94 -0
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +170 -0
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +383 -0
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +216 -0
- package/dist/global-skills/instrument-feature-flags/references/php.md +187 -0
- package/dist/global-skills/instrument-feature-flags/references/python.md +191 -0
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +166 -0
- package/dist/global-skills/instrument-feature-flags/references/react.md +302 -0
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +604 -0
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +200 -0
- package/dist/global-skills/instrument-feature-flags/references/rust.md +222 -0
- package/dist/global-skills/instrument-feature-flags/references/usage.md +600 -0
- package/dist/global-skills/instrument-feature-flags/references/web.md +193 -0
- package/dist/global-skills/instrument-product-analytics/SKILL.md +139 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-android.md +1639 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-angular.md +944 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +1001 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +1004 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +720 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +810 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +1167 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-expo.md +1412 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +1585 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +1208 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-laravel.md +2267 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-next-app-router.md +712 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-next-pages-router.md +767 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +939 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +1078 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-php.md +527 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-python.md +481 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-native.md +1823 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-6.md +582 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-data.md +892 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-declarative.md +649 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +1218 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-tanstack-router-code-based.md +793 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-tanstack-router-file-based.md +780 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +1320 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby.md +452 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-sveltekit.md +854 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-swift.md +665 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +1199 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-vue-3.md +910 -0
- package/dist/global-skills/instrument-product-analytics/references/android.md +811 -0
- package/dist/global-skills/instrument-product-analytics/references/angular.md +376 -0
- package/dist/global-skills/instrument-product-analytics/references/astro.md +165 -0
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +299 -0
- package/dist/global-skills/instrument-product-analytics/references/django.md +263 -0
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +763 -0
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +414 -0
- package/dist/global-skills/instrument-product-analytics/references/flask.md +131 -0
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +845 -0
- package/dist/global-skills/instrument-product-analytics/references/go.md +567 -0
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +272 -0
- package/dist/global-skills/instrument-product-analytics/references/ios.md +154 -0
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +170 -0
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +383 -0
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +244 -0
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +253 -0
- package/dist/global-skills/instrument-product-analytics/references/php.md +646 -0
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +1675 -0
- package/dist/global-skills/instrument-product-analytics/references/python.md +898 -0
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +1338 -0
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +376 -0
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +364 -0
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +376 -0
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +479 -0
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +604 -0
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +759 -0
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +234 -0
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +193 -0
- package/dist/global-skills/instrument-product-analytics/references/usage.md +600 -0
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +306 -0
- package/dist/global-skills/manifest.json +125 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/SKILL.md +284 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/connection-configs.md +298 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/development-workflow.md +304 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/mcp-troubleshooting.md +55 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/output-diagnostics.md +150 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/pipeline-patterns.md +457 -0
- package/dist/global-skills/mongodb-atlas-stream-processing/references/sizing-and-parallelism.md +178 -0
- package/dist/global-skills/mongodb-connection/SKILL.md +201 -0
- package/dist/global-skills/mongodb-connection/references/monitoring-guide.md +191 -0
- package/dist/global-skills/mongodb-mcp-setup/SKILL.md +324 -0
- package/dist/global-skills/mongodb-natural-language-querying/SKILL.md +195 -0
- package/dist/global-skills/mongodb-query-optimizer/SKILL.md +150 -0
- package/dist/global-skills/mongodb-query-optimizer/references/aggregation-optimization.md +210 -0
- package/dist/global-skills/mongodb-query-optimizer/references/antipattern-examples.md +74 -0
- package/dist/global-skills/mongodb-query-optimizer/references/core-indexing-principles.md +134 -0
- package/dist/global-skills/mongodb-query-optimizer/references/update-query-examples.md +39 -0
- package/dist/global-skills/mongodb-schema-design/SKILL.md +181 -0
- package/dist/global-skills/mongodb-schema-design/references/antipattern-excessive-lookups.md +84 -0
- package/dist/global-skills/mongodb-schema-design/references/antipattern-unnecessary-collections.md +91 -0
- package/dist/global-skills/mongodb-schema-design/references/antipattern-unnecessary-indexes.md +95 -0
- package/dist/global-skills/mongodb-schema-design/references/fundamental-document-model.md +91 -0
- package/dist/global-skills/mongodb-schema-design/references/fundamental-document-size.md +226 -0
- package/dist/global-skills/mongodb-schema-design/references/fundamental-embed-vs-reference.md +418 -0
- package/dist/global-skills/mongodb-schema-design/references/fundamental-schema-validation.md +131 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-approximation.md +80 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-archive.md +143 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-attribute.md +77 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-bucket.md +102 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-computed.md +162 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-document-versioning.md +166 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-extended-reference.md +72 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-outlier.md +159 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-polymorphic.md +167 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-schema-versioning.md +273 -0
- package/dist/global-skills/mongodb-schema-design/references/pattern-time-series-collections.md +190 -0
- package/dist/global-skills/mongodb-schema-design/references/source-query-stats.md +123 -0
- package/dist/global-skills/mongodb-schema-design/references/source-slow-query-logs.md +63 -0
- package/dist/global-skills/mongodb-search-and-ai/SKILL.md +142 -0
- package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +697 -0
- package/dist/global-skills/mongodb-search-and-ai/references/lexical-search-indexing.md +584 -0
- package/dist/global-skills/mongodb-search-and-ai/references/lexical-search-querying.md +636 -0
- package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +746 -0
- package/dist/global-skills/native-data-fetching/SKILL.md +505 -0
- package/dist/global-skills/native-data-fetching/agents/openai.yaml +4 -0
- package/dist/global-skills/native-data-fetching/references/expo-router-loaders.md +341 -0
- package/dist/global-skills/neon/SKILL.md +343 -0
- package/dist/global-skills/neon-ai-gateway/SKILL.md +236 -0
- package/dist/global-skills/neon-functions/SKILL.md +490 -0
- package/dist/global-skills/neon-functions/references/ai-sdk.md +139 -0
- package/dist/global-skills/neon-functions/references/hono-websockets.md +145 -0
- package/dist/global-skills/neon-functions/references/mastra-studio.md +127 -0
- package/dist/global-skills/neon-functions/references/mcp.md +137 -0
- package/dist/global-skills/neon-functions/references/sentry.md +131 -0
- package/dist/global-skills/neon-functions/references/sse.md +143 -0
- package/dist/global-skills/neon-object-storage/SKILL.md +197 -0
- package/dist/global-skills/neon-postgres/SKILL.md +376 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +281 -0
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +247 -0
- package/dist/global-skills/onboarding/SKILL.md +101 -0
- package/dist/global-skills/plan-my-idea/SKILL.md +67 -0
- package/dist/global-skills/publish-app/SKILL.md +72 -0
- package/dist/global-skills/publish-extension/SKILL.md +47 -0
- package/dist/global-skills/resend/SKILL.md +294 -0
- package/dist/global-skills/resend/references/api-keys.md +98 -0
- package/dist/global-skills/resend/references/automations.md +228 -0
- package/dist/global-skills/resend/references/broadcasts.md +125 -0
- package/dist/global-skills/resend/references/contact-properties.md +111 -0
- package/dist/global-skills/resend/references/contacts.md +174 -0
- package/dist/global-skills/resend/references/domains.md +179 -0
- package/dist/global-skills/resend/references/events.md +119 -0
- package/dist/global-skills/resend/references/fetch-all-templates.mjs +37 -0
- package/dist/global-skills/resend/references/installation.md +142 -0
- package/dist/global-skills/resend/references/logs.md +161 -0
- package/dist/global-skills/resend/references/receiving.md +287 -0
- package/dist/global-skills/resend/references/segments.md +77 -0
- package/dist/global-skills/resend/references/sending/batch-email-examples.md +807 -0
- package/dist/global-skills/resend/references/sending/best-practices.md +453 -0
- package/dist/global-skills/resend/references/sending/email-management.md +135 -0
- package/dist/global-skills/resend/references/sending/overview.md +209 -0
- package/dist/global-skills/resend/references/sending/single-email-examples.md +470 -0
- package/dist/global-skills/resend/references/templates.md +202 -0
- package/dist/global-skills/resend/references/topics.md +104 -0
- package/dist/global-skills/resend/references/webhooks.md +317 -0
- package/dist/global-skills/reset-password/SKILL.md +59 -0
- package/dist/global-skills/save-data/SKILL.md +70 -0
- package/dist/global-skills/sentry-sdk-setup/SKILL.md +116 -0
- package/dist/global-skills/sentry-workflow/SKILL.md +32 -0
- package/dist/global-skills/setup-email/SKILL.md +69 -0
- package/dist/global-skills/setup-payments/SKILL.md +82 -0
- package/dist/global-skills/setup-sms/SKILL.md +51 -0
- package/dist/global-skills/sign-in-with-email-link/SKILL.md +53 -0
- package/dist/global-skills/sign-in-with-google/SKILL.md +68 -0
- package/dist/global-skills/sign-in-with-phone/SKILL.md +53 -0
- package/dist/global-skills/stripe-best-practices/SKILL.md +48 -0
- package/dist/global-skills/stripe-best-practices/references/billing.md +58 -0
- package/dist/global-skills/stripe-best-practices/references/connect.md +173 -0
- package/dist/global-skills/stripe-best-practices/references/payments.md +79 -0
- package/dist/global-skills/stripe-best-practices/references/security.md +109 -0
- package/dist/global-skills/stripe-best-practices/references/tax.md +37 -0
- package/dist/global-skills/stripe-best-practices/references/treasury.md +16 -0
- package/dist/global-skills/supabase/CHANGELOG.md +53 -0
- package/dist/global-skills/supabase/SKILL.md +145 -0
- package/dist/global-skills/supabase/assets/feedback-issue-template.md +17 -0
- package/dist/global-skills/supabase/references/skill-feedback.md +17 -0
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +43 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/dist/global-skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/dist/global-skills/track-errors/SKILL.md +67 -0
- package/dist/global-skills/update-kit/SKILL.md +75 -0
- package/dist/global-skills/upgrading-expo/SKILL.md +134 -0
- package/dist/global-skills/upgrading-expo/agents/openai.yaml +4 -0
- package/dist/global-skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
- package/dist/global-skills/upgrading-expo/references/expo-av-to-video.md +160 -0
- package/dist/global-skills/upgrading-expo/references/native-tabs.md +124 -0
- package/dist/global-skills/upgrading-expo/references/new-architecture.md +79 -0
- package/dist/global-skills/upgrading-expo/references/react-19.md +79 -0
- package/dist/global-skills/upgrading-expo/references/react-compiler.md +59 -0
- package/dist/global-skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
- package/dist/global-skills/use-dom/SKILL.md +417 -0
- package/dist/global-skills/use-dom/agents/openai.yaml +4 -0
- package/dist/global-skills/use-kit-mcp/SKILL.md +100 -0
- package/dist/global-skills/use-railway/SKILL.md +357 -0
- package/dist/global-skills/use-railway/references/analyze-db-mongo.md +84 -0
- package/dist/global-skills/use-railway/references/analyze-db-mysql.md +254 -0
- package/dist/global-skills/use-railway/references/analyze-db-postgres.md +479 -0
- package/dist/global-skills/use-railway/references/analyze-db-redis.md +208 -0
- package/dist/global-skills/use-railway/references/analyze-db.md +344 -0
- package/dist/global-skills/use-railway/references/configure.md +359 -0
- package/dist/global-skills/use-railway/references/deploy.md +225 -0
- package/dist/global-skills/use-railway/references/feature-flags.md +89 -0
- package/dist/global-skills/use-railway/references/iac.md +108 -0
- package/dist/global-skills/use-railway/references/operate.md +273 -0
- package/dist/global-skills/use-railway/references/request.md +262 -0
- package/dist/global-skills/use-railway/references/sandbox.md +167 -0
- package/dist/global-skills/use-railway/references/setup.md +364 -0
- package/dist/global-skills/use-railway/scripts/analyze-mongo.py +1549 -0
- package/dist/global-skills/use-railway/scripts/analyze-mysql.py +1195 -0
- package/dist/global-skills/use-railway/scripts/analyze-postgres.py +3058 -0
- package/dist/global-skills/use-railway/scripts/analyze-redis.py +1090 -0
- package/dist/global-skills/use-railway/scripts/dal.py +671 -0
- package/dist/global-skills/use-railway/scripts/enable-pg-stats.py +170 -0
- package/dist/global-skills/use-railway/scripts/pg-extensions.py +370 -0
- package/dist/global-skills/use-railway/scripts/railway-api.sh +52 -0
- package/dist/global-skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/dist/global-skills/vercel-composition-patterns/README.md +60 -0
- package/dist/global-skills/vercel-composition-patterns/SKILL.md +89 -0
- package/dist/global-skills/vercel-composition-patterns/metadata.json +11 -0
- package/dist/global-skills/vercel-composition-patterns/rules/_sections.md +29 -0
- package/dist/global-skills/vercel-composition-patterns/rules/_template.md +24 -0
- package/dist/global-skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/dist/global-skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/dist/global-skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/dist/global-skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/dist/global-skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/dist/global-skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/dist/global-skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/dist/global-skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/dist/global-skills/vercel-react-best-practices/AGENTS.md +3810 -0
- package/dist/global-skills/vercel-react-best-practices/README.md +123 -0
- package/dist/global-skills/vercel-react-best-practices/SKILL.md +149 -0
- package/dist/global-skills/vercel-react-best-practices/metadata.json +15 -0
- package/dist/global-skills/vercel-react-best-practices/rules/_sections.md +46 -0
- package/dist/global-skills/vercel-react-best-practices/rules/_template.md +28 -0
- package/dist/global-skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/dist/global-skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/global-skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/dist/global-skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/dist/global-skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/global-skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/global-skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/global-skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/global-skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/global-skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/global-skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/dist/global-skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/dist/global-skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/dist/global-skills/web-to-native/SKILL.md +83 -0
- package/dist/global-skills/web-to-native/references/false-friends.md +119 -0
- package/dist/global-skills/web-to-native/references/native-patterns.md +39 -0
- package/dist/global-skills/web-to-native/references/run-as-goal.md +48 -0
- package/dist/global-skills/web-to-native/references/verify-on-device.md +45 -0
- package/dist/global-skills/wire-auth/SKILL.md +28 -0
- package/dist/global-skills/wire-database/SKILL.md +28 -0
- package/dist/global-skills/wire-email/SKILL.md +27 -0
- package/dist/global-skills/wire-payments/SKILL.md +27 -0
- package/dist/global-skills/workers-best-practices/SKILL.md +127 -0
- package/dist/global-skills/workers-best-practices/references/review.md +174 -0
- package/dist/global-skills/workers-best-practices/references/rules.md +463 -0
- package/dist/global-skills/wrangler/SKILL.md +922 -0
- package/dist/global-skills/xcode-project-setup/SKILL.md +140 -0
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Package.resolved +41 -0
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Package.swift +17 -0
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +232 -0
- package/package.json +21 -20
- package/LICENSE.md +0 -47
- package/dist/index.js +0 -21593
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Extended Reference Pattern
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: "Reduces repeated `$lookup` on hot paths by caching selected referenced fields"
|
|
5
|
+
tags: schema, patterns, extended-reference, denormalization, caching
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Extended Reference Pattern
|
|
9
|
+
|
|
10
|
+
**Copy frequently-accessed fields from referenced documents into the parent.** If you always display author name with articles, embed it. This eliminates $lookup for common queries while keeping the full data normalized—best of both worlds.
|
|
11
|
+
|
|
12
|
+
**Incorrect (always $lookup for display data):**
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
// Order references customer by ID only
|
|
16
|
+
{
|
|
17
|
+
_id: "order123",
|
|
18
|
+
customerId: "cust456", // Customer reference by ID only
|
|
19
|
+
items: [...],
|
|
20
|
+
total: 299.99
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Every order list/display requires $lookup
|
|
24
|
+
db.orders.aggregate([
|
|
25
|
+
{ $match: { status: "pending" } },
|
|
26
|
+
{ $lookup: {
|
|
27
|
+
from: "customers",
|
|
28
|
+
localField: "customerId",
|
|
29
|
+
foreignField: "_id",
|
|
30
|
+
as: "customer"
|
|
31
|
+
}},
|
|
32
|
+
{ $unwind: "$customer" }
|
|
33
|
+
])
|
|
34
|
+
// Repeated joins add avoidable work for a common list view
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Correct (extended reference):**
|
|
38
|
+
|
|
39
|
+
Embed frequently-needed customer fields directly in the order document: include a `customer` subdocument with `_id` (kept as a reference for full lookups), `name`, and `email`. The order list query returns customer display data without `$lookup`. Full customer data is still available via a targeted read to the `customers` collection when needed.
|
|
40
|
+
|
|
41
|
+
**Keeping cached data in sync:**
|
|
42
|
+
|
|
43
|
+
When the source field changes (e.g. customer name), update the source collection first, then update cached copies in the orders collection using `updateMany` on the embedded reference `_id`. This can be done synchronously or asynchronously via Change Streams / background jobs. For data that changes more often, add a `cachedAt` timestamp to the embedded subdocument so the application can refresh on read when the cache exceeds a staleness threshold.
|
|
44
|
+
|
|
45
|
+
**What to cache (extend):**
|
|
46
|
+
|
|
47
|
+
| Cache | Don't Cache |
|
|
48
|
+
|-------|-------------|
|
|
49
|
+
| Display name, avatar | Full bio, description |
|
|
50
|
+
| Status, type | Sensitive PII |
|
|
51
|
+
| Slowly-changing data | Real-time values (balance, inventory) |
|
|
52
|
+
| Fields used in sorting/filtering | Large binary data |
|
|
53
|
+
|
|
54
|
+
**Alternative: Hybrid pattern with cache expiry:**
|
|
55
|
+
|
|
56
|
+
Keep both a bare reference (`customerId`) and an optional cache subdocument (`customerCache`) with `name`, `email`, and `cachedAt`. On read, if the cache is missing or older than a threshold (e.g. one day), refresh it from the `customers` collection and write the updated cache back to the order.
|
|
57
|
+
|
|
58
|
+
**When NOT to use this pattern:**
|
|
59
|
+
|
|
60
|
+
- **Frequently-changing data**: If customer name changes daily, update overhead exceeds $lookup cost.
|
|
61
|
+
- **Large cached payloads**: Don't embed 50KB of author bio in every article.
|
|
62
|
+
- **Sensitive data segregation**: Don't copy PII into collections with different access controls.
|
|
63
|
+
- **Writes >> Reads**: If writes greatly outnumber reads, caching adds overhead.
|
|
64
|
+
|
|
65
|
+
## Verify with
|
|
66
|
+
|
|
67
|
+
Find lookup-heavy aggregations. See how often lookups hit the same collection. High count = candidate for extended reference
|
|
68
|
+
|
|
69
|
+
For Atlas M10+ use $queryStats. See [Query Stats](references/source-query-stats.md) and [Slow query logs](references/source-slow-query-logs.md)
|
|
70
|
+
Use codebase if available, ask the user.
|
|
71
|
+
|
|
72
|
+
Reference: [Reduce $lookup Operations](https://mongodb.com/docs/manual/data-modeling/design-antipatterns/reduce-lookup-operations/)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Outlier Pattern for Exceptional Documents
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: "Isolates unusually large documents so hot-path queries stay optimized for typical cases"
|
|
5
|
+
tags: schema, patterns, outlier, arrays, performance, edge-cases
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Outlier Pattern for Exceptional Documents
|
|
9
|
+
|
|
10
|
+
**Isolate atypical documents with large arrays to prevent them from degrading performance for typical queries.** When a small subset of documents is much larger than the rest, those outliers can dominate memory, index, and query costs. Split overflow data into a separate collection and flag the document.
|
|
11
|
+
|
|
12
|
+
**Problem scenario:**
|
|
13
|
+
|
|
14
|
+
A typical book might have 50 customers in an embedded array, while a bestseller like Harry Potter accumulates 50,000 (~2.5MB). Queries return the full document, so the outlier dominates memory and network cost. A multikey index on that array produces 50,000 entries for a single document.
|
|
15
|
+
|
|
16
|
+
**Correct (outlier pattern):**
|
|
17
|
+
|
|
18
|
+
Typical documents keep their full embedded array and set `hasExtras: false`. Outlier documents cap the embedded array at a threshold (e.g. 50), set `hasExtras: true`, store a denormalized `customerCount`, and overflow remaining items into a separate collection in batched documents (e.g. `{ bookId, customers: [...], batch: 1, count: 950 }`). Application code checks the `hasExtras` flag to decide whether to load overflow batches.
|
|
19
|
+
|
|
20
|
+
**Implementation with threshold (example; tune per workload):**
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const CUSTOMER_THRESHOLD = 50
|
|
24
|
+
|
|
25
|
+
async function addCustomer(bookId, customerId) {
|
|
26
|
+
// Try the normal case first: atomically add to the embedded array only if
|
|
27
|
+
// the current customerCount is below the threshold (treat missing/null as 0).
|
|
28
|
+
const result = await db.books.updateOne(
|
|
29
|
+
{
|
|
30
|
+
_id: bookId,
|
|
31
|
+
$or: [
|
|
32
|
+
{ customerCount: { $lt: CUSTOMER_THRESHOLD } },
|
|
33
|
+
{ customerCount: { $exists: false } },
|
|
34
|
+
{ customerCount: null }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
$push: { customers: customerId },
|
|
39
|
+
$inc: { customerCount: 1 }
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if (result.matchedCount > 0) {
|
|
44
|
+
// Normal case succeeded - customer added to embedded array
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Outlier case - add to overflow collection
|
|
49
|
+
const lastBatchDoc = await db.book_customers_extra
|
|
50
|
+
.find({ bookId: bookId })
|
|
51
|
+
.sort({ batch: -1 })
|
|
52
|
+
.limit(1)
|
|
53
|
+
.next()
|
|
54
|
+
|
|
55
|
+
const nextBatch = lastBatchDoc ? lastBatchDoc.batch + 1 : 1
|
|
56
|
+
const targetBatch =
|
|
57
|
+
lastBatchDoc && lastBatchDoc.count < 1000
|
|
58
|
+
? lastBatchDoc.batch
|
|
59
|
+
: nextBatch
|
|
60
|
+
|
|
61
|
+
// First, try to append to the intended batch, enforcing the 1000-item cap under concurrency.
|
|
62
|
+
const overflowFilter = { bookId: bookId, batch: targetBatch }
|
|
63
|
+
if (targetBatch !== nextBatch) {
|
|
64
|
+
// Only enforce the count cap when targeting an existing batch.
|
|
65
|
+
overflowFilter.count = { $lt: 1000 }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const overflowResult = await db.book_customers_extra.updateOne(
|
|
69
|
+
overflowFilter, // Write to the intended batch, respecting the count cap when reusing a batch
|
|
70
|
+
{
|
|
71
|
+
$push: { customers: customerId },
|
|
72
|
+
$inc: { count: 1 },
|
|
73
|
+
$setOnInsert: { bookId: bookId, batch: targetBatch }
|
|
74
|
+
},
|
|
75
|
+
{ upsert: targetBatch === nextBatch }
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
// If we failed to match when trying to reuse the previous batch (it filled concurrently),
|
|
79
|
+
// fall back to writing into the next batch.
|
|
80
|
+
if (overflowResult.matchedCount === 0 && targetBatch !== nextBatch) {
|
|
81
|
+
await db.book_customers_extra.updateOne(
|
|
82
|
+
{ bookId: bookId, batch: nextBatch },
|
|
83
|
+
{
|
|
84
|
+
$push: { customers: customerId },
|
|
85
|
+
$inc: { count: 1 },
|
|
86
|
+
$setOnInsert: { bookId: bookId, batch: nextBatch }
|
|
87
|
+
},
|
|
88
|
+
{ upsert: true }
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await db.books.updateOne(
|
|
93
|
+
{ _id: bookId },
|
|
94
|
+
{
|
|
95
|
+
$set: { hasExtras: true },
|
|
96
|
+
$inc: { customerCount: 1 }
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Index strategy:**
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// Index on main collection - only 50 entries per outlier doc
|
|
106
|
+
db.books.createIndex({ "customers": 1 })
|
|
107
|
+
|
|
108
|
+
// Index on overflow collection
|
|
109
|
+
db.book_customers_extra.createIndex({ bookId: 1 })
|
|
110
|
+
db.book_customers_extra.createIndex({ customers: 1 })
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**When to use outlier pattern:**
|
|
114
|
+
|
|
115
|
+
| Scenario | What to measure | Example |
|
|
116
|
+
|----------|-----------------|---------|
|
|
117
|
+
| Book customers | Array-size distribution and long tail | Bestsellers vs. typical books |
|
|
118
|
+
| Social followers | Growth rate and read-path impact | Celebrities vs. regular users |
|
|
119
|
+
| Product reviews | Index fan-out and read locality | Viral products vs. typical |
|
|
120
|
+
| Event attendees | Outlier frequency vs. implementation complexity | Major events vs. small meetups |
|
|
121
|
+
|
|
122
|
+
**When NOT to use this pattern:**
|
|
123
|
+
|
|
124
|
+
- **Uniform distribution**: If all documents have similar array sizes, no outliers to isolate.
|
|
125
|
+
- **Always need full data**: If you always display all 50,000 customers, pattern doesn't help.
|
|
126
|
+
- **Write-heavy outliers**: Complex update logic may not be worth the read optimization.
|
|
127
|
+
- **Small outliers**: If outliers are 200 vs typical 50, just use larger threshold.
|
|
128
|
+
|
|
129
|
+
## Verify with
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
// Find outlier documents
|
|
133
|
+
db.books.aggregate([
|
|
134
|
+
{ $project: {
|
|
135
|
+
title: 1,
|
|
136
|
+
customerCount: { $size: { $ifNull: ["$customers", []] } }
|
|
137
|
+
}},
|
|
138
|
+
{ $sort: { customerCount: -1 } },
|
|
139
|
+
{ $limit: 20 }
|
|
140
|
+
])
|
|
141
|
+
|
|
142
|
+
// Calculate distribution
|
|
143
|
+
db.books.aggregate([
|
|
144
|
+
{ $project: { count: { $size: { $ifNull: ["$customers", []] } } } },
|
|
145
|
+
{ $bucket: {
|
|
146
|
+
groupBy: "$count",
|
|
147
|
+
boundaries: [0, 50, 100, 500, 1000, 10000, 100000],
|
|
148
|
+
default: "100000+",
|
|
149
|
+
output: { count: { $sum: 1 } }
|
|
150
|
+
}}
|
|
151
|
+
])
|
|
152
|
+
// Look for a long-tail distribution where a small subset is far above median/p95
|
|
153
|
+
|
|
154
|
+
// Check index sizes
|
|
155
|
+
db.books.stats().indexSizes
|
|
156
|
+
// Large multikey index suggests outliers are bloating it
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Reference: [Outlier Pattern](https://mongodb.com/docs/manual/data-modeling/design-patterns/group-data/outlier-pattern/)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Polymorphic Pattern for Heterogeneous Documents
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: "Keeps related entities in one collection while preserving type-specific fields"
|
|
5
|
+
tags: schema, patterns, polymorphic, discriminator, flexible-schema, indexing, single-collection
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Polymorphic Pattern for Heterogeneous Documents
|
|
9
|
+
|
|
10
|
+
**Store related but different document shapes in one collection with a type discriminator.** This keeps shared queries and indexes simple while allowing type-specific fields. Common use cases: product catalogs with different product types, content management systems, event stores, and any domain with inheritance.
|
|
11
|
+
|
|
12
|
+
**Incorrect (separate collections per subtype):**
|
|
13
|
+
|
|
14
|
+
Using a separate collection per product type (e.g. `products_books`, `products_electronics`, `products_clothing`) means querying across all products requires multiple calls or `$unionWith`, shared indexes must be duplicated, adding new types requires new collections, and application code must branch on collection names.
|
|
15
|
+
|
|
16
|
+
**Correct (single collection using optional fields):**
|
|
17
|
+
|
|
18
|
+
Store all product types in one `products` collection. All documents share common fields (`name`, `price`, `inStock`); each type adds its own specific fields (books: `author`, `isbn`, `pages`; electronics: `brand`, `wattage`, `batteryHours`, `warranty`; clothing: `size`, `color`, `material`). If the categories are always fully disjoint, use a `type` discriminator field (e.g. `"book"`, `"electronics"`, `"clothing"`). Cross-type queries use shared fields; type-specific queries filter by `type` plus type-specific fields. If there is potential overlap (e.g. between different categories of users), you can omit this field and rely entirely on optional fields.
|
|
19
|
+
|
|
20
|
+
**Index strategies for polymorphic collections:**
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// Strategy 1: Compound index with type first
|
|
24
|
+
// Best for: Queries that always filter by type
|
|
25
|
+
db.products.createIndex({ type: 1, price: 1 })
|
|
26
|
+
db.products.createIndex({ type: 1, name: 1 })
|
|
27
|
+
|
|
28
|
+
// Query uses index efficiently:
|
|
29
|
+
db.products.find({ type: "book", price: { $lt: 50 } })
|
|
30
|
+
|
|
31
|
+
// Strategy 2: Compound index with type second
|
|
32
|
+
// Best for: Queries that rarely filter by type
|
|
33
|
+
db.products.createIndex({ price: 1, type: 1 })
|
|
34
|
+
|
|
35
|
+
// Query across all types uses index:
|
|
36
|
+
db.products.find({ price: { $lt: 50 } })
|
|
37
|
+
|
|
38
|
+
// Strategy 3: Partial indexes for type-specific fields
|
|
39
|
+
// Best for: Fields that only exist on some types
|
|
40
|
+
db.products.createIndex(
|
|
41
|
+
{ author: 1 },
|
|
42
|
+
{ partialFilterExpression: { type: "book" } }
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
db.products.createIndex(
|
|
46
|
+
{ brand: 1, wattage: 1 },
|
|
47
|
+
{ partialFilterExpression: { type: "electronics" } }
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
// Strategy 4: Wildcard index for varying fields
|
|
51
|
+
// Best for: Many type-specific fields, ad-hoc queries
|
|
52
|
+
db.products.createIndex({ "specs.$**": 1 })
|
|
53
|
+
|
|
54
|
+
// Documents store type-specific data in specs:
|
|
55
|
+
{ type: "book", specs: { author: "...", isbn: "..." } }
|
|
56
|
+
{ type: "electronics", specs: { brand: "...", wattage: 20 } }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Query patterns across types:**
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// Pattern 1: Query all types with shared fields
|
|
63
|
+
db.products.find({ price: { $lt: 100 }, inStock: true })
|
|
64
|
+
.sort({ price: 1 })
|
|
65
|
+
|
|
66
|
+
// Pattern 2: Query specific type with type-specific fields
|
|
67
|
+
db.products.find({
|
|
68
|
+
type: "book",
|
|
69
|
+
pages: { $gt: 300 },
|
|
70
|
+
author: /bradshaw/i
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// Pattern 3: Aggregation across types with type-specific handling
|
|
74
|
+
db.products.aggregate([
|
|
75
|
+
{ $match: { inStock: true } },
|
|
76
|
+
{ $group: {
|
|
77
|
+
_id: "$type",
|
|
78
|
+
count: { $sum: 1 },
|
|
79
|
+
avgPrice: { $avg: "$price" }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
// Pattern 4: Faceted search with type breakdown
|
|
85
|
+
db.products.aggregate([
|
|
86
|
+
{ $match: { price: { $lt: 100 } } },
|
|
87
|
+
{ $facet: {
|
|
88
|
+
byType: [{ $group: { _id: "$type", count: { $sum: 1 } } }],
|
|
89
|
+
priceRanges: [
|
|
90
|
+
{ $bucket: {
|
|
91
|
+
groupBy: "$price",
|
|
92
|
+
boundaries: [0, 25, 50, 100],
|
|
93
|
+
default: "100+"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
])
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Validation per type:**
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// Use JSON Schema with discriminator-based validation
|
|
106
|
+
db.runCommand({
|
|
107
|
+
collMod: "products",
|
|
108
|
+
validator: {
|
|
109
|
+
$jsonSchema: {
|
|
110
|
+
bsonType: "object",
|
|
111
|
+
required: ["type", "name", "price"],
|
|
112
|
+
properties: {
|
|
113
|
+
type: { enum: ["book", "electronics", "clothing"] },
|
|
114
|
+
name: { bsonType: "string" },
|
|
115
|
+
price: { bsonType: "number", minimum: 0 }
|
|
116
|
+
},
|
|
117
|
+
oneOf: [
|
|
118
|
+
{
|
|
119
|
+
properties: { type: { enum: ["book"] } },
|
|
120
|
+
required: ["author", "isbn"]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
properties: { type: { enum: ["electronics"] } },
|
|
124
|
+
required: ["brand"]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
properties: { type: { enum: ["clothing"] } },
|
|
128
|
+
required: ["size", "color"]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
validationLevel: "moderate"
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Adding new types:**
|
|
138
|
+
|
|
139
|
+
The polymorphic pattern makes adding types straightforward — no schema migration needed. Insert documents with the new `type` value and any type-specific fields. Add partial indexes for type-specific queries as needed, and update schema validation to include the new type if using strict validation.
|
|
140
|
+
|
|
141
|
+
**When NOT to use polymorphic pattern:**
|
|
142
|
+
|
|
143
|
+
- **Completely different access patterns**: If each type is queried independently with no cross-type queries, separate collections may be cleaner.
|
|
144
|
+
- **Conflicting index requirements**: If types need many different indexes, the index overhead may outweigh benefits.
|
|
145
|
+
- **Strict type separation required**: Regulatory or security requirements may mandate separate collections.
|
|
146
|
+
- **Vastly different document sizes**: If one type has 100-byte docs and another has 100KB docs, working set suffers.
|
|
147
|
+
- **Type-specific sharding needs**: Different types may need different shard keys.
|
|
148
|
+
|
|
149
|
+
## Verify with
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
// Get type distribution
|
|
153
|
+
db.products.aggregate([
|
|
154
|
+
{ $group: {
|
|
155
|
+
_id: "$type",
|
|
156
|
+
count: { $sum: 1 },
|
|
157
|
+
avgSize: { $avg: { $bsonSize: "$$ROOT" } }
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{ $sort: { count: -1 } }
|
|
161
|
+
])
|
|
162
|
+
|
|
163
|
+
// Check for missing type field
|
|
164
|
+
db.products.countDocuments({ type: { $exists: false } })
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Reference: [Polymorphic Schema Pattern](https://mongodb.com/docs/manual/data-modeling/design-patterns/polymorphic-data/polymorphic-schema-pattern/)
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Schema Evolution and Preventing Drift
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: "Prevents application errors from inconsistent schemas and enables safe online migrations"
|
|
5
|
+
tags: schema, patterns, versioning, migration, evolution, backward-compatibility, backfill, anti-pattern, validation, consistency, data-quality, atlas-suggestion
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Schema Evolution and Preventing Drift
|
|
9
|
+
|
|
10
|
+
**Schema changes are inevitable, but uncontrolled changes cause schema drift** — documents in the same collection with inconsistent structures, leading to application errors and query failures. Use `schemaVersion` fields for safe migration and schema validation to prevent unexpected drift.
|
|
11
|
+
|
|
12
|
+
### The problem: schema drift
|
|
13
|
+
|
|
14
|
+
MongoDB's flexibility is a feature, but undisciplined field additions lead to code that must handle many document shapes.
|
|
15
|
+
|
|
16
|
+
**Incorrect (uncontrolled drift over time):**
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
// Over time, different versions of "user" documents accumulate
|
|
20
|
+
{ _id: 1, name: "Alice", email: "alice@ex.com" } // 2021
|
|
21
|
+
{ _id: 3, firstName: "Carol", lastName: "Smith", email: "carol@ex.com" } // 2022 - restructured name
|
|
22
|
+
{ _id: 4, firstName: "Dave", lastName: "Jones", emails: ["dave@ex.com"] } // 2023 - email → emails
|
|
23
|
+
|
|
24
|
+
// Application code becomes defensive nightmare
|
|
25
|
+
function getUserEmail(user) {
|
|
26
|
+
if (user.email) return user.email
|
|
27
|
+
if (user.emails) return user.emails[0]
|
|
28
|
+
throw new Error("No email found")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Queries fail silently
|
|
32
|
+
db.users.find({ email: "test@ex.com" }) // Misses users with emails[] array
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Solution: versioned documents with migration path
|
|
36
|
+
|
|
37
|
+
Add a `schemaVersion` field to every document. Application code checks version and handles both formats. This allows old and new documents to coexist, new code to deploy before data migration, gradual migration during low-traffic periods, and easy rollback.
|
|
38
|
+
|
|
39
|
+
**Correct (versioned with validation):**
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// Define and enforce consistent schema
|
|
43
|
+
db.createCollection("users", {
|
|
44
|
+
validator: {
|
|
45
|
+
$jsonSchema: {
|
|
46
|
+
bsonType: "object",
|
|
47
|
+
required: ["emails", "profile", "schemaVersion"],
|
|
48
|
+
properties: {
|
|
49
|
+
emails: {
|
|
50
|
+
bsonType: "array",
|
|
51
|
+
items: {
|
|
52
|
+
bsonType: "string",
|
|
53
|
+
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
profile: {
|
|
57
|
+
bsonType: "object",
|
|
58
|
+
required: ["firstName", "lastName"],
|
|
59
|
+
properties: {
|
|
60
|
+
firstName: { bsonType: "string", minLength: 1 },
|
|
61
|
+
lastName: { bsonType: "string", minLength: 1 }
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
schemaVersion: {
|
|
65
|
+
bsonType: "int",
|
|
66
|
+
enum: [1, 2] // Accept both during migration
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
validationLevel: "strict",
|
|
72
|
+
validationAction: "error"
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Online migration strategies
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
// Strategy 1: Background batch migration
|
|
80
|
+
// Best for: Large collections, can tolerate mixed versions temporarily
|
|
81
|
+
|
|
82
|
+
function migrateToV2(batchSize = 1000) {
|
|
83
|
+
let migrated = 0
|
|
84
|
+
let cursor = db.users.find({ schemaVersion: { $lt: 2 } }).limit(batchSize)
|
|
85
|
+
|
|
86
|
+
for (const doc of cursor) {
|
|
87
|
+
const [firstName, ...rest] = (doc.name || "").split(" ")
|
|
88
|
+
const lastName = rest.join(" ") || "Unknown"
|
|
89
|
+
|
|
90
|
+
db.users.updateOne(
|
|
91
|
+
{ _id: doc._id, schemaVersion: { $lt: 2 } }, // Prevent double-migration
|
|
92
|
+
{
|
|
93
|
+
$set: {
|
|
94
|
+
schemaVersion: 2,
|
|
95
|
+
profile: { firstName, lastName },
|
|
96
|
+
emails: doc.emails || (doc.email ? [doc.email] : []),
|
|
97
|
+
},
|
|
98
|
+
$unset: { name: "", email: "" }
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
migrated++
|
|
102
|
+
}
|
|
103
|
+
return migrated
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Run in batches during off-peak hours
|
|
107
|
+
while (migrateToV2(1000) > 0) {
|
|
108
|
+
sleep(100) // Throttle to reduce load
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// Strategy 2: Aggregation pipeline update (MongoDB 4.2+)
|
|
113
|
+
// Best for: Simple transformations, moderate collection sizes
|
|
114
|
+
|
|
115
|
+
db.users.updateMany(
|
|
116
|
+
{ schemaVersion: { $lt: 2 } },
|
|
117
|
+
[
|
|
118
|
+
{
|
|
119
|
+
$set: {
|
|
120
|
+
schemaVersion: 2,
|
|
121
|
+
profile: {
|
|
122
|
+
$cond: {
|
|
123
|
+
if: { $eq: [{ $type: "$name" }, "string"] },
|
|
124
|
+
then: {
|
|
125
|
+
firstName: { $arrayElemAt: [{ $split: ["$name", " "] }, 0] },
|
|
126
|
+
lastName: { $ifNull: [
|
|
127
|
+
{ $arrayElemAt: [{ $split: ["$name", " "] }, 1] },
|
|
128
|
+
"Unknown"
|
|
129
|
+
]}
|
|
130
|
+
},
|
|
131
|
+
else: "$profile"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
emails: {
|
|
135
|
+
$cond: {
|
|
136
|
+
if: { $eq: [{ $type: "$email" }, "string"] },
|
|
137
|
+
then: ["$email"],
|
|
138
|
+
else: { $ifNull: ["$emails", []] }
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{ $unset: ["name", "email"] }
|
|
144
|
+
]
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
// Strategy 3: Read-time migration (lazy migration)
|
|
149
|
+
// Best for: Low-traffic documents, immediate consistency needed
|
|
150
|
+
|
|
151
|
+
function getUser(userId) {
|
|
152
|
+
const user = db.users.findOne({ _id: userId })
|
|
153
|
+
|
|
154
|
+
if (user && user.schemaVersion < 2) {
|
|
155
|
+
const migrated = migrateUserToV2(user)
|
|
156
|
+
db.users.replaceOne({ _id: userId }, migrated)
|
|
157
|
+
return migrated
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return user
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Handling multiple version jumps
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// v1 → v2 → v3: define transformation functions for each step
|
|
168
|
+
const migrations = {
|
|
169
|
+
1: (doc) => ({
|
|
170
|
+
...doc,
|
|
171
|
+
schemaVersion: 2,
|
|
172
|
+
profile: {
|
|
173
|
+
firstName: doc.name.split(" ")[0],
|
|
174
|
+
lastName: doc.name.split(" ").slice(1).join(" ") || "Unknown"
|
|
175
|
+
},
|
|
176
|
+
emails: doc.email ? [doc.email] : []
|
|
177
|
+
}),
|
|
178
|
+
2: (doc) => ({
|
|
179
|
+
...doc,
|
|
180
|
+
schemaVersion: 3,
|
|
181
|
+
profile: {
|
|
182
|
+
...doc.profile,
|
|
183
|
+
displayName: `${doc.profile.firstName} ${doc.profile.lastName}`
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function migrateToLatest(doc, targetVersion = 3) {
|
|
189
|
+
let current = doc
|
|
190
|
+
while (current.schemaVersion < targetVersion) {
|
|
191
|
+
const migrator = migrations[current.schemaVersion]
|
|
192
|
+
if (!migrator) throw new Error(`No migration from v${current.schemaVersion}`)
|
|
193
|
+
current = migrator(current)
|
|
194
|
+
}
|
|
195
|
+
return current
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### When a version bump is (and isn't) needed
|
|
200
|
+
|
|
201
|
+
**No version bump needed (backward-compatible):**
|
|
202
|
+
- Adding new optional fields (old code ignores them)
|
|
203
|
+
- Adding new indexes (transparent to application)
|
|
204
|
+
- Relaxing validation (making a required field optional)
|
|
205
|
+
|
|
206
|
+
**Version bump required (breaking):**
|
|
207
|
+
- Renaming fields (`address` → `shippingAddress`)
|
|
208
|
+
- Changing field types (`price: "19.99"` → `price: 19.99`)
|
|
209
|
+
- Restructuring (flat `firstName`/`lastName` → nested `name: { first, last }`)
|
|
210
|
+
- Removing fields that old code reads
|
|
211
|
+
|
|
212
|
+
### Detecting existing schema drift
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
// Find all unique field combinations
|
|
216
|
+
db.users.aggregate([
|
|
217
|
+
{ $project: { fields: { $objectToArray: "$$ROOT" } } },
|
|
218
|
+
{ $project: { keys: "$fields.k" } },
|
|
219
|
+
{ $group: { _id: "$keys", count: { $sum: 1 } } },
|
|
220
|
+
{ $sort: { count: -1 } }
|
|
221
|
+
])
|
|
222
|
+
// Multiple distinct key-sets = schema drift exists
|
|
223
|
+
|
|
224
|
+
// Find documents missing required fields
|
|
225
|
+
db.users.find({
|
|
226
|
+
$or: [
|
|
227
|
+
{ emails: { $exists: false } },
|
|
228
|
+
{ profile: { $exists: false } },
|
|
229
|
+
{ "profile.firstName": { $exists: false } }
|
|
230
|
+
]
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
// Find documents with wrong field types
|
|
234
|
+
db.users.find({
|
|
235
|
+
emails: { $not: { $type: "array" } }
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### When NOT to strictly enforce schema or use versioning
|
|
240
|
+
|
|
241
|
+
- **Truly polymorphic data**: Event logs with different event types may need flexible schemas — use `pattern-polymorphic` instead.
|
|
242
|
+
- **Early prototyping**: Skip validation during exploration, add before production.
|
|
243
|
+
- **User-defined fields**: Some applications allow custom metadata fields.
|
|
244
|
+
- **Small datasets with downtime window**: If you can migrate all data in minutes during maintenance.
|
|
245
|
+
- **Additive-only changes**: If you only add optional fields, versioning is overkill.
|
|
246
|
+
|
|
247
|
+
## Verify with
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
// Track version distribution
|
|
251
|
+
db.users.aggregate([
|
|
252
|
+
{ $group: { _id: "$schemaVersion", count: { $sum: 1 } } },
|
|
253
|
+
{ $sort: { _id: 1 } }
|
|
254
|
+
])
|
|
255
|
+
|
|
256
|
+
// Check for missing version field (implicit v1 documents)
|
|
257
|
+
db.users.countDocuments({ schemaVersion: { $exists: false } })
|
|
258
|
+
|
|
259
|
+
// Check if validation exists on the collection
|
|
260
|
+
const collInfo = db.getCollectionInfos({ name: "users" })[0]
|
|
261
|
+
const validator = collInfo?.options?.validator
|
|
262
|
+
// Missing validator = higher schema drift risk
|
|
263
|
+
|
|
264
|
+
// Find documents that don't match current validator
|
|
265
|
+
if (validator) {
|
|
266
|
+
db.users.find({ $nor: [validator] }).limit(20)
|
|
267
|
+
db.users.countDocuments({ $nor: [validator] })
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
References:
|
|
272
|
+
- [Schema Versioning Pattern](https://mongodb.com/docs/manual/data-modeling/design-patterns/data-versioning/schema-versioning/)
|
|
273
|
+
- [Schema Validation](https://mongodb.com/docs/manual/core/schema-validation/)
|