claudeinone-cli 1.0.2 → 1.0.3
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/kit/.claude/.ck.json +9 -0
- package/kit/.claude/.ckignore +12 -0
- package/kit/.claude/agents/accessibility-auditor.md +46 -0
- package/kit/.claude/agents/api-designer.md +43 -0
- package/kit/.claude/agents/backend-developer.md +54 -0
- package/kit/.claude/agents/brainstormer.md +33 -0
- package/kit/.claude/agents/campaign-manager.md +36 -0
- package/kit/.claude/agents/code-reviewer.md +39 -0
- package/kit/.claude/agents/content-creator.md +38 -0
- package/kit/.claude/agents/copywriter.md +42 -0
- package/kit/.claude/agents/database-admin.md +37 -0
- package/kit/.claude/agents/debugger.md +46 -0
- package/kit/.claude/agents/devops-engineer.md +41 -0
- package/kit/.claude/agents/docs-manager.md +33 -0
- package/kit/.claude/agents/email-wizard.md +40 -0
- package/kit/.claude/agents/frontend-developer.md +52 -0
- package/kit/.claude/agents/fullstack-developer.md +55 -0
- package/kit/.claude/agents/git-manager.md +40 -0
- package/kit/.claude/agents/i18n-specialist.md +46 -0
- package/kit/.claude/agents/integration-specialist.md +48 -0
- package/kit/.claude/agents/journal-writer.md +39 -0
- package/kit/.claude/agents/mcp-manager.md +57 -0
- package/kit/.claude/agents/mobile-developer.md +38 -0
- package/kit/.claude/agents/performance-optimizer.md +38 -0
- package/kit/.claude/agents/planner.md +56 -0
- package/kit/.claude/agents/project-manager.md +34 -0
- package/kit/.claude/agents/refactorer.md +43 -0
- package/kit/.claude/agents/researcher.md +45 -0
- package/kit/.claude/agents/risk-analyst.md +33 -0
- package/kit/.claude/agents/scalability-consultant.md +39 -0
- package/kit/.claude/agents/scout.md +25 -0
- package/kit/.claude/agents/security-auditor.md +42 -0
- package/kit/.claude/agents/seo-specialist.md +44 -0
- package/kit/.claude/agents/skill-creator.md +64 -0
- package/kit/.claude/agents/social-media-manager.md +35 -0
- package/kit/.claude/agents/systems-designer.md +35 -0
- package/kit/.claude/agents/technology-strategist.md +43 -0
- package/kit/.claude/agents/tester.md +40 -0
- package/kit/.claude/agents/ui-ux-designer.md +40 -0
- package/kit/.claude/commands/co/ask.md +29 -0
- package/kit/.claude/commands/co/bootstrap-auto-fast.md +28 -0
- package/kit/.claude/commands/co/bootstrap-auto-parallel.md +29 -0
- package/kit/.claude/commands/co/bootstrap-auto.md +30 -0
- package/kit/.claude/commands/co/bootstrap.md +31 -0
- package/kit/.claude/commands/co/brainstorm.md +27 -0
- package/kit/.claude/commands/co/campaign.md +28 -0
- package/kit/.claude/commands/co/changelog.md +25 -0
- package/kit/.claude/commands/co/checkpoint.md +25 -0
- package/kit/.claude/commands/co/ci.md +26 -0
- package/kit/.claude/commands/co/ck-help.md +24 -0
- package/kit/.claude/commands/co/coding-level.md +24 -0
- package/kit/.claude/commands/co/content-cro.md +26 -0
- package/kit/.claude/commands/co/content-enhance.md +26 -0
- package/kit/.claude/commands/co/content-fast.md +24 -0
- package/kit/.claude/commands/co/content-good.md +26 -0
- package/kit/.claude/commands/co/cook.md +33 -0
- package/kit/.claude/commands/co/debug.md +26 -0
- package/kit/.claude/commands/co/deploy.md +25 -0
- package/kit/.claude/commands/co/design-3d.md +27 -0
- package/kit/.claude/commands/co/design-describe.md +25 -0
- package/kit/.claude/commands/co/design-fast.md +25 -0
- package/kit/.claude/commands/co/design-good.md +28 -0
- package/kit/.claude/commands/co/design-screenshot.md +26 -0
- package/kit/.claude/commands/co/design-video.md +26 -0
- package/kit/.claude/commands/co/docker.md +24 -0
- package/kit/.claude/commands/co/docs-api.md +25 -0
- package/kit/.claude/commands/co/docs-init.md +26 -0
- package/kit/.claude/commands/co/docs-readme.md +24 -0
- package/kit/.claude/commands/co/docs-summarize.md +25 -0
- package/kit/.claude/commands/co/docs-update.md +25 -0
- package/kit/.claude/commands/co/env-check.md +25 -0
- package/kit/.claude/commands/co/fix-ci.md +29 -0
- package/kit/.claude/commands/co/fix-fast.md +28 -0
- package/kit/.claude/commands/co/fix-hard.md +33 -0
- package/kit/.claude/commands/co/fix-logs.md +28 -0
- package/kit/.claude/commands/co/fix-types.md +28 -0
- package/kit/.claude/commands/co/fix-ui.md +28 -0
- package/kit/.claude/commands/co/fix.md +27 -0
- package/kit/.claude/commands/co/git-cm.md +26 -0
- package/kit/.claude/commands/co/git-cp.md +26 -0
- package/kit/.claude/commands/co/git-pr.md +26 -0
- package/kit/.claude/commands/co/index.md +24 -0
- package/kit/.claude/commands/co/integrate-polar.md +29 -0
- package/kit/.claude/commands/co/integrate-sepay.md +29 -0
- package/kit/.claude/commands/co/journal.md +27 -0
- package/kit/.claude/commands/co/k8s.md +24 -0
- package/kit/.claude/commands/co/kanban.md +25 -0
- package/kit/.claude/commands/co/lint-fix.md +24 -0
- package/kit/.claude/commands/co/load.md +25 -0
- package/kit/.claude/commands/co/migrate.md +28 -0
- package/kit/.claude/commands/co/mock.md +26 -0
- package/kit/.claude/commands/co/mode.md +24 -0
- package/kit/.claude/commands/co/monitor.md +25 -0
- package/kit/.claude/commands/co/new-feature.md +27 -0
- package/kit/.claude/commands/co/optimize.md +26 -0
- package/kit/.claude/commands/co/plan-archive.md +24 -0
- package/kit/.claude/commands/co/plan-ci.md +28 -0
- package/kit/.claude/commands/co/plan-cro.md +27 -0
- package/kit/.claude/commands/co/plan-fast.md +24 -0
- package/kit/.claude/commands/co/plan-hard.md +27 -0
- package/kit/.claude/commands/co/plan-parallel.md +25 -0
- package/kit/.claude/commands/co/plan-two.md +29 -0
- package/kit/.claude/commands/co/plan-validate.md +27 -0
- package/kit/.claude/commands/co/plan.md +27 -0
- package/kit/.claude/commands/co/pr.md +25 -0
- package/kit/.claude/commands/co/preview.md +26 -0
- package/kit/.claude/commands/co/refactor.md +25 -0
- package/kit/.claude/commands/co/release.md +25 -0
- package/kit/.claude/commands/co/review-a11y.md +24 -0
- package/kit/.claude/commands/co/review-codebase-parallel.md +27 -0
- package/kit/.claude/commands/co/review-codebase.md +27 -0
- package/kit/.claude/commands/co/review-perf.md +24 -0
- package/kit/.claude/commands/co/review-security.md +25 -0
- package/kit/.claude/commands/co/scaffold.md +25 -0
- package/kit/.claude/commands/co/scout.md +26 -0
- package/kit/.claude/commands/co/secure.md +26 -0
- package/kit/.claude/commands/co/seed.md +25 -0
- package/kit/.claude/commands/co/seo-audit.md +24 -0
- package/kit/.claude/commands/co/seo-keywords.md +25 -0
- package/kit/.claude/commands/co/skill-create.md +29 -0
- package/kit/.claude/commands/co/skill-fix-logs.md +28 -0
- package/kit/.claude/commands/co/slide-create.md +24 -0
- package/kit/.claude/commands/co/spawn.md +24 -0
- package/kit/.claude/commands/co/terraform.md +24 -0
- package/kit/.claude/commands/co/test-gen.md +24 -0
- package/kit/.claude/commands/co/test-ui.md +27 -0
- package/kit/.claude/commands/co/test.md +26 -0
- package/kit/.claude/commands/co/use-mcp.md +25 -0
- package/kit/.claude/commands/co/video-script.md +25 -0
- package/kit/.claude/commands/co/watzup.md +25 -0
- package/kit/.claude/commands/co/worktree.md +25 -0
- package/kit/.claude/commands/co/write-blog.md +25 -0
- package/kit/.claude/commands/co/write-copy.md +24 -0
- package/kit/.claude/commands/co/write-email.md +25 -0
- package/kit/.claude/commands/content/content-cro.md +26 -0
- package/kit/.claude/commands/content/content-enhance.md +26 -0
- package/kit/.claude/commands/content/content-fast.md +24 -0
- package/kit/.claude/commands/content/content-good.md +26 -0
- package/kit/.claude/commands/content/enhance.md +26 -0
- package/kit/.claude/commands/content/good.md +26 -0
- package/kit/.claude/commands/core/ask.md +29 -0
- package/kit/.claude/commands/core/bootstrap-auto-fast.md +28 -0
- package/kit/.claude/commands/core/bootstrap-auto-parallel.md +29 -0
- package/kit/.claude/commands/core/bootstrap-auto.md +30 -0
- package/kit/.claude/commands/core/bootstrap.md +31 -0
- package/kit/.claude/commands/core/ck-help.md +24 -0
- package/kit/.claude/commands/core/coding-level.md +24 -0
- package/kit/.claude/commands/core/cook.md +33 -0
- package/kit/.claude/commands/core/debug.md +26 -0
- package/kit/.claude/commands/core/journal.md +27 -0
- package/kit/.claude/commands/core/kanban.md +25 -0
- package/kit/.claude/commands/core/preview.md +26 -0
- package/kit/.claude/commands/core/scout.md +26 -0
- package/kit/.claude/commands/core/test-ui.md +27 -0
- package/kit/.claude/commands/core/test.md +26 -0
- package/kit/.claude/commands/core/use-mcp.md +25 -0
- package/kit/.claude/commands/core/watzup.md +25 -0
- package/kit/.claude/commands/core/worktree.md +25 -0
- package/kit/.claude/commands/design/3d.md +27 -0
- package/kit/.claude/commands/design/design-3d.md +27 -0
- package/kit/.claude/commands/design/design-describe.md +25 -0
- package/kit/.claude/commands/design/design-fast.md +25 -0
- package/kit/.claude/commands/design/design-good.md +28 -0
- package/kit/.claude/commands/design/design-screenshot.md +26 -0
- package/kit/.claude/commands/design/design-video.md +26 -0
- package/kit/.claude/commands/design/good.md +28 -0
- package/kit/.claude/commands/design/video.md +26 -0
- package/kit/.claude/commands/docs/docs-init.md +26 -0
- package/kit/.claude/commands/docs/docs-summarize.md +25 -0
- package/kit/.claude/commands/docs/docs-update.md +25 -0
- package/kit/.claude/commands/docs/init.md +26 -0
- package/kit/.claude/commands/docs/summarize.md +25 -0
- package/kit/.claude/commands/fix/ci.md +29 -0
- package/kit/.claude/commands/fix/fast.md +28 -0
- package/kit/.claude/commands/fix/fix-ci.md +29 -0
- package/kit/.claude/commands/fix/fix-fast.md +28 -0
- package/kit/.claude/commands/fix/fix-hard.md +33 -0
- package/kit/.claude/commands/fix/fix-logs.md +28 -0
- package/kit/.claude/commands/fix/fix-types.md +28 -0
- package/kit/.claude/commands/fix/fix-ui.md +28 -0
- package/kit/.claude/commands/fix/hard.md +33 -0
- package/kit/.claude/commands/fix/logs.md +28 -0
- package/kit/.claude/commands/fix/types.md +28 -0
- package/kit/.claude/commands/fix/ui.md +28 -0
- package/kit/.claude/commands/git/cp.md +26 -0
- package/kit/.claude/commands/git/git-cm.md +26 -0
- package/kit/.claude/commands/git/git-cp.md +26 -0
- package/kit/.claude/commands/git/git-pr.md +26 -0
- package/kit/.claude/commands/integrate/integrate-polar.md +29 -0
- package/kit/.claude/commands/integrate/integrate-sepay.md +29 -0
- package/kit/.claude/commands/integrate/sepay.md +29 -0
- package/kit/.claude/commands/plan/ci.md +28 -0
- package/kit/.claude/commands/plan/cro.md +27 -0
- package/kit/.claude/commands/plan/hard.md +27 -0
- package/kit/.claude/commands/plan/plan-archive.md +24 -0
- package/kit/.claude/commands/plan/plan-ci.md +28 -0
- package/kit/.claude/commands/plan/plan-cro.md +27 -0
- package/kit/.claude/commands/plan/plan-fast.md +24 -0
- package/kit/.claude/commands/plan/plan-hard.md +27 -0
- package/kit/.claude/commands/plan/plan-parallel.md +25 -0
- package/kit/.claude/commands/plan/plan-two.md +29 -0
- package/kit/.claude/commands/plan/plan-validate.md +27 -0
- package/kit/.claude/commands/plan/plan.md +27 -0
- package/kit/.claude/commands/plan/validate.md +27 -0
- package/kit/.claude/commands/skill/fix-logs.md +28 -0
- package/kit/.claude/commands/skill/skill-create.md +29 -0
- package/kit/.claude/commands/skill/skill-fix-logs.md +28 -0
- package/kit/.claude/settings.json +16 -0
- package/kit/.claude/skills/ai-anthropic.md +100 -0
- package/kit/.claude/skills/ai-context-engineering.md +113 -0
- package/kit/.claude/skills/ai-gemini.md +152 -0
- package/kit/.claude/skills/ai-langchain.md +93 -0
- package/kit/.claude/skills/ai-llamaindex.md +179 -0
- package/kit/.claude/skills/ai-mcp-builder.md +101 -0
- package/kit/.claude/skills/ai-openai.md +250 -0
- package/kit/.claude/skills/ai-prompt-engineering.md +173 -0
- package/kit/.claude/skills/ai-rag.md +91 -0
- package/kit/.claude/skills/ai-vectordb.md +215 -0
- package/kit/.claude/skills/analytics-segment.md +161 -0
- package/kit/.claude/skills/api-caching.md +103 -0
- package/kit/.claude/skills/api-documentation.md +50 -0
- package/kit/.claude/skills/api-graphql.md +234 -0
- package/kit/.claude/skills/api-openapi.md +116 -0
- package/kit/.claude/skills/api-pagination-filtering.md +239 -0
- package/kit/.claude/skills/api-rate-limiting.md +179 -0
- package/kit/.claude/skills/api-rest-advanced.md +50 -0
- package/kit/.claude/skills/api-rest.md +217 -0
- package/kit/.claude/skills/api-trpc.md +173 -0
- package/kit/.claude/skills/api-versioning.md +70 -0
- package/kit/.claude/skills/api-webhooks.md +226 -0
- package/kit/.claude/skills/arch-clean-code.md +226 -0
- package/kit/.claude/skills/arch-clean.md +91 -0
- package/kit/.claude/skills/arch-cqrs.md +229 -0
- package/kit/.claude/skills/arch-ddd.md +85 -0
- package/kit/.claude/skills/arch-event-driven.md +189 -0
- package/kit/.claude/skills/arch-microservices.md +80 -0
- package/kit/.claude/skills/arch-monorepo.md +87 -0
- package/kit/.claude/skills/arch-multi-tenant.md +81 -0
- package/kit/.claude/skills/arch-serverless.md +86 -0
- package/kit/.claude/skills/auth-clerk.md +97 -0
- package/kit/.claude/skills/auth-jwt.md +143 -0
- package/kit/.claude/skills/auth-lucia.md +93 -0
- package/kit/.claude/skills/auth-nextauth.md +446 -0
- package/kit/.claude/skills/auth-oauth.md +208 -0
- package/kit/.claude/skills/auth-oauth2.md +110 -0
- package/kit/.claude/skills/auth-passkeys.md +109 -0
- package/kit/.claude/skills/auth-session.md +88 -0
- package/kit/.claude/skills/backend-dotnet.md +414 -0
- package/kit/.claude/skills/backend-express.md +129 -0
- package/kit/.claude/skills/backend-fastify.md +104 -0
- package/kit/.claude/skills/backend-go.md +205 -0
- package/kit/.claude/skills/backend-graphql.md +149 -0
- package/kit/.claude/skills/backend-grpc.md +382 -0
- package/kit/.claude/skills/backend-hono.md +95 -0
- package/kit/.claude/skills/backend-java-spring.md +198 -0
- package/kit/.claude/skills/backend-nodejs-express.md +165 -0
- package/kit/.claude/skills/backend-nodejs.md +143 -0
- package/kit/.claude/skills/backend-php-laravel.md +156 -0
- package/kit/.claude/skills/backend-python-django.md +200 -0
- package/kit/.claude/skills/backend-python-fastapi.md +169 -0
- package/kit/.claude/skills/backend-ruby-rails.md +190 -0
- package/kit/.claude/skills/backend-rust.md +182 -0
- package/kit/.claude/skills/backend-websockets.md +392 -0
- package/kit/.claude/skills/cache-redis.md +195 -0
- package/kit/.claude/skills/caching-strategies.md +100 -0
- package/kit/.claude/skills/cloud-aws.md +165 -0
- package/kit/.claude/skills/cloud-azure.md +187 -0
- package/kit/.claude/skills/cloud-cloudflare.md +74 -0
- package/kit/.claude/skills/cloud-fly.md +94 -0
- package/kit/.claude/skills/cloud-gcp.md +160 -0
- package/kit/.claude/skills/cloud-railway.md +92 -0
- package/kit/.claude/skills/cloud-render.md +70 -0
- package/kit/.claude/skills/cloud-serverless.md +68 -0
- package/kit/.claude/skills/cloud-vercel.md +76 -0
- package/kit/.claude/skills/component-patterns.md +50 -0
- package/kit/.claude/skills/content-management.md +197 -0
- package/kit/.claude/skills/cors-security.md +50 -0
- package/kit/.claude/skills/data-csv-excel.md +210 -0
- package/kit/.claude/skills/database-optimization.md +196 -0
- package/kit/.claude/skills/databases-transactions.md +68 -0
- package/kit/.claude/skills/db-cassandra.md +89 -0
- package/kit/.claude/skills/db-drizzle.md +363 -0
- package/kit/.claude/skills/db-dynamodb.md +83 -0
- package/kit/.claude/skills/db-elasticsearch.md +105 -0
- package/kit/.claude/skills/db-firebase-firestore.md +191 -0
- package/kit/.claude/skills/db-mongodb.md +198 -0
- package/kit/.claude/skills/db-mysql.md +50 -0
- package/kit/.claude/skills/db-neon.md +72 -0
- package/kit/.claude/skills/db-planetscale.md +76 -0
- package/kit/.claude/skills/db-postgresql.md +50 -0
- package/kit/.claude/skills/db-prisma.md +414 -0
- package/kit/.claude/skills/db-redis.md +50 -0
- package/kit/.claude/skills/db-sqlite.md +149 -0
- package/kit/.claude/skills/db-supabase.md +445 -0
- package/kit/.claude/skills/devops-ci-cd.md +271 -0
- package/kit/.claude/skills/devops-database-backup.md +77 -0
- package/kit/.claude/skills/devops-docker.md +93 -0
- package/kit/.claude/skills/devops-github-actions.md +82 -0
- package/kit/.claude/skills/devops-health-checks.md +50 -0
- package/kit/.claude/skills/devops-kubernetes.md +109 -0
- package/kit/.claude/skills/devops-logging.md +163 -0
- package/kit/.claude/skills/devops-monitoring.md +203 -0
- package/kit/.claude/skills/devops-pulumi.md +94 -0
- package/kit/.claude/skills/devops-secrets.md +166 -0
- package/kit/.claude/skills/devops-terraform.md +226 -0
- package/kit/.claude/skills/error-boundaries.md +84 -0
- package/kit/.claude/skills/file-storage.md +50 -0
- package/kit/.claude/skills/frontend-angular.md +104 -0
- package/kit/.claude/skills/frontend-astro.md +94 -0
- package/kit/.claude/skills/frontend-bundle-analysis.md +147 -0
- package/kit/.claude/skills/frontend-forms.md +134 -0
- package/kit/.claude/skills/frontend-htmx.md +86 -0
- package/kit/.claude/skills/frontend-nextjs.md +188 -0
- package/kit/.claude/skills/frontend-pwa.md +105 -0
- package/kit/.claude/skills/frontend-react-hooks.md +238 -0
- package/kit/.claude/skills/frontend-react.md +129 -0
- package/kit/.claude/skills/frontend-remix-advanced.md +106 -0
- package/kit/.claude/skills/frontend-remix.md +101 -0
- package/kit/.claude/skills/frontend-solid.md +99 -0
- package/kit/.claude/skills/frontend-state-management.md +134 -0
- package/kit/.claude/skills/frontend-state.md +106 -0
- package/kit/.claude/skills/frontend-svelte.md +121 -0
- package/kit/.claude/skills/frontend-testing.md +100 -0
- package/kit/.claude/skills/frontend-vite.md +94 -0
- package/kit/.claude/skills/frontend-vue.md +133 -0
- package/kit/.claude/skills/frontend-webpack.md +93 -0
- package/kit/.claude/skills/functional-programming.md +50 -0
- package/kit/.claude/skills/hooks-custom.md +50 -0
- package/kit/.claude/skills/http-server.md +50 -0
- package/kit/.claude/skills/i18n-general.md +89 -0
- package/kit/.claude/skills/i18n-localization.md +191 -0
- package/kit/.claude/skills/i18n-nextjs.md +127 -0
- package/kit/.claude/skills/infrastructure-docker-compose.md +77 -0
- package/kit/.claude/skills/infrastructure-serverless.md +177 -0
- package/kit/.claude/skills/jwt-tokens.md +50 -0
- package/kit/.claude/skills/logging-winston.md +106 -0
- package/kit/.claude/skills/messaging-kafka.md +102 -0
- package/kit/.claude/skills/messaging-rabbitmq.md +50 -0
- package/kit/.claude/skills/mobile-capacitor.md +109 -0
- package/kit/.claude/skills/mobile-expo.md +101 -0
- package/kit/.claude/skills/mobile-flutter.md +259 -0
- package/kit/.claude/skills/mobile-react-native.md +238 -0
- package/kit/.claude/skills/monitoring-apm.md +50 -0
- package/kit/.claude/skills/monitoring-error-tracking.md +217 -0
- package/kit/.claude/skills/nodejs-streams.md +168 -0
- package/kit/.claude/skills/oauth-integration.md +50 -0
- package/kit/.claude/skills/patterns-dependency-injection.md +218 -0
- package/kit/.claude/skills/patterns-factory-singleton.md +209 -0
- package/kit/.claude/skills/patterns-observer-pubsub.md +210 -0
- package/kit/.claude/skills/payment-lemonsqueezy.md +101 -0
- package/kit/.claude/skills/payment-square.md +178 -0
- package/kit/.claude/skills/payment-stripe.md +206 -0
- package/kit/.claude/skills/perf-bundle.md +100 -0
- package/kit/.claude/skills/perf-web-vitals.md +102 -0
- package/kit/.claude/skills/performance-database-connection-pooling.md +67 -0
- package/kit/.claude/skills/performance-metrics.md +73 -0
- package/kit/.claude/skills/performance-optimization.md +208 -0
- package/kit/.claude/skills/performance-web-vitals.md +169 -0
- package/kit/.claude/skills/rate-limiting.md +77 -0
- package/kit/.claude/skills/reactive-programming.md +50 -0
- package/kit/.claude/skills/realtime-database.md +50 -0
- package/kit/.claude/skills/realtime-subscriptions.md +218 -0
- package/kit/.claude/skills/saas-ab-testing.md +90 -0
- package/kit/.claude/skills/saas-analytics.md +113 -0
- package/kit/.claude/skills/saas-billing.md +106 -0
- package/kit/.claude/skills/saas-email.md +88 -0
- package/kit/.claude/skills/saas-feature-flags.md +83 -0
- package/kit/.claude/skills/saas-onboarding.md +96 -0
- package/kit/.claude/skills/saas-user-onboarding.md +207 -0
- package/kit/.claude/skills/security-encryption.md +216 -0
- package/kit/.claude/skills/security-owasp.md +212 -0
- package/kit/.claude/skills/security-secrets-rotation.md +64 -0
- package/kit/.claude/skills/seo-content.md +94 -0
- package/kit/.claude/skills/seo-technical.md +101 -0
- package/kit/.claude/skills/serverless-framework.md +151 -0
- package/kit/.claude/skills/sharding-scaling.md +50 -0
- package/kit/.claude/skills/styling-css-modules.md +219 -0
- package/kit/.claude/skills/styling-styled-components.md +206 -0
- package/kit/.claude/skills/styling-tailwind.md +206 -0
- package/kit/.claude/skills/test-e2e.md +86 -0
- package/kit/.claude/skills/test-integration.md +216 -0
- package/kit/.claude/skills/test-performance.md +162 -0
- package/kit/.claude/skills/test-tdd.md +170 -0
- package/kit/.claude/skills/test-unit.md +301 -0
- package/kit/.claude/skills/testing-accessibility.md +117 -0
- package/kit/.claude/skills/testing-contract.md +75 -0
- package/kit/.claude/skills/testing-e2e-advanced.md +50 -0
- package/kit/.claude/skills/testing-load-stress.md +79 -0
- package/kit/.claude/skills/testing-mutation.md +92 -0
- package/kit/.claude/skills/testing-snapshot.md +50 -0
- package/kit/.claude/skills/testing-vitest.md +172 -0
- package/kit/.claude/skills/tooling-biome.md +91 -0
- package/kit/.claude/skills/tooling-build-tools.md +166 -0
- package/kit/.claude/skills/tooling-bun.md +94 -0
- package/kit/.claude/skills/tooling-eslint.md +103 -0
- package/kit/.claude/skills/tooling-git.md +79 -0
- package/kit/.claude/skills/tooling-monorepo.md +162 -0
- package/kit/.claude/skills/tooling-testing-frameworks.md +207 -0
- package/kit/.claude/skills/tooling-typescript.md +156 -0
- package/kit/.claude/skills/ui-a11y.md +106 -0
- package/kit/.claude/skills/ui-framer.md +106 -0
- package/kit/.claude/skills/ui-gsap.md +102 -0
- package/kit/.claude/skills/ui-radix.md +82 -0
- package/kit/.claude/skills/ui-shadcn.md +463 -0
- package/kit/.claude/skills/ui-tailwind.md +98 -0
- package/kit/.claude/skills/ui-threejs.md +110 -0
- package/kit/.claude/skills/ui-tokens.md +97 -0
- package/kit/.claude/skills/utilities-date-time.md +170 -0
- package/kit/.claude/skills/validation-schemas.md +110 -0
- package/kit/.claude/skills/version-control-git.md +144 -0
- package/kit/.claude/skills/web-accessibility-wcag.md +102 -0
- package/kit/.claude/skills/web-astro.md +197 -0
- package/kit/.claude/skills/web-html-css.md +224 -0
- package/kit/.claude/skills/web-htmx.md +99 -0
- package/kit/.claude/skills/web-nextjs-advanced.md +202 -0
- package/kit/.claude/skills/web-remix.md +194 -0
- package/kit/.claude/skills/web-seo.md +99 -0
- package/kit/.claude/skills/web-svelte.md +234 -0
- package/kit/.claude/skills/websocket-server.md +50 -0
- package/kit/.claude/skills/writing-marketing.md +89 -0
- package/kit/.claude/skills/writing-technical.md +119 -0
- package/kit/CLAUDE.md +206 -0
- package/kit/README.md +150 -0
- package/kit/SKILLS_INDEX.md +188 -0
- package/kit/docs/README.md +3 -0
- package/kit/journals/README.md +3 -0
- package/kit/plans/README.md +3 -0
- package/package.json +3 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# CQRS (Command Query Responsibility Segregation)
|
|
2
|
+
|
|
3
|
+
Separate read and write models for scalability and clarity.
|
|
4
|
+
|
|
5
|
+
## Basic CQRS Pattern
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// Command: modifies state
|
|
9
|
+
interface Command {
|
|
10
|
+
execute(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class CreateUserCommand implements Command {
|
|
14
|
+
constructor(private userData: CreateUserInput) {}
|
|
15
|
+
|
|
16
|
+
async execute() {
|
|
17
|
+
const user = new User(this.userData);
|
|
18
|
+
await userRepository.save(user);
|
|
19
|
+
|
|
20
|
+
// Publish event for read model update
|
|
21
|
+
eventBus.publish('UserCreated', user);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Query: reads state
|
|
26
|
+
interface Query<T> {
|
|
27
|
+
execute(): Promise<T>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class GetUserQuery implements Query<UserDTO> {
|
|
31
|
+
constructor(private userId: string) {}
|
|
32
|
+
|
|
33
|
+
async execute(): Promise<UserDTO> {
|
|
34
|
+
// Read from optimized read model
|
|
35
|
+
return userReadModel.findById(this.userId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Command Handler
|
|
40
|
+
class CommandBus {
|
|
41
|
+
async execute(command: Command) {
|
|
42
|
+
return command.execute();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Query Handler
|
|
47
|
+
class QueryBus {
|
|
48
|
+
async execute<T>(query: Query<T>): Promise<T> {
|
|
49
|
+
return query.execute();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Separate Read/Write Models
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// Write Model (normalized, consistent)
|
|
58
|
+
interface User {
|
|
59
|
+
id: string;
|
|
60
|
+
email: string;
|
|
61
|
+
password_hash: string;
|
|
62
|
+
created_at: Date;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Read Model (denormalized, optimized)
|
|
66
|
+
interface UserReadModel {
|
|
67
|
+
id: string;
|
|
68
|
+
email: string;
|
|
69
|
+
display_name: string;
|
|
70
|
+
avatar_url: string;
|
|
71
|
+
created_at: Date;
|
|
72
|
+
post_count: number; // Denormalized
|
|
73
|
+
follower_count: number; // Denormalized
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Commands update write model
|
|
77
|
+
async function createUser(data: CreateUserInput) {
|
|
78
|
+
const user = await db('users').insert(data);
|
|
79
|
+
eventBus.emit('user:created', user);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Events update read model
|
|
83
|
+
eventBus.on('user:created', async (user) => {
|
|
84
|
+
// Hydrate read model with denormalized data
|
|
85
|
+
await readModelDb('users').insert({
|
|
86
|
+
id: user.id,
|
|
87
|
+
email: user.email,
|
|
88
|
+
display_name: user.email.split('@')[0],
|
|
89
|
+
post_count: 0,
|
|
90
|
+
follower_count: 0
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
eventBus.on('post:created', async (post) => {
|
|
95
|
+
// Update denormalized post_count
|
|
96
|
+
await readModelDb('users')
|
|
97
|
+
.where('id', post.user_id)
|
|
98
|
+
.increment('post_count', 1);
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Projections
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Projection: builds read model from events
|
|
106
|
+
class UserProjection {
|
|
107
|
+
async handle(event: DomainEvent) {
|
|
108
|
+
switch (event.type) {
|
|
109
|
+
case 'UserCreated':
|
|
110
|
+
await this.onUserCreated(event);
|
|
111
|
+
break;
|
|
112
|
+
case 'UserProfileUpdated':
|
|
113
|
+
await this.onUserProfileUpdated(event);
|
|
114
|
+
break;
|
|
115
|
+
case 'UserFollowedUser':
|
|
116
|
+
await this.onUserFollowedUser(event);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private async onUserCreated(event: any) {
|
|
122
|
+
await readModel.insert({
|
|
123
|
+
id: event.data.id,
|
|
124
|
+
email: event.data.email,
|
|
125
|
+
follower_count: 0,
|
|
126
|
+
following_count: 0
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private async onUserFollowedUser(event: any) {
|
|
131
|
+
await readModel
|
|
132
|
+
.where('id', event.data.followerId)
|
|
133
|
+
.increment('following_count', 1);
|
|
134
|
+
|
|
135
|
+
await readModel
|
|
136
|
+
.where('id', event.data.followedId)
|
|
137
|
+
.increment('follower_count', 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Replay events
|
|
142
|
+
async function rebuildReadModel() {
|
|
143
|
+
const events = await eventStore.getAll();
|
|
144
|
+
const projection = new UserProjection();
|
|
145
|
+
|
|
146
|
+
for (const event of events) {
|
|
147
|
+
await projection.handle(event);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## API Layer
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Routes use Command/Query buses
|
|
156
|
+
app.post('/users', async (req, res) => {
|
|
157
|
+
const command = new CreateUserCommand(req.body);
|
|
158
|
+
const user = await commandBus.execute(command);
|
|
159
|
+
res.json(user);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
app.get('/users/:id', async (req, res) => {
|
|
163
|
+
const query = new GetUserQuery(req.params.id);
|
|
164
|
+
const user = await queryBus.execute(query);
|
|
165
|
+
res.json(user);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
app.get('/users/:id/posts', async (req, res) => {
|
|
169
|
+
// Query read model directly (optimized)
|
|
170
|
+
const posts = await readModel.query()
|
|
171
|
+
.where('user_id', req.params.id)
|
|
172
|
+
.orderBy('created_at', 'desc');
|
|
173
|
+
res.json(posts);
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Consistency Handling
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// Handling eventual consistency
|
|
181
|
+
|
|
182
|
+
async function getUserWithRetry(userId: string, maxRetries = 3) {
|
|
183
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
184
|
+
const user = await readModel.findById(userId);
|
|
185
|
+
if (user) return user;
|
|
186
|
+
|
|
187
|
+
// Exponential backoff
|
|
188
|
+
await sleep(Math.pow(2, i) * 100);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
throw new Error(`User ${userId} not found after retries`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Version tracking
|
|
195
|
+
interface VersionedEntity {
|
|
196
|
+
id: string;
|
|
197
|
+
version: number;
|
|
198
|
+
data: any;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Client provides expected version
|
|
202
|
+
app.patch('/users/:id', async (req, res) => {
|
|
203
|
+
const { version, ...data } = req.body;
|
|
204
|
+
|
|
205
|
+
const current = await readModel.findById(req.params.id);
|
|
206
|
+
|
|
207
|
+
if (current.version !== version) {
|
|
208
|
+
return res.status(409).json({
|
|
209
|
+
error: 'Conflict: resource has been modified'
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
await commandBus.execute(new UpdateUserCommand(req.params.id, data));
|
|
214
|
+
res.json({ ok: true });
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Best Practices
|
|
219
|
+
|
|
220
|
+
✅ **Separate databases** - Use different DBs for read/write models
|
|
221
|
+
✅ **Event versioning** - Handle schema changes
|
|
222
|
+
✅ **Projection rebuilding** - Replay events to fix read model
|
|
223
|
+
✅ **Consistency guarantees** - Document eventual consistency window
|
|
224
|
+
✅ **Monitoring** - Track event processing lag
|
|
225
|
+
|
|
226
|
+
## Resources
|
|
227
|
+
|
|
228
|
+
- [CQRS Pattern](https://martinfowler.com/bliki/CQRS.html)
|
|
229
|
+
- [Event Sourcing](https://martinfowler.com/eaaDev/EventSourcing.html)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Domain-Driven Design (DDD)
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
DDD aligns software with business domains using aggregates, value objects, entities, and domain events.
|
|
5
|
+
|
|
6
|
+
## Value Object
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
export class Money {
|
|
10
|
+
private constructor(public readonly amount: number, public readonly currency: string) {}
|
|
11
|
+
|
|
12
|
+
static of(amount: number, currency: string): Money {
|
|
13
|
+
if (amount < 0) throw new Error('Amount must be non-negative');
|
|
14
|
+
return new Money(Math.round(amount * 100) / 100, currency);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
add(other: Money): Money {
|
|
18
|
+
if (other.currency !== this.currency) throw new Error('Currency mismatch');
|
|
19
|
+
return Money.of(this.amount + other.amount, this.currency);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
equals(other: Money): boolean {
|
|
23
|
+
return this.amount === other.amount && this.currency === other.currency;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Aggregate Root
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
export class Order {
|
|
32
|
+
private _events: DomainEvent[] = [];
|
|
33
|
+
private _items: OrderItem[] = [];
|
|
34
|
+
private _status: 'draft' | 'confirmed' | 'shipped' = 'draft';
|
|
35
|
+
|
|
36
|
+
private constructor(public readonly id: string, public readonly customerId: string) {}
|
|
37
|
+
|
|
38
|
+
static create(customerId: string): Order {
|
|
39
|
+
const order = new Order(crypto.randomUUID(), customerId);
|
|
40
|
+
order._events.push({ type: 'OrderCreated', orderId: order.id, customerId });
|
|
41
|
+
return order;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
addItem(productId: string, price: Money): void {
|
|
45
|
+
if (this._status !== 'draft') throw new Error('Order is already confirmed');
|
|
46
|
+
this._items.push({ productId, price });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
confirm(): void {
|
|
50
|
+
if (this._items.length === 0) throw new Error('Cannot confirm empty order');
|
|
51
|
+
this._status = 'confirmed';
|
|
52
|
+
this._events.push({ type: 'OrderConfirmed', orderId: this.id });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get events() { return [...this._events]; }
|
|
56
|
+
clearEvents() { this._events.length = 0; }
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Domain Service (publish events after save)
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
export class OrderService {
|
|
64
|
+
constructor(private repo: OrderRepository, private eventBus: EventBus) {}
|
|
65
|
+
|
|
66
|
+
async confirmOrder(orderId: string): Promise<void> {
|
|
67
|
+
const order = await this.repo.findById(orderId);
|
|
68
|
+
if (!order) throw new Error('Order not found');
|
|
69
|
+
order.confirm();
|
|
70
|
+
await this.repo.save(order);
|
|
71
|
+
for (const event of order.events) await this.eventBus.publish(event);
|
|
72
|
+
order.clearEvents();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Best Practices
|
|
78
|
+
- Model ubiquitous language — use domain terms directly in code
|
|
79
|
+
- Aggregates should be small — avoid deep joins
|
|
80
|
+
- Always update aggregates through their roots
|
|
81
|
+
- Use outbox pattern for reliable event publishing
|
|
82
|
+
- Keep bounded contexts loosely coupled via events
|
|
83
|
+
|
|
84
|
+
## Resources
|
|
85
|
+
- [DDD Reference (Eric Evans)](https://www.domainlanguage.com/ddd/)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Event-Driven Architecture
|
|
2
|
+
|
|
3
|
+
Decouple services through asynchronous event publishing and consumption.
|
|
4
|
+
|
|
5
|
+
## Event Emitter Pattern
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import EventEmitter from 'events';
|
|
9
|
+
|
|
10
|
+
class EventBus extends EventEmitter {}
|
|
11
|
+
|
|
12
|
+
const eventBus = new EventBus();
|
|
13
|
+
|
|
14
|
+
// Subscribe to events
|
|
15
|
+
eventBus.on('user:created', (user) => {
|
|
16
|
+
console.log(`User created: ${user.email}`);
|
|
17
|
+
// Send welcome email
|
|
18
|
+
sendWelcomeEmail(user.email);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
eventBus.on('user:created', (user) => {
|
|
22
|
+
console.log(`Tracking user signup: ${user.id}`);
|
|
23
|
+
// Track analytics
|
|
24
|
+
analytics.track('user_signup', user);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Publish events
|
|
28
|
+
async function createUser(data) {
|
|
29
|
+
const user = await db.users.create(data);
|
|
30
|
+
eventBus.emit('user:created', user);
|
|
31
|
+
return user;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Message Queue Pattern (RabbitMQ)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import amqp from 'amqplib';
|
|
39
|
+
|
|
40
|
+
const connection = await amqp.connect('amqp://localhost');
|
|
41
|
+
const channel = await connection.createChannel();
|
|
42
|
+
|
|
43
|
+
// Declare queue
|
|
44
|
+
await channel.assertQueue('user.created', { durable: true });
|
|
45
|
+
|
|
46
|
+
// Publish
|
|
47
|
+
async function publishUserCreated(user) {
|
|
48
|
+
channel.sendToQueue(
|
|
49
|
+
'user.created',
|
|
50
|
+
Buffer.from(JSON.stringify(user)),
|
|
51
|
+
{ persistent: true }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Consume
|
|
56
|
+
channel.consume('user.created', async (msg) => {
|
|
57
|
+
const user = JSON.parse(msg.content.toString());
|
|
58
|
+
|
|
59
|
+
// Send welcome email
|
|
60
|
+
await emailService.sendWelcome(user.email);
|
|
61
|
+
|
|
62
|
+
// Acknowledge
|
|
63
|
+
channel.ack(msg);
|
|
64
|
+
}, { noAck: false });
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Pub/Sub Pattern (Redis)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import Redis from 'ioredis';
|
|
71
|
+
|
|
72
|
+
const redis = new Redis();
|
|
73
|
+
|
|
74
|
+
// Subscribe
|
|
75
|
+
redis.subscribe('user:created', (err, count) => {
|
|
76
|
+
if (err) console.error('Subscribe error:', err);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
redis.on('message', (channel, message) => {
|
|
80
|
+
if (channel === 'user:created') {
|
|
81
|
+
const user = JSON.parse(message);
|
|
82
|
+
console.log(`Welcome email sent to ${user.email}`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Publish
|
|
87
|
+
async function createUser(data) {
|
|
88
|
+
const user = await db.users.create(data);
|
|
89
|
+
|
|
90
|
+
redis.publish('user:created', JSON.stringify(user));
|
|
91
|
+
|
|
92
|
+
return user;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Event Sourcing
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
interface Event {
|
|
100
|
+
id: string;
|
|
101
|
+
type: string;
|
|
102
|
+
aggregate_id: string;
|
|
103
|
+
data: any;
|
|
104
|
+
timestamp: Date;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Store events
|
|
108
|
+
async function createUserEvent(userId: string, userData: any) {
|
|
109
|
+
const event: Event = {
|
|
110
|
+
id: uuid(),
|
|
111
|
+
type: 'UserCreated',
|
|
112
|
+
aggregate_id: userId,
|
|
113
|
+
data: userData,
|
|
114
|
+
timestamp: new Date()
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
await db('events').insert(event);
|
|
118
|
+
return event;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Rebuild state from events
|
|
122
|
+
async function getUserState(userId: string) {
|
|
123
|
+
const events = await db('events')
|
|
124
|
+
.where('aggregate_id', userId)
|
|
125
|
+
.orderBy('timestamp');
|
|
126
|
+
|
|
127
|
+
let state = { id: userId };
|
|
128
|
+
|
|
129
|
+
for (const event of events) {
|
|
130
|
+
switch (event.type) {
|
|
131
|
+
case 'UserCreated':
|
|
132
|
+
state = { ...state, ...event.data };
|
|
133
|
+
break;
|
|
134
|
+
case 'UserUpdated':
|
|
135
|
+
state = { ...state, ...event.data };
|
|
136
|
+
break;
|
|
137
|
+
case 'UserDeleted':
|
|
138
|
+
state = { ...state, deleted: true };
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return state;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Saga Pattern (Choreography)
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Order saga coordinated by events
|
|
151
|
+
|
|
152
|
+
// 1. Order created → publish event
|
|
153
|
+
eventBus.on('order:created', async (order) => {
|
|
154
|
+
// Payment service listens and processes payment
|
|
155
|
+
eventBus.emit('payment:requested', order);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// 2. Payment processed → publish event
|
|
159
|
+
eventBus.on('payment:processed', async (payment) => {
|
|
160
|
+
// Inventory service listens and reserves stock
|
|
161
|
+
eventBus.emit('inventory:reserve', payment.order);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// 3. Stock reserved → publish event
|
|
165
|
+
eventBus.on('inventory:reserved', async (inventory) => {
|
|
166
|
+
// Shipping service listens and creates shipment
|
|
167
|
+
eventBus.emit('shipment:created', inventory.order);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Handle failures with compensating transactions
|
|
171
|
+
eventBus.on('payment:failed', async (payment) => {
|
|
172
|
+
// Compensating: Release reserved inventory
|
|
173
|
+
eventBus.emit('inventory:release', payment.order);
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Best Practices
|
|
178
|
+
|
|
179
|
+
✅ **Idempotency** - Handle duplicate event processing
|
|
180
|
+
✅ **Dead letter queues** - Capture failed messages
|
|
181
|
+
✅ **Event versioning** - Support multiple event versions
|
|
182
|
+
✅ **Eventual consistency** - Accept temporary inconsistency
|
|
183
|
+
✅ **Monitoring** - Track event lag and processing times
|
|
184
|
+
|
|
185
|
+
## Resources
|
|
186
|
+
|
|
187
|
+
- [Event Sourcing Pattern](https://martinfowler.com/eaaDev/EventSourcing.html)
|
|
188
|
+
- [RabbitMQ Tutorials](https://www.rabbitmq.com/getstarted.html)
|
|
189
|
+
- [Redis Pub/Sub](https://redis.io/docs/manual/pubsub/)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Microservices Architecture
|
|
2
|
+
|
|
3
|
+
Decompose applications into small, independent services communicating via APIs.
|
|
4
|
+
|
|
5
|
+
## Service Definition
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// User Service
|
|
9
|
+
export interface IUserService {
|
|
10
|
+
getUser(id: string): Promise<User>;
|
|
11
|
+
createUser(data: CreateUserInput): Promise<User>;
|
|
12
|
+
updateUser(id: string, data: UpdateUserInput): Promise<User>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Post Service
|
|
16
|
+
export interface IPostService {
|
|
17
|
+
getPost(id: string): Promise<Post>;
|
|
18
|
+
getUserPosts(userId: string): Promise<Post[]>;
|
|
19
|
+
createPost(data: CreatePostInput): Promise<Post>;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Inter-Service Communication
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// HTTP/REST
|
|
27
|
+
const user = await fetch('http://user-service/api/users/123')
|
|
28
|
+
.then(r => r.json());
|
|
29
|
+
|
|
30
|
+
// gRPC (efficient binary protocol)
|
|
31
|
+
const user = await userServiceClient.getUser({ id: '123' });
|
|
32
|
+
|
|
33
|
+
// Message Queue (async)
|
|
34
|
+
await messageQueue.publish('user-updated', { userId: '123' });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API Gateway
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// Centralized entry point
|
|
41
|
+
const gateway = express();
|
|
42
|
+
|
|
43
|
+
gateway.use('/users', userServiceProxy);
|
|
44
|
+
gateway.use('/posts', postServiceProxy);
|
|
45
|
+
gateway.use('/comments', commentServiceProxy);
|
|
46
|
+
|
|
47
|
+
// Handle cross-service calls
|
|
48
|
+
gateway.get('/users/:id/posts', async (req, res) => {
|
|
49
|
+
const user = await getUserService(req.params.id);
|
|
50
|
+
const posts = await getPostService(user.id);
|
|
51
|
+
res.json({ user, posts });
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Service Discovery
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
# Kubernetes automatically discovers services
|
|
59
|
+
# Service DNS: <service-name>.<namespace>.svc.cluster.local
|
|
60
|
+
|
|
61
|
+
# Docker Compose
|
|
62
|
+
services:
|
|
63
|
+
user-service:
|
|
64
|
+
container_name: user-service
|
|
65
|
+
# Other services access via: http://user-service:3000
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Best Practices
|
|
69
|
+
|
|
70
|
+
✅ **Bounded contexts** - Clear service boundaries
|
|
71
|
+
✅ **Database per service** - Data independence
|
|
72
|
+
✅ **Async communication** - Use message queues
|
|
73
|
+
✅ **Service discovery** - Dynamic registration
|
|
74
|
+
✅ **Health checks** - Monitor service health
|
|
75
|
+
✅ **Logging aggregation** - Centralized logs
|
|
76
|
+
|
|
77
|
+
## Resources
|
|
78
|
+
|
|
79
|
+
- [Microservices Patterns](https://microservices.io/patterns/)
|
|
80
|
+
- [12 Factor App](https://12factor.net/)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Monorepo with Turborepo
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Host multiple apps and packages in one repo with shared code, tooling, and independent deployments.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npx create-turbo@latest my-monorepo
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
my-monorepo/
|
|
16
|
+
├── apps/
|
|
17
|
+
│ ├── web/ # Next.js frontend
|
|
18
|
+
│ └── api/ # Express backend
|
|
19
|
+
├── packages/
|
|
20
|
+
│ ├── ui/ # Shared React components
|
|
21
|
+
│ ├── types/ # Shared TypeScript types
|
|
22
|
+
│ └── config/ # Shared ESLint, Tailwind, TS configs
|
|
23
|
+
├── turbo.json
|
|
24
|
+
└── package.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## turbo.json
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"$schema": "https://turbo.build/schema.json",
|
|
32
|
+
"tasks": {
|
|
33
|
+
"build": { "dependsOn": ["^build"], "outputs": [".next/**", "dist/**"] },
|
|
34
|
+
"dev": { "cache": false, "persistent": true },
|
|
35
|
+
"lint": {},
|
|
36
|
+
"test": { "outputs": ["coverage/**"] }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Shared UI Package
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
// packages/ui/package.json
|
|
45
|
+
{
|
|
46
|
+
"name": "@repo/ui",
|
|
47
|
+
"exports": {
|
|
48
|
+
"./button": "./src/button/index.tsx"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// packages/ui/src/button/index.tsx
|
|
55
|
+
export function Button({ children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
56
|
+
return <button className="px-4 py-2 bg-blue-600 text-white rounded" {...props}>{children}</button>;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Using Shared Packages
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
// apps/web/package.json
|
|
64
|
+
{ "dependencies": { "@repo/ui": "*" } }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { Button } from '@repo/ui/button';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Commands
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
turbo dev # all apps in dev mode
|
|
75
|
+
turbo build # build all
|
|
76
|
+
turbo build --filter=web # build specific app
|
|
77
|
+
turbo test # test all packages
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Best Practices
|
|
81
|
+
- Use `workspace:*` to link internal packages
|
|
82
|
+
- Enable Vercel Remote Cache for fast CI builds
|
|
83
|
+
- Keep `packages/config` for shared ESLint and Tailwind configs
|
|
84
|
+
- Build shared packages before dependent apps (`dependsOn: ["^build"]`)
|
|
85
|
+
|
|
86
|
+
## Resources
|
|
87
|
+
- [Turborepo docs](https://turbo.build/repo/docs)
|