@trieungoctam/vibekit 1.0.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/LICENSE +21 -0
- package/README.md +85 -0
- package/agents/debugger.md +158 -0
- package/agents/docs-manager.md +220 -0
- package/agents/planner.md +129 -0
- package/agents/researcher.md +58 -0
- package/agents/reviewer.md +152 -0
- package/agents/tester.md +126 -0
- package/bin/vibekit.js +18 -0
- package/hooks/lib/ck-config-utils.cjs +831 -0
- package/hooks/lib/colors.cjs +95 -0
- package/hooks/lib/config-counter.cjs +103 -0
- package/hooks/lib/context-builder.cjs +616 -0
- package/hooks/lib/git-info-cache.cjs +143 -0
- package/hooks/lib/hook-logger.cjs +92 -0
- package/hooks/lib/privacy-checker.cjs +297 -0
- package/hooks/lib/project-detector.cjs +474 -0
- package/hooks/lib/scout-checker.cjs +263 -0
- package/hooks/lib/transcript-parser.cjs +181 -0
- package/hooks/post-edit-simplify-reminder.cjs +156 -0
- package/hooks/privacy-block.cjs +166 -0
- package/hooks/scout-block.cjs +147 -0
- package/hooks/session-init.cjs +360 -0
- package/package.json +41 -0
- package/rules/development-rules.md +52 -0
- package/rules/documentation-management.md +121 -0
- package/rules/orchestration-protocol.md +43 -0
- package/rules/primary-workflow.md +57 -0
- package/rules/team-coordination-rules.md +90 -0
- package/skills/ai/agent-browser/SKILL.md +294 -0
- package/skills/ai/agent-browser/references/.gitkeep +0 -0
- package/skills/ai/agent-browser/references/agent-browser-vs-chrome-devtools.md +112 -0
- package/skills/ai/agent-browser/references/browserbase-cloud-setup.md +161 -0
- package/skills/ai/ai-artist/SKILL.md +122 -0
- package/skills/ai/ai-artist/data/awesome-prompts.csv +3592 -0
- package/skills/ai/ai-artist/data/lighting.csv +19 -0
- package/skills/ai/ai-artist/data/nano-banana-templates.csv +17 -0
- package/skills/ai/ai-artist/data/platforms.csv +11 -0
- package/skills/ai/ai-artist/data/styles.csv +26 -0
- package/skills/ai/ai-artist/data/techniques.csv +19 -0
- package/skills/ai/ai-artist/data/use-cases.csv +16 -0
- package/skills/ai/ai-artist/references/advanced-techniques.md +184 -0
- package/skills/ai/ai-artist/references/awesome-nano-banana-pro-prompts.md +8575 -0
- package/skills/ai/ai-artist/references/domain-code.md +66 -0
- package/skills/ai/ai-artist/references/domain-data.md +72 -0
- package/skills/ai/ai-artist/references/domain-marketing.md +66 -0
- package/skills/ai/ai-artist/references/domain-patterns.md +33 -0
- package/skills/ai/ai-artist/references/domain-writing.md +68 -0
- package/skills/ai/ai-artist/references/image-prompting.md +141 -0
- package/skills/ai/ai-artist/references/llm-prompting.md +165 -0
- package/skills/ai/ai-artist/references/nano-banana.md +136 -0
- package/skills/ai/ai-artist/references/reasoning-techniques.md +201 -0
- package/skills/ai/ai-artist/references/validation-workflow.md +117 -0
- package/skills/ai/ai-artist/scripts/core.py +197 -0
- package/skills/ai/ai-artist/scripts/extract_prompts.py +102 -0
- package/skills/ai/ai-artist/scripts/generate.py +370 -0
- package/skills/ai/ai-artist/scripts/search.py +147 -0
- package/skills/ai/ai-multimodal/.env.example +204 -0
- package/skills/ai/ai-multimodal/SKILL.md +110 -0
- package/skills/ai/ai-multimodal/references/audio-processing.md +387 -0
- package/skills/ai/ai-multimodal/references/image-generation.md +939 -0
- package/skills/ai/ai-multimodal/references/music-generation.md +311 -0
- package/skills/ai/ai-multimodal/references/video-analysis.md +515 -0
- package/skills/ai/ai-multimodal/references/video-generation.md +457 -0
- package/skills/ai/ai-multimodal/references/vision-understanding.md +492 -0
- package/skills/ai/ai-multimodal/scripts/.coverage +0 -0
- package/skills/ai/ai-multimodal/scripts/check_setup.py +315 -0
- package/skills/ai/ai-multimodal/scripts/document_converter.py +395 -0
- package/skills/ai/ai-multimodal/scripts/gemini_batch_process.py +1185 -0
- package/skills/ai/ai-multimodal/scripts/media_optimizer.py +506 -0
- package/skills/ai/ai-multimodal/scripts/requirements.txt +26 -0
- package/skills/ai/ai-multimodal/scripts/tests/.coverage +0 -0
- package/skills/ai/ai-multimodal/scripts/tests/requirements.txt +20 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_document_converter.py +74 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -0
- package/skills/ai/mcp-management/README.md +219 -0
- package/skills/ai/mcp-management/SKILL.md +210 -0
- package/skills/ai/mcp-management/assets/tools.json +3146 -0
- package/skills/ai/mcp-management/references/configuration.md +114 -0
- package/skills/ai/mcp-management/references/gemini-cli-integration.md +221 -0
- package/skills/ai/mcp-management/references/mcp-protocol.md +116 -0
- package/skills/ai/mcp-management/scripts/.env.example +10 -0
- package/skills/ai/mcp-management/scripts/cli.ts +195 -0
- package/skills/ai/mcp-management/scripts/dist/analyze-tools.js +70 -0
- package/skills/ai/mcp-management/scripts/dist/cli.js +160 -0
- package/skills/ai/mcp-management/scripts/dist/mcp-client.js +183 -0
- package/skills/ai/mcp-management/scripts/mcp-client.ts +230 -0
- package/skills/ai/mcp-management/scripts/package.json +20 -0
- package/skills/ai/mcp-management/scripts/tsconfig.json +15 -0
- package/skills/core/brainstorm/SKILL.md +164 -0
- package/skills/core/brainstorm/scripts/frame-template.html +214 -0
- package/skills/core/brainstorm/scripts/helper.js +88 -0
- package/skills/core/brainstorm/scripts/server.cjs +338 -0
- package/skills/core/brainstorm/scripts/start-server.sh +153 -0
- package/skills/core/brainstorm/scripts/stop-server.sh +55 -0
- package/skills/core/brainstorm/spec-document-reviewer-prompt.md +49 -0
- package/skills/core/brainstorm/visual-companion.md +286 -0
- package/skills/core/code-review/SKILL.md +147 -0
- package/skills/core/code-review/references/code-review-reception.md +113 -0
- package/skills/core/code-review/references/codebase-scan-workflow.md +29 -0
- package/skills/core/code-review/references/edge-case-scouting.md +119 -0
- package/skills/core/code-review/references/parallel-review-workflow.md +69 -0
- package/skills/core/code-review/references/requesting-code-review.md +116 -0
- package/skills/core/code-review/references/task-management-reviews.md +140 -0
- package/skills/core/code-review/references/verification-before-completion.md +139 -0
- package/skills/core/cook/README.md +86 -0
- package/skills/core/cook/SKILL.md +113 -0
- package/skills/core/cook/references/intent-detection.md +101 -0
- package/skills/core/cook/references/review-cycle.md +75 -0
- package/skills/core/cook/references/subagent-patterns.md +75 -0
- package/skills/core/cook/references/workflow-steps.md +172 -0
- package/skills/core/debug/SKILL.md +121 -0
- package/skills/core/debug/references/defense-in-depth.md +124 -0
- package/skills/core/debug/references/frontend-verification.md +103 -0
- package/skills/core/debug/references/investigation-methodology.md +101 -0
- package/skills/core/debug/references/log-and-ci-analysis.md +97 -0
- package/skills/core/debug/references/performance-diagnostics.md +113 -0
- package/skills/core/debug/references/reporting-standards.md +122 -0
- package/skills/core/debug/references/root-cause-tracing.md +122 -0
- package/skills/core/debug/references/systematic-debugging.md +102 -0
- package/skills/core/debug/references/task-management-debugging.md +155 -0
- package/skills/core/debug/references/verification.md +123 -0
- package/skills/core/debug/scripts/find-polluter.sh +63 -0
- package/skills/core/debug/scripts/find-polluter.test.md +102 -0
- package/skills/core/execute/SKILL.md +70 -0
- package/skills/core/fix/SKILL.md +111 -0
- package/skills/core/fix/references/complexity-assessment.md +72 -0
- package/skills/core/fix/references/mode-selection.md +46 -0
- package/skills/core/fix/references/parallel-exploration.md +100 -0
- package/skills/core/fix/references/review-cycle.md +77 -0
- package/skills/core/fix/references/skill-activation-matrix.md +78 -0
- package/skills/core/fix/references/task-orchestration.md +103 -0
- package/skills/core/fix/references/workflow-ci.md +28 -0
- package/skills/core/fix/references/workflow-deep.md +122 -0
- package/skills/core/fix/references/workflow-logs.md +72 -0
- package/skills/core/fix/references/workflow-quick.md +59 -0
- package/skills/core/fix/references/workflow-standard.md +111 -0
- package/skills/core/fix/references/workflow-test.md +75 -0
- package/skills/core/fix/references/workflow-types.md +33 -0
- package/skills/core/fix/references/workflow-ui.md +75 -0
- package/skills/core/plan/SKILL.md +145 -0
- package/skills/core/plan/plan-document-reviewer-prompt.md +49 -0
- package/skills/core/subagent-dev/SKILL.md +277 -0
- package/skills/core/subagent-dev/code-quality-reviewer-prompt.md +26 -0
- package/skills/core/subagent-dev/implementer-prompt.md +113 -0
- package/skills/core/subagent-dev/spec-reviewer-prompt.md +61 -0
- package/skills/core/tdd/SKILL.md +371 -0
- package/skills/core/tdd/testing-anti-patterns.md +299 -0
- package/skills/core/test/SKILL.md +109 -0
- package/skills/core/test/references/report-format.md +58 -0
- package/skills/core/test/references/test-execution-workflow.md +103 -0
- package/skills/core/test/references/ui-testing-workflow.md +65 -0
- package/skills/core/verify/SKILL.md +139 -0
- package/skills/dev/backend-dev/SKILL.md +96 -0
- package/skills/dev/backend-dev/references/backend-api-design.md +495 -0
- package/skills/dev/backend-dev/references/backend-architecture.md +454 -0
- package/skills/dev/backend-dev/references/backend-authentication.md +338 -0
- package/skills/dev/backend-dev/references/backend-code-quality.md +659 -0
- package/skills/dev/backend-dev/references/backend-debugging.md +904 -0
- package/skills/dev/backend-dev/references/backend-devops.md +494 -0
- package/skills/dev/backend-dev/references/backend-mindset.md +387 -0
- package/skills/dev/backend-dev/references/backend-performance.md +397 -0
- package/skills/dev/backend-dev/references/backend-security.md +290 -0
- package/skills/dev/backend-dev/references/backend-technologies.md +256 -0
- package/skills/dev/backend-dev/references/backend-testing.md +429 -0
- package/skills/dev/context-engineering/SKILL.md +108 -0
- package/skills/dev/context-engineering/references/context-compression.md +84 -0
- package/skills/dev/context-engineering/references/context-degradation.md +93 -0
- package/skills/dev/context-engineering/references/context-fundamentals.md +75 -0
- package/skills/dev/context-engineering/references/context-optimization.md +82 -0
- package/skills/dev/context-engineering/references/evaluation.md +89 -0
- package/skills/dev/context-engineering/references/memory-systems.md +88 -0
- package/skills/dev/context-engineering/references/multi-agent-patterns.md +90 -0
- package/skills/dev/context-engineering/references/project-development.md +97 -0
- package/skills/dev/context-engineering/references/runtime-awareness.md +202 -0
- package/skills/dev/context-engineering/references/tool-design.md +86 -0
- package/skills/dev/context-engineering/scripts/compression_evaluator.py +349 -0
- package/skills/dev/context-engineering/scripts/context_analyzer.py +317 -0
- package/skills/dev/context-engineering/scripts/tests/test_edge_cases.py +246 -0
- package/skills/dev/databases/SKILL.md +84 -0
- package/skills/dev/databases/analytics.md +198 -0
- package/skills/dev/databases/db-design.md +188 -0
- package/skills/dev/databases/incremental-etl.md +213 -0
- package/skills/dev/databases/references/mongodb-aggregation.md +447 -0
- package/skills/dev/databases/references/mongodb-atlas.md +465 -0
- package/skills/dev/databases/references/mongodb-crud.md +408 -0
- package/skills/dev/databases/references/mongodb-indexing.md +442 -0
- package/skills/dev/databases/references/postgresql-administration.md +594 -0
- package/skills/dev/databases/references/postgresql-performance.md +527 -0
- package/skills/dev/databases/references/postgresql-psql-cli.md +467 -0
- package/skills/dev/databases/references/postgresql-queries.md +475 -0
- package/skills/dev/databases/scripts/.coverage +0 -0
- package/skills/dev/databases/scripts/db_backup.py +502 -0
- package/skills/dev/databases/scripts/db_migrate.py +426 -0
- package/skills/dev/databases/scripts/db_performance_check.py +457 -0
- package/skills/dev/databases/scripts/requirements.txt +20 -0
- package/skills/dev/databases/scripts/tests/coverage-db.json +1 -0
- package/skills/dev/databases/scripts/tests/requirements.txt +4 -0
- package/skills/dev/databases/scripts/tests/test_db_backup.py +340 -0
- package/skills/dev/databases/scripts/tests/test_db_migrate.py +277 -0
- package/skills/dev/databases/scripts/tests/test_db_performance_check.py +370 -0
- package/skills/dev/databases/stacks/bigquery.md +231 -0
- package/skills/dev/databases/stacks/d1_cloudflare.md +137 -0
- package/skills/dev/databases/stacks/mysql.md +216 -0
- package/skills/dev/databases/stacks/postgres.md +235 -0
- package/skills/dev/databases/stacks/sqlite.md +244 -0
- package/skills/dev/databases/transactional.md +176 -0
- package/skills/dev/devops/.env.example +76 -0
- package/skills/dev/devops/SKILL.md +97 -0
- package/skills/dev/devops/references/browser-rendering.md +305 -0
- package/skills/dev/devops/references/cloudflare-d1-kv.md +123 -0
- package/skills/dev/devops/references/cloudflare-platform.md +271 -0
- package/skills/dev/devops/references/cloudflare-r2-storage.md +280 -0
- package/skills/dev/devops/references/cloudflare-workers-advanced.md +312 -0
- package/skills/dev/devops/references/cloudflare-workers-apis.md +309 -0
- package/skills/dev/devops/references/cloudflare-workers-basics.md +418 -0
- package/skills/dev/devops/references/docker-basics.md +297 -0
- package/skills/dev/devops/references/docker-compose.md +292 -0
- package/skills/dev/devops/references/gcloud-platform.md +297 -0
- package/skills/dev/devops/references/gcloud-services.md +304 -0
- package/skills/dev/devops/references/kubernetes-basics.md +99 -0
- package/skills/dev/devops/references/kubernetes-helm-advanced.md +75 -0
- package/skills/dev/devops/references/kubernetes-helm.md +81 -0
- package/skills/dev/devops/references/kubernetes-kubectl.md +74 -0
- package/skills/dev/devops/references/kubernetes-security-advanced.md +98 -0
- package/skills/dev/devops/references/kubernetes-security.md +95 -0
- package/skills/dev/devops/references/kubernetes-troubleshooting-advanced.md +74 -0
- package/skills/dev/devops/references/kubernetes-troubleshooting.md +49 -0
- package/skills/dev/devops/references/kubernetes-workflows-advanced.md +75 -0
- package/skills/dev/devops/references/kubernetes-workflows.md +78 -0
- package/skills/dev/devops/scripts/cloudflare_deploy.py +269 -0
- package/skills/dev/devops/scripts/docker_optimize.py +332 -0
- package/skills/dev/devops/scripts/requirements.txt +20 -0
- package/skills/dev/devops/scripts/tests/requirements.txt +3 -0
- package/skills/dev/devops/scripts/tests/test_cloudflare_deploy.py +285 -0
- package/skills/dev/devops/scripts/tests/test_docker_optimize.py +436 -0
- package/skills/dev/frontend-design/SKILL.md +78 -0
- package/skills/dev/frontend-design/references/ai-multimodal-overview.md +165 -0
- package/skills/dev/frontend-design/references/analysis-best-practices.md +80 -0
- package/skills/dev/frontend-design/references/analysis-prompts.md +141 -0
- package/skills/dev/frontend-design/references/analysis-techniques.md +118 -0
- package/skills/dev/frontend-design/references/animejs.md +396 -0
- package/skills/dev/frontend-design/references/asset-generation.md +337 -0
- package/skills/dev/frontend-design/references/design-extraction-overview.md +71 -0
- package/skills/dev/frontend-design/references/extraction-best-practices.md +141 -0
- package/skills/dev/frontend-design/references/extraction-output-templates.md +162 -0
- package/skills/dev/frontend-design/references/extraction-prompts.md +127 -0
- package/skills/dev/frontend-design/references/technical-accessibility.md +119 -0
- package/skills/dev/frontend-design/references/technical-best-practices.md +97 -0
- package/skills/dev/frontend-design/references/technical-optimization.md +44 -0
- package/skills/dev/frontend-design/references/technical-overview.md +90 -0
- package/skills/dev/frontend-design/references/technical-workflows.md +150 -0
- package/skills/dev/frontend-design/references/visual-analysis-overview.md +95 -0
- package/skills/dev/frontend-design/references/workflow-3d.md +102 -0
- package/skills/dev/frontend-design/references/workflow-describe.md +87 -0
- package/skills/dev/frontend-design/references/workflow-immersive.md +87 -0
- package/skills/dev/frontend-design/references/workflow-quick.md +57 -0
- package/skills/dev/frontend-design/references/workflow-screenshot.md +63 -0
- package/skills/dev/frontend-design/references/workflow-video.md +74 -0
- package/skills/dev/frontend-dev/SKILL.md +400 -0
- package/skills/dev/frontend-dev/resources/common-patterns.md +331 -0
- package/skills/dev/frontend-dev/resources/complete-examples.md +872 -0
- package/skills/dev/frontend-dev/resources/component-patterns.md +502 -0
- package/skills/dev/frontend-dev/resources/data-fetching.md +767 -0
- package/skills/dev/frontend-dev/resources/file-organization.md +502 -0
- package/skills/dev/frontend-dev/resources/loading-and-error-states.md +501 -0
- package/skills/dev/frontend-dev/resources/performance.md +406 -0
- package/skills/dev/frontend-dev/resources/routing-guide.md +364 -0
- package/skills/dev/frontend-dev/resources/styling-guide.md +428 -0
- package/skills/dev/frontend-dev/resources/typescript-standards.md +418 -0
- package/skills/dev/git/SKILL.md +114 -0
- package/skills/dev/git/references/branch-management.md +88 -0
- package/skills/dev/git/references/commit-standards.md +46 -0
- package/skills/dev/git/references/gh-cli-guide.md +109 -0
- package/skills/dev/git/references/safety-protocols.md +69 -0
- package/skills/dev/git/references/workflow-commit.md +58 -0
- package/skills/dev/git/references/workflow-merge.md +48 -0
- package/skills/dev/git/references/workflow-pr.md +58 -0
- package/skills/dev/git/references/workflow-push.md +52 -0
- package/skills/dev/git-worktree/SKILL.md +218 -0
- package/skills/utils/ask/SKILL.md +58 -0
- package/skills/utils/bootstrap/SKILL.md +101 -0
- package/skills/utils/bootstrap/references/shared-phases.md +59 -0
- package/skills/utils/bootstrap/references/workflow-auto.md +52 -0
- package/skills/utils/bootstrap/references/workflow-fast.md +50 -0
- package/skills/utils/bootstrap/references/workflow-full.md +60 -0
- package/skills/utils/bootstrap/references/workflow-parallel.md +59 -0
- package/skills/utils/ck-help/SKILL.md +102 -0
- package/skills/utils/ck-help/scripts/ck-help.py +1321 -0
- package/skills/utils/ck-help/scripts/commands_data.yaml +3 -0
- package/skills/utils/ck-help/scripts/skills_data.yaml +593 -0
- package/skills/utils/copywriting/SKILL.md +94 -0
- package/skills/utils/copywriting/references/copy-formulas.md +150 -0
- package/skills/utils/copywriting/references/cta-patterns.md +168 -0
- package/skills/utils/copywriting/references/email-copy.md +193 -0
- package/skills/utils/copywriting/references/headline-templates.md +140 -0
- package/skills/utils/copywriting/references/landing-page-copy.md +175 -0
- package/skills/utils/copywriting/references/power-words.md +189 -0
- package/skills/utils/copywriting/references/social-media-copy.md +222 -0
- package/skills/utils/copywriting/references/workflow-cro.md +83 -0
- package/skills/utils/copywriting/references/workflow-enhance.md +32 -0
- package/skills/utils/copywriting/references/workflow-fast.md +29 -0
- package/skills/utils/copywriting/references/workflow-good.md +39 -0
- package/skills/utils/copywriting/references/writing-styles.md +247 -0
- package/skills/utils/copywriting/scripts/extract-writing-styles.py +308 -0
- package/skills/utils/copywriting/templates/copy-brief.md +49 -0
- package/skills/utils/docs/SKILL.md +55 -0
- package/skills/utils/docs/references/init-workflow.md +32 -0
- package/skills/utils/docs/references/summarize-workflow.md +18 -0
- package/skills/utils/docs/references/update-workflow.md +59 -0
- package/skills/utils/journal/SKILL.md +11 -0
- package/skills/utils/kanban/SKILL.md +99 -0
- package/skills/utils/preview/SKILL.md +75 -0
- package/skills/utils/preview/references/generation-modes.md +95 -0
- package/skills/utils/preview/references/view-mode.md +42 -0
- package/skills/utils/repomix/SKILL.md +248 -0
- package/skills/utils/repomix/references/configuration.md +211 -0
- package/skills/utils/repomix/references/usage-patterns.md +232 -0
- package/skills/utils/repomix/scripts/.coverage +0 -0
- package/skills/utils/repomix/scripts/README.md +179 -0
- package/skills/utils/repomix/scripts/repomix_batch.py +455 -0
- package/skills/utils/repomix/scripts/repos.example.json +15 -0
- package/skills/utils/repomix/scripts/requirements.txt +15 -0
- package/skills/utils/repomix/scripts/tests/test_repomix_batch.py +531 -0
- package/skills/utils/research/SKILL.md +171 -0
- package/skills/utils/scout/SKILL.md +89 -0
- package/skills/utils/scout/references/external-scouting.md +140 -0
- package/skills/utils/scout/references/internal-scouting.md +119 -0
- package/skills/utils/scout/references/task-management-scouting.md +125 -0
- package/skills/utils/sequential-thinking/.env.example +8 -0
- package/skills/utils/sequential-thinking/README.md +183 -0
- package/skills/utils/sequential-thinking/SKILL.md +95 -0
- package/skills/utils/sequential-thinking/package.json +31 -0
- package/skills/utils/sequential-thinking/references/advanced-strategies.md +79 -0
- package/skills/utils/sequential-thinking/references/advanced-techniques.md +76 -0
- package/skills/utils/sequential-thinking/references/core-patterns.md +95 -0
- package/skills/utils/sequential-thinking/references/examples-api.md +88 -0
- package/skills/utils/sequential-thinking/references/examples-architecture.md +94 -0
- package/skills/utils/sequential-thinking/references/examples-debug.md +90 -0
- package/skills/utils/sequential-thinking/scripts/format-thought.js +159 -0
- package/skills/utils/sequential-thinking/scripts/process-thought.js +236 -0
- package/skills/utils/sequential-thinking/tests/format-thought.test.js +133 -0
- package/skills/utils/sequential-thinking/tests/process-thought.test.js +215 -0
- package/skills/utils/write-skill/SKILL.md +655 -0
- package/skills/utils/write-skill/anthropic-best-practices.md +1150 -0
- package/skills/utils/write-skill/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/utils/write-skill/graphviz-conventions.dot +172 -0
- package/skills/utils/write-skill/persuasion-principles.md +187 -0
- package/skills/utils/write-skill/render-graphs.js +168 -0
- package/skills/utils/write-skill/testing-skills-with-subagents.md +384 -0
- package/src/commands/init.js +238 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"""Tests for db_performance_check.py"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from unittest.mock import Mock, patch, MagicMock
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
# Add parent directory to path
|
|
12
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
13
|
+
|
|
14
|
+
from db_performance_check import (
|
|
15
|
+
SlowQuery, IndexRecommendation, PerformanceReport, PerformanceAnalyzer
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def mock_mongo_client():
|
|
21
|
+
"""Mock MongoDB client."""
|
|
22
|
+
mock_client = MagicMock()
|
|
23
|
+
mock_db = MagicMock()
|
|
24
|
+
mock_client.get_default_database.return_value = mock_db
|
|
25
|
+
mock_client.server_info.return_value = {}
|
|
26
|
+
return mock_client, mock_db
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.fixture
|
|
30
|
+
def mock_postgres_conn():
|
|
31
|
+
"""Mock PostgreSQL connection."""
|
|
32
|
+
mock_conn = MagicMock()
|
|
33
|
+
mock_cursor = MagicMock()
|
|
34
|
+
mock_conn.cursor.return_value.__enter__.return_value = mock_cursor
|
|
35
|
+
return mock_conn, mock_cursor
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TestSlowQuery:
|
|
39
|
+
"""Test SlowQuery dataclass."""
|
|
40
|
+
|
|
41
|
+
def test_slow_query_creation(self):
|
|
42
|
+
"""Test creating slow query object."""
|
|
43
|
+
query = SlowQuery(
|
|
44
|
+
query="SELECT * FROM users",
|
|
45
|
+
execution_time_ms=150.5,
|
|
46
|
+
count=10
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
assert query.query == "SELECT * FROM users"
|
|
50
|
+
assert query.execution_time_ms == 150.5
|
|
51
|
+
assert query.count == 10
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TestIndexRecommendation:
|
|
55
|
+
"""Test IndexRecommendation dataclass."""
|
|
56
|
+
|
|
57
|
+
def test_recommendation_creation(self):
|
|
58
|
+
"""Test creating index recommendation."""
|
|
59
|
+
rec = IndexRecommendation(
|
|
60
|
+
collection_or_table="users",
|
|
61
|
+
fields=["email"],
|
|
62
|
+
reason="Frequently queried field",
|
|
63
|
+
estimated_benefit="High"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
assert rec.collection_or_table == "users"
|
|
67
|
+
assert rec.fields == ["email"]
|
|
68
|
+
assert rec.reason == "Frequently queried field"
|
|
69
|
+
assert rec.estimated_benefit == "High"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestPerformanceReport:
|
|
73
|
+
"""Test PerformanceReport dataclass."""
|
|
74
|
+
|
|
75
|
+
def test_report_creation(self):
|
|
76
|
+
"""Test creating performance report."""
|
|
77
|
+
report = PerformanceReport(
|
|
78
|
+
database_type="mongodb",
|
|
79
|
+
database_name="testdb",
|
|
80
|
+
timestamp=datetime.now(),
|
|
81
|
+
slow_queries=[],
|
|
82
|
+
index_recommendations=[],
|
|
83
|
+
database_metrics={}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
assert report.database_type == "mongodb"
|
|
87
|
+
assert report.database_name == "testdb"
|
|
88
|
+
assert isinstance(report.slow_queries, list)
|
|
89
|
+
assert isinstance(report.index_recommendations, list)
|
|
90
|
+
assert isinstance(report.database_metrics, dict)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class TestPerformanceAnalyzer:
|
|
94
|
+
"""Test PerformanceAnalyzer class."""
|
|
95
|
+
|
|
96
|
+
def test_init(self):
|
|
97
|
+
"""Test analyzer initialization."""
|
|
98
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost", 100)
|
|
99
|
+
|
|
100
|
+
assert analyzer.db_type == "mongodb"
|
|
101
|
+
assert analyzer.connection_string == "mongodb://localhost"
|
|
102
|
+
assert analyzer.threshold_ms == 100
|
|
103
|
+
|
|
104
|
+
@patch('db_performance_check.MongoClient')
|
|
105
|
+
def test_connect_mongodb(self, mock_client_class, mock_mongo_client):
|
|
106
|
+
"""Test MongoDB connection."""
|
|
107
|
+
mock_client, mock_db = mock_mongo_client
|
|
108
|
+
mock_client_class.return_value = mock_client
|
|
109
|
+
|
|
110
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
111
|
+
result = analyzer.connect()
|
|
112
|
+
|
|
113
|
+
assert result is True
|
|
114
|
+
assert analyzer.client == mock_client
|
|
115
|
+
assert analyzer.db == mock_db
|
|
116
|
+
|
|
117
|
+
@patch('db_performance_check.psycopg2')
|
|
118
|
+
def test_connect_postgres(self, mock_psycopg2, mock_postgres_conn):
|
|
119
|
+
"""Test PostgreSQL connection."""
|
|
120
|
+
mock_conn, mock_cursor = mock_postgres_conn
|
|
121
|
+
mock_psycopg2.connect.return_value = mock_conn
|
|
122
|
+
|
|
123
|
+
analyzer = PerformanceAnalyzer("postgres", "postgresql://localhost")
|
|
124
|
+
result = analyzer.connect()
|
|
125
|
+
|
|
126
|
+
assert result is True
|
|
127
|
+
assert analyzer.conn == mock_conn
|
|
128
|
+
|
|
129
|
+
def test_connect_unsupported_db(self):
|
|
130
|
+
"""Test connection with unsupported database type."""
|
|
131
|
+
analyzer = PerformanceAnalyzer("unsupported", "connection_string")
|
|
132
|
+
result = analyzer.connect()
|
|
133
|
+
|
|
134
|
+
assert result is False
|
|
135
|
+
|
|
136
|
+
@patch('db_performance_check.MongoClient')
|
|
137
|
+
def test_analyze_mongodb(self, mock_client_class, mock_mongo_client):
|
|
138
|
+
"""Test MongoDB performance analysis."""
|
|
139
|
+
mock_client, mock_db = mock_mongo_client
|
|
140
|
+
mock_client_class.return_value = mock_client
|
|
141
|
+
|
|
142
|
+
# Mock profiling
|
|
143
|
+
mock_db.command.side_effect = [
|
|
144
|
+
{"was": 0}, # profile -1 (get status)
|
|
145
|
+
{}, # profile 1 (enable)
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
# Mock slow queries
|
|
149
|
+
mock_profile_cursor = MagicMock()
|
|
150
|
+
mock_profile_cursor.sort.return_value = [
|
|
151
|
+
{
|
|
152
|
+
"command": {"find": "users"},
|
|
153
|
+
"millis": 150,
|
|
154
|
+
"ns": "testdb.users",
|
|
155
|
+
"planSummary": "COLLSCAN"
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
mock_db.system.profile.find.return_value = mock_profile_cursor
|
|
159
|
+
|
|
160
|
+
# Mock collections
|
|
161
|
+
mock_db.list_collection_names.return_value = ["users", "orders"]
|
|
162
|
+
|
|
163
|
+
# Mock collection stats
|
|
164
|
+
mock_coll = MagicMock()
|
|
165
|
+
mock_coll.aggregate.return_value = [{"storageStats": {}}]
|
|
166
|
+
mock_coll.list_indexes.return_value = [{"name": "_id_"}]
|
|
167
|
+
mock_coll.find.return_value.limit.return_value = [
|
|
168
|
+
{"_id": 1, "name": "Alice", "email": "alice@example.com"}
|
|
169
|
+
]
|
|
170
|
+
mock_db.__getitem__.return_value = mock_coll
|
|
171
|
+
|
|
172
|
+
# Mock server status and db stats
|
|
173
|
+
mock_client.admin.command.return_value = {
|
|
174
|
+
"connections": {"current": 10},
|
|
175
|
+
"opcounters": {"query": 1000}
|
|
176
|
+
}
|
|
177
|
+
mock_db.command.return_value = {
|
|
178
|
+
"dataSize": 1024 * 1024 * 100,
|
|
179
|
+
"indexSize": 1024 * 1024 * 10,
|
|
180
|
+
"collections": 5
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
184
|
+
analyzer.connect()
|
|
185
|
+
|
|
186
|
+
report = analyzer.analyze()
|
|
187
|
+
|
|
188
|
+
assert report is not None
|
|
189
|
+
assert report.database_type == "mongodb"
|
|
190
|
+
assert isinstance(report.slow_queries, list)
|
|
191
|
+
assert isinstance(report.index_recommendations, list)
|
|
192
|
+
assert isinstance(report.database_metrics, dict)
|
|
193
|
+
|
|
194
|
+
@patch('db_performance_check.psycopg2')
|
|
195
|
+
def test_analyze_postgres(self, mock_psycopg2, mock_postgres_conn):
|
|
196
|
+
"""Test PostgreSQL performance analysis."""
|
|
197
|
+
mock_conn, mock_cursor = mock_postgres_conn
|
|
198
|
+
mock_psycopg2.connect.return_value = mock_conn
|
|
199
|
+
|
|
200
|
+
# Mock cursor results
|
|
201
|
+
mock_cursor.fetchone.side_effect = [
|
|
202
|
+
{"has_extension": True}, # pg_stat_statements check
|
|
203
|
+
{"connections": 10, "commits": 1000, "rollbacks": 5}, # stats
|
|
204
|
+
{"db_size": 1024 * 1024 * 500}, # database size
|
|
205
|
+
{"cache_hit_ratio": 0.95} # cache hit ratio
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
mock_cursor.fetchall.side_effect = [
|
|
209
|
+
# Slow queries
|
|
210
|
+
[
|
|
211
|
+
{
|
|
212
|
+
"query": "SELECT * FROM users",
|
|
213
|
+
"mean_exec_time": 150.5,
|
|
214
|
+
"calls": 100,
|
|
215
|
+
"total_exec_time": 15050
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
# Sequential scans
|
|
219
|
+
[
|
|
220
|
+
{
|
|
221
|
+
"schemaname": "public",
|
|
222
|
+
"tablename": "users",
|
|
223
|
+
"seq_scan": 5000,
|
|
224
|
+
"seq_tup_read": 500000,
|
|
225
|
+
"idx_scan": 100
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
# Unused indexes
|
|
229
|
+
[]
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
analyzer = PerformanceAnalyzer("postgres", "postgresql://localhost")
|
|
233
|
+
analyzer.connect()
|
|
234
|
+
|
|
235
|
+
report = analyzer.analyze()
|
|
236
|
+
|
|
237
|
+
assert report is not None
|
|
238
|
+
assert report.database_type == "postgres"
|
|
239
|
+
assert len(report.slow_queries) > 0
|
|
240
|
+
assert len(report.index_recommendations) > 0
|
|
241
|
+
|
|
242
|
+
def test_print_report(self, capsys):
|
|
243
|
+
"""Test report printing."""
|
|
244
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
245
|
+
|
|
246
|
+
report = PerformanceReport(
|
|
247
|
+
database_type="mongodb",
|
|
248
|
+
database_name="testdb",
|
|
249
|
+
timestamp=datetime.now(),
|
|
250
|
+
slow_queries=[
|
|
251
|
+
SlowQuery(
|
|
252
|
+
query="db.users.find({age: {$gte: 18}})",
|
|
253
|
+
execution_time_ms=150.5,
|
|
254
|
+
count=10,
|
|
255
|
+
collection_or_table="users"
|
|
256
|
+
)
|
|
257
|
+
],
|
|
258
|
+
index_recommendations=[
|
|
259
|
+
IndexRecommendation(
|
|
260
|
+
collection_or_table="users",
|
|
261
|
+
fields=["age"],
|
|
262
|
+
reason="Frequently queried field",
|
|
263
|
+
estimated_benefit="High"
|
|
264
|
+
)
|
|
265
|
+
],
|
|
266
|
+
database_metrics={
|
|
267
|
+
"connections": 10,
|
|
268
|
+
"database_size_mb": 100.5
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
analyzer.print_report(report)
|
|
273
|
+
|
|
274
|
+
captured = capsys.readouterr()
|
|
275
|
+
assert "Database Performance Report" in captured.out
|
|
276
|
+
assert "testdb" in captured.out
|
|
277
|
+
assert "150.5ms" in captured.out
|
|
278
|
+
assert "users" in captured.out
|
|
279
|
+
|
|
280
|
+
def test_save_report(self, tmp_path):
|
|
281
|
+
"""Test saving report to JSON."""
|
|
282
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
283
|
+
|
|
284
|
+
report = PerformanceReport(
|
|
285
|
+
database_type="mongodb",
|
|
286
|
+
database_name="testdb",
|
|
287
|
+
timestamp=datetime.now(),
|
|
288
|
+
slow_queries=[],
|
|
289
|
+
index_recommendations=[],
|
|
290
|
+
database_metrics={}
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
output_file = tmp_path / "report.json"
|
|
294
|
+
analyzer.save_report(report, str(output_file))
|
|
295
|
+
|
|
296
|
+
assert output_file.exists()
|
|
297
|
+
|
|
298
|
+
with open(output_file) as f:
|
|
299
|
+
data = json.load(f)
|
|
300
|
+
assert data["database_type"] == "mongodb"
|
|
301
|
+
assert data["database_name"] == "testdb"
|
|
302
|
+
|
|
303
|
+
def test_disconnect(self):
|
|
304
|
+
"""Test disconnection."""
|
|
305
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
306
|
+
|
|
307
|
+
# Mock client and connection
|
|
308
|
+
analyzer.client = MagicMock()
|
|
309
|
+
analyzer.conn = MagicMock()
|
|
310
|
+
|
|
311
|
+
analyzer.disconnect()
|
|
312
|
+
|
|
313
|
+
analyzer.client.close.assert_called_once()
|
|
314
|
+
analyzer.conn.close.assert_called_once()
|
|
315
|
+
|
|
316
|
+
@patch('db_performance_check.MongoClient')
|
|
317
|
+
def test_analyze_error_handling(self, mock_client_class, mock_mongo_client):
|
|
318
|
+
"""Test error handling during analysis."""
|
|
319
|
+
mock_client, mock_db = mock_mongo_client
|
|
320
|
+
mock_client_class.return_value = mock_client
|
|
321
|
+
|
|
322
|
+
# Simulate error
|
|
323
|
+
mock_db.command.side_effect = Exception("Database error")
|
|
324
|
+
|
|
325
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost")
|
|
326
|
+
analyzer.connect()
|
|
327
|
+
|
|
328
|
+
report = analyzer.analyze()
|
|
329
|
+
|
|
330
|
+
assert report is None
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class TestIntegration:
|
|
334
|
+
"""Integration tests."""
|
|
335
|
+
|
|
336
|
+
@patch('db_performance_check.MongoClient')
|
|
337
|
+
def test_full_mongodb_workflow(self, mock_client_class, mock_mongo_client, tmp_path):
|
|
338
|
+
"""Test complete MongoDB analysis workflow."""
|
|
339
|
+
mock_client, mock_db = mock_mongo_client
|
|
340
|
+
mock_client_class.return_value = mock_client
|
|
341
|
+
|
|
342
|
+
# Setup mocks
|
|
343
|
+
mock_db.command.return_value = {"was": 0}
|
|
344
|
+
mock_db.system.profile.find.return_value.sort.return_value = []
|
|
345
|
+
mock_db.list_collection_names.return_value = []
|
|
346
|
+
mock_client.admin.command.return_value = {
|
|
347
|
+
"connections": {"current": 10},
|
|
348
|
+
"opcounters": {"query": 1000}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
analyzer = PerformanceAnalyzer("mongodb", "mongodb://localhost", 100)
|
|
352
|
+
|
|
353
|
+
# Connect
|
|
354
|
+
assert analyzer.connect() is True
|
|
355
|
+
|
|
356
|
+
# Analyze
|
|
357
|
+
report = analyzer.analyze()
|
|
358
|
+
assert report is not None
|
|
359
|
+
|
|
360
|
+
# Save report
|
|
361
|
+
output_file = tmp_path / "report.json"
|
|
362
|
+
analyzer.save_report(report, str(output_file))
|
|
363
|
+
assert output_file.exists()
|
|
364
|
+
|
|
365
|
+
# Disconnect
|
|
366
|
+
analyzer.disconnect()
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
if __name__ == "__main__":
|
|
370
|
+
pytest.main([__file__, "-v"])
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# BigQuery Rules
|
|
2
|
+
|
|
3
|
+
Guidelines for designing schemas specific to Google BigQuery.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Data Types
|
|
8
|
+
|
|
9
|
+
| Use case | Type | Notes |
|
|
10
|
+
|----------|------|-------|
|
|
11
|
+
| Integer | `INT64` | |
|
|
12
|
+
| Decimal | `NUMERIC` or `BIGNUMERIC` | |
|
|
13
|
+
| Float | `FLOAT64` | |
|
|
14
|
+
| Boolean | `BOOL` | |
|
|
15
|
+
| String | `STRING` | |
|
|
16
|
+
| Timestamp | `TIMESTAMP` | |
|
|
17
|
+
| Date | `DATE` | |
|
|
18
|
+
| Time | `TIME` | |
|
|
19
|
+
| DateTime | `DATETIME` | No timezone |
|
|
20
|
+
| JSON | `JSON` | |
|
|
21
|
+
| Bytes | `BYTES` | |
|
|
22
|
+
| Nested | `STRUCT` | Record type |
|
|
23
|
+
| Repeated | `ARRAY` | |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Description (NO metadata tables needed)
|
|
28
|
+
|
|
29
|
+
BigQuery supports description via `OPTIONS`:
|
|
30
|
+
|
|
31
|
+
### Table description
|
|
32
|
+
```sql
|
|
33
|
+
CREATE TABLE orders (
|
|
34
|
+
...
|
|
35
|
+
) OPTIONS(description='Table storing customer orders');
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Column descriptions
|
|
39
|
+
```sql
|
|
40
|
+
CREATE TABLE orders (
|
|
41
|
+
id INT64 NOT NULL OPTIONS(description='Primary key'),
|
|
42
|
+
order_number STRING NOT NULL OPTIONS(description='Unique order code'),
|
|
43
|
+
status STRING NOT NULL OPTIONS(description='pending|confirmed|shipped|cancelled'),
|
|
44
|
+
total_amount NUMERIC OPTIONS(description='Total value')
|
|
45
|
+
);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Query descriptions
|
|
49
|
+
```sql
|
|
50
|
+
SELECT column_name, description
|
|
51
|
+
FROM `project.dataset.INFORMATION_SCHEMA.COLUMN_FIELD_PATHS`
|
|
52
|
+
WHERE table_name = 'orders';
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Partitioning & Clustering
|
|
58
|
+
|
|
59
|
+
BigQuery **does not have traditional indexes**. Instead, use partitioning and clustering:
|
|
60
|
+
|
|
61
|
+
### Partitioning (required for large tables)
|
|
62
|
+
|
|
63
|
+
```sql
|
|
64
|
+
-- Partition by date column
|
|
65
|
+
CREATE TABLE fact_orders (
|
|
66
|
+
order_date DATE,
|
|
67
|
+
customer_id INT64,
|
|
68
|
+
order_id INT64,
|
|
69
|
+
amount NUMERIC
|
|
70
|
+
)
|
|
71
|
+
PARTITION BY order_date;
|
|
72
|
+
|
|
73
|
+
-- Partition by timestamp (daily)
|
|
74
|
+
CREATE TABLE events (
|
|
75
|
+
event_time TIMESTAMP,
|
|
76
|
+
...
|
|
77
|
+
)
|
|
78
|
+
PARTITION BY DATE(event_time);
|
|
79
|
+
|
|
80
|
+
-- Integer range partitioning
|
|
81
|
+
CREATE TABLE logs (
|
|
82
|
+
log_id INT64,
|
|
83
|
+
...
|
|
84
|
+
)
|
|
85
|
+
PARTITION BY RANGE_BUCKET(log_id, GENERATE_ARRAY(0, 1000000, 10000));
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Clustering (optimize filter/group)
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
CREATE TABLE fact_orders (
|
|
92
|
+
order_date DATE,
|
|
93
|
+
customer_id INT64,
|
|
94
|
+
product_id INT64,
|
|
95
|
+
store_id INT64,
|
|
96
|
+
amount NUMERIC
|
|
97
|
+
)
|
|
98
|
+
PARTITION BY order_date
|
|
99
|
+
CLUSTER BY customer_id, product_id;
|
|
100
|
+
-- Can cluster up to 4 columns
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### When to use what?
|
|
104
|
+
- **Partition**: Filter by date range → reduces data scan
|
|
105
|
+
- **Cluster**: Filter/Group by specific columns → data is organized closer together
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Nested & Repeated Fields (Denormalization)
|
|
110
|
+
|
|
111
|
+
BigQuery encourages denormalization with STRUCT and ARRAY:
|
|
112
|
+
|
|
113
|
+
```sql
|
|
114
|
+
CREATE TABLE orders (
|
|
115
|
+
order_id INT64,
|
|
116
|
+
order_date DATE,
|
|
117
|
+
customer STRUCT<
|
|
118
|
+
id INT64,
|
|
119
|
+
name STRING,
|
|
120
|
+
email STRING
|
|
121
|
+
>,
|
|
122
|
+
items ARRAY<STRUCT<
|
|
123
|
+
product_id INT64,
|
|
124
|
+
product_name STRING,
|
|
125
|
+
quantity INT64,
|
|
126
|
+
unit_price NUMERIC
|
|
127
|
+
>>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
-- Query nested fields
|
|
131
|
+
SELECT
|
|
132
|
+
order_id,
|
|
133
|
+
customer.name,
|
|
134
|
+
item.product_name,
|
|
135
|
+
item.quantity
|
|
136
|
+
FROM orders, UNNEST(items) AS item;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Best Practices
|
|
142
|
+
|
|
143
|
+
### Query optimization
|
|
144
|
+
- **Avoid `SELECT *`** - only select needed columns
|
|
145
|
+
- **Filter early** - use partition column in WHERE
|
|
146
|
+
- **Avoid cross-join** with large tables
|
|
147
|
+
|
|
148
|
+
### Table design
|
|
149
|
+
- Partition tables > 1GB
|
|
150
|
+
- Cluster by frequently filtered/grouped columns
|
|
151
|
+
- Denormalize with STRUCT/ARRAY when appropriate
|
|
152
|
+
- Avoid too many small tables
|
|
153
|
+
|
|
154
|
+
### Cost control
|
|
155
|
+
- Partition pruning: always filter by partition column
|
|
156
|
+
- Use `--dry_run` to estimate cost
|
|
157
|
+
- Set up query quotas
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Example DDL
|
|
162
|
+
|
|
163
|
+
```sql
|
|
164
|
+
CREATE TABLE `project.dataset.fact_orders` (
|
|
165
|
+
-- Keys
|
|
166
|
+
order_id INT64 NOT NULL OPTIONS(description='PK from source'),
|
|
167
|
+
order_date DATE NOT NULL OPTIONS(description='Order date'),
|
|
168
|
+
|
|
169
|
+
-- Dimensions (denormalized)
|
|
170
|
+
customer_id INT64 NOT NULL,
|
|
171
|
+
customer_name STRING,
|
|
172
|
+
customer_segment STRING OPTIONS(description='VIP|Regular|New'),
|
|
173
|
+
|
|
174
|
+
-- Measures
|
|
175
|
+
item_count INT64 NOT NULL,
|
|
176
|
+
gross_amount NUMERIC NOT NULL,
|
|
177
|
+
discount_amount NUMERIC DEFAULT 0,
|
|
178
|
+
net_amount NUMERIC NOT NULL,
|
|
179
|
+
|
|
180
|
+
-- Nested items
|
|
181
|
+
items ARRAY<STRUCT<
|
|
182
|
+
product_id INT64,
|
|
183
|
+
product_name STRING,
|
|
184
|
+
quantity INT64,
|
|
185
|
+
unit_price NUMERIC
|
|
186
|
+
>> OPTIONS(description='Product details in order'),
|
|
187
|
+
|
|
188
|
+
-- Metadata
|
|
189
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
|
|
190
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP()
|
|
191
|
+
)
|
|
192
|
+
PARTITION BY order_date
|
|
193
|
+
CLUSTER BY customer_id
|
|
194
|
+
OPTIONS(
|
|
195
|
+
description='Fact table for orders, partitioned by date, clustered by customer'
|
|
196
|
+
);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Scheduled Queries / Materialized Views
|
|
202
|
+
|
|
203
|
+
### Materialized View
|
|
204
|
+
```sql
|
|
205
|
+
CREATE MATERIALIZED VIEW `project.dataset.mv_daily_sales`
|
|
206
|
+
PARTITION BY report_date
|
|
207
|
+
CLUSTER BY store_id
|
|
208
|
+
AS
|
|
209
|
+
SELECT
|
|
210
|
+
DATE(order_date) as report_date,
|
|
211
|
+
store_id,
|
|
212
|
+
COUNT(*) as order_count,
|
|
213
|
+
SUM(net_amount) as revenue
|
|
214
|
+
FROM `project.dataset.fact_orders`
|
|
215
|
+
GROUP BY 1, 2;
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Scheduled Query (ETL)
|
|
219
|
+
Create via BigQuery Console or API with schedule expression.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Checklist
|
|
224
|
+
|
|
225
|
+
- [ ] Partition large tables by date column
|
|
226
|
+
- [ ] Cluster by frequently filtered/grouped columns (max 4)
|
|
227
|
+
- [ ] `OPTIONS(description=...)` for tables and columns
|
|
228
|
+
- [ ] Denormalize with STRUCT/ARRAY when appropriate
|
|
229
|
+
- [ ] Avoid `SELECT *` and cross-join large tables
|
|
230
|
+
- [ ] Filter by partition column in queries
|
|
231
|
+
- [ ] Consider Materialized Views for frequently used aggregations
|