@caddis/cli 0.1.0 → 0.2.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/README.md +29 -16
- package/bundles/antigravity-plugin-extras/plugin.json +5 -0
- package/bundles/antigravity-plugin-extras/skills/_registry.md +154 -0
- package/bundles/antigravity-plugin-extras/skills/agent-md-refactor/SKILL.md +356 -0
- package/bundles/antigravity-plugin-extras/skills/agent-orchestration/SKILL.md +517 -0
- package/bundles/antigravity-plugin-extras/skills/algorithmic-art/SKILL.md +293 -0
- package/bundles/antigravity-plugin-extras/skills/anchor-review/SKILL.md +135 -0
- package/bundles/antigravity-plugin-extras/skills/api-client-patterns/SKILL.md +367 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-design/SKILL.md +244 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-diagram/SKILL.md +156 -0
- package/bundles/antigravity-plugin-extras/skills/architecture-document/SKILL.md +321 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/SKILL.md +74 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/bundles/antigravity-plugin-extras/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/bundles/antigravity-plugin-extras/skills/ascii-art/SKILL.md +144 -0
- package/bundles/antigravity-plugin-extras/skills/asking-questions/SKILL.md +81 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/SKILL.md +118 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/cross-service/credential-management.md +450 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/browser/README.md +363 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/code-interpreter/README.md +232 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/README.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deploy-template.sh +117 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/deployment-strategies.md +416 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/troubleshooting-guide.md +384 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/gateway/validate-deployment.sh +186 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/identity/README.md +186 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/memory/README.md +253 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/observability/README.md +517 -0
- package/bundles/antigravity-plugin-extras/skills/aws-agentic-ai/services/runtime/README.md +215 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/SKILL.md +279 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/references/cdk-patterns.md +431 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cdk-development/scripts/validate-stack.sh +240 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/SKILL.md +318 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/cloudwatch-alarms.md +567 -0
- package/bundles/antigravity-plugin-extras/skills/aws-cost-operations/references/operations-patterns.md +394 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/SKILL.md +758 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/deployment-best-practices.md +830 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/eda-patterns.md +1002 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/observability-best-practices.md +770 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/performance-optimization.md +671 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/security-best-practices.md +625 -0
- package/bundles/antigravity-plugin-extras/skills/aws-serverless-eda/references/serverless-patterns.md +838 -0
- package/bundles/antigravity-plugin-extras/skills/backend-to-frontend-handoff/SKILL.md +139 -0
- package/bundles/antigravity-plugin-extras/skills/banner-design/SKILL.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/brand-design/SKILL.md +298 -0
- package/bundles/antigravity-plugin-extras/skills/brand-guidelines/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/brand-guidelines/SKILL.md +118 -0
- package/bundles/antigravity-plugin-extras/skills/brand-voice/SKILL.md +93 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/SKILL.md +392 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/agent-patterns.md +461 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/examples.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/state-patterns.md +360 -0
- package/bundles/antigravity-plugin-extras/skills/building-ai-agent-on-cloudflare/references/troubleshooting.md +362 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/SKILL.md +266 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/examples.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/oauth-setup.md +338 -0
- package/bundles/antigravity-plugin-extras/skills/building-mcp-server-on-cloudflare/references/troubleshooting.md +317 -0
- package/bundles/antigravity-plugin-extras/skills/caching-patterns/SKILL.md +385 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/SKILL.md +91 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/bundles/antigravity-plugin-extras/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/bundles/antigravity-plugin-extras/skills/changelog-generator/SKILL.md +105 -0
- package/bundles/antigravity-plugin-extras/skills/code-explainer/SKILL.md +91 -0
- package/bundles/antigravity-plugin-extras/skills/competitive-ads-extractor/SKILL.md +294 -0
- package/bundles/antigravity-plugin-extras/skills/component-testing/SKILL.md +310 -0
- package/bundles/antigravity-plugin-extras/skills/content-research-writer/SKILL.md +539 -0
- package/bundles/antigravity-plugin-extras/skills/cross-review/SKILL.md +51 -0
- package/bundles/antigravity-plugin-extras/skills/data-analysis/SKILL.md +111 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/README.md +248 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/SKILL.md +203 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/adapter.py.template +44 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/api-router.py.template +43 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/contract-test.py.template +384 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/display-dto.py.template +39 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-service.ts.template +46 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/frontend-types.ts.template +38 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/ingestion-model.py.template +42 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/mapping-doc.md.template +46 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/normalizer.py.template +48 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_requirements.md +36 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/extract_ui_demand.md +35 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/prompts/reconcile_mapping.md +66 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/assets/query-catalog.md.template +62 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/consumer-driven-contracts.md +131 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/drift-check-catalog.md +305 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/references/layer-responsibilities.md +333 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_connections.py +170 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/discover_sources.py +161 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/drift_check.py +171 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/extract_schema.py +1363 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_gap_report.py +81 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/generate_mapping_doc.py +294 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/ts_dto_compare.py +214 -0
- package/bundles/antigravity-plugin-extras/skills/data-contract-pipeline/scripts/validate_lineage.py +51 -0
- package/bundles/antigravity-plugin-extras/skills/data-loader/SKILL.md +753 -0
- package/bundles/antigravity-plugin-extras/skills/data-validation/SKILL.md +220 -0
- package/bundles/antigravity-plugin-extras/skills/db-testing/SKILL.md +117 -0
- package/bundles/antigravity-plugin-extras/skills/deploy-local/SKILL.md +259 -0
- package/bundles/antigravity-plugin-extras/skills/design-md/SKILL.md +167 -0
- package/bundles/antigravity-plugin-extras/skills/design-system-tokens/SKILL.md +240 -0
- package/bundles/antigravity-plugin-extras/skills/design-system-tokens/references/DESIGN-SYSTEM-TEMPLATE.md +577 -0
- package/bundles/antigravity-plugin-extras/skills/developer-growth-analysis/SKILL.md +323 -0
- package/bundles/antigravity-plugin-extras/skills/doc-coauthoring/SKILL.md +378 -0
- package/bundles/antigravity-plugin-extras/skills/documentation-analyzer/SKILL.md +78 -0
- package/bundles/antigravity-plugin-extras/skills/domain-name-brainstormer/SKILL.md +213 -0
- package/bundles/antigravity-plugin-extras/skills/enterprise-dashboard-aesthetic-system/SKILL.md +120 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/SKILL.md +193 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/element-types.md +497 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/excalidraw-schema.md +356 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/references/reliable-diagrams.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/README.md +60 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-arrow.py +354 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/add-icon-to-diagram.py +412 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/scripts/split-excalidraw-library.py +183 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/business-flow-swimlane-template.excalidraw +334 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/class-diagram-template.excalidraw +558 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/data-flow-diagram-template.excalidraw +279 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/er-diagram-template.excalidraw +662 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/flowchart-template.excalidraw +179 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/mindmap-template.excalidraw +244 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/relationship-template.excalidraw +145 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/reliable-flowchart.excalidraw +1 -0
- package/bundles/antigravity-plugin-extras/skills/excalidraw/templates/sequence-diagram-template.excalidraw +509 -0
- package/bundles/antigravity-plugin-extras/skills/file-organizer/SKILL.md +434 -0
- package/bundles/antigravity-plugin-extras/skills/game-changing-features/README.md +221 -0
- package/bundles/antigravity-plugin-extras/skills/game-changing-features/SKILL.md +265 -0
- package/bundles/antigravity-plugin-extras/skills/github-issues/SKILL.md +359 -0
- package/bundles/antigravity-plugin-extras/skills/github-issues/references/templates.md +90 -0
- package/bundles/antigravity-plugin-extras/skills/golden-nuggets/SKILL.md +192 -0
- package/bundles/antigravity-plugin-extras/skills/humanizer/SKILL.md +194 -0
- package/bundles/antigravity-plugin-extras/skills/image-enhancer/SKILL.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/intent-writer/SKILL.md +201 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/SKILL.md +124 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/3p-updates.md +47 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/company-newsletter.md +65 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/faq-answers.md +30 -0
- package/bundles/antigravity-plugin-extras/skills/internal-comms/examples/general-comms.md +16 -0
- package/bundles/antigravity-plugin-extras/skills/invoice-organizer/SKILL.md +447 -0
- package/bundles/antigravity-plugin-extras/skills/jira-issues/SKILL.md +182 -0
- package/bundles/antigravity-plugin-extras/skills/job-application/SKILL.md +188 -0
- package/bundles/antigravity-plugin-extras/skills/lead-research-assistant/SKILL.md +200 -0
- package/bundles/antigravity-plugin-extras/skills/llm-application-dev/SKILL.md +217 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/SKILL.md +100 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/evaluation.md +602 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/mcp_best_practices.md +915 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/node_mcp_server.md +916 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/references/python_mcp_server.md +752 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/connections.py +151 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/bundles/antigravity-plugin-extras/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/bundles/antigravity-plugin-extras/skills/meeting-insights-analyzer/SKILL.md +328 -0
- package/bundles/antigravity-plugin-extras/skills/monorepo/SKILL.md +267 -0
- package/bundles/antigravity-plugin-extras/skills/naming-analyzer/SKILL.md +376 -0
- package/bundles/antigravity-plugin-extras/skills/nextjs-app-router/SKILL.md +271 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/AUTHENTICATION.md +154 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/SKILL.md +270 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/api_reference.md +309 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/troubleshooting.md +376 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/references/usage_patterns.md +338 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/__init__.py +81 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/ask_question.py +256 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/auth_manager.py +358 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_session.py +255 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/browser_utils.py +107 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/cleanup_manager.py +302 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/config.py +44 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/notebook_manager.py +410 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/run.py +102 -0
- package/bundles/antigravity-plugin-extras/skills/notebooklm/scripts/setup_environment.py +204 -0
- package/bundles/antigravity-plugin-extras/skills/observability/SKILL.md +371 -0
- package/bundles/antigravity-plugin-extras/skills/onboard-project/SKILL.md +192 -0
- package/bundles/antigravity-plugin-extras/skills/performance-testing/SKILL.md +226 -0
- package/bundles/antigravity-plugin-extras/skills/pipeline-state/SKILL.md +208 -0
- package/bundles/antigravity-plugin-extras/skills/plantuml/SKILL.md +228 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/SKILL.md +142 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/linear.app.md +196 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/stripe.md +214 -0
- package/bundles/antigravity-plugin-extras/skills/popular-web-designs/templates/vercel.md +218 -0
- package/bundles/antigravity-plugin-extras/skills/prd-to-code/SKILL.md +127 -0
- package/bundles/antigravity-plugin-extras/skills/raffle-winner-picker/SKILL.md +159 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/README.md +320 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/SKILL.md +53 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/alternatives.md +258 -0
- package/bundles/antigravity-plugin-extras/skills/react-useeffect/anti-patterns.md +290 -0
- package/bundles/antigravity-plugin-extras/skills/receiving-code-review/SKILL.md +213 -0
- package/bundles/antigravity-plugin-extras/skills/relay/SKILL.md +246 -0
- package/bundles/antigravity-plugin-extras/skills/requesting-code-review/SKILL.md +105 -0
- package/bundles/antigravity-plugin-extras/skills/requesting-code-review/code-reviewer.md +146 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/SKILL.md +350 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/pwa-checklist.md +226 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/touch-and-interaction.md +265 -0
- package/bundles/antigravity-plugin-extras/skills/responsive-mobile-native/references/transformation-catalogue.md +326 -0
- package/bundles/antigravity-plugin-extras/skills/schema-migration/SKILL.md +275 -0
- package/bundles/antigravity-plugin-extras/skills/setup-project-ai/SKILL.md +120 -0
- package/bundles/antigravity-plugin-extras/skills/shadcn-radix/SKILL.md +330 -0
- package/bundles/antigravity-plugin-extras/skills/sketch/SKILL.md +104 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/SKILL.md +646 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/color_palettes.py +302 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/easing.py +230 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/frame_composer.py +469 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/gif_builder.py +246 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/typography.py +357 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/validators.py +264 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/core/visual_effects.py +494 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/requirements.txt +4 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/bounce.py +106 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/explode.py +331 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/fade.py +329 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/flip.py +291 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/kaleidoscope.py +211 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/morph.py +329 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/move.py +293 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/pulse.py +268 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/shake.py +127 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/slide.py +291 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/spin.py +269 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/wiggle.py +300 -0
- package/bundles/antigravity-plugin-extras/skills/slack-gif-creator/templates/zoom.py +312 -0
- package/bundles/antigravity-plugin-extras/skills/slides/SKILL.md +38 -0
- package/bundles/antigravity-plugin-extras/skills/state-tracking/SKILL.md +131 -0
- package/bundles/antigravity-plugin-extras/skills/streamlit-dev/SKILL.md +268 -0
- package/bundles/antigravity-plugin-extras/skills/svg-create/SKILL.md +251 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/SKILL.md +59 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/theme-showcase.pdf +0 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/desert-rose.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/golden-hour.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/LICENSE.txt +202 -0
- package/bundles/antigravity-plugin-extras/skills/ui-styling-patterns/SKILL.md +320 -0
- package/bundles/antigravity-plugin-extras/skills/ui-testing/SKILL.md +660 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/SKILL.md +660 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/_sync_all.py +414 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/app-interface.csv +31 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/charts.csv +26 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/colors.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/design.csv +1776 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/draft.csv +1779 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/google-fonts.csv +1924 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/icons.csv +106 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/landing.csv +35 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/products.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/react-performance.csv +45 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/styles.csv +85 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/typography.csv +74 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ui-reasoning.csv +162 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/data/ux-guidelines.csv +100 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/core.py +247 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/design_system.py +1067 -0
- package/bundles/antigravity-plugin-extras/skills/ui-ux-intelligence/scripts/search.py +114 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/SKILL.md +140 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/commands.md +252 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/graph-schema.md +116 -0
- package/bundles/antigravity-plugin-extras/skills/understand-anything/references/pipeline.md +331 -0
- package/bundles/antigravity-plugin-extras/skills/update-readme/SKILL.md +74 -0
- package/bundles/antigravity-plugin-extras/skills/verification-loop/SKILL.md +209 -0
- package/bundles/antigravity-plugin-extras/skills/video-downloader/SKILL.md +107 -0
- package/bundles/antigravity-plugin-extras/skills/webapp-development/SKILL.md +288 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/SKILL.md +339 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/agents/agent-interface.md +175 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/html.md +384 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/nlp-keywords.md +127 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/palettes.md +149 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/python.md +249 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/react.md +427 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/shapes.md +135 -0
- package/bundles/antigravity-plugin-extras/skills/word-cloud/references/stopwords.md +115 -0
- package/bundles/antigravity-plugin-extras/skills/youtube-transcript/SKILL.md +416 -0
- package/bundles/manifest.json +2 -1
- package/dist/cli.js +166 -37
- package/package.json +1 -1
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
# Serverless Architecture Patterns
|
|
2
|
+
|
|
3
|
+
Comprehensive patterns for building serverless applications on AWS based on Well-Architected Framework principles.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Core Serverless Patterns](#core-serverless-patterns)
|
|
8
|
+
- [API Patterns](#api-patterns)
|
|
9
|
+
- [Data Processing Patterns](#data-processing-patterns)
|
|
10
|
+
- [Integration Patterns](#integration-patterns)
|
|
11
|
+
- [Orchestration Patterns](#orchestration-patterns)
|
|
12
|
+
- [Anti-Patterns](#anti-patterns)
|
|
13
|
+
|
|
14
|
+
## Core Serverless Patterns
|
|
15
|
+
|
|
16
|
+
### Pattern: Serverless Microservices
|
|
17
|
+
|
|
18
|
+
**Use case**: Independent, scalable services with separate databases
|
|
19
|
+
|
|
20
|
+
**Architecture**:
|
|
21
|
+
```
|
|
22
|
+
API Gateway → Lambda Functions → DynamoDB/RDS
|
|
23
|
+
↓ (events)
|
|
24
|
+
EventBridge → Other Services
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**CDK Implementation**:
|
|
28
|
+
```typescript
|
|
29
|
+
// User Service
|
|
30
|
+
const userTable = new dynamodb.Table(this, 'Users', {
|
|
31
|
+
partitionKey: { name: 'userId', type: dynamodb.AttributeType.STRING },
|
|
32
|
+
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const userFunction = new NodejsFunction(this, 'UserHandler', {
|
|
36
|
+
entry: 'src/services/users/handler.ts',
|
|
37
|
+
environment: {
|
|
38
|
+
TABLE_NAME: userTable.tableName,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
userTable.grantReadWriteData(userFunction);
|
|
43
|
+
|
|
44
|
+
// Order Service (separate database)
|
|
45
|
+
const orderTable = new dynamodb.Table(this, 'Orders', {
|
|
46
|
+
partitionKey: { name: 'orderId', type: dynamodb.AttributeType.STRING },
|
|
47
|
+
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const orderFunction = new NodejsFunction(this, 'OrderHandler', {
|
|
51
|
+
entry: 'src/services/orders/handler.ts',
|
|
52
|
+
environment: {
|
|
53
|
+
TABLE_NAME: orderTable.tableName,
|
|
54
|
+
EVENT_BUS: eventBus.eventBusName,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
orderTable.grantReadWriteData(orderFunction);
|
|
59
|
+
eventBus.grantPutEventsTo(orderFunction);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Benefits**:
|
|
63
|
+
- Independent deployment and scaling
|
|
64
|
+
- Database per service (data isolation)
|
|
65
|
+
- Technology diversity
|
|
66
|
+
- Fault isolation
|
|
67
|
+
|
|
68
|
+
### Pattern: Serverless API Backend
|
|
69
|
+
|
|
70
|
+
**Use case**: REST or GraphQL API with serverless compute
|
|
71
|
+
|
|
72
|
+
**REST API with API Gateway**:
|
|
73
|
+
```typescript
|
|
74
|
+
const api = new apigateway.RestApi(this, 'Api', {
|
|
75
|
+
restApiName: 'serverless-api',
|
|
76
|
+
deployOptions: {
|
|
77
|
+
stageName: 'prod',
|
|
78
|
+
tracingEnabled: true,
|
|
79
|
+
loggingLevel: apigateway.MethodLoggingLevel.INFO,
|
|
80
|
+
dataTraceEnabled: true,
|
|
81
|
+
metricsEnabled: true,
|
|
82
|
+
},
|
|
83
|
+
defaultCorsPreflightOptions: {
|
|
84
|
+
allowOrigins: apigateway.Cors.ALL_ORIGINS,
|
|
85
|
+
allowMethods: apigateway.Cors.ALL_METHODS,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Resource-based routing
|
|
90
|
+
const items = api.root.addResource('items');
|
|
91
|
+
items.addMethod('GET', new apigateway.LambdaIntegration(listFunction));
|
|
92
|
+
items.addMethod('POST', new apigateway.LambdaIntegration(createFunction));
|
|
93
|
+
|
|
94
|
+
const item = items.addResource('{id}');
|
|
95
|
+
item.addMethod('GET', new apigateway.LambdaIntegration(getFunction));
|
|
96
|
+
item.addMethod('PUT', new apigateway.LambdaIntegration(updateFunction));
|
|
97
|
+
item.addMethod('DELETE', new apigateway.LambdaIntegration(deleteFunction));
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**GraphQL API with AppSync**:
|
|
101
|
+
```typescript
|
|
102
|
+
const api = new appsync.GraphqlApi(this, 'Api', {
|
|
103
|
+
name: 'serverless-graphql-api',
|
|
104
|
+
schema: appsync.SchemaFile.fromAsset('schema.graphql'),
|
|
105
|
+
authorizationConfig: {
|
|
106
|
+
defaultAuthorization: {
|
|
107
|
+
authorizationType: appsync.AuthorizationType.API_KEY,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
xrayEnabled: true,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Lambda resolver
|
|
114
|
+
const dataSource = api.addLambdaDataSource('lambda-ds', resolverFunction);
|
|
115
|
+
|
|
116
|
+
dataSource.createResolver('QueryGetItem', {
|
|
117
|
+
typeName: 'Query',
|
|
118
|
+
fieldName: 'getItem',
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Pattern: Serverless Data Lake
|
|
123
|
+
|
|
124
|
+
**Use case**: Ingest, process, and analyze large-scale data
|
|
125
|
+
|
|
126
|
+
**Architecture**:
|
|
127
|
+
```
|
|
128
|
+
S3 (raw data) → Lambda (transform) → S3 (processed)
|
|
129
|
+
↓ (catalog)
|
|
130
|
+
AWS Glue → Athena (query)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Implementation**:
|
|
134
|
+
```typescript
|
|
135
|
+
const rawBucket = new s3.Bucket(this, 'RawData');
|
|
136
|
+
const processedBucket = new s3.Bucket(this, 'ProcessedData');
|
|
137
|
+
|
|
138
|
+
// Trigger Lambda on file upload
|
|
139
|
+
rawBucket.addEventNotification(
|
|
140
|
+
s3.EventType.OBJECT_CREATED,
|
|
141
|
+
new s3n.LambdaDestination(transformFunction),
|
|
142
|
+
{ prefix: 'incoming/' }
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Transform function
|
|
146
|
+
export const transform = async (event: S3Event) => {
|
|
147
|
+
for (const record of event.Records) {
|
|
148
|
+
const key = record.s3.object.key;
|
|
149
|
+
|
|
150
|
+
// Get raw data
|
|
151
|
+
const raw = await s3.getObject({
|
|
152
|
+
Bucket: record.s3.bucket.name,
|
|
153
|
+
Key: key,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Transform data
|
|
157
|
+
const transformed = await transformData(raw.Body);
|
|
158
|
+
|
|
159
|
+
// Write to processed bucket
|
|
160
|
+
await s3.putObject({
|
|
161
|
+
Bucket: process.env.PROCESSED_BUCKET,
|
|
162
|
+
Key: `processed/${key}`,
|
|
163
|
+
Body: JSON.stringify(transformed),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## API Patterns
|
|
170
|
+
|
|
171
|
+
### Pattern: Authorizer Pattern
|
|
172
|
+
|
|
173
|
+
**Use case**: Custom authentication and authorization
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Lambda authorizer
|
|
177
|
+
const authorizer = new apigateway.TokenAuthorizer(this, 'Authorizer', {
|
|
178
|
+
handler: authorizerFunction,
|
|
179
|
+
identitySource: 'method.request.header.Authorization',
|
|
180
|
+
resultsCacheTtl: Duration.minutes(5),
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Apply to API methods
|
|
184
|
+
const resource = api.root.addResource('protected');
|
|
185
|
+
resource.addMethod('GET', new apigateway.LambdaIntegration(protectedFunction), {
|
|
186
|
+
authorizer,
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Pattern: Request Validation
|
|
191
|
+
|
|
192
|
+
**Use case**: Validate requests before Lambda invocation
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
const requestModel = api.addModel('RequestModel', {
|
|
196
|
+
contentType: 'application/json',
|
|
197
|
+
schema: {
|
|
198
|
+
type: apigateway.JsonSchemaType.OBJECT,
|
|
199
|
+
required: ['name', 'email'],
|
|
200
|
+
properties: {
|
|
201
|
+
name: { type: apigateway.JsonSchemaType.STRING, minLength: 1 },
|
|
202
|
+
email: { type: apigateway.JsonSchemaType.STRING, format: 'email' },
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
resource.addMethod('POST', integration, {
|
|
208
|
+
requestValidator: new apigateway.RequestValidator(this, 'Validator', {
|
|
209
|
+
api,
|
|
210
|
+
validateRequestBody: true,
|
|
211
|
+
validateRequestParameters: true,
|
|
212
|
+
}),
|
|
213
|
+
requestModels: {
|
|
214
|
+
'application/json': requestModel,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Pattern: Response Caching
|
|
220
|
+
|
|
221
|
+
**Use case**: Reduce backend load and improve latency
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
const api = new apigateway.RestApi(this, 'Api', {
|
|
225
|
+
deployOptions: {
|
|
226
|
+
cachingEnabled: true,
|
|
227
|
+
cacheTtl: Duration.minutes(5),
|
|
228
|
+
cacheClusterEnabled: true,
|
|
229
|
+
cacheClusterSize: '0.5', // GB
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Enable caching per method
|
|
234
|
+
resource.addMethod('GET', integration, {
|
|
235
|
+
methodResponses: [{
|
|
236
|
+
statusCode: '200',
|
|
237
|
+
responseParameters: {
|
|
238
|
+
'method.response.header.Cache-Control': true,
|
|
239
|
+
},
|
|
240
|
+
}],
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Data Processing Patterns
|
|
245
|
+
|
|
246
|
+
### Pattern: S3 Event Processing
|
|
247
|
+
|
|
248
|
+
**Use case**: Process files uploaded to S3
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
const bucket = new s3.Bucket(this, 'DataBucket');
|
|
252
|
+
|
|
253
|
+
// Process images
|
|
254
|
+
bucket.addEventNotification(
|
|
255
|
+
s3.EventType.OBJECT_CREATED,
|
|
256
|
+
new s3n.LambdaDestination(imageProcessingFunction),
|
|
257
|
+
{ suffix: '.jpg' }
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
// Process CSV files
|
|
261
|
+
bucket.addEventNotification(
|
|
262
|
+
s3.EventType.OBJECT_CREATED,
|
|
263
|
+
new s3n.LambdaDestination(csvProcessingFunction),
|
|
264
|
+
{ suffix: '.csv' }
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
// Large file processing with Step Functions
|
|
268
|
+
bucket.addEventNotification(
|
|
269
|
+
s3.EventType.OBJECT_CREATED,
|
|
270
|
+
new s3n.SfnDestination(processingStateMachine),
|
|
271
|
+
{ prefix: 'large-files/' }
|
|
272
|
+
);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Pattern: DynamoDB Streams Processing
|
|
276
|
+
|
|
277
|
+
**Use case**: React to database changes
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const table = new dynamodb.Table(this, 'Table', {
|
|
281
|
+
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
|
|
282
|
+
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Process stream changes
|
|
286
|
+
new lambda.EventSourceMapping(this, 'StreamConsumer', {
|
|
287
|
+
target: streamProcessorFunction,
|
|
288
|
+
eventSourceArn: table.tableStreamArn,
|
|
289
|
+
startingPosition: lambda.StartingPosition.LATEST,
|
|
290
|
+
batchSize: 100,
|
|
291
|
+
maxBatchingWindow: Duration.seconds(5),
|
|
292
|
+
bisectBatchOnError: true,
|
|
293
|
+
retryAttempts: 3,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Example: Sync to search index
|
|
297
|
+
export const processStream = async (event: DynamoDBStreamEvent) => {
|
|
298
|
+
for (const record of event.Records) {
|
|
299
|
+
if (record.eventName === 'INSERT' || record.eventName === 'MODIFY') {
|
|
300
|
+
const newImage = record.dynamodb?.NewImage;
|
|
301
|
+
await elasticSearch.index({
|
|
302
|
+
index: 'items',
|
|
303
|
+
id: newImage?.id.S,
|
|
304
|
+
body: unmarshall(newImage),
|
|
305
|
+
});
|
|
306
|
+
} else if (record.eventName === 'REMOVE') {
|
|
307
|
+
await elasticSearch.delete({
|
|
308
|
+
index: 'items',
|
|
309
|
+
id: record.dynamodb?.Keys?.id.S,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Pattern: Kinesis Stream Processing
|
|
317
|
+
|
|
318
|
+
**Use case**: Real-time data streaming and analytics
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
const stream = new kinesis.Stream(this, 'EventStream', {
|
|
322
|
+
shardCount: 2,
|
|
323
|
+
streamMode: kinesis.StreamMode.PROVISIONED,
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Fan-out with multiple consumers
|
|
327
|
+
const consumer1 = new lambda.EventSourceMapping(this, 'Analytics', {
|
|
328
|
+
target: analyticsFunction,
|
|
329
|
+
eventSourceArn: stream.streamArn,
|
|
330
|
+
startingPosition: lambda.StartingPosition.LATEST,
|
|
331
|
+
batchSize: 100,
|
|
332
|
+
parallelizationFactor: 10, // Process 10 batches per shard in parallel
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const consumer2 = new lambda.EventSourceMapping(this, 'Alerting', {
|
|
336
|
+
target: alertingFunction,
|
|
337
|
+
eventSourceArn: stream.streamArn,
|
|
338
|
+
startingPosition: lambda.StartingPosition.LATEST,
|
|
339
|
+
filters: [
|
|
340
|
+
lambda.FilterCriteria.filter({
|
|
341
|
+
eventName: lambda.FilterRule.isEqual('CRITICAL_EVENT'),
|
|
342
|
+
}),
|
|
343
|
+
],
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Integration Patterns
|
|
348
|
+
|
|
349
|
+
### Pattern: Service Integration with EventBridge
|
|
350
|
+
|
|
351
|
+
**Use case**: Decouple services with events
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
const eventBus = new events.EventBus(this, 'AppBus');
|
|
355
|
+
|
|
356
|
+
// Service A publishes events
|
|
357
|
+
const serviceA = new NodejsFunction(this, 'ServiceA', {
|
|
358
|
+
entry: 'src/services/a/handler.ts',
|
|
359
|
+
environment: {
|
|
360
|
+
EVENT_BUS: eventBus.eventBusName,
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
eventBus.grantPutEventsTo(serviceA);
|
|
365
|
+
|
|
366
|
+
// Service B subscribes to events
|
|
367
|
+
new events.Rule(this, 'ServiceBRule', {
|
|
368
|
+
eventBus,
|
|
369
|
+
eventPattern: {
|
|
370
|
+
source: ['service.a'],
|
|
371
|
+
detailType: ['EntityCreated'],
|
|
372
|
+
},
|
|
373
|
+
targets: [new targets.LambdaFunction(serviceBFunction)],
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// Service C subscribes to same events
|
|
377
|
+
new events.Rule(this, 'ServiceCRule', {
|
|
378
|
+
eventBus,
|
|
379
|
+
eventPattern: {
|
|
380
|
+
source: ['service.a'],
|
|
381
|
+
detailType: ['EntityCreated'],
|
|
382
|
+
},
|
|
383
|
+
targets: [new targets.LambdaFunction(serviceCFunction)],
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Pattern: API Gateway + SQS Integration
|
|
388
|
+
|
|
389
|
+
**Use case**: Async API requests without Lambda
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const queue = new sqs.Queue(this, 'RequestQueue');
|
|
393
|
+
|
|
394
|
+
const api = new apigateway.RestApi(this, 'Api');
|
|
395
|
+
|
|
396
|
+
// Direct SQS integration (no Lambda)
|
|
397
|
+
const sqsIntegration = new apigateway.AwsIntegration({
|
|
398
|
+
service: 'sqs',
|
|
399
|
+
path: `${process.env.AWS_ACCOUNT_ID}/${queue.queueName}`,
|
|
400
|
+
integrationHttpMethod: 'POST',
|
|
401
|
+
options: {
|
|
402
|
+
credentialsRole: sqsRole,
|
|
403
|
+
requestParameters: {
|
|
404
|
+
'integration.request.header.Content-Type': "'application/x-www-form-urlencoded'",
|
|
405
|
+
},
|
|
406
|
+
requestTemplates: {
|
|
407
|
+
'application/json': 'Action=SendMessage&MessageBody=$input.body',
|
|
408
|
+
},
|
|
409
|
+
integrationResponses: [{
|
|
410
|
+
statusCode: '200',
|
|
411
|
+
}],
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
api.root.addMethod('POST', sqsIntegration, {
|
|
416
|
+
methodResponses: [{ statusCode: '200' }],
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Pattern: EventBridge + Step Functions
|
|
421
|
+
|
|
422
|
+
**Use case**: Event-triggered workflow orchestration
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
// State machine for order processing
|
|
426
|
+
const orderStateMachine = new stepfunctions.StateMachine(this, 'OrderFlow', {
|
|
427
|
+
definition: /* ... */,
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// EventBridge triggers state machine
|
|
431
|
+
new events.Rule(this, 'OrderPlacedRule', {
|
|
432
|
+
eventPattern: {
|
|
433
|
+
source: ['orders'],
|
|
434
|
+
detailType: ['OrderPlaced'],
|
|
435
|
+
},
|
|
436
|
+
targets: [new targets.SfnStateMachine(orderStateMachine)],
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Orchestration Patterns
|
|
441
|
+
|
|
442
|
+
### Pattern: Sequential Workflow
|
|
443
|
+
|
|
444
|
+
**Use case**: Multi-step process with dependencies
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
const definition = new tasks.LambdaInvoke(this, 'Step1', {
|
|
448
|
+
lambdaFunction: step1Function,
|
|
449
|
+
outputPath: '$.Payload',
|
|
450
|
+
})
|
|
451
|
+
.next(new tasks.LambdaInvoke(this, 'Step2', {
|
|
452
|
+
lambdaFunction: step2Function,
|
|
453
|
+
outputPath: '$.Payload',
|
|
454
|
+
}))
|
|
455
|
+
.next(new tasks.LambdaInvoke(this, 'Step3', {
|
|
456
|
+
lambdaFunction: step3Function,
|
|
457
|
+
outputPath: '$.Payload',
|
|
458
|
+
}));
|
|
459
|
+
|
|
460
|
+
new stepfunctions.StateMachine(this, 'Sequential', {
|
|
461
|
+
definition,
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Pattern: Parallel Execution
|
|
466
|
+
|
|
467
|
+
**Use case**: Execute independent tasks concurrently
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
const parallel = new stepfunctions.Parallel(this, 'ParallelProcessing');
|
|
471
|
+
|
|
472
|
+
parallel.branch(new tasks.LambdaInvoke(this, 'ProcessA', {
|
|
473
|
+
lambdaFunction: functionA,
|
|
474
|
+
}));
|
|
475
|
+
|
|
476
|
+
parallel.branch(new tasks.LambdaInvoke(this, 'ProcessB', {
|
|
477
|
+
lambdaFunction: functionB,
|
|
478
|
+
}));
|
|
479
|
+
|
|
480
|
+
parallel.branch(new tasks.LambdaInvoke(this, 'ProcessC', {
|
|
481
|
+
lambdaFunction: functionC,
|
|
482
|
+
}));
|
|
483
|
+
|
|
484
|
+
const definition = parallel.next(new tasks.LambdaInvoke(this, 'Aggregate', {
|
|
485
|
+
lambdaFunction: aggregateFunction,
|
|
486
|
+
}));
|
|
487
|
+
|
|
488
|
+
new stepfunctions.StateMachine(this, 'Parallel', { definition });
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### Pattern: Map State (Dynamic Parallelism)
|
|
492
|
+
|
|
493
|
+
**Use case**: Process array of items in parallel
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
const mapState = new stepfunctions.Map(this, 'ProcessItems', {
|
|
497
|
+
maxConcurrency: 10,
|
|
498
|
+
itemsPath: '$.items',
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
mapState.iterator(new tasks.LambdaInvoke(this, 'ProcessItem', {
|
|
502
|
+
lambdaFunction: processItemFunction,
|
|
503
|
+
}));
|
|
504
|
+
|
|
505
|
+
const definition = mapState.next(new tasks.LambdaInvoke(this, 'Finalize', {
|
|
506
|
+
lambdaFunction: finalizeFunction,
|
|
507
|
+
}));
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Pattern: Choice State (Conditional Logic)
|
|
511
|
+
|
|
512
|
+
**Use case**: Branching logic based on input
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
const choice = new stepfunctions.Choice(this, 'OrderType');
|
|
516
|
+
|
|
517
|
+
choice.when(
|
|
518
|
+
stepfunctions.Condition.stringEquals('$.orderType', 'STANDARD'),
|
|
519
|
+
standardProcessing
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
choice.when(
|
|
523
|
+
stepfunctions.Condition.stringEquals('$.orderType', 'EXPRESS'),
|
|
524
|
+
expressProcessing
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
choice.otherwise(defaultProcessing);
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Pattern: Wait State
|
|
531
|
+
|
|
532
|
+
**Use case**: Delay between steps or wait for callbacks
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
// Fixed delay
|
|
536
|
+
const wait = new stepfunctions.Wait(this, 'Wait30Seconds', {
|
|
537
|
+
time: stepfunctions.WaitTime.duration(Duration.seconds(30)),
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
// Wait until timestamp
|
|
541
|
+
const waitUntil = new stepfunctions.Wait(this, 'WaitUntil', {
|
|
542
|
+
time: stepfunctions.WaitTime.timestampPath('$.expiryTime'),
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Wait for callback (.waitForTaskToken)
|
|
546
|
+
const waitForCallback = new tasks.LambdaInvoke(this, 'WaitForApproval', {
|
|
547
|
+
lambdaFunction: approvalFunction,
|
|
548
|
+
integrationPattern: stepfunctions.IntegrationPattern.WAIT_FOR_TASK_TOKEN,
|
|
549
|
+
payload: stepfunctions.TaskInput.fromObject({
|
|
550
|
+
token: stepfunctions.JsonPath.taskToken,
|
|
551
|
+
data: stepfunctions.JsonPath.entirePayload,
|
|
552
|
+
}),
|
|
553
|
+
});
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## Anti-Patterns
|
|
557
|
+
|
|
558
|
+
### ❌ Lambda Monolith
|
|
559
|
+
|
|
560
|
+
**Problem**: Single Lambda handling all operations
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
// BAD
|
|
564
|
+
export const handler = async (event: any) => {
|
|
565
|
+
switch (event.operation) {
|
|
566
|
+
case 'createUser': return createUser(event);
|
|
567
|
+
case 'getUser': return getUser(event);
|
|
568
|
+
case 'updateUser': return updateUser(event);
|
|
569
|
+
case 'deleteUser': return deleteUser(event);
|
|
570
|
+
case 'createOrder': return createOrder(event);
|
|
571
|
+
// ... 20 more operations
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**Solution**: Separate Lambda functions per operation
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
// GOOD - Separate functions
|
|
580
|
+
export const createUser = async (event: any) => { /* ... */ };
|
|
581
|
+
export const getUser = async (event: any) => { /* ... */ };
|
|
582
|
+
export const updateUser = async (event: any) => { /* ... */ };
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### ❌ Recursive Lambda Pattern
|
|
586
|
+
|
|
587
|
+
**Problem**: Lambda invoking itself (runaway costs)
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
// BAD
|
|
591
|
+
export const handler = async (event: any) => {
|
|
592
|
+
await processItem(event);
|
|
593
|
+
|
|
594
|
+
if (hasMoreItems()) {
|
|
595
|
+
await lambda.invoke({
|
|
596
|
+
FunctionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
597
|
+
InvocationType: 'Event',
|
|
598
|
+
Payload: JSON.stringify({ /* next batch */ }),
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**Solution**: Use SQS or Step Functions
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
// GOOD - Use SQS for iteration
|
|
608
|
+
export const handler = async (event: SQSEvent) => {
|
|
609
|
+
for (const record of event.Records) {
|
|
610
|
+
await processItem(record);
|
|
611
|
+
}
|
|
612
|
+
// SQS handles iteration automatically
|
|
613
|
+
};
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### ❌ Lambda Chaining
|
|
617
|
+
|
|
618
|
+
**Problem**: Lambda directly invoking another Lambda
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
// BAD
|
|
622
|
+
export const handler1 = async (event: any) => {
|
|
623
|
+
const result = await processStep1(event);
|
|
624
|
+
|
|
625
|
+
// Directly invoking next Lambda
|
|
626
|
+
await lambda.invoke({
|
|
627
|
+
FunctionName: 'handler2',
|
|
628
|
+
Payload: JSON.stringify(result),
|
|
629
|
+
});
|
|
630
|
+
};
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Solution**: Use EventBridge, SQS, or Step Functions
|
|
634
|
+
|
|
635
|
+
```typescript
|
|
636
|
+
// GOOD - Publish to EventBridge
|
|
637
|
+
export const handler1 = async (event: any) => {
|
|
638
|
+
const result = await processStep1(event);
|
|
639
|
+
|
|
640
|
+
await eventBridge.putEvents({
|
|
641
|
+
Entries: [{
|
|
642
|
+
Source: 'service.step1',
|
|
643
|
+
DetailType: 'Step1Completed',
|
|
644
|
+
Detail: JSON.stringify(result),
|
|
645
|
+
}],
|
|
646
|
+
});
|
|
647
|
+
};
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### ❌ Synchronous Waiting in Lambda
|
|
651
|
+
|
|
652
|
+
**Problem**: Lambda waiting for slow operations
|
|
653
|
+
|
|
654
|
+
```typescript
|
|
655
|
+
// BAD - Blocking on slow operation
|
|
656
|
+
export const handler = async (event: any) => {
|
|
657
|
+
await startBatchJob(); // Returns immediately
|
|
658
|
+
|
|
659
|
+
// Wait for job to complete (wastes Lambda time)
|
|
660
|
+
while (true) {
|
|
661
|
+
const status = await checkJobStatus();
|
|
662
|
+
if (status === 'COMPLETE') break;
|
|
663
|
+
await sleep(1000);
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
**Solution**: Use Step Functions with callback pattern
|
|
669
|
+
|
|
670
|
+
```typescript
|
|
671
|
+
// GOOD - Step Functions waits, not Lambda
|
|
672
|
+
const waitForJob = new tasks.LambdaInvoke(this, 'StartJob', {
|
|
673
|
+
lambdaFunction: startJobFunction,
|
|
674
|
+
integrationPattern: stepfunctions.IntegrationPattern.WAIT_FOR_TASK_TOKEN,
|
|
675
|
+
payload: stepfunctions.TaskInput.fromObject({
|
|
676
|
+
token: stepfunctions.JsonPath.taskToken,
|
|
677
|
+
}),
|
|
678
|
+
});
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### ❌ Large Deployment Packages
|
|
682
|
+
|
|
683
|
+
**Problem**: Large Lambda packages increase cold start time
|
|
684
|
+
|
|
685
|
+
**Solution**:
|
|
686
|
+
- Use layers for shared dependencies
|
|
687
|
+
- Externalize AWS SDK
|
|
688
|
+
- Minimize bundle size
|
|
689
|
+
|
|
690
|
+
```typescript
|
|
691
|
+
new NodejsFunction(this, 'Function', {
|
|
692
|
+
entry: 'src/handler.ts',
|
|
693
|
+
bundling: {
|
|
694
|
+
minify: true,
|
|
695
|
+
externalModules: ['@aws-sdk/*'], // Provided by runtime
|
|
696
|
+
nodeModules: ['only-needed-deps'], // Selective bundling
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
## Performance Optimization
|
|
702
|
+
|
|
703
|
+
### Cold Start Optimization
|
|
704
|
+
|
|
705
|
+
**Techniques**:
|
|
706
|
+
1. Minimize package size
|
|
707
|
+
2. Use provisioned concurrency for critical paths
|
|
708
|
+
3. Lazy load dependencies
|
|
709
|
+
4. Reuse connections outside handler
|
|
710
|
+
5. Use Lambda SnapStart (Java)
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
// For latency-sensitive APIs
|
|
714
|
+
const apiFunction = new NodejsFunction(this, 'ApiFunction', {
|
|
715
|
+
entry: 'src/api.ts',
|
|
716
|
+
memorySize: 1769, // 1 vCPU for faster initialization
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
const alias = apiFunction.currentVersion.addAlias('live');
|
|
720
|
+
alias.addAutoScaling({
|
|
721
|
+
minCapacity: 2,
|
|
722
|
+
maxCapacity: 10,
|
|
723
|
+
}).scaleOnUtilization({
|
|
724
|
+
utilizationTarget: 0.7,
|
|
725
|
+
});
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### Right-Sizing Memory
|
|
729
|
+
|
|
730
|
+
**Test different memory configurations**:
|
|
731
|
+
|
|
732
|
+
```typescript
|
|
733
|
+
// CPU-bound workload
|
|
734
|
+
new NodejsFunction(this, 'ComputeFunction', {
|
|
735
|
+
memorySize: 1769, // 1 vCPU
|
|
736
|
+
timeout: Duration.seconds(30),
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
// I/O-bound workload
|
|
740
|
+
new NodejsFunction(this, 'IOFunction', {
|
|
741
|
+
memorySize: 512, // Less CPU needed
|
|
742
|
+
timeout: Duration.seconds(60),
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
// Simple operations
|
|
746
|
+
new NodejsFunction(this, 'SimpleFunction', {
|
|
747
|
+
memorySize: 256,
|
|
748
|
+
timeout: Duration.seconds(10),
|
|
749
|
+
});
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### Concurrent Execution Control
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
// Protect downstream services
|
|
756
|
+
new NodejsFunction(this, 'Function', {
|
|
757
|
+
reservedConcurrentExecutions: 10, // Max 10 concurrent
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
// Unreserved concurrency (shared pool)
|
|
761
|
+
new NodejsFunction(this, 'Function', {
|
|
762
|
+
// Uses unreserved account concurrency
|
|
763
|
+
});
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
## Testing Strategies
|
|
767
|
+
|
|
768
|
+
### Unit Testing
|
|
769
|
+
|
|
770
|
+
Test business logic separate from AWS services:
|
|
771
|
+
|
|
772
|
+
```typescript
|
|
773
|
+
// handler.ts
|
|
774
|
+
export const processOrder = async (order: Order): Promise<Result> => {
|
|
775
|
+
// Business logic (easily testable)
|
|
776
|
+
const validated = validateOrder(order);
|
|
777
|
+
const priced = calculatePrice(validated);
|
|
778
|
+
return transformResult(priced);
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
export const handler = async (event: any): Promise<any> => {
|
|
782
|
+
const order = parseEvent(event);
|
|
783
|
+
const result = await processOrder(order);
|
|
784
|
+
await saveToDatabase(result);
|
|
785
|
+
return formatResponse(result);
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// handler.test.ts
|
|
789
|
+
test('processOrder calculates price correctly', () => {
|
|
790
|
+
const order = { items: [{ price: 10, quantity: 2 }] };
|
|
791
|
+
const result = processOrder(order);
|
|
792
|
+
expect(result.total).toBe(20);
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Integration Testing
|
|
797
|
+
|
|
798
|
+
Test with actual AWS services:
|
|
799
|
+
|
|
800
|
+
```typescript
|
|
801
|
+
// integration.test.ts
|
|
802
|
+
import { LambdaClient, InvokeCommand } from '@aws-sdk/client-lambda';
|
|
803
|
+
|
|
804
|
+
test('Lambda processes order correctly', async () => {
|
|
805
|
+
const lambda = new LambdaClient({});
|
|
806
|
+
|
|
807
|
+
const response = await lambda.send(new InvokeCommand({
|
|
808
|
+
FunctionName: process.env.FUNCTION_NAME,
|
|
809
|
+
Payload: JSON.stringify({ orderId: '123' }),
|
|
810
|
+
}));
|
|
811
|
+
|
|
812
|
+
const result = JSON.parse(Buffer.from(response.Payload!).toString());
|
|
813
|
+
expect(result.statusCode).toBe(200);
|
|
814
|
+
});
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Local Testing with SAM
|
|
818
|
+
|
|
819
|
+
```bash
|
|
820
|
+
# Test API locally
|
|
821
|
+
sam local start-api
|
|
822
|
+
|
|
823
|
+
# Invoke function locally
|
|
824
|
+
sam local invoke MyFunction -e events/test-event.json
|
|
825
|
+
|
|
826
|
+
# Generate sample event
|
|
827
|
+
sam local generate-event apigateway aws-proxy > event.json
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
## Summary
|
|
831
|
+
|
|
832
|
+
- **Single Purpose**: One function, one responsibility
|
|
833
|
+
- **Concurrent Design**: Think concurrency, not volume
|
|
834
|
+
- **Stateless**: Use external storage for state
|
|
835
|
+
- **State Machines**: Orchestrate with Step Functions
|
|
836
|
+
- **Event-Driven**: Use events over direct calls
|
|
837
|
+
- **Idempotent**: Handle failures and duplicates gracefully
|
|
838
|
+
- **Observability**: Enable tracing and structured logging
|