claudeinone-cli 1.0.1 → 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/dist/index.js +16 -1
- 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,96 @@
|
|
|
1
|
+
# User Onboarding
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Guide new users to their first value moment with checklists, product tours, and progressive disclosure.
|
|
5
|
+
|
|
6
|
+
## Onboarding Checklist Component
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
interface OnboardingStep {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
completed: boolean;
|
|
14
|
+
action?: { label: string; href: string };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function OnboardingChecklist({ steps }: { steps: OnboardingStep[] }) {
|
|
18
|
+
const completed = steps.filter(s => s.completed).length;
|
|
19
|
+
const progress = (completed / steps.length) * 100;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="border rounded-lg p-4">
|
|
23
|
+
<div className="flex items-center justify-between mb-3">
|
|
24
|
+
<h3 className="font-semibold">Get started ({completed}/{steps.length})</h3>
|
|
25
|
+
<span className="text-sm text-gray-500">{Math.round(progress)}%</span>
|
|
26
|
+
</div>
|
|
27
|
+
<div className="w-full bg-gray-200 rounded-full h-2 mb-4">
|
|
28
|
+
<div className="bg-blue-600 h-2 rounded-full transition-all" style={{ width: `${progress}%` }} />
|
|
29
|
+
</div>
|
|
30
|
+
<ul className="space-y-3">
|
|
31
|
+
{steps.map(step => (
|
|
32
|
+
<li key={step.id} className="flex items-start gap-3">
|
|
33
|
+
<div className={`mt-0.5 flex-shrink-0 w-5 h-5 rounded-full border-2 flex items-center justify-center
|
|
34
|
+
${step.completed ? 'bg-blue-600 border-blue-600' : 'border-gray-300'}`}>
|
|
35
|
+
{step.completed && <span className="text-white text-xs">✓</span>}
|
|
36
|
+
</div>
|
|
37
|
+
<div>
|
|
38
|
+
<p className={`font-medium ${step.completed ? 'line-through text-gray-400' : ''}`}>{step.title}</p>
|
|
39
|
+
{!step.completed && step.action && (
|
|
40
|
+
<a href={step.action.href} className="text-sm text-blue-600 hover:underline">{step.action.label}</a>
|
|
41
|
+
)}
|
|
42
|
+
</div>
|
|
43
|
+
</li>
|
|
44
|
+
))}
|
|
45
|
+
</ul>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Track Onboarding Progress in DB
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Track completion of each step
|
|
55
|
+
async function markStepComplete(userId: string, step: string) {
|
|
56
|
+
await prisma.onboardingProgress.upsert({
|
|
57
|
+
where: { userId_step: { userId, step } },
|
|
58
|
+
create: { userId, step, completedAt: new Date() },
|
|
59
|
+
update: { completedAt: new Date() },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check if onboarding is complete
|
|
64
|
+
async function getOnboardingStatus(userId: string) {
|
|
65
|
+
const REQUIRED_STEPS = ['profile_completed', 'first_project', 'team_invited'];
|
|
66
|
+
const completed = await prisma.onboardingProgress.findMany({ where: { userId } });
|
|
67
|
+
const completedSteps = new Set(completed.map(c => c.step));
|
|
68
|
+
return {
|
|
69
|
+
steps: REQUIRED_STEPS.map(step => ({ step, completed: completedSteps.has(step) })),
|
|
70
|
+
isComplete: REQUIRED_STEPS.every(step => completedSteps.has(step)),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Send Activation Email Sequence
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// lib/onboarding.ts - trigger drip emails
|
|
79
|
+
async function handleUserSignup(user: User) {
|
|
80
|
+
await sendWelcomeEmail(user);
|
|
81
|
+
|
|
82
|
+
// Day 1: if not activated, send tips email
|
|
83
|
+
await addToEmailQueue({ userId: user.id, template: 'activation-tips', delayMs: 24 * 60 * 60 * 1000 });
|
|
84
|
+
// Day 3: check-in email
|
|
85
|
+
await addToEmailQueue({ userId: user.id, template: 'day3-checkin', delayMs: 3 * 24 * 60 * 60 * 1000 });
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Best Practices
|
|
90
|
+
- Show checklist on dashboard (not in a modal that gets dismissed)
|
|
91
|
+
- Auto-detect and pre-complete steps when possible
|
|
92
|
+
- Define your activation event (e.g., "created first project") and optimize for it
|
|
93
|
+
- Remove the checklist once all steps are done
|
|
94
|
+
|
|
95
|
+
## Resources
|
|
96
|
+
- [Intercom onboarding](https://www.intercom.com/blog/onboarding-saas/)
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# SaaS User Onboarding
|
|
2
|
+
|
|
3
|
+
Implementing effective user onboarding flows.
|
|
4
|
+
|
|
5
|
+
## Onboarding Checklist
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
interface OnboardingStep {
|
|
9
|
+
id: string;
|
|
10
|
+
title: string;
|
|
11
|
+
description: string;
|
|
12
|
+
completed: boolean;
|
|
13
|
+
required: boolean;
|
|
14
|
+
action?: () => Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface OnboardingProgress {
|
|
18
|
+
userId: string;
|
|
19
|
+
steps: OnboardingStep[];
|
|
20
|
+
completedAt?: Date;
|
|
21
|
+
completionPercentage: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function createOnboardingFlow(userId: string) {
|
|
25
|
+
const steps: OnboardingStep[] = [
|
|
26
|
+
{
|
|
27
|
+
id: 'profile',
|
|
28
|
+
title: 'Complete Profile',
|
|
29
|
+
description: 'Add name and avatar',
|
|
30
|
+
completed: false,
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'payment',
|
|
35
|
+
title: 'Add Payment Method',
|
|
36
|
+
description: 'Set up billing',
|
|
37
|
+
completed: false,
|
|
38
|
+
required: true
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'workspace',
|
|
42
|
+
title: 'Create First Workspace',
|
|
43
|
+
description: 'Organize your work',
|
|
44
|
+
completed: false,
|
|
45
|
+
required: false
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'invite',
|
|
49
|
+
title: 'Invite Team Members',
|
|
50
|
+
description: 'Collaborate with others',
|
|
51
|
+
completed: false,
|
|
52
|
+
required: false
|
|
53
|
+
}
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
await db.onboarding.create({
|
|
57
|
+
userId,
|
|
58
|
+
steps,
|
|
59
|
+
completionPercentage: 0
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function completeStep(userId: string, stepId: string) {
|
|
64
|
+
const progress = await db.onboarding.findByUserId(userId);
|
|
65
|
+
const step = progress.steps.find(s => s.id === stepId);
|
|
66
|
+
|
|
67
|
+
if (step) {
|
|
68
|
+
step.completed = true;
|
|
69
|
+
|
|
70
|
+
const completed = progress.steps.filter(s => s.completed).length;
|
|
71
|
+
progress.completionPercentage = (completed / progress.steps.length) * 100;
|
|
72
|
+
|
|
73
|
+
if (progress.completionPercentage === 100) {
|
|
74
|
+
progress.completedAt = new Date();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await db.onboarding.update(userId, progress);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Progress Tracking
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// Track engagement metrics
|
|
86
|
+
interface OnboardingMetrics {
|
|
87
|
+
userId: string;
|
|
88
|
+
startDate: Date;
|
|
89
|
+
timeToCompletion?: number;
|
|
90
|
+
stepsCompleted: number;
|
|
91
|
+
totalSteps: number;
|
|
92
|
+
conversionRate: number;
|
|
93
|
+
churnRisk: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function analyzeOnboardingHealth(userId: string) {
|
|
97
|
+
const progress = await db.onboarding.findByUserId(userId);
|
|
98
|
+
const user = await db.users.findById(userId);
|
|
99
|
+
|
|
100
|
+
const timeToCompletion = progress.completedAt
|
|
101
|
+
? progress.completedAt.getTime() - user.createdAt.getTime()
|
|
102
|
+
: null;
|
|
103
|
+
|
|
104
|
+
const metrics: OnboardingMetrics = {
|
|
105
|
+
userId,
|
|
106
|
+
startDate: user.createdAt,
|
|
107
|
+
timeToCompletion: timeToCompletion ? timeToCompletion / 1000 / 60 : undefined, // minutes
|
|
108
|
+
stepsCompleted: progress.steps.filter(s => s.completed).length,
|
|
109
|
+
totalSteps: progress.steps.length,
|
|
110
|
+
conversionRate: progress.completionPercentage,
|
|
111
|
+
churnRisk: !progress.completedAt && timeToCompletion > 7 * 24 * 60 * 60 * 1000
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
return metrics;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Interactive Tours
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Using shepherd.js
|
|
122
|
+
import Shepherd from 'shepherd.js';
|
|
123
|
+
|
|
124
|
+
function initializeProductTour() {
|
|
125
|
+
const tour = new Shepherd.Tour({
|
|
126
|
+
useModalOverlay: true,
|
|
127
|
+
defaultStepOptions: {
|
|
128
|
+
classes: 'shadow-md bg-white rounded-lg p-4'
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
tour.addStep({
|
|
133
|
+
id: 'welcome',
|
|
134
|
+
title: 'Welcome!',
|
|
135
|
+
text: 'Let\'s get you started with our platform',
|
|
136
|
+
buttons: [
|
|
137
|
+
{ action: tour.next, text: 'Next' }
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
tour.addStep({
|
|
142
|
+
id: 'dashboard',
|
|
143
|
+
attachTo: { element: '.dashboard-nav', on: 'right' },
|
|
144
|
+
title: 'Dashboard',
|
|
145
|
+
text: 'View your overview and key metrics',
|
|
146
|
+
buttons: [
|
|
147
|
+
{ action: tour.back, text: 'Back' },
|
|
148
|
+
{ action: tour.next, text: 'Next' }
|
|
149
|
+
]
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
tour.start();
|
|
153
|
+
|
|
154
|
+
// Save progress
|
|
155
|
+
tour.on('complete', () => {
|
|
156
|
+
completeStep(userId, 'tour');
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Email Onboarding
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Drip email campaign
|
|
165
|
+
async function startOnboardingEmails(userId: string) {
|
|
166
|
+
const user = await db.users.findById(userId);
|
|
167
|
+
|
|
168
|
+
// Day 0: Welcome
|
|
169
|
+
await emailService.send(user.email, 'welcome', {
|
|
170
|
+
name: user.name,
|
|
171
|
+
dashboardUrl: `https://app.example.com/dashboard`
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Day 1: Getting started
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
emailService.send(user.email, 'getting-started', {
|
|
177
|
+
docsUrl: 'https://docs.example.com'
|
|
178
|
+
});
|
|
179
|
+
}, 24 * 60 * 60 * 1000);
|
|
180
|
+
|
|
181
|
+
// Day 3: Explore features
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
emailService.send(user.email, 'explore-features');
|
|
184
|
+
}, 3 * 24 * 60 * 60 * 1000);
|
|
185
|
+
|
|
186
|
+
// Day 7: Re-engagement
|
|
187
|
+
const progress = await db.onboarding.findByUserId(userId);
|
|
188
|
+
if (progress.completionPercentage < 100) {
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
emailService.send(user.email, 're-engagement');
|
|
191
|
+
}, 7 * 24 * 60 * 60 * 1000);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Best Practices
|
|
197
|
+
|
|
198
|
+
✅ **Keep it simple** - Minimum required steps
|
|
199
|
+
✅ **Progress visibility** - Show completion percentage
|
|
200
|
+
✅ **Optional tasks** - Don't require all steps
|
|
201
|
+
✅ **Contextual help** - Tips at right moments
|
|
202
|
+
✅ **Track metrics** - Monitor completion rates
|
|
203
|
+
|
|
204
|
+
## Resources
|
|
205
|
+
|
|
206
|
+
- [Onboarding Best Practices](https://www.useronboard.com/)
|
|
207
|
+
- [Shepherd.js](https://shepherdjs.dev/)
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Encryption & Security
|
|
2
|
+
|
|
3
|
+
Data encryption, hashing, and secure communication.
|
|
4
|
+
|
|
5
|
+
## Password Hashing
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import bcrypt from 'bcrypt';
|
|
9
|
+
|
|
10
|
+
// Hash password
|
|
11
|
+
async function hashPassword(password: string) {
|
|
12
|
+
const salt = await bcrypt.genSalt(10);
|
|
13
|
+
return await bcrypt.hash(password, salt);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Verify password
|
|
17
|
+
async function verifyPassword(password: string, hash: string) {
|
|
18
|
+
return await bcrypt.compare(password, hash);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Usage
|
|
22
|
+
async function registerUser(email: string, password: string) {
|
|
23
|
+
const hashedPassword = await hashPassword(password);
|
|
24
|
+
|
|
25
|
+
return await db.users.create({
|
|
26
|
+
email,
|
|
27
|
+
password: hashedPassword
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function login(email: string, password: string) {
|
|
32
|
+
const user = await db.users.findByEmail(email);
|
|
33
|
+
|
|
34
|
+
if (!user) throw new Error('User not found');
|
|
35
|
+
|
|
36
|
+
const valid = await verifyPassword(password, user.password);
|
|
37
|
+
|
|
38
|
+
if (!valid) throw new Error('Invalid password');
|
|
39
|
+
|
|
40
|
+
return user;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## JWT Tokens
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import jwt from 'jsonwebtoken';
|
|
48
|
+
|
|
49
|
+
// Create token
|
|
50
|
+
function createToken(userId: string) {
|
|
51
|
+
return jwt.sign(
|
|
52
|
+
{ userId, role: 'user' },
|
|
53
|
+
process.env.JWT_SECRET,
|
|
54
|
+
{ expiresIn: '24h' }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Verify token
|
|
59
|
+
function verifyToken(token: string) {
|
|
60
|
+
try {
|
|
61
|
+
return jwt.verify(token, process.env.JWT_SECRET);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
throw new Error('Invalid token');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Middleware
|
|
68
|
+
const authMiddleware = (req: any, res: any, next: any) => {
|
|
69
|
+
const token = req.headers.authorization?.split(' ')[1];
|
|
70
|
+
|
|
71
|
+
if (!token) {
|
|
72
|
+
return res.status(401).json({ error: 'No token' });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
req.user = verifyToken(token);
|
|
77
|
+
next();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
res.status(401).json({ error: 'Invalid token' });
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Data Encryption
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import crypto from 'crypto';
|
|
88
|
+
|
|
89
|
+
// Encrypt sensitive data
|
|
90
|
+
function encryptData(data: string, key: string) {
|
|
91
|
+
const iv = crypto.randomBytes(16);
|
|
92
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', Buffer.from(key), iv);
|
|
93
|
+
|
|
94
|
+
let encrypted = cipher.update(data, 'utf8', 'hex');
|
|
95
|
+
encrypted += cipher.final('hex');
|
|
96
|
+
|
|
97
|
+
const authTag = cipher.getAuthTag();
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
iv: iv.toString('hex'),
|
|
101
|
+
data: encrypted,
|
|
102
|
+
tag: authTag.toString('hex')
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Decrypt data
|
|
107
|
+
function decryptData(encrypted: any, key: string) {
|
|
108
|
+
const decipher = crypto.createDecipheriv(
|
|
109
|
+
'aes-256-gcm',
|
|
110
|
+
Buffer.from(key),
|
|
111
|
+
Buffer.from(encrypted.iv, 'hex')
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
decipher.setAuthTag(Buffer.from(encrypted.tag, 'hex'));
|
|
115
|
+
|
|
116
|
+
let decrypted = decipher.update(encrypted.data, 'hex', 'utf8');
|
|
117
|
+
decrypted += decipher.final('utf8');
|
|
118
|
+
|
|
119
|
+
return decrypted;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## HTTPS & TLS
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import https from 'https';
|
|
127
|
+
import fs from 'fs';
|
|
128
|
+
|
|
129
|
+
const options = {
|
|
130
|
+
key: fs.readFileSync('private-key.pem'),
|
|
131
|
+
cert: fs.readFileSync('certificate.pem')
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
https.createServer(options, app).listen(443);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## CORS & CSRF Protection
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import cors from 'cors';
|
|
141
|
+
import csrf from 'csurf';
|
|
142
|
+
|
|
143
|
+
app.use(cors({
|
|
144
|
+
origin: process.env.ALLOWED_ORIGINS?.split(','),
|
|
145
|
+
credentials: true
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
app.use(csrf({ cookie: false }));
|
|
149
|
+
|
|
150
|
+
// Include token in forms
|
|
151
|
+
app.get('/form', (req, res) => {
|
|
152
|
+
res.send(`
|
|
153
|
+
<form action="/submit" method="POST">
|
|
154
|
+
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
|
|
155
|
+
<input type="email" name="email">
|
|
156
|
+
<button type="submit">Submit</button>
|
|
157
|
+
</form>
|
|
158
|
+
`);
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Rate Limiting
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import rateLimit from 'express-rate-limit';
|
|
166
|
+
|
|
167
|
+
const limiter = rateLimit({
|
|
168
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
169
|
+
max: 100, // 100 requests per windowMs
|
|
170
|
+
message: 'Too many requests',
|
|
171
|
+
standardHeaders: true,
|
|
172
|
+
legacyHeaders: false
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
app.use('/api/', limiter);
|
|
176
|
+
|
|
177
|
+
// Strict limiter for auth
|
|
178
|
+
const authLimiter = rateLimit({
|
|
179
|
+
windowMs: 60 * 1000, // 1 minute
|
|
180
|
+
max: 5 // 5 requests per minute
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
app.post('/login', authLimiter, (req, res) => {
|
|
184
|
+
// Handle login
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## SQL Injection Prevention
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// SAFE: Parameterized queries
|
|
192
|
+
const user = await db.query(
|
|
193
|
+
'SELECT * FROM users WHERE email = $1',
|
|
194
|
+
['user@example.com']
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// SAFE: ORM usage
|
|
198
|
+
const user = await User.findOne({ email: 'user@example.com' });
|
|
199
|
+
|
|
200
|
+
// UNSAFE: String concatenation (never do this!)
|
|
201
|
+
// const user = await db.query(`SELECT * FROM users WHERE email = '${email}'`);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Best Practices
|
|
205
|
+
|
|
206
|
+
✅ **Never log passwords** - Remove from logs
|
|
207
|
+
✅ **Use HTTPS** - Always encrypt in transit
|
|
208
|
+
✅ **Rotate secrets** - Update API keys regularly
|
|
209
|
+
✅ **Input validation** - Sanitize all user input
|
|
210
|
+
✅ **Principle of least privilege** - Grant minimal permissions
|
|
211
|
+
|
|
212
|
+
## Resources
|
|
213
|
+
|
|
214
|
+
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
|
215
|
+
- [bcrypt Documentation](https://github.com/kelektiv/node.bcrypt.js)
|
|
216
|
+
- [JWT Best Practices](https://tools.ietf.org/html/rfc8725)
|