@kensaurus/skills 0.0.0-stage → 2.1.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/.claude-plugin/marketplace.json +53 -0
- package/.claude-plugin/plugin.json +40 -0
- package/.cursor-plugin/plugin.json +38 -0
- package/.mcp.json +28 -0
- package/CHANGELOG.md +1790 -0
- package/LICENSE +21 -0
- package/LICENSE-APACHE +62 -0
- package/NOTICE +13 -0
- package/README.md +821 -2
- package/SECURITY.md +55 -0
- package/agents/code-reviewer.md +60 -0
- package/agents/completion-judge.md +89 -0
- package/agents/db-migrator.md +125 -0
- package/agents/debugger.md +47 -0
- package/agents/deploy-checker.md +100 -0
- package/agents/perf-monitor.md +74 -0
- package/assets/favicon.png +0 -0
- package/assets/logo-light.png +0 -0
- package/assets/logo.png +0 -0
- package/assets/logo.svg +6 -0
- package/assets/og.png +0 -0
- package/bin/install.mjs +1127 -0
- package/bin/kenji.js +2 -0
- package/commands/adr.md +17 -0
- package/commands/aeo-plan.md +18 -0
- package/commands/arch-boundaries.md +17 -0
- package/commands/aso-plan.md +18 -0
- package/commands/auth-flows.md +19 -0
- package/commands/backup-plan.md +17 -0
- package/commands/burndown-full.md +25 -0
- package/commands/capacitor-plan.md +18 -0
- package/commands/codemod-safety.md +22 -0
- package/commands/commit.md +18 -0
- package/commands/complete-everything.md +40 -0
- package/commands/cost-plan.md +19 -0
- package/commands/deadcode-plan.md +26 -0
- package/commands/deadcode.md +32 -0
- package/commands/debug-issue.md +17 -0
- package/commands/deps-plan.md +18 -0
- package/commands/docs-plan.md +17 -0
- package/commands/doctrine.md +19 -0
- package/commands/error-plan.md +19 -0
- package/commands/feedback-to-closure.md +36 -0
- package/commands/fix-issue.md +76 -0
- package/commands/gate-logic.md +26 -0
- package/commands/green-repo.md +36 -0
- package/commands/grill-me.md +19 -0
- package/commands/gtm-plan.md +21 -0
- package/commands/gtm-weekly.md +17 -0
- package/commands/gtm.md +22 -0
- package/commands/handoff.md +15 -0
- package/commands/housekeep-backlog.md +18 -0
- package/commands/housekeep-files.md +22 -0
- package/commands/housekeep-gates.md +18 -0
- package/commands/instant-nav.md +11 -0
- package/commands/integrity-plan.md +19 -0
- package/commands/launch-kit.md +16 -0
- package/commands/mcp-guide.md +40 -0
- package/commands/mobile-plan.md +19 -0
- package/commands/native-rn-monorepo/README.md +78 -0
- package/commands/native-rn-monorepo/android-build.md +26 -0
- package/commands/native-rn-monorepo/android-install.md +32 -0
- package/commands/native-rn-monorepo/android-logcat.md +37 -0
- package/commands/native-rn-monorepo/ios-ci-logs.md +56 -0
- package/commands/native-rn-monorepo/ios-ci-status.md +52 -0
- package/commands/native-rn-monorepo/ios-ci-trigger.md +59 -0
- package/commands/native-rn-monorepo/rn-reset.md +50 -0
- package/commands/native-rn-monorepo/rn-ship-ios.md +67 -0
- package/commands/native-rn-monorepo/rn-verify.md +53 -0
- package/commands/perf-plan.md +18 -0
- package/commands/plan-mode.md +74 -0
- package/commands/pr.md +16 -0
- package/commands/pricing-plan.md +20 -0
- package/commands/privacy-plan.md +18 -0
- package/commands/readability.md +12 -0
- package/commands/readme.md +15 -0
- package/commands/refactor.md +15 -0
- package/commands/release-prep.md +17 -0
- package/commands/research.md +25 -0
- package/commands/responsive-audit.md +21 -0
- package/commands/review-code.md +18 -0
- package/commands/rls-plan.md +18 -0
- package/commands/secrets-plan.md +18 -0
- package/commands/security-plan.md +19 -0
- package/commands/ship-and-observe.md +36 -0
- package/commands/skill-conflicts.md +19 -0
- package/commands/slop-plan.md +18 -0
- package/commands/stub-plan.md +18 -0
- package/commands/test-mutation.md +16 -0
- package/commands/test-plan.md +17 -0
- package/commands/test.md +29 -0
- package/commands/thirdparty-web-interface-guidelines.md +185 -0
- package/commands/uiux-plan.md +18 -0
- package/commands/uiux.md +45 -0
- package/commands/update-deps.md +21 -0
- package/commands/validation-plan.md +19 -0
- package/commands-portable/fix-issue.md +72 -0
- package/commands-portable/plan-mode.md +92 -0
- package/commands-portable/research.md +91 -0
- package/docs/screenshots/README.md +5 -0
- package/docs/screenshots/audit-dark.png +0 -0
- package/docs/screenshots/build-dark.png +0 -0
- package/docs/screenshots/grill-dark.png +0 -0
- package/docs/screenshots/hero-dark.png +0 -0
- package/docs/screenshots/hero-light.png +0 -0
- package/docs/screenshots/ship-dark.png +0 -0
- package/docs/screenshots/src/showcase.html +320 -0
- package/hooks/completion-gate.mjs +258 -0
- package/hooks/cursor-hooks.json +13 -0
- package/hooks/hooks.json +15 -0
- package/install.sh +21 -0
- package/llms.txt +40 -0
- package/mcp/README.md +266 -0
- package/mcp/VERSIONS.md +41 -0
- package/mcp/mcp-full.json.template +124 -0
- package/mcp/mcp.json.template +29 -0
- package/mcp/pinned-versions.json +27 -0
- package/package.json +94 -4
- package/rules/approved-plan-execution.mdc +65 -0
- package/rules/full-stack-ship-discipline.mdc +37 -0
- package/rules/native-rn-monorepo/README.md +63 -0
- package/rules/native-rn-monorepo/_project.mdc +69 -0
- package/rules/native-rn-monorepo/native-android.mdc +72 -0
- package/rules/native-rn-monorepo/native-ios.mdc +61 -0
- package/rules/native-rn-monorepo/react-native-js.mdc +78 -0
- package/rules/native-rn-monorepo/web.mdc +60 -0
- package/rules/project-starter/components.mdc +54 -0
- package/rules/project-starter/data-fetching.mdc +77 -0
- package/rules/project-starter/git.mdc +41 -0
- package/rules/project-starter/supabase.mdc +37 -0
- package/rules/project-starter/tailwind.mdc +48 -0
- package/rules/project-starter/typescript.mdc +36 -0
- package/rules/project-starter/web-performance.mdc +42 -0
- package/rules/senior-engineer.mdc +30 -0
- package/rules/shell-first-search.mdc +19 -0
- package/rules/skill-workflows.mdc +35 -0
- package/rules/verification-before-completion.mdc +57 -0
- package/skills/audit-accessibility/SKILL.md +441 -0
- package/skills/audit-agent-speed/SKILL.md +181 -0
- package/skills/audit-agent-speed/scripts/stop-typecheck.mjs +151 -0
- package/skills/audit-analytics/SKILL.md +138 -0
- package/skills/audit-auth-flows/SKILL.md +267 -0
- package/skills/audit-backend-architecture/SKILL.md +266 -0
- package/skills/audit-backend-architecture/references/patterns.md +386 -0
- package/skills/audit-bundle-size/SKILL.md +295 -0
- package/skills/audit-cicd/SKILL.md +218 -0
- package/skills/audit-code-quality/SKILL.md +314 -0
- package/skills/audit-code-review/SKILL.md +289 -0
- package/skills/audit-codemod-safety/SKILL.md +159 -0
- package/skills/audit-db-schema/SKILL.md +465 -0
- package/skills/audit-db-schema/references/details.md +110 -0
- package/skills/audit-doctrine/SKILL.md +189 -0
- package/skills/audit-env-parity/SKILL.md +133 -0
- package/skills/audit-fe-api/SKILL.md +458 -0
- package/skills/audit-gate-logic/SKILL.md +219 -0
- package/skills/audit-i18n/SKILL.md +339 -0
- package/skills/audit-infra-cost/SKILL.md +142 -0
- package/skills/audit-langfuse-llm/SKILL.md +468 -0
- package/skills/audit-langfuse-llm/references/details.md +226 -0
- package/skills/audit-llm-security/SKILL.md +147 -0
- package/skills/audit-monetization-iap/SKILL.md +137 -0
- package/skills/audit-payment-system/SKILL.md +268 -0
- package/skills/audit-payment-system/references/checklist.md +283 -0
- package/skills/audit-performance/SKILL.md +383 -0
- package/skills/audit-performance/references/loading-priority-2026.md +81 -0
- package/skills/audit-realworld/SKILL.md +287 -0
- package/skills/audit-registry-listing/SKILL.md +122 -0
- package/skills/audit-resilience/SKILL.md +153 -0
- package/skills/audit-responsive/SKILL.md +221 -0
- package/skills/audit-responsive/references/checklist.md +166 -0
- package/skills/audit-security/SKILL.md +289 -0
- package/skills/audit-skill-conflicts/SKILL.md +178 -0
- package/skills/audit-ui-states/SKILL.md +146 -0
- package/skills/audit-uiux-design-system/SKILL.md +475 -0
- package/skills/audit-uiux-design-system/references/details.md +71 -0
- package/skills/audit-ux/SKILL.md +381 -0
- package/skills/audit-ux/references/details.md +245 -0
- package/skills/audit-ux-journeys/SKILL.md +215 -0
- package/skills/audit-ux-journeys/references/checklist.md +179 -0
- package/skills/backend-db-performance/SKILL.md +441 -0
- package/skills/backend-error-handling/SKILL.md +489 -0
- package/skills/backend-error-handling/references/details.md +58 -0
- package/skills/backend-observability/SKILL.md +88 -0
- package/skills/backend-patterns/SKILL.md +499 -0
- package/skills/backend-patterns/references/architecture-patterns.md +298 -0
- package/skills/backend-realtime/SKILL.md +403 -0
- package/skills/backend-realtime/references/patterns.md +74 -0
- package/skills/burndown-full/SKILL.md +174 -0
- package/skills/complete-everything/SKILL.md +295 -0
- package/skills/data-pipeline/SKILL.md +109 -0
- package/skills/data-visualization/SKILL.md +488 -0
- package/skills/debug-error/SKILL.md +322 -0
- package/skills/debug-fe-be-integration/SKILL.md +459 -0
- package/skills/debug-sentry-monitor/SKILL.md +497 -0
- package/skills/debug-sentry-monitor/references/details.md +165 -0
- package/skills/deploy-npm/SKILL.md +394 -0
- package/skills/deploy-npm/references/example-mushi-mushi.md +52 -0
- package/skills/deploy-verify/SKILL.md +489 -0
- package/skills/design-api/SKILL.md +379 -0
- package/skills/design-canvas/SKILL.md +155 -0
- package/skills/design-email/SKILL.md +370 -0
- package/skills/design-frontend/SKILL.md +143 -0
- package/skills/design-generative-art/SKILL.md +474 -0
- package/skills/design-mobile-first/SKILL.md +506 -0
- package/skills/design-motion/SKILL.md +333 -0
- package/skills/design-motion/references/delight-interactions.md +191 -0
- package/skills/design-prd/SKILL.md +443 -0
- package/skills/design-system/SKILL.md +457 -0
- package/skills/design-theme/SKILL.md +226 -0
- package/skills/design-theme/themes/tsumagoi-ranch.md +150 -0
- package/skills/docs-adr/SKILL.md +168 -0
- package/skills/docs-coauthor/SKILL.md +368 -0
- package/skills/docs-comparison-pages/SKILL.md +117 -0
- package/skills/docs-domain-modeling/SKILL.md +97 -0
- package/skills/docs-launch-kit/SKILL.md +139 -0
- package/skills/docs-writer/SKILL.md +469 -0
- package/skills/enhance-agent-guardrails/SKILL.md +164 -0
- package/skills/enhance-arch-boundaries/SKILL.md +154 -0
- package/skills/enhance-capacitor-ui/SKILL.md +463 -0
- package/skills/enhance-capacitor-ui/references/details.md +750 -0
- package/skills/enhance-email-deliverability/SKILL.md +143 -0
- package/skills/enhance-growth-loops/SKILL.md +122 -0
- package/skills/enhance-lifecycle-email/SKILL.md +130 -0
- package/skills/enhance-motion/SKILL.md +193 -0
- package/skills/enhance-onboarding/SKILL.md +148 -0
- package/skills/enhance-pwa/SKILL.md +303 -0
- package/skills/enhance-readability/SKILL.md +146 -0
- package/skills/enhance-readme/SKILL.md +496 -0
- package/skills/enhance-readme/package-lock.json +187 -0
- package/skills/enhance-readme/package.json +17 -0
- package/skills/enhance-readme/scripts/generate-readme-blocks.mjs +199 -0
- package/skills/enhance-readme/scripts/record-readme-tour.mjs +442 -0
- package/skills/enhance-skill-prompts/SKILL.md +167 -0
- package/skills/enhance-skill-prompts/references/exemplar-audit-auth-flows.md +311 -0
- package/skills/enhance-ux-laws/SKILL.md +409 -0
- package/skills/enhance-web-conversion/SKILL.md +155 -0
- package/skills/enhance-web-forms/SKILL.md +154 -0
- package/skills/enhance-web-instant-nav/SKILL.md +138 -0
- package/skills/enhance-web-instant-nav/references/bfcache-blockers.md +23 -0
- package/skills/enhance-web-instant-nav/references/early-hints.md +33 -0
- package/skills/enhance-web-instant-nav/references/speculation-rules.md +44 -0
- package/skills/enhance-web-landing/SKILL.md +459 -0
- package/skills/enhance-web-landing/references/details.md +773 -0
- package/skills/enhance-web-redesign/SKILL.md +228 -0
- package/skills/enhance-web-seo/SKILL.md +276 -0
- package/skills/enhance-web-ui/SKILL.md +473 -0
- package/skills/enhance-web-ui/references/details.md +674 -0
- package/skills/enhance-web-ux/HEURISTICS.md +248 -0
- package/skills/enhance-web-ux/PATTERNS.md +375 -0
- package/skills/enhance-web-ux/SKILL.md +464 -0
- package/skills/enhance-web-ux/examples.md +222 -0
- package/skills/enhance-web-ux/references/details.md +406 -0
- package/skills/enhance-web-web3d/SKILL.md +397 -0
- package/skills/enhance-web-web3d/references/css-canvas-effects.md +180 -0
- package/skills/handoff/SKILL.md +66 -0
- package/skills/housekeep-backlog/SKILL.md +149 -0
- package/skills/housekeep-dead-code/SKILL.md +387 -0
- package/skills/housekeep-dead-code/references/ratchet-ci.md +205 -0
- package/skills/housekeep-dead-code/references/supabase-hygiene.md +152 -0
- package/skills/housekeep-design/SKILL.md +207 -0
- package/skills/housekeep-files/SKILL.md +220 -0
- package/skills/housekeep-files/references/naming-and-catalog.md +86 -0
- package/skills/housekeep-files/scripts/housekeep-files.ps1 +360 -0
- package/skills/housekeep-files/scripts/housekeep-files.sh +238 -0
- package/skills/housekeep-gates/SKILL.md +174 -0
- package/skills/iterate-agent-harness/SKILL.md +137 -0
- package/skills/iterate-gtm-weekly/SKILL.md +103 -0
- package/skills/iterate-post-launch/SKILL.md +292 -0
- package/skills/meta-mcp-builder/SKILL.md +313 -0
- package/skills/meta-skill-creator/SKILL.md +304 -0
- package/skills/mobile-capacitor-platform/SKILL.md +103 -0
- package/skills/mobile-emulator-start/SKILL.md +296 -0
- package/skills/mobile-emulator-test/SKILL.md +491 -0
- package/skills/mobile-emulator-test/references/details.md +478 -0
- package/skills/mobile-rn-performance/SKILL.md +107 -0
- package/skills/mobile-rn-screen/SKILL.md +476 -0
- package/skills/mobile-rn-screen/references/details.md +785 -0
- package/skills/mushi-health/SKILL.md +206 -0
- package/skills/mushi-integration/SKILL.md +257 -0
- package/skills/plan-aeo-readiness/SKILL.md +166 -0
- package/skills/plan-antislop/SKILL.md +281 -0
- package/skills/plan-aso/SKILL.md +149 -0
- package/skills/plan-backup-dr/SKILL.md +131 -0
- package/skills/plan-capacitor-hardening/SKILL.md +217 -0
- package/skills/plan-data-integrity/SKILL.md +187 -0
- package/skills/plan-dead-code/SKILL.md +386 -0
- package/skills/plan-dead-code/references/knip-config.md +214 -0
- package/skills/plan-dead-code/references/output-templates.md +133 -0
- package/skills/plan-dead-code/references/preservation-contract.md +50 -0
- package/skills/plan-dead-code/references/residue-greps.md +84 -0
- package/skills/plan-dependency-provenance/SKILL.md +200 -0
- package/skills/plan-docs-sync/SKILL.md +143 -0
- package/skills/plan-docs-sync/references/drift-taxonomy.md +43 -0
- package/skills/plan-docs-sync/references/output-templates.md +33 -0
- package/skills/plan-docs-sync/references/preservation-contract.md +17 -0
- package/skills/plan-error-handling/SKILL.md +205 -0
- package/skills/plan-gtm/SKILL.md +276 -0
- package/skills/plan-gtm/references/benchmarks-2026.md +183 -0
- package/skills/plan-input-validation/SKILL.md +179 -0
- package/skills/plan-llm-cost-guardrails/SKILL.md +176 -0
- package/skills/plan-mobile-readiness/SKILL.md +171 -0
- package/skills/plan-perf-audit/SKILL.md +145 -0
- package/skills/plan-perf-audit/references/audit-scope.md +51 -0
- package/skills/plan-perf-audit/references/output-templates.md +33 -0
- package/skills/plan-perf-audit/references/preservation-contract.md +13 -0
- package/skills/plan-pricing/SKILL.md +173 -0
- package/skills/plan-privacy-compliance/SKILL.md +148 -0
- package/skills/plan-rls-audit/SKILL.md +231 -0
- package/skills/plan-secrets-audit/SKILL.md +181 -0
- package/skills/plan-security-audit/SKILL.md +168 -0
- package/skills/plan-security-audit/references/output-templates.md +36 -0
- package/skills/plan-security-audit/references/owasp-supabase-scope.md +55 -0
- package/skills/plan-security-audit/references/preservation-contract.md +18 -0
- package/skills/plan-stub-checker/SKILL.md +216 -0
- package/skills/plan-stub-checker/references/detection-methodology.md +75 -0
- package/skills/plan-stub-checker/references/detection-taxonomy.md +34 -0
- package/skills/plan-stub-checker/references/output-templates.md +63 -0
- package/skills/plan-stub-checker/references/preservation-contract.md +24 -0
- package/skills/plan-test-coverage/SKILL.md +170 -0
- package/skills/plan-test-coverage/references/methodology.md +54 -0
- package/skills/plan-test-coverage/references/output-templates.md +34 -0
- package/skills/plan-test-coverage/references/preservation-contract.md +15 -0
- package/skills/plan-uiux-unification/SKILL.md +230 -0
- package/skills/plan-uiux-unification/references/output-templates.md +67 -0
- package/skills/plan-uiux-unification/references/phase-workbook.md +85 -0
- package/skills/plan-uiux-unification/references/preservation-contract.md +24 -0
- package/skills/protocol-browser-anti-stall/SKILL.md +211 -0
- package/skills/protocol-browser-anti-stall/references/mcp-to-cli-map.md +113 -0
- package/skills/protocol-browser-anti-stall/references/playwright-session-coordination.md +170 -0
- package/skills/research/SKILL.md +422 -0
- package/skills/test-exploratory/SKILL.md +165 -0
- package/skills/test-exploratory/references/charter-template.md +29 -0
- package/skills/test-load/SKILL.md +126 -0
- package/skills/test-mutation/SKILL.md +160 -0
- package/skills/test-playwright/SKILL.md +354 -0
- package/skills/test-qa/SKILL.md +364 -0
- package/skills/test-qa/references/details.md +268 -0
- package/skills/test-red-team/SKILL.md +386 -0
- package/skills/test-red-team/references/owasp-attack-checklist.md +193 -0
- package/skills/test-unit/SKILL.md +259 -0
- package/skills/test-unit/references/details.md +267 -0
- package/skills/test-visual-regression/SKILL.md +132 -0
- package/skills/thirdparty-emil-design-eng/ATTRIBUTION.md +20 -0
- package/skills/thirdparty-emil-design-eng/SKILL.md +21 -0
- package/skills/thirdparty-emil-design-eng/references/emil-design-eng.md +676 -0
- package/skills/thirdparty-ui-ux-pro-max/ATTRIBUTION.md +22 -0
- package/skills/thirdparty-ui-ux-pro-max/SKILL.md +304 -0
- package/skills/thirdparty-ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/thirdparty-ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/thirdparty-ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/thirdparty-ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/thirdparty-ui-ux-pro-max/data/products.csv +97 -0
- package/skills/thirdparty-ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/thirdparty-ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/thirdparty-ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/thirdparty-ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/thirdparty-ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/thirdparty-ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/thirdparty-ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/thirdparty-ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/thirdparty-ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/skills/thirdparty-ui-ux-pro-max/scripts/search.py +114 -0
- package/skills/thirdparty-web-interface-guidelines/ATTRIBUTION.md +23 -0
- package/skills/thirdparty-web-interface-guidelines/SKILL.md +190 -0
- package/skills/workflow-build-feature/SKILL.md +118 -0
- package/skills/workflow-coding-discipline/SKILL.md +140 -0
- package/skills/workflow-environment-ready/SKILL.md +128 -0
- package/skills/workflow-feature-flag/SKILL.md +262 -0
- package/skills/workflow-feedback-to-closure/SKILL.md +165 -0
- package/skills/workflow-fix-and-ship/SKILL.md +136 -0
- package/skills/workflow-git-commit/SKILL.md +200 -0
- package/skills/workflow-green-repo/SKILL.md +166 -0
- package/skills/workflow-grilling/SKILL.md +73 -0
- package/skills/workflow-gtm/SKILL.md +153 -0
- package/skills/workflow-housekeep/SKILL.md +453 -0
- package/skills/workflow-housekeep/references/templates.md +109 -0
- package/skills/workflow-launch-ready/SKILL.md +145 -0
- package/skills/workflow-merge-conflicts/SKILL.md +62 -0
- package/skills/workflow-onboard/SKILL.md +99 -0
- package/skills/workflow-parallel-agents/SKILL.md +164 -0
- package/skills/workflow-pr/SKILL.md +197 -0
- package/skills/workflow-quality-gate/SKILL.md +147 -0
- package/skills/workflow-refactor/SKILL.md +274 -0
- package/skills/workflow-release-prep/SKILL.md +207 -0
- package/skills/workflow-ship-and-observe/SKILL.md +164 -0
- package/skills/workflow-spec-tdd/SKILL.md +141 -0
- package/skills/workflow-spec-tdd/references/spec-template.md +126 -0
- package/skills/workflow-spec-tdd/references/tdd-patterns.md +167 -0
- package/skills-cursor/babysit/SKILL.md +17 -0
- package/skills-cursor/canvas/SKILL.md +142 -0
- package/skills-cursor/canvas/sdk/canvas-tokens.d.ts +235 -0
- package/skills-cursor/canvas/sdk/chart-primitives.d.ts +200 -0
- package/skills-cursor/canvas/sdk/dag-layout.d.ts +102 -0
- package/skills-cursor/canvas/sdk/diff-view.d.ts +130 -0
- package/skills-cursor/canvas/sdk/form-primitives.d.ts +194 -0
- package/skills-cursor/canvas/sdk/hooks.d.ts +117 -0
- package/skills-cursor/canvas/sdk/index.d.ts +47 -0
- package/skills-cursor/canvas/sdk/theme.d.ts +61 -0
- package/skills-cursor/canvas/sdk/todo-list.d.ts +49 -0
- package/skills-cursor/canvas/sdk/ui-primitives.d.ts +549 -0
- package/skills-cursor/canvas/sdk/ui-primitives.test.d.ts +2 -0
- package/skills-cursor/create-hook/SKILL.md +238 -0
- package/skills-cursor/create-rule/SKILL.md +185 -0
- package/skills-cursor/create-skill/SKILL.md +269 -0
- package/skills-cursor/create-skill/references/authoring-guide.md +182 -0
- package/skills-cursor/create-subagent/SKILL.md +228 -0
- package/skills-cursor/migrate-to-skills/SKILL.md +121 -0
- package/skills-cursor/shell/SKILL.md +22 -0
- package/skills-cursor/split-to-prs/SKILL.md +47 -0
- package/skills-cursor/statusline/SKILL.md +193 -0
- package/skills-cursor/update-cli-config/SKILL.md +85 -0
- package/skills-cursor/update-cursor-settings/SKILL.md +137 -0
- package/skills.sh.json +297 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backend-patterns
|
|
3
|
+
description: >
|
|
4
|
+
Apply backend patterns — queues, caching, rate limits, serverless/edge.
|
|
5
|
+
Use when "queue jobs", "caching layer", "rate limiting", "server
|
|
6
|
+
actions", or "edge function". Which architecture to pick →
|
|
7
|
+
audit-backend-architecture.
|
|
8
|
+
license: MIT
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Backend Patterns Skill
|
|
12
|
+
|
|
13
|
+
**Degree of freedom: MIXED.** Which pattern to apply `[HIGH freedom]`;
|
|
14
|
+
existing-architecture probes and the validation list `[LOW freedom — run exactly]`.
|
|
15
|
+
|
|
16
|
+
## How to reason
|
|
17
|
+
|
|
18
|
+
1. **Observe** — existing server/api/actions, ORM, queues, cache
|
|
19
|
+
2. **Interpret** — missing pattern vs duplicate vs wrong layer
|
|
20
|
+
3. **Classify** — reuse / add-queue / add-cache / add-rate-limit / edge-fn
|
|
21
|
+
4. **Severity** — unauthenticated mutation outranks a missing cache
|
|
22
|
+
|
|
23
|
+
## Worked example
|
|
24
|
+
|
|
25
|
+
> **Observe:** `createOrder` sends email inline; no Inngest/queue; checkout p95 4s.
|
|
26
|
+
> **Interpret:** confirmation is post-response work, not request-path.
|
|
27
|
+
> **Classify:** `after()` or an `order/created` job; keep the write transactional.
|
|
28
|
+
> **Verify:** order row commits; email/inventory run after response; retries do not double-charge.
|
|
29
|
+
|
|
30
|
+
## Self-critique before reporting
|
|
31
|
+
|
|
32
|
+
- **Existing first** — searched server/api/actions before adding a second pattern
|
|
33
|
+
- **Auth + validate** — every mutation checks session and Zod
|
|
34
|
+
- **Idempotent** — retries on the new path do not double-apply
|
|
35
|
+
- **Right owner** — which architecture to pick → `audit-backend-architecture`
|
|
36
|
+
|
|
37
|
+
Design scalable, maintainable backend architectures using modern patterns and best practices.
|
|
38
|
+
|
|
39
|
+
> Code examples lean on **Next.js App Router + Supabase/Prisma**. The patterns are
|
|
40
|
+
> stack-agnostic — adapt ORMs, client libraries, and deploy targets to your detected
|
|
41
|
+
> ecosystem.
|
|
42
|
+
|
|
43
|
+
## Check existing first [LOW freedom — run exactly]
|
|
44
|
+
|
|
45
|
+
**Before implementing ANY backend pattern, verify:**
|
|
46
|
+
|
|
47
|
+
1. **Check existing architecture:**
|
|
48
|
+
```bash
|
|
49
|
+
ls -la src/server/ src/api/ app/api/ supabase/functions/ 2>/dev/null
|
|
50
|
+
cat package.json | grep -i "prisma\|drizzle\|supabase\|trpc"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Check existing patterns:**
|
|
54
|
+
```bash
|
|
55
|
+
rg "createTRPCRouter|publicProcedure" --type ts -l
|
|
56
|
+
rg "'use server'" --type ts -l
|
|
57
|
+
ls -la supabase/migrations/*.sql 2>/dev/null | tail -5
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. **Check database setup:**
|
|
61
|
+
```bash
|
|
62
|
+
cat prisma/schema.prisma 2>/dev/null | head -50
|
|
63
|
+
cat supabase/config.toml 2>/dev/null
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Why:** Backend changes have wide impact. Understand existing architecture first.
|
|
67
|
+
|
|
68
|
+
## Server Actions (Next.js 16+) [HIGH freedom]
|
|
69
|
+
|
|
70
|
+
Next.js 16: Turbopack default; `'use cache'` + `cacheComponents`; `reactCompiler: true`; `middleware.ts` → `proxy.ts` (grep both). Instant navigations → `enhance-web-instant-nav`.
|
|
71
|
+
|
|
72
|
+
### Basic Pattern
|
|
73
|
+
```tsx
|
|
74
|
+
// app/actions/users.ts
|
|
75
|
+
'use server'
|
|
76
|
+
|
|
77
|
+
import { z } from 'zod'
|
|
78
|
+
import { revalidatePath } from 'next/cache'
|
|
79
|
+
import { auth } from '@/lib/auth'
|
|
80
|
+
import { db } from '@/lib/db'
|
|
81
|
+
|
|
82
|
+
const CreateUserSchema = z.object({
|
|
83
|
+
email: z.string().email(),
|
|
84
|
+
name: z.string().min(1).max(100),
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
type ActionResult<T> =
|
|
88
|
+
| { success: true; data: T }
|
|
89
|
+
| { success: false; error: string; fieldErrors?: Record<string, string[]> }
|
|
90
|
+
|
|
91
|
+
export async function createUser(
|
|
92
|
+
prevState: ActionResult<User> | null,
|
|
93
|
+
formData: FormData
|
|
94
|
+
): Promise<ActionResult<User>> {
|
|
95
|
+
// 1. Auth check
|
|
96
|
+
const session = await auth()
|
|
97
|
+
if (!session?.user) {
|
|
98
|
+
return { success: false, error: 'Unauthorized' }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 2. Validate input
|
|
102
|
+
const result = CreateUserSchema.safeParse({
|
|
103
|
+
email: formData.get('email'),
|
|
104
|
+
name: formData.get('name'),
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: 'Invalid input',
|
|
111
|
+
fieldErrors: result.error.flatten().fieldErrors,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 3. Execute
|
|
116
|
+
try {
|
|
117
|
+
const user = await db.user.create({
|
|
118
|
+
data: result.data,
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
revalidatePath('/users')
|
|
122
|
+
return { success: true, data: user }
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (isPrismaError(error, 'P2002')) {
|
|
125
|
+
return { success: false, error: 'Email already exists' }
|
|
126
|
+
}
|
|
127
|
+
console.error('createUser error:', error)
|
|
128
|
+
return { success: false, error: 'Failed to create user' }
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### With Background Tasks
|
|
134
|
+
```tsx
|
|
135
|
+
'use server'
|
|
136
|
+
|
|
137
|
+
import { after } from 'next/server'
|
|
138
|
+
|
|
139
|
+
export async function createOrder(formData: FormData) {
|
|
140
|
+
const order = await db.order.create({ data: { ... } })
|
|
141
|
+
|
|
142
|
+
// Run after response sent (Next.js 16)
|
|
143
|
+
after(async () => {
|
|
144
|
+
await sendOrderConfirmation(order.id)
|
|
145
|
+
await updateInventory(order.items)
|
|
146
|
+
await notifyWarehouse(order.id)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
revalidatePath('/orders')
|
|
150
|
+
return { success: true, data: order }
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## tRPC Setup [HIGH freedom]
|
|
155
|
+
|
|
156
|
+
### Router Definition
|
|
157
|
+
```tsx
|
|
158
|
+
// server/api/routers/users.ts
|
|
159
|
+
import { z } from 'zod'
|
|
160
|
+
import { createTRPCRouter, protectedProcedure, publicProcedure } from '../trpc'
|
|
161
|
+
|
|
162
|
+
export const usersRouter = createTRPCRouter({
|
|
163
|
+
getById: publicProcedure
|
|
164
|
+
.input(z.object({ id: z.string() }))
|
|
165
|
+
.query(async ({ ctx, input }) => {
|
|
166
|
+
return ctx.db.user.findUnique({
|
|
167
|
+
where: { id: input.id },
|
|
168
|
+
})
|
|
169
|
+
}),
|
|
170
|
+
|
|
171
|
+
create: protectedProcedure
|
|
172
|
+
.input(z.object({
|
|
173
|
+
email: z.string().email(),
|
|
174
|
+
name: z.string().min(1),
|
|
175
|
+
}))
|
|
176
|
+
.mutation(async ({ ctx, input }) => {
|
|
177
|
+
return ctx.db.user.create({
|
|
178
|
+
data: {
|
|
179
|
+
...input,
|
|
180
|
+
createdById: ctx.session.user.id,
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
}),
|
|
184
|
+
|
|
185
|
+
list: protectedProcedure
|
|
186
|
+
.input(z.object({
|
|
187
|
+
limit: z.number().min(1).max(100).default(10),
|
|
188
|
+
cursor: z.string().optional(),
|
|
189
|
+
}))
|
|
190
|
+
.query(async ({ ctx, input }) => {
|
|
191
|
+
const items = await ctx.db.user.findMany({
|
|
192
|
+
take: input.limit + 1,
|
|
193
|
+
cursor: input.cursor ? { id: input.cursor } : undefined,
|
|
194
|
+
orderBy: { createdAt: 'desc' },
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
let nextCursor: string | undefined
|
|
198
|
+
if (items.length > input.limit) {
|
|
199
|
+
const nextItem = items.pop()
|
|
200
|
+
nextCursor = nextItem?.id
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return { items, nextCursor }
|
|
204
|
+
}),
|
|
205
|
+
})
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Supabase Edge Functions [HIGH freedom]
|
|
209
|
+
|
|
210
|
+
### Basic Function
|
|
211
|
+
```tsx
|
|
212
|
+
// supabase/functions/process-webhook/index.ts
|
|
213
|
+
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
|
|
214
|
+
|
|
215
|
+
const corsHeaders = {
|
|
216
|
+
'Access-Control-Allow-Origin': '*',
|
|
217
|
+
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
Deno.serve(async (req) => {
|
|
221
|
+
// Handle CORS preflight
|
|
222
|
+
if (req.method === 'OPTIONS') {
|
|
223
|
+
return new Response('ok', { headers: corsHeaders })
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
// Verify webhook signature
|
|
228
|
+
const signature = req.headers.get('x-webhook-signature')
|
|
229
|
+
if (!verifySignature(signature, await req.text())) {
|
|
230
|
+
return new Response('Invalid signature', { status: 401 })
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const payload = await req.json()
|
|
234
|
+
|
|
235
|
+
// Create admin client (bypasses RLS)
|
|
236
|
+
const supabase = createClient(
|
|
237
|
+
Deno.env.get('SUPABASE_URL')!,
|
|
238
|
+
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
// Process webhook
|
|
242
|
+
await supabase.from('events').insert({
|
|
243
|
+
type: payload.type,
|
|
244
|
+
data: payload.data,
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
return new Response(
|
|
248
|
+
JSON.stringify({ success: true }),
|
|
249
|
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
|
250
|
+
)
|
|
251
|
+
} catch (error) {
|
|
252
|
+
console.error('Webhook error:', error)
|
|
253
|
+
return new Response(
|
|
254
|
+
JSON.stringify({ error: 'Internal error' }),
|
|
255
|
+
{ status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Database Patterns [HIGH freedom]
|
|
262
|
+
|
|
263
|
+
### Optimistic Locking
|
|
264
|
+
```sql
|
|
265
|
+
-- Add version column
|
|
266
|
+
ALTER TABLE orders ADD COLUMN version INT DEFAULT 1;
|
|
267
|
+
|
|
268
|
+
-- Update with version check
|
|
269
|
+
UPDATE orders
|
|
270
|
+
SET
|
|
271
|
+
status = 'shipped',
|
|
272
|
+
version = version + 1
|
|
273
|
+
WHERE id = $1 AND version = $2;
|
|
274
|
+
-- Returns 0 rows if version mismatch (concurrent update)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Soft Deletes
|
|
278
|
+
```prisma
|
|
279
|
+
model Post {
|
|
280
|
+
id String @id @default(cuid())
|
|
281
|
+
title String
|
|
282
|
+
deletedAt DateTime?
|
|
283
|
+
|
|
284
|
+
@@index([deletedAt])
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Query active records
|
|
288
|
+
const posts = await db.post.findMany({
|
|
289
|
+
where: { deletedAt: null }
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
// Soft delete
|
|
293
|
+
await db.post.update({
|
|
294
|
+
where: { id },
|
|
295
|
+
data: { deletedAt: new Date() }
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Audit Logging
|
|
300
|
+
```sql
|
|
301
|
+
-- Audit table
|
|
302
|
+
CREATE TABLE audit_logs (
|
|
303
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
304
|
+
table_name TEXT NOT NULL,
|
|
305
|
+
record_id UUID NOT NULL,
|
|
306
|
+
action TEXT NOT NULL, -- INSERT, UPDATE, DELETE
|
|
307
|
+
old_data JSONB,
|
|
308
|
+
new_data JSONB,
|
|
309
|
+
user_id UUID REFERENCES auth.users(id),
|
|
310
|
+
created_at TIMESTAMPTZ DEFAULT now()
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
-- Trigger function
|
|
314
|
+
CREATE OR REPLACE FUNCTION audit_trigger()
|
|
315
|
+
RETURNS TRIGGER AS $$
|
|
316
|
+
BEGIN
|
|
317
|
+
INSERT INTO audit_logs (table_name, record_id, action, old_data, new_data, user_id)
|
|
318
|
+
VALUES (
|
|
319
|
+
TG_TABLE_NAME,
|
|
320
|
+
COALESCE(NEW.id, OLD.id),
|
|
321
|
+
TG_OP,
|
|
322
|
+
CASE WHEN TG_OP IN ('UPDATE', 'DELETE') THEN row_to_json(OLD) END,
|
|
323
|
+
CASE WHEN TG_OP IN ('INSERT', 'UPDATE') THEN row_to_json(NEW) END,
|
|
324
|
+
auth.uid()
|
|
325
|
+
);
|
|
326
|
+
RETURN COALESCE(NEW, OLD);
|
|
327
|
+
END;
|
|
328
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
329
|
+
|
|
330
|
+
-- Apply to table
|
|
331
|
+
CREATE TRIGGER orders_audit
|
|
332
|
+
AFTER INSERT OR UPDATE OR DELETE ON orders
|
|
333
|
+
FOR EACH ROW EXECUTE FUNCTION audit_trigger();
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Caching Patterns [HIGH freedom]
|
|
337
|
+
|
|
338
|
+
### Next.js Cache
|
|
339
|
+
```tsx
|
|
340
|
+
// Cached fetch
|
|
341
|
+
const data = await fetch('https://api.example.com/data', {
|
|
342
|
+
next: {
|
|
343
|
+
revalidate: 3600, // 1 hour
|
|
344
|
+
tags: ['data']
|
|
345
|
+
}
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
// Revalidate on demand
|
|
349
|
+
import { revalidateTag } from 'next/cache'
|
|
350
|
+
revalidateTag('data')
|
|
351
|
+
|
|
352
|
+
// unstable_cache for database queries
|
|
353
|
+
import { unstable_cache } from 'next/cache'
|
|
354
|
+
|
|
355
|
+
const getCachedUser = unstable_cache(
|
|
356
|
+
async (id: string) => db.user.findUnique({ where: { id } }),
|
|
357
|
+
['user'],
|
|
358
|
+
{ revalidate: 3600, tags: ['users'] }
|
|
359
|
+
)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Redis Caching
|
|
363
|
+
```tsx
|
|
364
|
+
import { Redis } from '@upstash/redis'
|
|
365
|
+
|
|
366
|
+
const redis = Redis.fromEnv()
|
|
367
|
+
|
|
368
|
+
async function getCachedData<T>(
|
|
369
|
+
key: string,
|
|
370
|
+
fetcher: () => Promise<T>,
|
|
371
|
+
ttl = 3600
|
|
372
|
+
): Promise<T> {
|
|
373
|
+
// Try cache
|
|
374
|
+
const cached = await redis.get<T>(key)
|
|
375
|
+
if (cached) return cached
|
|
376
|
+
|
|
377
|
+
// Fetch and cache
|
|
378
|
+
const data = await fetcher()
|
|
379
|
+
await redis.set(key, data, { ex: ttl })
|
|
380
|
+
return data
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Usage
|
|
384
|
+
const user = await getCachedData(
|
|
385
|
+
`user:${id}`,
|
|
386
|
+
() => db.user.findUnique({ where: { id } }),
|
|
387
|
+
600 // 10 minutes
|
|
388
|
+
)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Background Jobs [HIGH freedom]
|
|
392
|
+
|
|
393
|
+
### Inngest
|
|
394
|
+
```tsx
|
|
395
|
+
// inngest/functions.ts
|
|
396
|
+
import { inngest } from './client'
|
|
397
|
+
|
|
398
|
+
export const processOrder = inngest.createFunction(
|
|
399
|
+
{ id: 'process-order' },
|
|
400
|
+
{ event: 'order/created' },
|
|
401
|
+
async ({ event, step }) => {
|
|
402
|
+
// Step 1: Validate inventory
|
|
403
|
+
const inventory = await step.run('check-inventory', async () => {
|
|
404
|
+
return await checkInventory(event.data.items)
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
if (!inventory.available) {
|
|
408
|
+
await step.run('notify-out-of-stock', async () => {
|
|
409
|
+
await notifyCustomer(event.data.userId, 'out-of-stock')
|
|
410
|
+
})
|
|
411
|
+
return { status: 'cancelled' }
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Step 2: Charge payment
|
|
415
|
+
const payment = await step.run('charge-payment', async () => {
|
|
416
|
+
return await chargeCustomer(event.data.paymentMethod)
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
// Step 3: Send confirmation
|
|
420
|
+
await step.run('send-confirmation', async () => {
|
|
421
|
+
await sendOrderConfirmation(event.data.orderId)
|
|
422
|
+
})
|
|
423
|
+
|
|
424
|
+
return { status: 'completed', paymentId: payment.id }
|
|
425
|
+
}
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
// Trigger from server action
|
|
429
|
+
await inngest.send({
|
|
430
|
+
name: 'order/created',
|
|
431
|
+
data: { orderId, userId, items, paymentMethod }
|
|
432
|
+
})
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Trigger.dev
|
|
436
|
+
```tsx
|
|
437
|
+
// trigger/sync.ts
|
|
438
|
+
import { schedules } from '@trigger.dev/sdk'
|
|
439
|
+
|
|
440
|
+
export const syncJob = schedules.task({
|
|
441
|
+
id: 'sync-data',
|
|
442
|
+
cron: '0 * * * *', // every hour (UTC)
|
|
443
|
+
run: async () => {
|
|
444
|
+
const data = await fetchExternalAPI()
|
|
445
|
+
await db.externalData.upsert({
|
|
446
|
+
where: { externalId: data.id },
|
|
447
|
+
create: data,
|
|
448
|
+
update: data,
|
|
449
|
+
})
|
|
450
|
+
return { synced: data.length }
|
|
451
|
+
},
|
|
452
|
+
})
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Rate Limiting [HIGH freedom]
|
|
456
|
+
|
|
457
|
+
```tsx
|
|
458
|
+
import { Ratelimit } from '@upstash/ratelimit'
|
|
459
|
+
import { Redis } from '@upstash/redis'
|
|
460
|
+
|
|
461
|
+
const ratelimit = new Ratelimit({
|
|
462
|
+
redis: Redis.fromEnv(),
|
|
463
|
+
limiter: Ratelimit.slidingWindow(10, '10 s'), // 10 requests per 10 seconds
|
|
464
|
+
analytics: true,
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
export async function rateLimitedAction(userId: string) {
|
|
468
|
+
const { success, limit, remaining, reset } = await ratelimit.limit(userId)
|
|
469
|
+
|
|
470
|
+
if (!success) {
|
|
471
|
+
return {
|
|
472
|
+
success: false,
|
|
473
|
+
error: 'Too many requests',
|
|
474
|
+
retryAfter: Math.ceil((reset - Date.now()) / 1000),
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Proceed with action...
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Architecture patterns (distributed systems) [HIGH freedom]
|
|
483
|
+
|
|
484
|
+
Gateway, BFF, bulkhead, circuit breaker, outbox+CDC, saga, hexagonal, ACL, and strangler-fig →
|
|
485
|
+
[references/architecture-patterns.md](references/architecture-patterns.md). Pick the pattern for the
|
|
486
|
+
topology (no mesh on a monolith; no CQRS unless reads/writes diverge). Timeouts/retries/idempotency
|
|
487
|
+
→ `audit-resilience`; structural gap report → `audit-backend-architecture`.
|
|
488
|
+
|
|
489
|
+
## Validation [LOW freedom — do not skip]
|
|
490
|
+
|
|
491
|
+
After implementing backend patterns:
|
|
492
|
+
|
|
493
|
+
1. **Error handling** → All errors caught, logged, safe response returned
|
|
494
|
+
2. **Auth checks** → Every mutation verifies authentication
|
|
495
|
+
3. **Input validation** → Zod schema on all inputs
|
|
496
|
+
4. **Rate limiting** → Sensitive endpoints protected
|
|
497
|
+
5. **Idempotency** → Critical operations handle retries
|
|
498
|
+
6. **Logging** → Structured logs without sensitive data
|
|
499
|
+
7. **Testing** → Unit tests for business logic, integration for APIs
|