moai-adk 0.35.1__py3-none-any.whl
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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +10 -0
- moai_adk/__main__.py +199 -0
- moai_adk/cli/__init__.py +6 -0
- moai_adk/cli/commands/__init__.py +17 -0
- moai_adk/cli/commands/analyze.py +116 -0
- moai_adk/cli/commands/doctor.py +272 -0
- moai_adk/cli/commands/init.py +372 -0
- moai_adk/cli/commands/language.py +248 -0
- moai_adk/cli/commands/status.py +104 -0
- moai_adk/cli/commands/update.py +2686 -0
- moai_adk/cli/main.py +13 -0
- moai_adk/cli/prompts/__init__.py +5 -0
- moai_adk/cli/prompts/init_prompts.py +219 -0
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +683 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +493 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +422 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/__init__.py +1 -0
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +400 -0
- moai_adk/core/claude_integration.py +393 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/__init__.py +19 -0
- moai_adk/core/config/auto_spec_config.py +340 -0
- moai_adk/core/config/migration.py +244 -0
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/diagnostics/__init__.py +19 -0
- moai_adk/core/diagnostics/slash_commands.py +159 -0
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +1902 -0
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +31 -0
- moai_adk/core/git/branch.py +25 -0
- moai_adk/core/git/branch_manager.py +129 -0
- moai_adk/core/git/checkpoint.py +134 -0
- moai_adk/core/git/commit.py +67 -0
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/event_detector.py +79 -0
- moai_adk/core/git/manager.py +216 -0
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +157 -0
- moai_adk/core/integration/integration_tester.py +226 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +305 -0
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_config_resolver.py +572 -0
- moai_adk/core/language_validator.py +543 -0
- moai_adk/core/mcp/setup.py +116 -0
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +605 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +277 -0
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +209 -0
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +139 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +316 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/__init__.py +1 -0
- moai_adk/core/project/backup_utils.py +70 -0
- moai_adk/core/project/checker.py +300 -0
- moai_adk/core/project/detector.py +293 -0
- moai_adk/core/project/initializer.py +387 -0
- moai_adk/core/project/phase_executor.py +716 -0
- moai_adk/core/project/validator.py +139 -0
- moai_adk/core/quality/__init__.py +6 -0
- moai_adk/core/quality/trust_checker.py +377 -0
- moai_adk/core/quality/validators/__init__.py +6 -0
- moai_adk/core/quality/validators/base_validator.py +19 -0
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +918 -0
- moai_adk/core/session_manager.py +651 -0
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +680 -0
- moai_adk/core/spec/ears_template_engine.py +1247 -0
- moai_adk/core/spec/quality_validator.py +687 -0
- moai_adk/core/spec_status_manager.py +478 -0
- moai_adk/core/template/__init__.py +7 -0
- moai_adk/core/template/backup.py +174 -0
- moai_adk/core/template/config.py +191 -0
- moai_adk/core/template/languages.py +43 -0
- moai_adk/core/template/merger.py +233 -0
- moai_adk/core/template/processor.py +1200 -0
- moai_adk/core/template_engine.py +310 -0
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +557 -0
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +676 -0
- moai_adk/foundation/trust/validation_checklist.py +1573 -0
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +105 -0
- moai_adk/statusline/config.py +376 -0
- moai_adk/statusline/enhanced_output_style_detector.py +372 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +322 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +343 -0
- moai_adk/statusline/update_checker.py +129 -0
- moai_adk/statusline/version_reader.py +741 -0
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
- moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
- moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
- moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +128 -0
- moai_adk/templates/.git-hooks/pre-push +365 -0
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
- moai_adk/templates/.gitignore +222 -0
- moai_adk/templates/.mcp.json +13 -0
- moai_adk/templates/.moai/config/config.yaml +58 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
- moai_adk/templates/.moai/config/sections/system.yaml +24 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +642 -0
- moai_adk/utils/__init__.py +30 -0
- moai_adk/utils/banner.py +38 -0
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +241 -0
- moai_adk/utils/logger.py +147 -0
- moai_adk/utils/safe_file_reader.py +206 -0
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.35.1.dist-info/METADATA +3018 -0
- moai_adk-0.35.1.dist-info/RECORD +502 -0
- moai_adk-0.35.1.dist-info/WHEEL +4 -0
- moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
- moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
# Backend Development Examples
|
|
2
|
+
|
|
3
|
+
Multishot prompting examples demonstrating practical backend development patterns covering API design, database integration, microservices, and security.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Example 1: RESTful API with Authentication
|
|
8
|
+
|
|
9
|
+
**Scenario**: Create a secure user management API with JWT authentication.
|
|
10
|
+
|
|
11
|
+
**Input**:
|
|
12
|
+
```python
|
|
13
|
+
from fastapi import FastAPI, Depends, HTTPException, status
|
|
14
|
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
15
|
+
from pydantic import BaseModel, EmailStr
|
|
16
|
+
from typing import List
|
|
17
|
+
import jwt
|
|
18
|
+
from datetime import datetime, timedelta
|
|
19
|
+
|
|
20
|
+
app = FastAPI(title="User Management API", version="1.0.0")
|
|
21
|
+
security = HTTPBearer()
|
|
22
|
+
|
|
23
|
+
# Models
|
|
24
|
+
class UserCreate(BaseModel):
|
|
25
|
+
email: EmailStr
|
|
26
|
+
password: str
|
|
27
|
+
name: str
|
|
28
|
+
|
|
29
|
+
class UserResponse(BaseModel):
|
|
30
|
+
id: int
|
|
31
|
+
email: str
|
|
32
|
+
name: str
|
|
33
|
+
created_at: datetime
|
|
34
|
+
|
|
35
|
+
class TokenResponse(BaseModel):
|
|
36
|
+
access_token: str
|
|
37
|
+
token_type: str
|
|
38
|
+
expires_in: int
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Output**:
|
|
42
|
+
```python
|
|
43
|
+
# Complete implementation with authentication
|
|
44
|
+
SECRET_KEY = "your-secret-key" # Use environment variable in production
|
|
45
|
+
ALGORITHM = "HS256"
|
|
46
|
+
|
|
47
|
+
def create_access_token(user_id: int) -> str:
|
|
48
|
+
expire = datetime.utcnow() + timedelta(hours=24)
|
|
49
|
+
payload = {"sub": str(user_id), "exp": expire}
|
|
50
|
+
return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
|
|
51
|
+
|
|
52
|
+
async def get_current_user(
|
|
53
|
+
credentials: HTTPAuthorizationCredentials = Depends(security)
|
|
54
|
+
) -> int:
|
|
55
|
+
try:
|
|
56
|
+
payload = jwt.decode(
|
|
57
|
+
credentials.credentials,
|
|
58
|
+
SECRET_KEY,
|
|
59
|
+
algorithms=[ALGORITHM]
|
|
60
|
+
)
|
|
61
|
+
user_id = int(payload.get("sub"))
|
|
62
|
+
return user_id
|
|
63
|
+
except jwt.ExpiredSignatureError:
|
|
64
|
+
raise HTTPException(
|
|
65
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
66
|
+
detail="Token has expired"
|
|
67
|
+
)
|
|
68
|
+
except jwt.InvalidTokenError:
|
|
69
|
+
raise HTTPException(
|
|
70
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
71
|
+
detail="Invalid token"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@app.post("/auth/login", response_model=TokenResponse)
|
|
75
|
+
async def login(email: str, password: str):
|
|
76
|
+
user = await user_service.authenticate(email, password)
|
|
77
|
+
if not user:
|
|
78
|
+
raise HTTPException(
|
|
79
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
80
|
+
detail="Invalid credentials"
|
|
81
|
+
)
|
|
82
|
+
token = create_access_token(user.id)
|
|
83
|
+
return TokenResponse(
|
|
84
|
+
access_token=token,
|
|
85
|
+
token_type="bearer",
|
|
86
|
+
expires_in=86400
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
@app.get("/users/me", response_model=UserResponse)
|
|
90
|
+
async def get_current_user_profile(
|
|
91
|
+
user_id: int = Depends(get_current_user)
|
|
92
|
+
):
|
|
93
|
+
user = await user_service.get_by_id(user_id)
|
|
94
|
+
return user
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Explanation**: This pattern demonstrates secure JWT authentication with proper error handling, token expiration, and dependency injection for protected routes.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Example 2: Database Repository Pattern with Caching
|
|
102
|
+
|
|
103
|
+
**Scenario**: Implement a repository pattern with Redis caching for optimal performance.
|
|
104
|
+
|
|
105
|
+
**Input**:
|
|
106
|
+
```python
|
|
107
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
108
|
+
from sqlalchemy import select
|
|
109
|
+
import redis.asyncio as redis
|
|
110
|
+
import json
|
|
111
|
+
from typing import Optional, List
|
|
112
|
+
|
|
113
|
+
class UserRepository:
|
|
114
|
+
def __init__(
|
|
115
|
+
self,
|
|
116
|
+
session: AsyncSession,
|
|
117
|
+
cache: redis.Redis
|
|
118
|
+
):
|
|
119
|
+
self.session = session
|
|
120
|
+
self.cache = cache
|
|
121
|
+
self.cache_ttl = 3600 # 1 hour
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Output**:
|
|
125
|
+
```python
|
|
126
|
+
class UserRepository:
|
|
127
|
+
def __init__(
|
|
128
|
+
self,
|
|
129
|
+
session: AsyncSession,
|
|
130
|
+
cache: redis.Redis
|
|
131
|
+
):
|
|
132
|
+
self.session = session
|
|
133
|
+
self.cache = cache
|
|
134
|
+
self.cache_ttl = 3600
|
|
135
|
+
|
|
136
|
+
async def get_by_id(self, user_id: int) -> Optional[User]:
|
|
137
|
+
# Try cache first
|
|
138
|
+
cache_key = f"user:{user_id}"
|
|
139
|
+
cached = await self.cache.get(cache_key)
|
|
140
|
+
|
|
141
|
+
if cached:
|
|
142
|
+
return User(**json.loads(cached))
|
|
143
|
+
|
|
144
|
+
# Query database
|
|
145
|
+
result = await self.session.execute(
|
|
146
|
+
select(User).where(User.id == user_id)
|
|
147
|
+
)
|
|
148
|
+
user = result.scalar_one_or_none()
|
|
149
|
+
|
|
150
|
+
if user:
|
|
151
|
+
# Cache the result
|
|
152
|
+
await self.cache.setex(
|
|
153
|
+
cache_key,
|
|
154
|
+
self.cache_ttl,
|
|
155
|
+
json.dumps(user.to_dict())
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
return user
|
|
159
|
+
|
|
160
|
+
async def get_all(
|
|
161
|
+
self,
|
|
162
|
+
skip: int = 0,
|
|
163
|
+
limit: int = 100
|
|
164
|
+
) -> List[User]:
|
|
165
|
+
result = await self.session.execute(
|
|
166
|
+
select(User)
|
|
167
|
+
.offset(skip)
|
|
168
|
+
.limit(limit)
|
|
169
|
+
.order_by(User.created_at.desc())
|
|
170
|
+
)
|
|
171
|
+
return result.scalars().all()
|
|
172
|
+
|
|
173
|
+
async def create(self, user_data: UserCreate) -> User:
|
|
174
|
+
user = User(**user_data.model_dump())
|
|
175
|
+
self.session.add(user)
|
|
176
|
+
await self.session.commit()
|
|
177
|
+
await self.session.refresh(user)
|
|
178
|
+
|
|
179
|
+
# Invalidate list cache
|
|
180
|
+
await self.cache.delete("users:list:*")
|
|
181
|
+
|
|
182
|
+
return user
|
|
183
|
+
|
|
184
|
+
async def update(
|
|
185
|
+
self,
|
|
186
|
+
user_id: int,
|
|
187
|
+
user_data: UserUpdate
|
|
188
|
+
) -> Optional[User]:
|
|
189
|
+
user = await self.get_by_id(user_id)
|
|
190
|
+
if not user:
|
|
191
|
+
return None
|
|
192
|
+
|
|
193
|
+
for key, value in user_data.model_dump(exclude_unset=True).items():
|
|
194
|
+
setattr(user, key, value)
|
|
195
|
+
|
|
196
|
+
await self.session.commit()
|
|
197
|
+
|
|
198
|
+
# Invalidate cache
|
|
199
|
+
await self.cache.delete(f"user:{user_id}")
|
|
200
|
+
|
|
201
|
+
return user
|
|
202
|
+
|
|
203
|
+
async def delete(self, user_id: int) -> bool:
|
|
204
|
+
user = await self.get_by_id(user_id)
|
|
205
|
+
if not user:
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
await self.session.delete(user)
|
|
209
|
+
await self.session.commit()
|
|
210
|
+
|
|
211
|
+
# Invalidate cache
|
|
212
|
+
await self.cache.delete(f"user:{user_id}")
|
|
213
|
+
|
|
214
|
+
return True
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Explanation**: The repository pattern encapsulates data access logic with Redis caching for read operations and automatic cache invalidation on writes.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Example 3: Event-Driven Microservice Architecture
|
|
222
|
+
|
|
223
|
+
**Scenario**: Implement an order processing service with event-driven communication.
|
|
224
|
+
|
|
225
|
+
**Input**:
|
|
226
|
+
```python
|
|
227
|
+
from aio_pika import connect_robust, Message, ExchangeType
|
|
228
|
+
import json
|
|
229
|
+
from dataclasses import dataclass
|
|
230
|
+
from datetime import datetime
|
|
231
|
+
from typing import Optional
|
|
232
|
+
|
|
233
|
+
@dataclass
|
|
234
|
+
class OrderCreatedEvent:
|
|
235
|
+
order_id: str
|
|
236
|
+
user_id: int
|
|
237
|
+
total_amount: float
|
|
238
|
+
items: list
|
|
239
|
+
created_at: datetime
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Output**:
|
|
243
|
+
```python
|
|
244
|
+
import asyncio
|
|
245
|
+
from aio_pika import connect_robust, Message, ExchangeType
|
|
246
|
+
import json
|
|
247
|
+
from dataclasses import dataclass, asdict
|
|
248
|
+
from datetime import datetime
|
|
249
|
+
from typing import Optional, Callable, Dict
|
|
250
|
+
import logging
|
|
251
|
+
|
|
252
|
+
logger = logging.getLogger(__name__)
|
|
253
|
+
|
|
254
|
+
@dataclass
|
|
255
|
+
class OrderCreatedEvent:
|
|
256
|
+
order_id: str
|
|
257
|
+
user_id: int
|
|
258
|
+
total_amount: float
|
|
259
|
+
items: list
|
|
260
|
+
created_at: datetime
|
|
261
|
+
|
|
262
|
+
class EventBus:
|
|
263
|
+
def __init__(self, amqp_url: str):
|
|
264
|
+
self.amqp_url = amqp_url
|
|
265
|
+
self.connection = None
|
|
266
|
+
self.channel = None
|
|
267
|
+
self.exchange = None
|
|
268
|
+
self.handlers: Dict[str, Callable] = {}
|
|
269
|
+
|
|
270
|
+
async def connect(self):
|
|
271
|
+
self.connection = await connect_robust(self.amqp_url)
|
|
272
|
+
self.channel = await self.connection.channel()
|
|
273
|
+
self.exchange = await self.channel.declare_exchange(
|
|
274
|
+
"events",
|
|
275
|
+
ExchangeType.TOPIC,
|
|
276
|
+
durable=True
|
|
277
|
+
)
|
|
278
|
+
logger.info("Connected to message broker")
|
|
279
|
+
|
|
280
|
+
async def publish(self, event_type: str, event_data: dict):
|
|
281
|
+
message = Message(
|
|
282
|
+
json.dumps({
|
|
283
|
+
"type": event_type,
|
|
284
|
+
"data": event_data,
|
|
285
|
+
"timestamp": datetime.utcnow().isoformat()
|
|
286
|
+
}).encode(),
|
|
287
|
+
content_type="application/json",
|
|
288
|
+
delivery_mode=2 # Persistent
|
|
289
|
+
)
|
|
290
|
+
await self.exchange.publish(message, routing_key=event_type)
|
|
291
|
+
logger.info(f"Published event: {event_type}")
|
|
292
|
+
|
|
293
|
+
async def subscribe(
|
|
294
|
+
self,
|
|
295
|
+
event_type: str,
|
|
296
|
+
handler: Callable,
|
|
297
|
+
queue_name: str
|
|
298
|
+
):
|
|
299
|
+
queue = await self.channel.declare_queue(
|
|
300
|
+
queue_name,
|
|
301
|
+
durable=True
|
|
302
|
+
)
|
|
303
|
+
await queue.bind(self.exchange, routing_key=event_type)
|
|
304
|
+
|
|
305
|
+
async def process_message(message):
|
|
306
|
+
async with message.process():
|
|
307
|
+
try:
|
|
308
|
+
data = json.loads(message.body.decode())
|
|
309
|
+
await handler(data)
|
|
310
|
+
except Exception as e:
|
|
311
|
+
logger.error(f"Error processing message: {e}")
|
|
312
|
+
raise
|
|
313
|
+
|
|
314
|
+
await queue.consume(process_message)
|
|
315
|
+
logger.info(f"Subscribed to: {event_type}")
|
|
316
|
+
|
|
317
|
+
class OrderService:
|
|
318
|
+
def __init__(self, event_bus: EventBus, db_session):
|
|
319
|
+
self.event_bus = event_bus
|
|
320
|
+
self.db = db_session
|
|
321
|
+
|
|
322
|
+
async def create_order(self, order_data: dict) -> Order:
|
|
323
|
+
# Create order in database
|
|
324
|
+
order = Order(**order_data)
|
|
325
|
+
self.db.add(order)
|
|
326
|
+
await self.db.commit()
|
|
327
|
+
|
|
328
|
+
# Publish event
|
|
329
|
+
event = OrderCreatedEvent(
|
|
330
|
+
order_id=str(order.id),
|
|
331
|
+
user_id=order.user_id,
|
|
332
|
+
total_amount=order.total_amount,
|
|
333
|
+
items=order.items,
|
|
334
|
+
created_at=order.created_at
|
|
335
|
+
)
|
|
336
|
+
await self.event_bus.publish(
|
|
337
|
+
"order.created",
|
|
338
|
+
asdict(event)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return order
|
|
342
|
+
|
|
343
|
+
class NotificationService:
|
|
344
|
+
def __init__(self, event_bus: EventBus):
|
|
345
|
+
self.event_bus = event_bus
|
|
346
|
+
|
|
347
|
+
async def start(self):
|
|
348
|
+
await self.event_bus.subscribe(
|
|
349
|
+
"order.created",
|
|
350
|
+
self.handle_order_created,
|
|
351
|
+
"notification-service-orders"
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
async def handle_order_created(self, event_data: dict):
|
|
355
|
+
order_data = event_data["data"]
|
|
356
|
+
user_id = order_data["user_id"]
|
|
357
|
+
order_id = order_data["order_id"]
|
|
358
|
+
|
|
359
|
+
# Send notification
|
|
360
|
+
await self.send_email(
|
|
361
|
+
user_id=user_id,
|
|
362
|
+
subject=f"Order {order_id} Confirmed",
|
|
363
|
+
body=f"Your order for ${order_data['total_amount']} has been confirmed."
|
|
364
|
+
)
|
|
365
|
+
logger.info(f"Sent order confirmation for {order_id}")
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Explanation**: This pattern demonstrates event-driven architecture with RabbitMQ, enabling loose coupling between services and reliable message delivery.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Common Patterns
|
|
373
|
+
|
|
374
|
+
### Pattern 1: Circuit Breaker for External Services
|
|
375
|
+
|
|
376
|
+
Protect your service from cascading failures:
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
from tenacity import (
|
|
380
|
+
retry,
|
|
381
|
+
stop_after_attempt,
|
|
382
|
+
wait_exponential,
|
|
383
|
+
retry_if_exception_type
|
|
384
|
+
)
|
|
385
|
+
import httpx
|
|
386
|
+
from dataclasses import dataclass
|
|
387
|
+
from datetime import datetime, timedelta
|
|
388
|
+
|
|
389
|
+
@dataclass
|
|
390
|
+
class CircuitBreakerState:
|
|
391
|
+
failures: int = 0
|
|
392
|
+
last_failure: datetime = None
|
|
393
|
+
is_open: bool = False
|
|
394
|
+
|
|
395
|
+
class CircuitBreaker:
|
|
396
|
+
def __init__(
|
|
397
|
+
self,
|
|
398
|
+
failure_threshold: int = 5,
|
|
399
|
+
recovery_timeout: int = 30
|
|
400
|
+
):
|
|
401
|
+
self.failure_threshold = failure_threshold
|
|
402
|
+
self.recovery_timeout = timedelta(seconds=recovery_timeout)
|
|
403
|
+
self.state = CircuitBreakerState()
|
|
404
|
+
|
|
405
|
+
def can_execute(self) -> bool:
|
|
406
|
+
if not self.state.is_open:
|
|
407
|
+
return True
|
|
408
|
+
|
|
409
|
+
if datetime.utcnow() - self.state.last_failure > self.recovery_timeout:
|
|
410
|
+
self.state.is_open = False
|
|
411
|
+
self.state.failures = 0
|
|
412
|
+
return True
|
|
413
|
+
|
|
414
|
+
return False
|
|
415
|
+
|
|
416
|
+
def record_failure(self):
|
|
417
|
+
self.state.failures += 1
|
|
418
|
+
self.state.last_failure = datetime.utcnow()
|
|
419
|
+
|
|
420
|
+
if self.state.failures >= self.failure_threshold:
|
|
421
|
+
self.state.is_open = True
|
|
422
|
+
|
|
423
|
+
def record_success(self):
|
|
424
|
+
self.state.failures = 0
|
|
425
|
+
self.state.is_open = False
|
|
426
|
+
|
|
427
|
+
class ExternalPaymentService:
|
|
428
|
+
def __init__(self, base_url: str):
|
|
429
|
+
self.base_url = base_url
|
|
430
|
+
self.circuit_breaker = CircuitBreaker()
|
|
431
|
+
self.client = httpx.AsyncClient()
|
|
432
|
+
|
|
433
|
+
@retry(
|
|
434
|
+
stop=stop_after_attempt(3),
|
|
435
|
+
wait=wait_exponential(multiplier=1, min=1, max=10),
|
|
436
|
+
retry=retry_if_exception_type(httpx.TransportError)
|
|
437
|
+
)
|
|
438
|
+
async def process_payment(self, payment_data: dict) -> dict:
|
|
439
|
+
if not self.circuit_breaker.can_execute():
|
|
440
|
+
raise ServiceUnavailableError("Payment service circuit open")
|
|
441
|
+
|
|
442
|
+
try:
|
|
443
|
+
response = await self.client.post(
|
|
444
|
+
f"{self.base_url}/payments",
|
|
445
|
+
json=payment_data,
|
|
446
|
+
timeout=10.0
|
|
447
|
+
)
|
|
448
|
+
response.raise_for_status()
|
|
449
|
+
self.circuit_breaker.record_success()
|
|
450
|
+
return response.json()
|
|
451
|
+
except Exception as e:
|
|
452
|
+
self.circuit_breaker.record_failure()
|
|
453
|
+
raise
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Pattern 2: Request Validation Middleware
|
|
457
|
+
|
|
458
|
+
Comprehensive request validation:
|
|
459
|
+
|
|
460
|
+
```python
|
|
461
|
+
from fastapi import Request, HTTPException
|
|
462
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
463
|
+
from pydantic import ValidationError
|
|
464
|
+
import time
|
|
465
|
+
import logging
|
|
466
|
+
|
|
467
|
+
logger = logging.getLogger(__name__)
|
|
468
|
+
|
|
469
|
+
class RequestValidationMiddleware(BaseHTTPMiddleware):
|
|
470
|
+
async def dispatch(self, request: Request, call_next):
|
|
471
|
+
start_time = time.time()
|
|
472
|
+
request_id = request.headers.get("X-Request-ID", str(uuid.uuid4()))
|
|
473
|
+
|
|
474
|
+
# Add request ID to context
|
|
475
|
+
request.state.request_id = request_id
|
|
476
|
+
|
|
477
|
+
# Log incoming request
|
|
478
|
+
logger.info(f"[{request_id}] {request.method} {request.url.path}")
|
|
479
|
+
|
|
480
|
+
try:
|
|
481
|
+
response = await call_next(request)
|
|
482
|
+
|
|
483
|
+
# Add response headers
|
|
484
|
+
response.headers["X-Request-ID"] = request_id
|
|
485
|
+
response.headers["X-Response-Time"] = str(time.time() - start_time)
|
|
486
|
+
|
|
487
|
+
logger.info(
|
|
488
|
+
f"[{request_id}] Completed {response.status_code} "
|
|
489
|
+
f"in {time.time() - start_time:.3f}s"
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
return response
|
|
493
|
+
|
|
494
|
+
except ValidationError as e:
|
|
495
|
+
logger.warning(f"[{request_id}] Validation error: {e}")
|
|
496
|
+
raise HTTPException(status_code=422, detail=e.errors())
|
|
497
|
+
except Exception as e:
|
|
498
|
+
logger.error(f"[{request_id}] Unexpected error: {e}")
|
|
499
|
+
raise
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Pattern 3: Database Connection Pool Management
|
|
503
|
+
|
|
504
|
+
Optimized database connections:
|
|
505
|
+
|
|
506
|
+
```python
|
|
507
|
+
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
508
|
+
from sqlalchemy.orm import sessionmaker
|
|
509
|
+
from sqlalchemy.pool import QueuePool
|
|
510
|
+
from contextlib import asynccontextmanager
|
|
511
|
+
|
|
512
|
+
class DatabaseManager:
|
|
513
|
+
def __init__(self, database_url: str):
|
|
514
|
+
self.engine = create_async_engine(
|
|
515
|
+
database_url,
|
|
516
|
+
poolclass=QueuePool,
|
|
517
|
+
pool_size=20,
|
|
518
|
+
max_overflow=30,
|
|
519
|
+
pool_pre_ping=True,
|
|
520
|
+
pool_recycle=3600,
|
|
521
|
+
echo=False
|
|
522
|
+
)
|
|
523
|
+
self.async_session = sessionmaker(
|
|
524
|
+
self.engine,
|
|
525
|
+
class_=AsyncSession,
|
|
526
|
+
expire_on_commit=False
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
@asynccontextmanager
|
|
530
|
+
async def get_session(self):
|
|
531
|
+
session = self.async_session()
|
|
532
|
+
try:
|
|
533
|
+
yield session
|
|
534
|
+
await session.commit()
|
|
535
|
+
except Exception:
|
|
536
|
+
await session.rollback()
|
|
537
|
+
raise
|
|
538
|
+
finally:
|
|
539
|
+
await session.close()
|
|
540
|
+
|
|
541
|
+
async def health_check(self) -> bool:
|
|
542
|
+
try:
|
|
543
|
+
async with self.get_session() as session:
|
|
544
|
+
await session.execute("SELECT 1")
|
|
545
|
+
return True
|
|
546
|
+
except Exception:
|
|
547
|
+
return False
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## Anti-Patterns (Patterns to Avoid)
|
|
553
|
+
|
|
554
|
+
### Anti-Pattern 1: N+1 Query Problem
|
|
555
|
+
|
|
556
|
+
**Problem**: Making individual database queries for related entities.
|
|
557
|
+
|
|
558
|
+
```python
|
|
559
|
+
# Incorrect approach
|
|
560
|
+
async def get_orders_with_items():
|
|
561
|
+
orders = await session.execute(select(Order))
|
|
562
|
+
for order in orders.scalars():
|
|
563
|
+
# N+1 problem: one query per order
|
|
564
|
+
items = await session.execute(
|
|
565
|
+
select(OrderItem).where(OrderItem.order_id == order.id)
|
|
566
|
+
)
|
|
567
|
+
order.items = items.scalars().all()
|
|
568
|
+
return orders
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Solution**: Use eager loading with joins.
|
|
572
|
+
|
|
573
|
+
```python
|
|
574
|
+
# Correct approach
|
|
575
|
+
async def get_orders_with_items():
|
|
576
|
+
result = await session.execute(
|
|
577
|
+
select(Order)
|
|
578
|
+
.options(selectinload(Order.items))
|
|
579
|
+
.order_by(Order.created_at.desc())
|
|
580
|
+
)
|
|
581
|
+
return result.scalars().all()
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Anti-Pattern 2: Synchronous Operations in Async Context
|
|
585
|
+
|
|
586
|
+
**Problem**: Blocking the event loop with synchronous operations.
|
|
587
|
+
|
|
588
|
+
```python
|
|
589
|
+
# Incorrect approach
|
|
590
|
+
@app.get("/data")
|
|
591
|
+
async def get_data():
|
|
592
|
+
# This blocks the event loop!
|
|
593
|
+
data = requests.get("https://api.example.com/data")
|
|
594
|
+
return data.json()
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Solution**: Use async-compatible libraries.
|
|
598
|
+
|
|
599
|
+
```python
|
|
600
|
+
# Correct approach
|
|
601
|
+
@app.get("/data")
|
|
602
|
+
async def get_data():
|
|
603
|
+
async with httpx.AsyncClient() as client:
|
|
604
|
+
response = await client.get("https://api.example.com/data")
|
|
605
|
+
return response.json()
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Anti-Pattern 3: Hardcoded Configuration
|
|
609
|
+
|
|
610
|
+
**Problem**: Hardcoding configuration values in code.
|
|
611
|
+
|
|
612
|
+
```python
|
|
613
|
+
# Incorrect approach
|
|
614
|
+
DATABASE_URL = "postgresql://user:password@localhost:5432/db"
|
|
615
|
+
SECRET_KEY = "my-super-secret-key"
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
**Solution**: Use environment variables with validation.
|
|
619
|
+
|
|
620
|
+
```python
|
|
621
|
+
# Correct approach
|
|
622
|
+
from pydantic_settings import BaseSettings
|
|
623
|
+
|
|
624
|
+
class Settings(BaseSettings):
|
|
625
|
+
database_url: str
|
|
626
|
+
secret_key: str
|
|
627
|
+
redis_url: str = "redis://localhost:6379"
|
|
628
|
+
debug: bool = False
|
|
629
|
+
|
|
630
|
+
class Config:
|
|
631
|
+
env_file = ".env"
|
|
632
|
+
case_sensitive = False
|
|
633
|
+
|
|
634
|
+
settings = Settings()
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
## Integration Examples
|
|
640
|
+
|
|
641
|
+
### Health Check Endpoint
|
|
642
|
+
|
|
643
|
+
```python
|
|
644
|
+
from fastapi import APIRouter
|
|
645
|
+
from datetime import datetime
|
|
646
|
+
|
|
647
|
+
router = APIRouter(prefix="/health", tags=["Health"])
|
|
648
|
+
|
|
649
|
+
@router.get("")
|
|
650
|
+
async def health_check(
|
|
651
|
+
db: DatabaseManager = Depends(get_db),
|
|
652
|
+
cache: redis.Redis = Depends(get_cache)
|
|
653
|
+
):
|
|
654
|
+
checks = {
|
|
655
|
+
"status": "healthy",
|
|
656
|
+
"timestamp": datetime.utcnow().isoformat(),
|
|
657
|
+
"checks": {}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
# Database check
|
|
661
|
+
checks["checks"]["database"] = await db.health_check()
|
|
662
|
+
|
|
663
|
+
# Cache check
|
|
664
|
+
try:
|
|
665
|
+
await cache.ping()
|
|
666
|
+
checks["checks"]["cache"] = True
|
|
667
|
+
except Exception:
|
|
668
|
+
checks["checks"]["cache"] = False
|
|
669
|
+
|
|
670
|
+
# Overall status
|
|
671
|
+
if not all(checks["checks"].values()):
|
|
672
|
+
checks["status"] = "degraded"
|
|
673
|
+
|
|
674
|
+
return checks
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### Structured Logging
|
|
678
|
+
|
|
679
|
+
```python
|
|
680
|
+
import structlog
|
|
681
|
+
from fastapi import FastAPI
|
|
682
|
+
|
|
683
|
+
def configure_logging():
|
|
684
|
+
structlog.configure(
|
|
685
|
+
processors=[
|
|
686
|
+
structlog.stdlib.filter_by_level,
|
|
687
|
+
structlog.stdlib.add_logger_name,
|
|
688
|
+
structlog.stdlib.add_log_level,
|
|
689
|
+
structlog.processors.TimeStamper(fmt="iso"),
|
|
690
|
+
structlog.processors.JSONRenderer()
|
|
691
|
+
],
|
|
692
|
+
wrapper_class=structlog.stdlib.BoundLogger,
|
|
693
|
+
context_class=dict,
|
|
694
|
+
logger_factory=structlog.stdlib.LoggerFactory(),
|
|
695
|
+
cache_logger_on_first_use=True
|
|
696
|
+
)
|
|
697
|
+
|
|
698
|
+
logger = structlog.get_logger()
|
|
699
|
+
|
|
700
|
+
@app.middleware("http")
|
|
701
|
+
async def log_requests(request: Request, call_next):
|
|
702
|
+
logger.info(
|
|
703
|
+
"request_started",
|
|
704
|
+
method=request.method,
|
|
705
|
+
path=request.url.path,
|
|
706
|
+
client_ip=request.client.host
|
|
707
|
+
)
|
|
708
|
+
response = await call_next(request)
|
|
709
|
+
logger.info(
|
|
710
|
+
"request_completed",
|
|
711
|
+
status_code=response.status_code
|
|
712
|
+
)
|
|
713
|
+
return response
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
---
|
|
717
|
+
|
|
718
|
+
*For additional patterns and advanced configurations, see the related skills and documentation.*
|