@jhm1909/ag-kit 0.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/.agent/ARCHITECTURE.md +189 -0
- package/.agent/known-registries.json +181 -0
- package/.agent/mcp_config.json +19 -0
- package/.agent/rules/clean-code.md +107 -0
- package/.agent/rules/documents.md +177 -0
- package/.agent/rules/git-workflow.md +68 -0
- package/.agent/rules/nano-banana.md +46 -0
- package/.agent/rules/research.md +35 -0
- package/.agent/rules/skill-loading.md +100 -0
- package/.agent/rules/skill-suggestion.md +47 -0
- package/.agent/rules/testing.md +52 -0
- package/.agent/rules/workflow-advisor.md +108 -0
- package/.agent/rules/workflow-skill-convention.md +127 -0
- package/.agent/skills/ai-engineer/SKILL.md +824 -0
- package/.agent/skills/ai-engineer/references/agentic-patterns.md +329 -0
- package/.agent/skills/ai-engineer/references/evaluation.md +493 -0
- package/.agent/skills/ai-engineer/references/llm.md +490 -0
- package/.agent/skills/ai-engineer/references/rag-advanced.md +444 -0
- package/.agent/skills/ai-engineer/references/serving-optimization.md +531 -0
- package/.agent/skills/ai-engineer/vector-db/README.md +137 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +41 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/backend-developer/SKILL.md +763 -0
- package/.agent/skills/backend-developer/references/general-patterns.md +65 -0
- package/.agent/skills/backend-developer/references/go-echo.md +68 -0
- package/.agent/skills/backend-developer/references/go-gin.md +76 -0
- package/.agent/skills/backend-developer/references/java-springboot.md +83 -0
- package/.agent/skills/backend-developer/references/node-express.md +64 -0
- package/.agent/skills/backend-developer/references/node-nestjs.md +69 -0
- package/.agent/skills/backend-developer/references/python-django.md +67 -0
- package/.agent/skills/backend-developer/references/python-fastapi.md +80 -0
- package/.agent/skills/blockchain-engineer/SKILL.md +975 -0
- package/.agent/skills/blockchain-engineer/references/deployment.md +28 -0
- package/.agent/skills/blockchain-engineer/references/evm.md +14 -0
- package/.agent/skills/blockchain-engineer/references/mechanisms.md +32 -0
- package/.agent/skills/blockchain-engineer/references/solidity.md +32 -0
- package/.agent/skills/business-analysis/SKILL.md +85 -0
- package/.agent/skills/business-analysis/references/best-practices/diagrams.md +141 -0
- package/.agent/skills/business-analysis/references/domains/ai-agent.md +94 -0
- package/.agent/skills/business-analysis/references/domains/blockchain-dapp.md +86 -0
- package/.agent/skills/business-analysis/references/domains/ecommerce.md +77 -0
- package/.agent/skills/business-analysis/references/domains/education.md +42 -0
- package/.agent/skills/business-analysis/references/domains/fintech.md +44 -0
- package/.agent/skills/business-analysis/references/domains/fnb.md +82 -0
- package/.agent/skills/business-analysis/references/domains/healthtech.md +44 -0
- package/.agent/skills/business-analysis/references/domains/internal-tools.md +38 -0
- package/.agent/skills/business-analysis/references/domains/marketplace.md +52 -0
- package/.agent/skills/business-analysis/references/domains/saas.md +36 -0
- package/.agent/skills/business-analysis/references/workflows/collaboration.md +41 -0
- package/.agent/skills/business-analysis/scripts/verify_mermaid.py +86 -0
- package/.agent/skills/business-analysis/templates/brd.md +46 -0
- package/.agent/skills/business-analysis/templates/change-request.md +41 -0
- package/.agent/skills/business-analysis/templates/prd-functional.md +38 -0
- package/.agent/skills/business-analysis/templates/use-case.md +40 -0
- package/.agent/skills/business-analysis/templates/user-story-detailed.md +36 -0
- package/.agent/skills/code-review/SKILL.md +113 -0
- package/.agent/skills/code-review/references/code-review-reception.md +209 -0
- package/.agent/skills/code-review/references/differential_review.md +59 -0
- package/.agent/skills/code-review/references/requesting-code-review.md +105 -0
- package/.agent/skills/code-review/references/spec_compliance.md +43 -0
- package/.agent/skills/code-review/references/verification-before-completion.md +139 -0
- package/.agent/skills/context-engineering/SKILL.md +68 -0
- package/.agent/skills/context-engineering/references/context-compression.md +84 -0
- package/.agent/skills/context-engineering/references/context-degradation.md +93 -0
- package/.agent/skills/context-engineering/references/context-fundamentals.md +75 -0
- package/.agent/skills/context-engineering/references/context-optimization.md +82 -0
- package/.agent/skills/context-engineering/references/evaluation.md +89 -0
- package/.agent/skills/context-engineering/references/memory-systems.md +88 -0
- package/.agent/skills/context-engineering/references/multi-agent-patterns.md +90 -0
- package/.agent/skills/context-engineering/references/project-development.md +97 -0
- package/.agent/skills/context-engineering/references/tool-design.md +86 -0
- package/.agent/skills/debugging/SKILL.md +60 -0
- package/.agent/skills/debugging/references/defense-in-depth.md +130 -0
- package/.agent/skills/debugging/references/root-cause-tracing.md +177 -0
- package/.agent/skills/debugging/references/systematic-debugging.md +295 -0
- package/.agent/skills/debugging/references/verification-before-completion.md +142 -0
- package/.agent/skills/designer/SKILL.md +159 -0
- package/.agent/skills/designer/concepts/apple-glass.md +48 -0
- package/.agent/skills/designer/concepts/aurora-gradients.md +26 -0
- package/.agent/skills/designer/concepts/bento-grids.md +14 -0
- package/.agent/skills/designer/concepts/claymorphism.md +27 -0
- package/.agent/skills/designer/concepts/neo-brutalism.md +32 -0
- package/.agent/skills/designer/data/app-interface.csv +31 -0
- package/.agent/skills/designer/data/charts.csv +26 -0
- package/.agent/skills/designer/data/colors.csv +162 -0
- package/.agent/skills/designer/data/design.csv +1776 -0
- package/.agent/skills/designer/data/icons.csv +106 -0
- package/.agent/skills/designer/data/landing.csv +35 -0
- package/.agent/skills/designer/data/products.csv +162 -0
- package/.agent/skills/designer/data/react-performance.csv +45 -0
- package/.agent/skills/designer/data/styles.csv +85 -0
- package/.agent/skills/designer/data/typography.csv +74 -0
- package/.agent/skills/designer/data/ui-reasoning.csv +162 -0
- package/.agent/skills/designer/data/ux-guidelines.csv +100 -0
- package/.agent/skills/designer/references/accessibility.md +172 -0
- package/.agent/skills/designer/references/branding.md +88 -0
- package/.agent/skills/designer/references/color-theory.md +139 -0
- package/.agent/skills/designer/references/creation.md +118 -0
- package/.agent/skills/designer/references/design-systems.md +219 -0
- package/.agent/skills/designer/references/frontend_design_aesthetics.md +57 -0
- package/.agent/skills/designer/references/layout.md +200 -0
- package/.agent/skills/designer/references/motion.md +92 -0
- package/.agent/skills/designer/references/review.md +100 -0
- package/.agent/skills/designer/references/trends.md +209 -0
- package/.agent/skills/designer/references/typography.md +190 -0
- package/.agent/skills/designer/scripts/remove_background.py +135 -0
- package/.agent/skills/designer/scripts/ui-search/__pycache__/core.cpython-314.pyc +0 -0
- package/.agent/skills/designer/scripts/ui-search/__pycache__/design_system.cpython-314.pyc +0 -0
- package/.agent/skills/designer/scripts/ui-search/core.py +217 -0
- package/.agent/skills/designer/scripts/ui-search/design_system.py +1067 -0
- package/.agent/skills/designer/scripts/ui-search/search.py +114 -0
- package/.agent/skills/designer/templates/design-motion-spec.md +30 -0
- package/.agent/skills/devops-engineer/SKILL.md +90 -0
- package/.agent/skills/devops-engineer/docker-compose/README.md +47 -0
- package/.agent/skills/devops-engineer/references/ci-cd-pipelines.md +76 -0
- package/.agent/skills/devops-engineer/references/cloud-providers.md +57 -0
- package/.agent/skills/devops-engineer/references/codebase-normalization.md +104 -0
- package/.agent/skills/devops-engineer/references/container-orchestration.md +69 -0
- package/.agent/skills/devops-engineer/references/iac-tools.md +63 -0
- package/.agent/skills/devops-engineer/references/observability-security.md +45 -0
- package/.agent/skills/devops-engineer/references/vercel-supabase.md +17 -0
- package/.agent/skills/devops-engineer/templates/release-notes.md +8 -0
- package/.agent/skills/frontend-developer/SKILL.md +125 -0
- package/.agent/skills/frontend-developer/react-nextjs/README.md +90 -0
- package/.agent/skills/frontend-developer/references/angular.md +52 -0
- package/.agent/skills/frontend-developer/references/composition_patterns.md +60 -0
- package/.agent/skills/frontend-developer/references/core-performance.md +68 -0
- package/.agent/skills/frontend-developer/references/modern-signals.md +43 -0
- package/.agent/skills/frontend-developer/references/react_performance_rules.md +55 -0
- package/.agent/skills/frontend-developer/references/vue-nuxt.md +55 -0
- package/.agent/skills/frontend-developer/scripts/validate_compliance.py +65 -0
- package/.agent/skills/frontend-developer/threejs/README.md +89 -0
- package/.agent/skills/frontend-developer/threejs/animation.md +552 -0
- package/.agent/skills/frontend-developer/threejs/fundamentals.md +488 -0
- package/.agent/skills/frontend-developer/threejs/geometry.md +548 -0
- package/.agent/skills/frontend-developer/threejs/interaction.md +660 -0
- package/.agent/skills/frontend-developer/threejs/lighting.md +481 -0
- package/.agent/skills/frontend-developer/threejs/loaders.md +623 -0
- package/.agent/skills/frontend-developer/threejs/materials.md +520 -0
- package/.agent/skills/frontend-developer/threejs/postprocessing.md +602 -0
- package/.agent/skills/frontend-developer/threejs/router.json +181 -0
- package/.agent/skills/frontend-developer/threejs/shaders.md +642 -0
- package/.agent/skills/frontend-developer/threejs/textures.md +628 -0
- package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/.agent/skills/game-development/SKILL.md +167 -0
- package/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/.agent/skills/lead-architect/SKILL.md +85 -0
- package/.agent/skills/lead-architect/references/application-architecture.md +70 -0
- package/.agent/skills/lead-architect/references/infrastructure.md +51 -0
- package/.agent/skills/lead-architect/references/process.md +42 -0
- package/.agent/skills/lead-architect/references/system-architecture.md +62 -0
- package/.agent/skills/lead-architect/references/web-fullstack.md +82 -0
- package/.agent/skills/lead-architect/templates/adr.md +62 -0
- package/.agent/skills/lead-architect/templates/rfc.md +46 -0
- package/.agent/skills/lead-architect/templates/sdd.md +62 -0
- package/.agent/skills/lead-architect/templates/technical-spec.md +61 -0
- package/.agent/skills/marketer/SKILL.md +66 -0
- package/.agent/skills/marketer/remotion-best-practices/SKILL.md +58 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/3d.md +86 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/animations.md +29 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/assets.md +78 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/audio.md +172 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/can-decode.md +75 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/charts.md +58 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/compositions.md +146 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/display-captions.md +126 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/extract-frames.md +229 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/fonts.md +152 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/gifs.md +138 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/images.md +130 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/lottie.md +68 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/measuring-text.md +143 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/sequencing.md +106 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/tailwind.md +11 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/text-animations.md +20 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/timing.md +179 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/transitions.md +122 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/trimming.md +53 -0
- package/.agent/skills/marketer/remotion-best-practices/rules/videos.md +171 -0
- package/.agent/skills/mcp-builder/SKILL.md +76 -0
- package/.agent/skills/mcp-builder/references/evaluation.md +602 -0
- package/.agent/skills/mcp-builder/references/mcp_best_practices.md +249 -0
- package/.agent/skills/mcp-builder/references/node_mcp_server.md +970 -0
- package/.agent/skills/mcp-builder/references/python_mcp_server.md +719 -0
- package/.agent/skills/mobile-developer/SKILL.md +83 -0
- package/.agent/skills/mobile-developer/api-routes/SKILL.md +389 -0
- package/.agent/skills/mobile-developer/building-ui/SKILL.md +335 -0
- package/.agent/skills/mobile-developer/building-ui/references/animations.md +220 -0
- package/.agent/skills/mobile-developer/building-ui/references/controls.md +270 -0
- package/.agent/skills/mobile-developer/building-ui/references/form-sheet.md +227 -0
- package/.agent/skills/mobile-developer/building-ui/references/gradients.md +106 -0
- package/.agent/skills/mobile-developer/building-ui/references/icons.md +213 -0
- package/.agent/skills/mobile-developer/building-ui/references/media.md +198 -0
- package/.agent/skills/mobile-developer/building-ui/references/route-structure.md +229 -0
- package/.agent/skills/mobile-developer/building-ui/references/search.md +248 -0
- package/.agent/skills/mobile-developer/building-ui/references/storage.md +121 -0
- package/.agent/skills/mobile-developer/building-ui/references/tabs.md +368 -0
- package/.agent/skills/mobile-developer/building-ui/references/visual-effects.md +197 -0
- package/.agent/skills/mobile-developer/building-ui/references/webgpu-three.md +605 -0
- package/.agent/skills/mobile-developer/cicd-workflows/SKILL.md +107 -0
- package/.agent/skills/mobile-developer/cicd-workflows/scripts/fetch.js +109 -0
- package/.agent/skills/mobile-developer/cicd-workflows/scripts/package.json +11 -0
- package/.agent/skills/mobile-developer/cicd-workflows/scripts/validate.js +84 -0
- package/.agent/skills/mobile-developer/data-fetching/SKILL.md +508 -0
- package/.agent/skills/mobile-developer/deployment/SKILL.md +207 -0
- package/.agent/skills/mobile-developer/deployment/references/app-store-metadata.md +479 -0
- package/.agent/skills/mobile-developer/deployment/references/ios-app-store.md +355 -0
- package/.agent/skills/mobile-developer/deployment/references/play-store.md +246 -0
- package/.agent/skills/mobile-developer/deployment/references/testflight.md +58 -0
- package/.agent/skills/mobile-developer/deployment/references/workflows.md +200 -0
- package/.agent/skills/mobile-developer/dev-client/SKILL.md +181 -0
- package/.agent/skills/mobile-developer/tailwind-setup/SKILL.md +501 -0
- package/.agent/skills/mobile-developer/upgrading-expo/SKILL.md +116 -0
- package/.agent/skills/mobile-developer/upgrading-expo/references/new-architecture.md +79 -0
- package/.agent/skills/mobile-developer/upgrading-expo/references/react-19.md +79 -0
- package/.agent/skills/mobile-developer/upgrading-expo/references/react-compiler.md +59 -0
- package/.agent/skills/mobile-developer/use-dom/SKILL.md +434 -0
- package/.agent/skills/modern-python/SKILL.md +122 -0
- package/.agent/skills/project-manager/SKILL.md +110 -0
- package/.agent/skills/project-manager/references/ba-collaboration.md +62 -0
- package/.agent/skills/project-manager/references/discovery_process.md +52 -0
- package/.agent/skills/project-manager/references/jobs_to_be_done.md +51 -0
- package/.agent/skills/project-manager/references/prd_development.md +52 -0
- package/.agent/skills/project-manager/references/rules-guide.md +55 -0
- package/.agent/skills/project-manager/references/skill-creation.md +98 -0
- package/.agent/skills/project-manager/references/strategic-frameworks.md +62 -0
- package/.agent/skills/project-manager/references/task-decomposition.md +194 -0
- package/.agent/skills/project-manager/references/workflows-guide.md +44 -0
- package/.agent/skills/project-manager/router.json +160 -0
- package/.agent/skills/project-manager/scripts/compare_skill.py +177 -0
- package/.agent/skills/project-manager/scripts/encoding_utils.py +36 -0
- package/.agent/skills/project-manager/scripts/init_skill.py +190 -0
- package/.agent/skills/project-manager/scripts/quick_validate.py +123 -0
- package/.agent/skills/project-manager/templates/pm-strategy-one-pager.md +6 -0
- package/.agent/skills/project-manager/templates/prd-strategic.md +38 -0
- package/.agent/skills/project-manager/templates/skill-questionnaire.md +118 -0
- package/.agent/skills/project-manager/templates/user-story-simple.md +14 -0
- package/.agent/skills/prompt-engineer/SKILL.md +319 -0
- package/.agent/skills/prompt-engineer/skill-creator/README.md +47 -0
- package/.agent/skills/qa-tester/SKILL.md +142 -0
- package/.agent/skills/qa-tester/assets/README.md +8 -0
- package/.agent/skills/qa-tester/references/accessibility_testing.md +35 -0
- package/.agent/skills/qa-tester/references/agent_browser.md +38 -0
- package/.agent/skills/qa-tester/references/automation/api_testing.md +23 -0
- package/.agent/skills/qa-tester/references/automation/best_practices.md +14 -0
- package/.agent/skills/qa-tester/references/automation/jest_vitest.md +26 -0
- package/.agent/skills/qa-tester/references/automation/playwright.md +30 -0
- package/.agent/skills/qa-tester/references/e2e_testing.md +46 -0
- package/.agent/skills/qa-tester/references/integration_testing.md +39 -0
- package/.agent/skills/qa-tester/references/performance_testing.md +44 -0
- package/.agent/skills/qa-tester/references/property_based_testing.md +44 -0
- package/.agent/skills/qa-tester/references/security_audit.md +53 -0
- package/.agent/skills/qa-tester/references/security_testing.md +30 -0
- package/.agent/skills/qa-tester/references/sharp_edges.md +49 -0
- package/.agent/skills/qa-tester/references/static_analysis.md +52 -0
- package/.agent/skills/qa-tester/references/supply_chain_audit.md +54 -0
- package/.agent/skills/qa-tester/references/test_case_standards.md +96 -0
- package/.agent/skills/qa-tester/references/test_report_template.md +32 -0
- package/.agent/skills/qa-tester/references/unit_testing.md +50 -0
- package/.agent/skills/qa-tester/references/visual_testing.md +32 -0
- package/.agent/skills/qa-tester/templates/uat-plan.md +34 -0
- package/.agent/skills/research-first/SKILL.md +118 -0
- package/.agent/skills-manifest.json +264 -0
- package/.agent/workflows/absorb.md +176 -0
- package/.agent/workflows/bootstrap.md +91 -0
- package/.agent/workflows/brainstorm.md +168 -0
- package/.agent/workflows/break-tasks.md +77 -0
- package/.agent/workflows/commit.md +349 -0
- package/.agent/workflows/custom-behavior.md +64 -0
- package/.agent/workflows/debug.md +65 -0
- package/.agent/workflows/development.md +49 -0
- package/.agent/workflows/documentation.md +221 -0
- package/.agent/workflows/gen-tests.md +53 -0
- package/.agent/workflows/guide.md +196 -0
- package/.agent/workflows/implement-feature.md +182 -0
- package/.agent/workflows/install-skill.md +193 -0
- package/.agent/workflows/qa.md +54 -0
- package/.agent/workflows/ui-ux-design.md +108 -0
- package/LICENSE +21 -0
- package/README.md +258 -0
- package/cli/index.js +345 -0
- package/cli/migrate-skills.js +113 -0
- package/cli/verify.js +291 -0
- package/package.json +49 -0
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backend-developer
|
|
3
|
+
description: >
|
|
4
|
+
API design, system architecture, security, and scalability. Use for Node.js, Python, Go, or Java backend systems.
|
|
5
|
+
license: MIT
|
|
6
|
+
compatibility: Claude Code, Cursor, Gemini CLI, GitHub Copilot
|
|
7
|
+
metadata:
|
|
8
|
+
author: jhm1909
|
|
9
|
+
version: "2.0.0"
|
|
10
|
+
domain: infra
|
|
11
|
+
estimated_tokens: 35000
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Backend Developer
|
|
15
|
+
|
|
16
|
+
Expert guidelines for building robust, scalable, and secure distributed systems.
|
|
17
|
+
|
|
18
|
+
## Knowledge Graph
|
|
19
|
+
|
|
20
|
+
- **extends**: []
|
|
21
|
+
- **requires**: []
|
|
22
|
+
- **suggests**: [[devops-engineer]], [[lead-architect]]
|
|
23
|
+
- **conflicts**: []
|
|
24
|
+
- **enhances**: [[frontend-developer]] (fullstack), [[ai-engineer]] (AI APIs), [[blockchain-engineer]] (Web3 APIs)
|
|
25
|
+
- **moc**: [[web-development-moc]]
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. System Architecture
|
|
30
|
+
|
|
31
|
+
### 1.1 Architecture Patterns
|
|
32
|
+
|
|
33
|
+
| Pattern | Best For | Trade-offs |
|
|
34
|
+
|:--------|:---------|:-----------|
|
|
35
|
+
| **Monolith** | Small-medium teams, rapid iteration | Simple deployment, harder to scale independently |
|
|
36
|
+
| **Microservices** | Large teams, independent scaling | Operational complexity, network latency |
|
|
37
|
+
| **Modular Monolith** | Mid-size, clean boundaries | Best of both worlds, easier migration |
|
|
38
|
+
| **Serverless** | Variable load, event-driven | Cold starts, vendor lock-in |
|
|
39
|
+
| **Event-Driven** | Async processing, loose coupling | Eventual consistency, debugging complexity |
|
|
40
|
+
|
|
41
|
+
### 1.2 Service Boundaries
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
45
|
+
│ API Gateway │
|
|
46
|
+
│ (Auth, Rate Limiting, Routing) │
|
|
47
|
+
└────────────────────────┬────────────────────────────────────┘
|
|
48
|
+
│
|
|
49
|
+
┌────────────────────┼────────────────────┐
|
|
50
|
+
↓ ↓ ↓
|
|
51
|
+
┌─────────┐ ┌─────────────┐ ┌─────────────┐
|
|
52
|
+
│ User │ │ Order │ │ Payment │
|
|
53
|
+
│ Service │ │ Service │ │ Service │
|
|
54
|
+
│ │ │ │ │ │
|
|
55
|
+
│ - Auth │ │ - Cart │ │ - Stripe │
|
|
56
|
+
│ - Profile│ │ - Checkout │ │ - Webhooks │
|
|
57
|
+
└────┬────┘ └──────┬──────┘ └──────┬──────┘
|
|
58
|
+
│ │ │
|
|
59
|
+
└──────────────────┼────────────────────┘
|
|
60
|
+
│
|
|
61
|
+
┌─────────┴──────────┐
|
|
62
|
+
↓ ↓
|
|
63
|
+
┌──────────┐ ┌──────────┐
|
|
64
|
+
│ PostgreSQL│ │ Redis │
|
|
65
|
+
│ (Users) │ │ (Cache) │
|
|
66
|
+
└──────────┘ └──────────┘
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 1.3 Communication Patterns
|
|
70
|
+
|
|
71
|
+
**Synchronous (REST/gRPC)**
|
|
72
|
+
- Use for: Real-time requirements, simple request-response
|
|
73
|
+
- Timeout: Always set (5-30s depending on operation)
|
|
74
|
+
- Circuit breaker: Mandatory for external calls
|
|
75
|
+
|
|
76
|
+
**Asynchronous (Message Queue)**
|
|
77
|
+
- Use for: Background jobs, high throughput, decoupling
|
|
78
|
+
- Patterns: Pub/sub, work queues, routing
|
|
79
|
+
- Guarantees: At-least-once delivery, idempotent consumers
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
# Async pattern with retry
|
|
83
|
+
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
|
|
84
|
+
async def process_order(order_id: str):
|
|
85
|
+
order = await db.orders.find_one({"_id": order_id})
|
|
86
|
+
|
|
87
|
+
# Idempotent: check if already processed
|
|
88
|
+
if order.status == "processed":
|
|
89
|
+
return {"status": "already_processed"}
|
|
90
|
+
|
|
91
|
+
# Process
|
|
92
|
+
result = await payment.charge(order.payment_token)
|
|
93
|
+
|
|
94
|
+
# Update with idempotency key
|
|
95
|
+
await db.orders.update_one(
|
|
96
|
+
{"_id": order_id},
|
|
97
|
+
{"$set": {"status": "processed", "processed_at": now()}}
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return result
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 2. API Design
|
|
106
|
+
|
|
107
|
+
### 2.1 REST Best Practices
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
GET /api/v1/users # List (paginated)
|
|
111
|
+
GET /api/v1/users/:id # Get one
|
|
112
|
+
POST /api/v1/users # Create
|
|
113
|
+
PUT /api/v1/users/:id # Full update
|
|
114
|
+
PATCH /api/v1/users/:id # Partial update
|
|
115
|
+
DELETE /api/v1/users/:id # Delete
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Status Codes**
|
|
119
|
+
- `200 OK` — Success
|
|
120
|
+
- `201 Created` — Resource created
|
|
121
|
+
- `204 No Content` — Success, no body
|
|
122
|
+
- `400 Bad Request` — Validation error
|
|
123
|
+
- `401 Unauthorized` — Auth required
|
|
124
|
+
- `403 Forbidden` — No permission
|
|
125
|
+
- `404 Not Found` — Resource doesn't exist
|
|
126
|
+
- `409 Conflict` — Resource already exists
|
|
127
|
+
- `422 Unprocessable` — Business logic error
|
|
128
|
+
- `429 Too Many Requests` — Rate limited
|
|
129
|
+
- `500 Internal Error` — Server error
|
|
130
|
+
|
|
131
|
+
### 2.2 GraphQL
|
|
132
|
+
|
|
133
|
+
```graphql
|
|
134
|
+
# Schema-first design
|
|
135
|
+
type User {
|
|
136
|
+
id: ID!
|
|
137
|
+
email: String!
|
|
138
|
+
name: String
|
|
139
|
+
orders: [Order!]! @relation
|
|
140
|
+
createdAt: DateTime!
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type Query {
|
|
144
|
+
user(id: ID!): User
|
|
145
|
+
users(limit: Int = 20, offset: Int = 0): [User!]!
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
type Mutation {
|
|
149
|
+
createUser(input: CreateUserInput!): User!
|
|
150
|
+
updateUser(id: ID!, input: UpdateUserInput!): User!
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
# N+1 prevention with DataLoader
|
|
154
|
+
const userLoader = new DataLoader(async (userIds) => {
|
|
155
|
+
const users = await db.users.findMany({
|
|
156
|
+
where: { id: { in: userIds } }
|
|
157
|
+
});
|
|
158
|
+
return userIds.map(id => users.find(u => u.id === id));
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 2.3 API Versioning
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
/api/v1/users # URL versioning (recommended)
|
|
166
|
+
/api/v2/users
|
|
167
|
+
|
|
168
|
+
# or Header versioning
|
|
169
|
+
Accept: application/vnd.api+json;version=2
|
|
170
|
+
|
|
171
|
+
# Never break existing clients
|
|
172
|
+
# Deprecation: 6-12 months notice with sunset headers
|
|
173
|
+
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
|
|
174
|
+
Deprecation: true
|
|
175
|
+
Link: </api/v2/users>; rel="successor-version"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 3. Database Design
|
|
181
|
+
|
|
182
|
+
### 3.1 Schema Design
|
|
183
|
+
|
|
184
|
+
**Relational (3NF)**
|
|
185
|
+
```sql
|
|
186
|
+
-- Users table
|
|
187
|
+
CREATE TABLE users (
|
|
188
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
189
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
190
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
191
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
192
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
-- Orders with FK
|
|
196
|
+
CREATE TABLE orders (
|
|
197
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
198
|
+
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
199
|
+
total_amount DECIMAL(10,2) NOT NULL,
|
|
200
|
+
status VARCHAR(50) DEFAULT 'pending',
|
|
201
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
-- Indexes for query patterns
|
|
205
|
+
CREATE INDEX idx_orders_user_id ON orders(user_id);
|
|
206
|
+
CREATE INDEX idx_orders_status ON orders(status) WHERE status = 'pending';
|
|
207
|
+
CREATE INDEX idx_orders_created_at ON orders(created_at DESC);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Document (MongoDB)**
|
|
211
|
+
```javascript
|
|
212
|
+
// Denormalized for read-heavy access patterns
|
|
213
|
+
{
|
|
214
|
+
_id: ObjectId("..."),
|
|
215
|
+
userId: "user_123",
|
|
216
|
+
items: [
|
|
217
|
+
{ productId: "prod_1", name: "T-Shirt", price: 29.99, quantity: 2 }
|
|
218
|
+
],
|
|
219
|
+
total: 59.98,
|
|
220
|
+
status: "shipped",
|
|
221
|
+
shippingAddress: { /* embedded */ },
|
|
222
|
+
createdAt: ISODate("2024-01-15")
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 3.2 Query Optimization
|
|
227
|
+
|
|
228
|
+
```sql
|
|
229
|
+
-- EXPLAIN before optimizing
|
|
230
|
+
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 'uuid' ORDER BY created_at DESC;
|
|
231
|
+
|
|
232
|
+
-- Composite indexes for multi-column filters
|
|
233
|
+
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at DESC);
|
|
234
|
+
|
|
235
|
+
-- Partial indexes for hot data
|
|
236
|
+
CREATE INDEX idx_orders_pending ON orders(created_at) WHERE status = 'pending';
|
|
237
|
+
|
|
238
|
+
-- Covering indexes to avoid table lookups
|
|
239
|
+
CREATE INDEX idx_users_email_name ON users(email) INCLUDE (name, created_at);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 3.3 Migrations
|
|
243
|
+
|
|
244
|
+
```python
|
|
245
|
+
# Alembic (Python)
|
|
246
|
+
"""
|
|
247
|
+
Revision ID: 001_create_users
|
|
248
|
+
Create Date: 2024-01-15
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
def upgrade():
|
|
252
|
+
op.create_table(
|
|
253
|
+
'users',
|
|
254
|
+
sa.Column('id', sa.UUID(), nullable=False),
|
|
255
|
+
sa.Column('email', sa.String(), nullable=False),
|
|
256
|
+
sa.PrimaryKeyConstraint('id'),
|
|
257
|
+
sa.UniqueConstraint('email')
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def downgrade():
|
|
261
|
+
op.drop_table('users')
|
|
262
|
+
|
|
263
|
+
# Always make migrations reversible
|
|
264
|
+
# Test migrations on copy of production data before deploying
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 4. Security
|
|
270
|
+
|
|
271
|
+
### 4.1 Authentication
|
|
272
|
+
|
|
273
|
+
**JWT (Stateless)**
|
|
274
|
+
```python
|
|
275
|
+
import jwt
|
|
276
|
+
from datetime import datetime, timedelta
|
|
277
|
+
|
|
278
|
+
def create_token(user_id: str, secret: str) -> str:
|
|
279
|
+
payload = {
|
|
280
|
+
"sub": user_id,
|
|
281
|
+
"iat": datetime.utcnow(),
|
|
282
|
+
"exp": datetime.utcnow() + timedelta(hours=24),
|
|
283
|
+
"type": "access"
|
|
284
|
+
}
|
|
285
|
+
return jwt.encode(payload, secret, algorithm="HS256")
|
|
286
|
+
|
|
287
|
+
def verify_token(token: str, secret: str) -> dict:
|
|
288
|
+
try:
|
|
289
|
+
return jwt.decode(token, secret, algorithms=["HS256"])
|
|
290
|
+
except jwt.ExpiredSignatureError:
|
|
291
|
+
raise Unauthorized("Token expired")
|
|
292
|
+
except jwt.InvalidTokenError:
|
|
293
|
+
raise Unauthorized("Invalid token")
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Sessions (Stateful)**
|
|
297
|
+
```python
|
|
298
|
+
# Redis-backed sessions
|
|
299
|
+
import redis
|
|
300
|
+
|
|
301
|
+
session_store = redis.Redis(host='localhost', port=6379, db=0)
|
|
302
|
+
|
|
303
|
+
def create_session(user_id: str) -> str:
|
|
304
|
+
session_id = secrets.token_urlsafe(32)
|
|
305
|
+
session_store.setex(
|
|
306
|
+
f"session:{session_id}",
|
|
307
|
+
timedelta(days=7),
|
|
308
|
+
json.dumps({"user_id": user_id})
|
|
309
|
+
)
|
|
310
|
+
return session_id
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 4.2 Authorization (RBAC/ABAC)
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
# Role-Based Access Control
|
|
317
|
+
class RBACMiddleware:
|
|
318
|
+
def __init__(self, required_role: str):
|
|
319
|
+
self.required_role = required_role
|
|
320
|
+
|
|
321
|
+
async def __call__(self, request: Request):
|
|
322
|
+
user = request.state.user
|
|
323
|
+
|
|
324
|
+
if self.required_role not in user.roles:
|
|
325
|
+
raise Forbidden(f"Requires {self.required_role} role")
|
|
326
|
+
|
|
327
|
+
return await self.handler(request)
|
|
328
|
+
|
|
329
|
+
# Permission check decorator
|
|
330
|
+
@require_permission("orders:write")
|
|
331
|
+
async def create_order(request: Request):
|
|
332
|
+
# Only users with orders:write can access
|
|
333
|
+
pass
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 4.3 Input Validation
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
from pydantic import BaseModel, EmailStr, validator
|
|
340
|
+
import re
|
|
341
|
+
|
|
342
|
+
class CreateUserRequest(BaseModel):
|
|
343
|
+
email: EmailStr
|
|
344
|
+
password: str
|
|
345
|
+
name: str
|
|
346
|
+
|
|
347
|
+
@validator('password')
|
|
348
|
+
def validate_password(cls, v):
|
|
349
|
+
if len(v) < 12:
|
|
350
|
+
raise ValueError('Password must be at least 12 characters')
|
|
351
|
+
if not re.search(r'[A-Z]', v):
|
|
352
|
+
raise ValueError('Password must contain uppercase')
|
|
353
|
+
if not re.search(r'[a-z]', v):
|
|
354
|
+
raise ValueError('Password must contain lowercase')
|
|
355
|
+
if not re.search(r'\d', v):
|
|
356
|
+
raise ValueError('Password must contain digit')
|
|
357
|
+
return v
|
|
358
|
+
|
|
359
|
+
@validator('name')
|
|
360
|
+
def validate_name(cls, v):
|
|
361
|
+
# Prevent injection
|
|
362
|
+
if re.search(r'[<>"\']', v):
|
|
363
|
+
raise ValueError('Invalid characters in name')
|
|
364
|
+
return v.strip()
|
|
365
|
+
|
|
366
|
+
# Sanitize all inputs
|
|
367
|
+
def sanitize_input(value: str) -> str:
|
|
368
|
+
"""Remove potentially dangerous characters"""
|
|
369
|
+
return bleach.clean(value, tags=[], strip=True)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 4.4 Secrets Management
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
# NEVER: API_KEY = "sk-12345" # ❌
|
|
376
|
+
|
|
377
|
+
# ALWAYS use environment variables
|
|
378
|
+
import os
|
|
379
|
+
from pydantic import BaseSettings
|
|
380
|
+
|
|
381
|
+
class Settings(BaseSettings):
|
|
382
|
+
database_url: str
|
|
383
|
+
jwt_secret: str
|
|
384
|
+
stripe_key: str
|
|
385
|
+
|
|
386
|
+
class Config:
|
|
387
|
+
env_file = ".env"
|
|
388
|
+
env_file_encoding = "utf-8"
|
|
389
|
+
|
|
390
|
+
settings = Settings()
|
|
391
|
+
|
|
392
|
+
# Or use secret managers
|
|
393
|
+
import boto3
|
|
394
|
+
|
|
395
|
+
def get_secret(secret_name: str) -> str:
|
|
396
|
+
client = boto3.client('secretsmanager')
|
|
397
|
+
response = client.get_secret_value(SecretId=secret_name)
|
|
398
|
+
return response['SecretString']
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 5. Testing
|
|
404
|
+
|
|
405
|
+
### 5.1 Unit Tests
|
|
406
|
+
|
|
407
|
+
```python
|
|
408
|
+
import pytest
|
|
409
|
+
from unittest.mock import Mock, patch
|
|
410
|
+
|
|
411
|
+
class TestUserService:
|
|
412
|
+
def test_create_user_hashes_password(self):
|
|
413
|
+
# Arrange
|
|
414
|
+
password = "SecurePass123!"
|
|
415
|
+
|
|
416
|
+
# Act
|
|
417
|
+
user = UserService.create_user(email="test@example.com", password=password)
|
|
418
|
+
|
|
419
|
+
# Assert
|
|
420
|
+
assert user.password_hash != password
|
|
421
|
+
assert bcrypt.checkpw(password.encode(), user.password_hash)
|
|
422
|
+
|
|
423
|
+
@patch('services.email.send')
|
|
424
|
+
def test_create_user_sends_welcome_email(self, mock_send):
|
|
425
|
+
UserService.create_user(email="test@example.com", password="pass")
|
|
426
|
+
mock_send.assert_called_once_with(to="test@example.com", template="welcome")
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 5.2 Integration Tests
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
import pytest
|
|
433
|
+
from httpx import AsyncClient
|
|
434
|
+
|
|
435
|
+
@pytest.fixture
|
|
436
|
+
async def client():
|
|
437
|
+
async with AsyncClient(app=app, base_url="http://test") as client:
|
|
438
|
+
yield client
|
|
439
|
+
|
|
440
|
+
@pytest.fixture
|
|
441
|
+
async def test_user(db):
|
|
442
|
+
user = await User.create(email="test@example.com", password="hash")
|
|
443
|
+
yield user
|
|
444
|
+
await user.delete()
|
|
445
|
+
|
|
446
|
+
async def test_create_order(client, test_user, auth_headers):
|
|
447
|
+
response = await client.post(
|
|
448
|
+
"/api/v1/orders",
|
|
449
|
+
json={"items": [{"product_id": "123", "quantity": 2}]},
|
|
450
|
+
headers=auth_headers
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
assert response.status_code == 201
|
|
454
|
+
data = response.json()
|
|
455
|
+
assert data["user_id"] == str(test_user.id)
|
|
456
|
+
assert data["status"] == "pending"
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### 5.3 Contract Tests (Pact)
|
|
460
|
+
|
|
461
|
+
```python
|
|
462
|
+
# Consumer (Frontend)
|
|
463
|
+
from pact import Consumer, Provider
|
|
464
|
+
|
|
465
|
+
pact = Consumer('web-app').has_pact_with(Provider('api'))
|
|
466
|
+
|
|
467
|
+
@pact.given('user exists').upon_receiving('get user').with_request('GET', '/users/123').will_respond_with(200, body={
|
|
468
|
+
'id': '123',
|
|
469
|
+
'email': 'test@example.com'
|
|
470
|
+
})
|
|
471
|
+
def test_get_user():
|
|
472
|
+
with pact:
|
|
473
|
+
result = user_service.get_user('123')
|
|
474
|
+
assert result.email == 'test@example.com'
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## 6. Performance & Scaling
|
|
480
|
+
|
|
481
|
+
### 6.1 Caching Strategies
|
|
482
|
+
|
|
483
|
+
```python
|
|
484
|
+
import redis
|
|
485
|
+
from functools import wraps
|
|
486
|
+
|
|
487
|
+
cache = redis.Redis(host='localhost', port=6379, db=0)
|
|
488
|
+
|
|
489
|
+
def cached(ttl: int = 300):
|
|
490
|
+
def decorator(func):
|
|
491
|
+
@wraps(func)
|
|
492
|
+
async def wrapper(*args, **kwargs):
|
|
493
|
+
# Build cache key
|
|
494
|
+
cache_key = f"{func.__name__}:{hash(args)}:{hash(tuple(kwargs.items()))}"
|
|
495
|
+
|
|
496
|
+
# Try cache
|
|
497
|
+
cached_value = cache.get(cache_key)
|
|
498
|
+
if cached_value:
|
|
499
|
+
return json.loads(cached_value)
|
|
500
|
+
|
|
501
|
+
# Execute and cache
|
|
502
|
+
result = await func(*args, **kwargs)
|
|
503
|
+
cache.setex(cache_key, ttl, json.dumps(result))
|
|
504
|
+
|
|
505
|
+
return result
|
|
506
|
+
return wrapper
|
|
507
|
+
return decorator
|
|
508
|
+
|
|
509
|
+
@cached(ttl=60)
|
|
510
|
+
async def get_user(user_id: str):
|
|
511
|
+
return await db.users.find_one({"_id": user_id})
|
|
512
|
+
|
|
513
|
+
# Cache invalidation
|
|
514
|
+
async def update_user(user_id: str, data: dict):
|
|
515
|
+
await db.users.update_one({"_id": user_id}, {"$set": data})
|
|
516
|
+
cache.delete(f"get_user:{hash((user_id,))}:...")
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### 6.2 Connection Pooling
|
|
520
|
+
|
|
521
|
+
```python
|
|
522
|
+
# Database
|
|
523
|
+
from sqlalchemy import create_engine
|
|
524
|
+
|
|
525
|
+
engine = create_engine(
|
|
526
|
+
DATABASE_URL,
|
|
527
|
+
pool_size=20, # Default connections
|
|
528
|
+
max_overflow=10, # Extra under load
|
|
529
|
+
pool_timeout=30, # Wait for available
|
|
530
|
+
pool_recycle=3600, # Recycle after 1 hour
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
# HTTP clients
|
|
534
|
+
import httpx
|
|
535
|
+
|
|
536
|
+
async_client = httpx.AsyncClient(
|
|
537
|
+
limits=httpx.Limits(max_connections=100, max_keepalive_connections=20),
|
|
538
|
+
timeout=httpx.Timeout(30.0)
|
|
539
|
+
)
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 6.3 Rate Limiting
|
|
543
|
+
|
|
544
|
+
```python
|
|
545
|
+
from slowapi import Limiter
|
|
546
|
+
from slowapi.util import get_remote_address
|
|
547
|
+
|
|
548
|
+
limiter = Limiter(key_func=get_remote_address)
|
|
549
|
+
|
|
550
|
+
@app.get("/api/users")
|
|
551
|
+
@limiter.limit("100/minute") # Per IP
|
|
552
|
+
async def list_users(request: Request):
|
|
553
|
+
return await get_users()
|
|
554
|
+
|
|
555
|
+
@app.post("/api/login")
|
|
556
|
+
@limiter.limit("5/minute") # Stricter for auth
|
|
557
|
+
async def login(request: Request):
|
|
558
|
+
return await authenticate(request)
|
|
559
|
+
|
|
560
|
+
# User-specific limits
|
|
561
|
+
@limiter.limit(lambda: f"{current_user.id}:1000/hour")
|
|
562
|
+
async def api_endpoint():
|
|
563
|
+
pass
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## 7. Observability
|
|
569
|
+
|
|
570
|
+
### 7.1 Structured Logging
|
|
571
|
+
|
|
572
|
+
```python
|
|
573
|
+
import structlog
|
|
574
|
+
import logging
|
|
575
|
+
|
|
576
|
+
structlog.configure(
|
|
577
|
+
processors=[
|
|
578
|
+
structlog.stdlib.filter_by_level,
|
|
579
|
+
structlog.stdlib.add_logger_name,
|
|
580
|
+
structlog.stdlib.add_log_level,
|
|
581
|
+
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
582
|
+
structlog.processors.TimeStamper(fmt="iso"),
|
|
583
|
+
structlog.processors.StackInfoRenderer(),
|
|
584
|
+
structlog.processors.format_exc_info,
|
|
585
|
+
structlog.processors.UnicodeDecoder(),
|
|
586
|
+
structlog.processors.JSONRenderer()
|
|
587
|
+
],
|
|
588
|
+
context_class=dict,
|
|
589
|
+
logger_factory=structlog.stdlib.LoggerFactory(),
|
|
590
|
+
wrapper_class=structlog.stdlib.BoundLogger,
|
|
591
|
+
cache_logger_on_first_use=True,
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
logger = structlog.get_logger()
|
|
595
|
+
|
|
596
|
+
# Usage
|
|
597
|
+
logger.info(
|
|
598
|
+
"order_created",
|
|
599
|
+
order_id=order.id,
|
|
600
|
+
user_id=user.id,
|
|
601
|
+
amount=order.total,
|
|
602
|
+
items_count=len(order.items)
|
|
603
|
+
)
|
|
604
|
+
# {"event": "order_created", "order_id": "...", "user_id": "...", ...}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### 7.2 Distributed Tracing
|
|
608
|
+
|
|
609
|
+
```python
|
|
610
|
+
from opentelemetry import trace
|
|
611
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
|
612
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
613
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
614
|
+
|
|
615
|
+
trace.set_tracer_provider(TracerProvider())
|
|
616
|
+
tracer = trace.get_tracer(__name__)
|
|
617
|
+
|
|
618
|
+
otlp_exporter = OTLPSpanExporter(endpoint="http://jaeger:4317")
|
|
619
|
+
span_processor = BatchSpanProcessor(otlp_exporter)
|
|
620
|
+
trace.get_tracer_provider().add_span_processor(span_processor)
|
|
621
|
+
|
|
622
|
+
@app.get("/api/orders/{order_id}")
|
|
623
|
+
async def get_order(order_id: str):
|
|
624
|
+
with tracer.start_as_current_span("get_order") as span:
|
|
625
|
+
span.set_attribute("order.id", order_id)
|
|
626
|
+
|
|
627
|
+
with tracer.start_as_current_span("fetch_from_db"):
|
|
628
|
+
order = await db.orders.find_one({"_id": order_id})
|
|
629
|
+
|
|
630
|
+
with tracer.start_as_current_span("enrich_data"):
|
|
631
|
+
order.items = await fetch_items(order.item_ids)
|
|
632
|
+
|
|
633
|
+
return order
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
### 7.3 Health Checks
|
|
637
|
+
|
|
638
|
+
```python
|
|
639
|
+
from fastapi import FastAPI
|
|
640
|
+
from pydantic import BaseModel
|
|
641
|
+
|
|
642
|
+
class HealthStatus(BaseModel):
|
|
643
|
+
status: str
|
|
644
|
+
version: str
|
|
645
|
+
checks: dict
|
|
646
|
+
|
|
647
|
+
@app.get("/health", response_model=HealthStatus)
|
|
648
|
+
async def health_check():
|
|
649
|
+
checks = {
|
|
650
|
+
"database": await check_database(),
|
|
651
|
+
"cache": await check_cache(),
|
|
652
|
+
"queue": await check_queue()
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
all_healthy = all(c["status"] == "ok" for c in checks.values())
|
|
656
|
+
|
|
657
|
+
return HealthStatus(
|
|
658
|
+
status="healthy" if all_healthy else "degraded",
|
|
659
|
+
version=APP_VERSION,
|
|
660
|
+
checks=checks
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
async def check_database():
|
|
664
|
+
try:
|
|
665
|
+
await db.execute("SELECT 1")
|
|
666
|
+
return {"status": "ok", "latency_ms": 5}
|
|
667
|
+
except Exception as e:
|
|
668
|
+
return {"status": "error", "message": str(e)}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## 8. Error Handling
|
|
674
|
+
|
|
675
|
+
### 8.1 Exception Hierarchy
|
|
676
|
+
|
|
677
|
+
```python
|
|
678
|
+
class AppException(Exception):
|
|
679
|
+
"""Base application exception"""
|
|
680
|
+
status_code = 500
|
|
681
|
+
error_code = "internal_error"
|
|
682
|
+
|
|
683
|
+
def __init__(self, message: str, details: dict = None):
|
|
684
|
+
self.message = message
|
|
685
|
+
self.details = details or {}
|
|
686
|
+
|
|
687
|
+
class ValidationError(AppException):
|
|
688
|
+
status_code = 400
|
|
689
|
+
error_code = "validation_error"
|
|
690
|
+
|
|
691
|
+
class NotFoundError(AppException):
|
|
692
|
+
status_code = 404
|
|
693
|
+
error_code = "not_found"
|
|
694
|
+
|
|
695
|
+
class ConflictError(AppException):
|
|
696
|
+
status_code = 409
|
|
697
|
+
error_code = "conflict"
|
|
698
|
+
|
|
699
|
+
# Error handler
|
|
700
|
+
@app.exception_handler(AppException)
|
|
701
|
+
async def app_exception_handler(request: Request, exc: AppException):
|
|
702
|
+
return JSONResponse(
|
|
703
|
+
status_code=exc.status_code,
|
|
704
|
+
content={
|
|
705
|
+
"error": exc.error_code,
|
|
706
|
+
"message": exc.message,
|
|
707
|
+
"details": exc.details,
|
|
708
|
+
"request_id": request.state.request_id
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
### 8.2 Global Error Handling
|
|
714
|
+
|
|
715
|
+
```python
|
|
716
|
+
@app.middleware("http")
|
|
717
|
+
async def error_handling_middleware(request: Request, call_next):
|
|
718
|
+
request_id = str(uuid.uuid4())
|
|
719
|
+
request.state.request_id = request_id
|
|
720
|
+
|
|
721
|
+
try:
|
|
722
|
+
response = await call_next(request)
|
|
723
|
+
response.headers["X-Request-ID"] = request_id
|
|
724
|
+
return response
|
|
725
|
+
|
|
726
|
+
except Exception as e:
|
|
727
|
+
logger.exception("Unhandled error", request_id=request_id, path=request.url.path)
|
|
728
|
+
|
|
729
|
+
return JSONResponse(
|
|
730
|
+
status_code=500,
|
|
731
|
+
content={
|
|
732
|
+
"error": "internal_error",
|
|
733
|
+
"message": "An unexpected error occurred",
|
|
734
|
+
"request_id": request_id # For debugging, not in production
|
|
735
|
+
}
|
|
736
|
+
)
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
## 9. Stack-Specific Guides
|
|
742
|
+
|
|
743
|
+
| Stack | Reference |
|
|
744
|
+
|:------|:----------|
|
|
745
|
+
| Node.js (Express) | `references/node-express.md` |
|
|
746
|
+
| Node.js (NestJS) | `references/node-nestjs.md` |
|
|
747
|
+
| Python (FastAPI) | `references/python-fastapi.md` |
|
|
748
|
+
| Python (Django) | `references/python-django.md` |
|
|
749
|
+
| Go (Gin/Echo) | `references/go-gin.md`, `references/go-echo.md` |
|
|
750
|
+
| Java (Spring Boot) | `references/java-springboot.md` |
|
|
751
|
+
| General Patterns | `references/general-patterns.md` |
|
|
752
|
+
|
|
753
|
+
## Related Skills
|
|
754
|
+
|
|
755
|
+
- [[ai-engineer]] — LLM/AI integration patterns
|
|
756
|
+
- [[devops-engineer]] — Deployment and infrastructure
|
|
757
|
+
- [[frontend-developer]] — Fullstack development
|
|
758
|
+
- [[blockchain-engineer]] — Web3 and smart contract integration
|
|
759
|
+
- [[lead-architect]] — System design and architecture decisions
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
*Part of [[web-development-moc]] | Foundation for AI, DevOps, and Blockchain*
|