@hivehub/rulebook 5.1.1 → 5.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/continue.md +33 -33
- package/.claude/commands/ralph-config.md +112 -112
- package/.claude/commands/ralph-history.md +110 -110
- package/.claude/commands/ralph-init.md +72 -72
- package/.claude/commands/ralph-pause-resume.md +105 -105
- package/.claude/commands/ralph-run.md +101 -101
- package/.claude/commands/ralph-status.md +76 -76
- package/.claude/commands/rulebook-decision-create.md +55 -55
- package/.claude/commands/rulebook-decision-list.md +15 -15
- package/.claude/commands/rulebook-knowledge-add.md +41 -41
- package/.claude/commands/rulebook-knowledge-list.md +15 -15
- package/.claude/commands/rulebook-learn-capture.md +48 -48
- package/.claude/commands/rulebook-learn-list.md +13 -13
- package/.claude/commands/rulebook-memory-save.md +48 -48
- package/.claude/commands/rulebook-memory-search.md +47 -47
- package/.claude/commands/rulebook-task-apply.md +67 -67
- package/.claude/commands/rulebook-task-archive.md +94 -94
- package/.claude/commands/rulebook-task-create.md +93 -93
- package/.claude/commands/rulebook-task-list.md +42 -42
- package/.claude/commands/rulebook-task-show.md +52 -52
- package/.claude/commands/rulebook-task-validate.md +53 -53
- package/.claude-plugin/marketplace.json +28 -28
- package/.claude-plugin/plugin.json +8 -8
- package/README.md +8 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +39 -8
- package/dist/cli/commands.js.map +1 -1
- package/dist/core/agent-template-engine.d.ts.map +1 -1
- package/dist/core/agent-template-engine.js +36 -30
- package/dist/core/agent-template-engine.js.map +1 -1
- package/dist/core/complexity-detector.d.ts.map +1 -1
- package/dist/core/complexity-detector.js +109 -29
- package/dist/core/complexity-detector.js.map +1 -1
- package/dist/core/decision-manager.d.ts.map +1 -1
- package/dist/core/decision-manager.js +2 -7
- package/dist/core/decision-manager.js.map +1 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +28 -28
- package/dist/core/generator.js.map +1 -1
- package/dist/core/indexer/background-indexer.d.ts +1 -0
- package/dist/core/indexer/background-indexer.d.ts.map +1 -1
- package/dist/core/indexer/background-indexer.js +107 -19
- package/dist/core/indexer/background-indexer.js.map +1 -1
- package/dist/core/indexer/indexer-types.d.ts +2 -0
- package/dist/core/indexer/indexer-types.d.ts.map +1 -1
- package/dist/core/knowledge-manager.d.ts.map +1 -1
- package/dist/core/knowledge-manager.js +1 -1
- package/dist/core/knowledge-manager.js.map +1 -1
- package/dist/core/learn-manager.d.ts.map +1 -1
- package/dist/core/learn-manager.js +1 -1
- package/dist/core/learn-manager.js.map +1 -1
- package/dist/core/rule-engine.d.ts.map +1 -1
- package/dist/core/rule-engine.js +1 -3
- package/dist/core/rule-engine.js.map +1 -1
- package/dist/core/task-manager.d.ts.map +1 -1
- package/dist/core/task-manager.js +24 -24
- package/dist/core/task-manager.js.map +1 -1
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/rulebook-server.d.ts +12 -2
- package/dist/mcp/rulebook-server.d.ts.map +1 -1
- package/dist/mcp/rulebook-server.js +100 -30
- package/dist/mcp/rulebook-server.js.map +1 -1
- package/dist/memory/hnsw-index.d.ts.map +1 -1
- package/dist/memory/hnsw-index.js +12 -4
- package/dist/memory/hnsw-index.js.map +1 -1
- package/dist/memory/memory-store.d.ts.map +1 -1
- package/dist/memory/memory-store.js +136 -107
- package/dist/memory/memory-store.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +22 -21
- package/templates/agents/accessibility-reviewer.md +43 -43
- package/templates/agents/api-designer.md +42 -42
- package/templates/agents/architect.md +51 -51
- package/templates/agents/build-engineer.md +36 -36
- package/templates/agents/code-reviewer.md +47 -47
- package/templates/agents/compiler/codegen-debugger.md +34 -34
- package/templates/agents/compiler/stdlib-engineer.md +28 -28
- package/templates/agents/compiler/test-coverage-guardian.md +31 -31
- package/templates/agents/context-intelligence.md +52 -52
- package/templates/agents/database-architect.md +41 -41
- package/templates/agents/devops-engineer.md +42 -42
- package/templates/agents/docs-writer.md +38 -38
- package/templates/agents/game-engine/cpp-core-expert.md +35 -35
- package/templates/agents/game-engine/render-engineer.md +22 -22
- package/templates/agents/game-engine/shader-engineer.md +38 -38
- package/templates/agents/game-engine/systems-integration.md +43 -43
- package/templates/agents/generic/code-reviewer.md +41 -41
- package/templates/agents/generic/docs-writer.md +25 -25
- package/templates/agents/generic/project-manager.md +36 -36
- package/templates/agents/generic/researcher.md +34 -34
- package/templates/agents/generic/test-engineer.md +41 -41
- package/templates/agents/i18n-engineer.md +42 -42
- package/templates/agents/implementer.md +42 -42
- package/templates/agents/migration-engineer.md +42 -42
- package/templates/agents/mobile/platform-specialist.md +22 -22
- package/templates/agents/mobile/ui-engineer.md +22 -22
- package/templates/agents/performance-engineer.md +49 -49
- package/templates/agents/refactoring-agent.md +41 -41
- package/templates/agents/researcher.md +38 -38
- package/templates/agents/security-reviewer.md +40 -40
- package/templates/agents/team-lead.md +37 -37
- package/templates/agents/tester.md +48 -48
- package/templates/agents/ux-reviewer.md +43 -43
- package/templates/agents/web-app/api-designer.md +22 -22
- package/templates/agents/web-app/backend-engineer.md +30 -30
- package/templates/agents/web-app/database-engineer.md +22 -22
- package/templates/agents/web-app/frontend-engineer.md +29 -29
- package/templates/agents/web-app/security-reviewer.md +32 -32
- package/templates/ci/rulebook-review.yml +26 -26
- package/templates/cli/AIDER.md +49 -49
- package/templates/cli/AMAZON_Q.md +25 -25
- package/templates/cli/AUGGIE.md +32 -32
- package/templates/cli/CLAUDE.md +117 -117
- package/templates/cli/CLINE.md +99 -99
- package/templates/cli/CODEBUDDY.md +20 -20
- package/templates/cli/CODEIUM.md +20 -20
- package/templates/cli/CODEX.md +21 -21
- package/templates/cli/CONTINUE.md +34 -34
- package/templates/cli/CURSOR_CLI.md +62 -62
- package/templates/cli/FACTORY.md +18 -18
- package/templates/cli/GEMINI.md +35 -35
- package/templates/cli/KILOCODE.md +18 -18
- package/templates/cli/OPENCODE.md +18 -18
- package/templates/cli/_GENERIC_TEMPLATE.md +29 -29
- package/templates/commands/rulebook-decision-create.md +55 -55
- package/templates/commands/rulebook-decision-list.md +15 -15
- package/templates/commands/rulebook-knowledge-add.md +41 -41
- package/templates/commands/rulebook-knowledge-list.md +15 -15
- package/templates/commands/rulebook-learn-capture.md +48 -48
- package/templates/commands/rulebook-learn-list.md +13 -13
- package/templates/commands/rulebook-memory-save.md +48 -48
- package/templates/commands/rulebook-memory-search.md +47 -47
- package/templates/commands/rulebook-task-apply.md +67 -67
- package/templates/commands/rulebook-task-archive.md +94 -94
- package/templates/commands/rulebook-task-create.md +93 -93
- package/templates/commands/rulebook-task-list.md +42 -42
- package/templates/commands/rulebook-task-show.md +52 -52
- package/templates/commands/rulebook-task-validate.md +53 -53
- package/templates/core/AGENTS_LEAN.md +25 -25
- package/templates/core/AGENTS_OVERRIDE.md +16 -16
- package/templates/core/AGENT_AUTOMATION.md +296 -296
- package/templates/core/DAG.md +304 -304
- package/templates/core/DECISIONS.md +38 -38
- package/templates/core/DOCUMENTATION_RULES.md +36 -36
- package/templates/core/KNOWLEDGE.md +49 -49
- package/templates/core/MULTI_AGENT.md +74 -74
- package/templates/core/PLANS.md +28 -28
- package/templates/core/QUALITY_ENFORCEMENT.md +68 -68
- package/templates/core/RALPH.md +471 -471
- package/templates/core/RULEBOOK.md +1947 -1947
- package/templates/core/TIER1_PROHIBITIONS.md +154 -154
- package/templates/core/TOKEN_OPTIMIZATION.md +49 -49
- package/templates/frameworks/ANGULAR.md +36 -36
- package/templates/frameworks/DJANGO.md +83 -83
- package/templates/frameworks/ELECTRON.md +147 -147
- package/templates/frameworks/FLASK.md +38 -38
- package/templates/frameworks/FLUTTER.md +55 -55
- package/templates/frameworks/JQUERY.md +32 -32
- package/templates/frameworks/LARAVEL.md +38 -38
- package/templates/frameworks/NESTJS.md +43 -43
- package/templates/frameworks/NEXTJS.md +127 -127
- package/templates/frameworks/NUXT.md +40 -40
- package/templates/frameworks/RAILS.md +66 -66
- package/templates/frameworks/REACT.md +38 -38
- package/templates/frameworks/REACT_NATIVE.md +47 -47
- package/templates/frameworks/SPRING.md +39 -39
- package/templates/frameworks/SYMFONY.md +36 -36
- package/templates/frameworks/VUE.md +36 -36
- package/templates/frameworks/ZEND.md +35 -35
- package/templates/git/CI_CD_PATTERNS.md +661 -661
- package/templates/git/GITHUB_ACTIONS.md +728 -728
- package/templates/git/GITLAB_CI.md +730 -730
- package/templates/git/GIT_WORKFLOW.md +1192 -1192
- package/templates/git/SECRETS_MANAGEMENT.md +585 -585
- package/templates/hooks/COMMIT_MSG.md +530 -530
- package/templates/hooks/POST_CHECKOUT.md +546 -546
- package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -619
- package/templates/hooks/PRE_COMMIT.md +414 -414
- package/templates/hooks/PRE_PUSH.md +601 -601
- package/templates/ides/CONTINUE_RULES.md +16 -16
- package/templates/ides/COPILOT.md +37 -37
- package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -23
- package/templates/ides/CURSOR.md +43 -43
- package/templates/ides/GEMINI_RULES.md +17 -17
- package/templates/ides/JETBRAINS_AI.md +35 -35
- package/templates/ides/REPLIT.md +36 -36
- package/templates/ides/TABNINE.md +29 -29
- package/templates/ides/VSCODE.md +40 -40
- package/templates/ides/WINDSURF.md +36 -36
- package/templates/ides/WINDSURF_RULES.md +14 -14
- package/templates/ides/ZED.md +32 -32
- package/templates/ides/cursor-mdc/go.mdc +24 -24
- package/templates/ides/cursor-mdc/python.mdc +24 -24
- package/templates/ides/cursor-mdc/quality.mdc +25 -25
- package/templates/ides/cursor-mdc/ralph.mdc +39 -39
- package/templates/ides/cursor-mdc/rulebook.mdc +38 -38
- package/templates/ides/cursor-mdc/rust.mdc +24 -24
- package/templates/ides/cursor-mdc/typescript.mdc +25 -25
- package/templates/languages/C.md +333 -333
- package/templates/languages/CPP.md +743 -743
- package/templates/languages/CSHARP.md +417 -417
- package/templates/languages/ELIXIR.md +454 -454
- package/templates/languages/ERLANG.md +361 -361
- package/templates/languages/GO.md +645 -645
- package/templates/languages/HASKELL.md +177 -177
- package/templates/languages/JAVA.md +607 -607
- package/templates/languages/JAVASCRIPT.md +631 -631
- package/templates/languages/JULIA.md +97 -97
- package/templates/languages/KOTLIN.md +511 -511
- package/templates/languages/LISP.md +100 -100
- package/templates/languages/LUA.md +74 -74
- package/templates/languages/OBJECTIVEC.md +90 -90
- package/templates/languages/PHP.md +416 -416
- package/templates/languages/PYTHON.md +682 -682
- package/templates/languages/RUBY.md +421 -421
- package/templates/languages/RUST.md +477 -477
- package/templates/languages/SAS.md +73 -73
- package/templates/languages/SCALA.md +348 -348
- package/templates/languages/SOLIDITY.md +580 -580
- package/templates/languages/SQL.md +137 -137
- package/templates/languages/SWIFT.md +466 -466
- package/templates/languages/TYPESCRIPT.md +591 -591
- package/templates/languages/ZIG.md +265 -265
- package/templates/modules/ATLASSIAN.md +255 -255
- package/templates/modules/CONTEXT7.md +54 -54
- package/templates/modules/FIGMA.md +267 -267
- package/templates/modules/GITHUB_MCP.md +64 -64
- package/templates/modules/GRAFANA.md +328 -328
- package/templates/modules/MEMORY.md +126 -126
- package/templates/modules/NOTION.md +247 -247
- package/templates/modules/PLAYWRIGHT.md +90 -90
- package/templates/modules/RULEBOOK_MCP.md +156 -156
- package/templates/modules/SERENA.md +337 -337
- package/templates/modules/SUPABASE.md +223 -223
- package/templates/modules/SYNAP.md +69 -69
- package/templates/modules/VECTORIZER.md +63 -63
- package/templates/modules/sequential-thinking.md +42 -42
- package/templates/ralph/ralph-history.bat +4 -4
- package/templates/ralph/ralph-history.sh +5 -5
- package/templates/ralph/ralph-init.bat +5 -5
- package/templates/ralph/ralph-init.sh +5 -5
- package/templates/ralph/ralph-pause.bat +5 -5
- package/templates/ralph/ralph-pause.sh +5 -5
- package/templates/ralph/ralph-run.bat +5 -5
- package/templates/ralph/ralph-run.sh +5 -5
- package/templates/ralph/ralph-status.bat +4 -4
- package/templates/ralph/ralph-status.sh +5 -5
- package/templates/rules/follow-task-sequence.md +36 -36
- package/templates/rules/git-safety.md +29 -29
- package/templates/rules/incremental-tests.md +29 -29
- package/templates/rules/no-deferred.md +31 -31
- package/templates/rules/no-shortcuts.md +30 -30
- package/templates/rules/research-first.md +30 -30
- package/templates/rules/sequential-editing.md +21 -21
- package/templates/rules/session-workflow.md +24 -24
- package/templates/rules/task-decomposition.md +32 -32
- package/templates/services/AZURE_BLOB.md +184 -184
- package/templates/services/CASSANDRA.md +239 -239
- package/templates/services/DATADOG.md +26 -26
- package/templates/services/DOCKER.md +124 -124
- package/templates/services/DOCKER_COMPOSE.md +168 -168
- package/templates/services/DYNAMODB.md +308 -308
- package/templates/services/ELASTICSEARCH.md +347 -347
- package/templates/services/GCS.md +178 -178
- package/templates/services/HELM.md +194 -194
- package/templates/services/INFLUXDB.md +265 -265
- package/templates/services/KAFKA.md +341 -341
- package/templates/services/KUBERNETES.md +208 -208
- package/templates/services/MARIADB.md +183 -183
- package/templates/services/MEMCACHED.md +242 -242
- package/templates/services/MINIO.md +201 -201
- package/templates/services/MONGODB.md +268 -268
- package/templates/services/MYSQL.md +358 -358
- package/templates/services/NEO4J.md +247 -247
- package/templates/services/OPENTELEMETRY.md +25 -25
- package/templates/services/ORACLE.md +290 -290
- package/templates/services/PINO.md +24 -24
- package/templates/services/POSTGRESQL.md +326 -326
- package/templates/services/PROMETHEUS.md +33 -33
- package/templates/services/RABBITMQ.md +286 -286
- package/templates/services/REDIS.md +292 -292
- package/templates/services/S3.md +298 -298
- package/templates/services/SENTRY.md +23 -23
- package/templates/services/SQLITE.md +294 -294
- package/templates/services/SQLSERVER.md +294 -294
- package/templates/services/WINSTON.md +30 -30
- package/templates/skills/cli/aider/SKILL.md +59 -59
- package/templates/skills/cli/amazon-q/SKILL.md +35 -35
- package/templates/skills/cli/auggie/SKILL.md +42 -42
- package/templates/skills/cli/claude/SKILL.md +42 -42
- package/templates/skills/cli/cline/SKILL.md +42 -42
- package/templates/skills/cli/codebuddy/SKILL.md +30 -30
- package/templates/skills/cli/codeium/SKILL.md +30 -30
- package/templates/skills/cli/codex/SKILL.md +31 -31
- package/templates/skills/cli/continue/SKILL.md +44 -44
- package/templates/skills/cli/cursor-cli/SKILL.md +38 -38
- package/templates/skills/cli/factory/SKILL.md +28 -28
- package/templates/skills/cli/gemini/SKILL.md +45 -45
- package/templates/skills/cli/kilocode/SKILL.md +28 -28
- package/templates/skills/cli/opencode/SKILL.md +28 -28
- package/templates/skills/core/agent-automation/SKILL.md +194 -194
- package/templates/skills/core/dag/SKILL.md +314 -314
- package/templates/skills/core/documentation-rules/SKILL.md +46 -46
- package/templates/skills/core/quality-enforcement/SKILL.md +78 -78
- package/templates/skills/core/rulebook/SKILL.md +176 -176
- package/templates/skills/dev/accessibility/SKILL.md +17 -17
- package/templates/skills/dev/api-design/SKILL.md +15 -15
- package/templates/skills/dev/architect/SKILL.md +17 -17
- package/templates/skills/dev/build-fix/SKILL.md +17 -17
- package/templates/skills/dev/db-design/SKILL.md +15 -15
- package/templates/skills/dev/debug/SKILL.md +16 -16
- package/templates/skills/dev/deploy/SKILL.md +17 -17
- package/templates/skills/dev/docs/SKILL.md +17 -17
- package/templates/skills/dev/migrate/SKILL.md +15 -15
- package/templates/skills/dev/perf/SKILL.md +17 -17
- package/templates/skills/dev/refactor/SKILL.md +17 -17
- package/templates/skills/dev/research/SKILL.md +14 -14
- package/templates/skills/dev/review/SKILL.md +18 -18
- package/templates/skills/dev/security-audit/SKILL.md +17 -17
- package/templates/skills/frameworks/angular/SKILL.md +46 -46
- package/templates/skills/frameworks/django/SKILL.md +93 -93
- package/templates/skills/frameworks/electron/SKILL.md +157 -157
- package/templates/skills/frameworks/flask/SKILL.md +48 -48
- package/templates/skills/frameworks/flutter/SKILL.md +65 -65
- package/templates/skills/frameworks/jquery/SKILL.md +42 -42
- package/templates/skills/frameworks/laravel/SKILL.md +48 -48
- package/templates/skills/frameworks/nestjs/SKILL.md +53 -53
- package/templates/skills/frameworks/nextjs/SKILL.md +137 -137
- package/templates/skills/frameworks/nuxt/SKILL.md +50 -50
- package/templates/skills/frameworks/rails/SKILL.md +76 -76
- package/templates/skills/frameworks/react/SKILL.md +48 -48
- package/templates/skills/frameworks/react-native/SKILL.md +57 -57
- package/templates/skills/frameworks/spring/SKILL.md +49 -49
- package/templates/skills/frameworks/symfony/SKILL.md +46 -46
- package/templates/skills/frameworks/vue/SKILL.md +46 -46
- package/templates/skills/frameworks/zend/SKILL.md +45 -45
- package/templates/skills/ides/copilot/SKILL.md +47 -47
- package/templates/skills/ides/cursor/SKILL.md +53 -53
- package/templates/skills/ides/jetbrains-ai/SKILL.md +45 -45
- package/templates/skills/ides/replit/SKILL.md +46 -46
- package/templates/skills/ides/tabnine/SKILL.md +39 -39
- package/templates/skills/ides/vscode/SKILL.md +50 -50
- package/templates/skills/ides/windsurf/SKILL.md +46 -46
- package/templates/skills/ides/zed/SKILL.md +42 -42
- package/templates/skills/languages/c/SKILL.md +343 -343
- package/templates/skills/languages/cpp/SKILL.md +753 -753
- package/templates/skills/languages/csharp/SKILL.md +427 -427
- package/templates/skills/languages/elixir/SKILL.md +464 -464
- package/templates/skills/languages/erlang/SKILL.md +371 -371
- package/templates/skills/languages/go/SKILL.md +655 -655
- package/templates/skills/languages/haskell/SKILL.md +187 -187
- package/templates/skills/languages/java/SKILL.md +617 -617
- package/templates/skills/languages/javascript/SKILL.md +641 -641
- package/templates/skills/languages/julia/SKILL.md +107 -107
- package/templates/skills/languages/kotlin/SKILL.md +521 -521
- package/templates/skills/languages/lisp/SKILL.md +110 -110
- package/templates/skills/languages/lua/SKILL.md +84 -84
- package/templates/skills/languages/objectivec/SKILL.md +100 -100
- package/templates/skills/languages/php/SKILL.md +426 -426
- package/templates/skills/languages/python/SKILL.md +692 -692
- package/templates/skills/languages/ruby/SKILL.md +431 -431
- package/templates/skills/languages/rust/SKILL.md +487 -487
- package/templates/skills/languages/sas/SKILL.md +83 -83
- package/templates/skills/languages/scala/SKILL.md +358 -358
- package/templates/skills/languages/solidity/SKILL.md +590 -590
- package/templates/skills/languages/sql/SKILL.md +147 -147
- package/templates/skills/languages/swift/SKILL.md +476 -476
- package/templates/skills/languages/typescript/SKILL.md +302 -302
- package/templates/skills/languages/zig/SKILL.md +275 -275
- package/templates/skills/modules/atlassian/SKILL.md +265 -265
- package/templates/skills/modules/context7/SKILL.md +64 -64
- package/templates/skills/modules/figma/SKILL.md +277 -277
- package/templates/skills/modules/github-mcp/SKILL.md +74 -74
- package/templates/skills/modules/grafana/SKILL.md +338 -338
- package/templates/skills/modules/memory/SKILL.md +73 -73
- package/templates/skills/modules/notion/SKILL.md +257 -257
- package/templates/skills/modules/playwright/SKILL.md +100 -100
- package/templates/skills/modules/rulebook-mcp/SKILL.md +166 -166
- package/templates/skills/modules/serena/SKILL.md +347 -347
- package/templates/skills/modules/supabase/SKILL.md +233 -233
- package/templates/skills/modules/synap/SKILL.md +79 -79
- package/templates/skills/modules/vectorizer/SKILL.md +73 -73
- package/templates/skills/services/azure-blob/SKILL.md +194 -194
- package/templates/skills/services/cassandra/SKILL.md +249 -249
- package/templates/skills/services/dynamodb/SKILL.md +318 -318
- package/templates/skills/services/elasticsearch/SKILL.md +357 -357
- package/templates/skills/services/gcs/SKILL.md +188 -188
- package/templates/skills/services/influxdb/SKILL.md +275 -275
- package/templates/skills/services/kafka/SKILL.md +351 -351
- package/templates/skills/services/mariadb/SKILL.md +193 -193
- package/templates/skills/services/memcached/SKILL.md +252 -252
- package/templates/skills/services/minio/SKILL.md +211 -211
- package/templates/skills/services/mongodb/SKILL.md +278 -278
- package/templates/skills/services/mysql/SKILL.md +368 -368
- package/templates/skills/services/neo4j/SKILL.md +257 -257
- package/templates/skills/services/oracle/SKILL.md +300 -300
- package/templates/skills/services/postgresql/SKILL.md +336 -336
- package/templates/skills/services/rabbitmq/SKILL.md +296 -296
- package/templates/skills/services/redis/SKILL.md +302 -302
- package/templates/skills/services/s3/SKILL.md +308 -308
- package/templates/skills/services/sqlite/SKILL.md +304 -304
- package/templates/skills/services/sqlserver/SKILL.md +304 -304
- package/templates/skills/workflows/ralph/SKILL.md +309 -309
- package/templates/skills/workflows/ralph/install.sh +87 -87
- package/templates/skills/workflows/ralph/manifest.json +158 -158
|
@@ -1,358 +1,358 @@
|
|
|
1
|
-
<!-- MYSQL:START -->
|
|
2
|
-
# MySQL Database Instructions
|
|
3
|
-
|
|
4
|
-
**CRITICAL**: Use MySQL for relational data storage with high performance, replication, and wide ecosystem support.
|
|
5
|
-
|
|
6
|
-
## Core Features
|
|
7
|
-
|
|
8
|
-
### Connection
|
|
9
|
-
```typescript
|
|
10
|
-
// Using mysql2 (Node.js)
|
|
11
|
-
import mysql from 'mysql2/promise'
|
|
12
|
-
|
|
13
|
-
const pool = mysql.createPool({
|
|
14
|
-
host: process.env.DB_HOST,
|
|
15
|
-
port: parseInt(process.env.DB_PORT || '3306'),
|
|
16
|
-
database: process.env.DB_NAME,
|
|
17
|
-
user: process.env.DB_USER,
|
|
18
|
-
password: process.env.DB_PASSWORD,
|
|
19
|
-
waitForConnections: true,
|
|
20
|
-
connectionLimit: 10,
|
|
21
|
-
queueLimit: 0,
|
|
22
|
-
enableKeepAlive: true,
|
|
23
|
-
keepAliveInitialDelay: 0,
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Using Prisma
|
|
27
|
-
import { PrismaClient } from '@prisma/client'
|
|
28
|
-
const prisma = new PrismaClient()
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Basic Queries
|
|
32
|
-
```typescript
|
|
33
|
-
// SELECT
|
|
34
|
-
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId])
|
|
35
|
-
const users = rows as User[]
|
|
36
|
-
|
|
37
|
-
// INSERT
|
|
38
|
-
const [result] = await pool.execute(
|
|
39
|
-
'INSERT INTO users (name, email) VALUES (?, ?)',
|
|
40
|
-
['John Doe', 'john@example.com']
|
|
41
|
-
)
|
|
42
|
-
const insertId = (result as any).insertId
|
|
43
|
-
|
|
44
|
-
// UPDATE
|
|
45
|
-
const [result] = await pool.execute(
|
|
46
|
-
'UPDATE users SET name = ? WHERE id = ?',
|
|
47
|
-
['Jane Doe', userId]
|
|
48
|
-
)
|
|
49
|
-
const affectedRows = (result as any).affectedRows
|
|
50
|
-
|
|
51
|
-
// DELETE
|
|
52
|
-
const [result] = await pool.execute('DELETE FROM users WHERE id = ?', [userId])
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Transactions
|
|
56
|
-
```typescript
|
|
57
|
-
const connection = await pool.getConnection()
|
|
58
|
-
try {
|
|
59
|
-
await connection.beginTransaction()
|
|
60
|
-
|
|
61
|
-
await connection.execute('INSERT INTO accounts (user_id, balance) VALUES (?, ?)', [userId, 1000])
|
|
62
|
-
await connection.execute('INSERT INTO transactions (account_id, amount) VALUES (?, ?)', [accountId, 1000])
|
|
63
|
-
|
|
64
|
-
await connection.commit()
|
|
65
|
-
} catch (error) {
|
|
66
|
-
await connection.rollback()
|
|
67
|
-
throw error
|
|
68
|
-
} finally {
|
|
69
|
-
connection.release()
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Advanced Features
|
|
74
|
-
```typescript
|
|
75
|
-
// JSON queries (MySQL 5.7+)
|
|
76
|
-
const [rows] = await pool.execute(
|
|
77
|
-
"SELECT * FROM products WHERE JSON_EXTRACT(metadata, '$.category') = ?",
|
|
78
|
-
['electronics']
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
// Full-text search
|
|
82
|
-
const [rows] = await pool.execute(
|
|
83
|
-
"SELECT * FROM articles WHERE MATCH(title, content) AGAINST(? IN NATURAL LANGUAGE MODE)",
|
|
84
|
-
['search term']
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
// Window functions (MySQL 8.0+)
|
|
88
|
-
const [rows] = await pool.execute(`
|
|
89
|
-
SELECT
|
|
90
|
-
name,
|
|
91
|
-
salary,
|
|
92
|
-
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank
|
|
93
|
-
FROM employees
|
|
94
|
-
`)
|
|
95
|
-
|
|
96
|
-
// Common Table Expressions (CTE) (MySQL 8.0+)
|
|
97
|
-
const [rows] = await pool.execute(`
|
|
98
|
-
WITH RECURSIVE cte AS (
|
|
99
|
-
SELECT id, name, parent_id FROM categories WHERE parent_id IS NULL
|
|
100
|
-
UNION ALL
|
|
101
|
-
SELECT c.id, c.name, c.parent_id FROM categories c
|
|
102
|
-
INNER JOIN cte ON c.parent_id = cte.id
|
|
103
|
-
)
|
|
104
|
-
SELECT * FROM cte
|
|
105
|
-
`)
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Common Patterns
|
|
109
|
-
|
|
110
|
-
### Connection Pooling
|
|
111
|
-
```typescript
|
|
112
|
-
// Reuse connection pool
|
|
113
|
-
let pool: mysql.Pool | null = null
|
|
114
|
-
|
|
115
|
-
export function getPool(): mysql.Pool {
|
|
116
|
-
if (!pool) {
|
|
117
|
-
pool = mysql.createPool({
|
|
118
|
-
// ... config
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
pool.on('connection', (connection) => {
|
|
122
|
-
connection.query('SET SESSION sql_mode = "STRICT_TRANS_TABLES"')
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
return pool
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Graceful shutdown
|
|
129
|
-
process.on('SIGINT', async () => {
|
|
130
|
-
if (pool) {
|
|
131
|
-
await pool.end()
|
|
132
|
-
}
|
|
133
|
-
process.exit(0)
|
|
134
|
-
})
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Prepared Statements
|
|
138
|
-
```typescript
|
|
139
|
-
// Always use parameterized queries (?) to prevent SQL injection
|
|
140
|
-
// ❌ WRONG
|
|
141
|
-
await pool.execute(`SELECT * FROM users WHERE email = '${email}'`)
|
|
142
|
-
|
|
143
|
-
// ✅ CORRECT
|
|
144
|
-
await pool.execute('SELECT * FROM users WHERE email = ?', [email])
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Error Handling
|
|
148
|
-
```typescript
|
|
149
|
-
try {
|
|
150
|
-
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId])
|
|
151
|
-
if ((rows as any[]).length === 0) {
|
|
152
|
-
throw new Error('User not found')
|
|
153
|
-
}
|
|
154
|
-
return rows[0]
|
|
155
|
-
} catch (error: any) {
|
|
156
|
-
if (error.code === 'ER_DUP_ENTRY') {
|
|
157
|
-
throw new Error('Duplicate entry')
|
|
158
|
-
}
|
|
159
|
-
if (error.code === 'ER_NO_REFERENCED_ROW_2') {
|
|
160
|
-
throw new Error('Referenced record does not exist')
|
|
161
|
-
}
|
|
162
|
-
throw error
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Migrations
|
|
167
|
-
```typescript
|
|
168
|
-
// Using db-migrate
|
|
169
|
-
import { migrate } from 'db-migrate'
|
|
170
|
-
|
|
171
|
-
await migrate({
|
|
172
|
-
config: {
|
|
173
|
-
dev: {
|
|
174
|
-
driver: 'mysql',
|
|
175
|
-
database: process.env.DB_NAME,
|
|
176
|
-
user: process.env.DB_USER,
|
|
177
|
-
password: process.env.DB_PASSWORD,
|
|
178
|
-
host: process.env.DB_HOST,
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
env: 'dev',
|
|
182
|
-
})
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Best Practices
|
|
186
|
-
|
|
187
|
-
✅ **DO:**
|
|
188
|
-
- Use connection pooling (10-20 connections typically)
|
|
189
|
-
- Always use parameterized queries (? placeholders)
|
|
190
|
-
- Use transactions for multi-step operations
|
|
191
|
-
- Create indexes on frequently queried columns
|
|
192
|
-
- Use EXPLAIN to optimize queries
|
|
193
|
-
- Enable query caching for read-heavy workloads
|
|
194
|
-
- Use InnoDB engine (ACID compliance)
|
|
195
|
-
- Set appropriate charset (utf8mb4 for full Unicode)
|
|
196
|
-
- Monitor slow query log
|
|
197
|
-
- Use prepared statements for repeated queries
|
|
198
|
-
|
|
199
|
-
❌ **DON'T:**
|
|
200
|
-
- Use string concatenation for queries (SQL injection risk)
|
|
201
|
-
- Create too many connections (exhaust pool)
|
|
202
|
-
- Skip error handling
|
|
203
|
-
- Ignore connection pool limits
|
|
204
|
-
- Use SELECT * in production (specify columns)
|
|
205
|
-
- Skip indexes on foreign keys
|
|
206
|
-
- Hardcode connection strings
|
|
207
|
-
- Use MyISAM engine (no transactions)
|
|
208
|
-
- Ignore query performance
|
|
209
|
-
- Use synchronous queries
|
|
210
|
-
|
|
211
|
-
## Configuration
|
|
212
|
-
|
|
213
|
-
### Environment Variables
|
|
214
|
-
```bash
|
|
215
|
-
DB_HOST=localhost
|
|
216
|
-
DB_PORT=3306
|
|
217
|
-
DB_NAME=myapp
|
|
218
|
-
DB_USER=myuser
|
|
219
|
-
DB_PASSWORD=securepassword
|
|
220
|
-
DATABASE_URL=mysql://user:password@host:port/database
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Docker Compose
|
|
224
|
-
```yaml
|
|
225
|
-
services:
|
|
226
|
-
mysql:
|
|
227
|
-
image: mysql:8.0
|
|
228
|
-
environment:
|
|
229
|
-
MYSQL_DATABASE: myapp
|
|
230
|
-
MYSQL_USER: myuser
|
|
231
|
-
MYSQL_PASSWORD: securepassword
|
|
232
|
-
MYSQL_ROOT_PASSWORD: rootpassword
|
|
233
|
-
ports:
|
|
234
|
-
- "3306:3306"
|
|
235
|
-
volumes:
|
|
236
|
-
- mysql_data:/var/lib/mysql
|
|
237
|
-
command: --default-authentication-plugin=mysql_native_password
|
|
238
|
-
healthcheck:
|
|
239
|
-
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
240
|
-
interval: 10s
|
|
241
|
-
timeout: 5s
|
|
242
|
-
retries: 5
|
|
243
|
-
|
|
244
|
-
volumes:
|
|
245
|
-
mysql_data:
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### Prisma Schema
|
|
249
|
-
```prisma
|
|
250
|
-
datasource db {
|
|
251
|
-
provider = "mysql"
|
|
252
|
-
url = env("DATABASE_URL")
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
model User {
|
|
256
|
-
id Int @id @default(autoincrement())
|
|
257
|
-
email String @unique @db.VarChar(255)
|
|
258
|
-
name String? @db.VarChar(255)
|
|
259
|
-
createdAt DateTime @default(now()) @db.Timestamp(6)
|
|
260
|
-
posts Post[]
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
model Post {
|
|
264
|
-
id Int @id @default(autoincrement())
|
|
265
|
-
title String @db.VarChar(255)
|
|
266
|
-
content String? @db.Text
|
|
267
|
-
authorId Int
|
|
268
|
-
author User @relation(fields: [authorId], references: [id])
|
|
269
|
-
createdAt DateTime @default(now()) @db.Timestamp(6)
|
|
270
|
-
|
|
271
|
-
@@index([authorId, createdAt(sort: Desc)])
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Performance Optimization
|
|
276
|
-
|
|
277
|
-
### Indexing
|
|
278
|
-
```sql
|
|
279
|
-
-- Single column index
|
|
280
|
-
CREATE INDEX idx_users_email ON users(email);
|
|
281
|
-
|
|
282
|
-
-- Composite index
|
|
283
|
-
CREATE INDEX idx_posts_author_created ON posts(author_id, created_at DESC);
|
|
284
|
-
|
|
285
|
-
-- Full-text index
|
|
286
|
-
CREATE FULLTEXT INDEX idx_articles_content ON articles(title, content);
|
|
287
|
-
|
|
288
|
-
-- Prefix index (for long strings)
|
|
289
|
-
CREATE INDEX idx_users_name_prefix ON users(name(10));
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Query Optimization
|
|
293
|
-
```typescript
|
|
294
|
-
// Use LIMIT for pagination
|
|
295
|
-
const [rows] = await pool.execute(
|
|
296
|
-
'SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?',
|
|
297
|
-
[limit, offset]
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
// Use EXISTS instead of COUNT
|
|
301
|
-
const [rows] = await pool.execute(
|
|
302
|
-
'SELECT EXISTS(SELECT 1 FROM users WHERE email = ?) as exists',
|
|
303
|
-
[email]
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
// Use JOIN instead of subqueries when possible
|
|
307
|
-
const [rows] = await pool.execute(`
|
|
308
|
-
SELECT u.*, COUNT(p.id) as post_count
|
|
309
|
-
FROM users u
|
|
310
|
-
LEFT JOIN posts p ON u.id = p.author_id
|
|
311
|
-
GROUP BY u.id
|
|
312
|
-
`)
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Integration with Development
|
|
316
|
-
|
|
317
|
-
### Testing
|
|
318
|
-
```typescript
|
|
319
|
-
// Use test database
|
|
320
|
-
const testPool = mysql.createPool({
|
|
321
|
-
database: 'myapp_test',
|
|
322
|
-
// ... config
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
// Clean up after tests
|
|
326
|
-
afterEach(async () => {
|
|
327
|
-
await testPool.execute('SET FOREIGN_KEY_CHECKS = 0')
|
|
328
|
-
await testPool.execute('TRUNCATE TABLE users')
|
|
329
|
-
await testPool.execute('TRUNCATE TABLE posts')
|
|
330
|
-
await testPool.execute('SET FOREIGN_KEY_CHECKS = 1')
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
// Use transactions for test isolation
|
|
334
|
-
beforeEach(async () => {
|
|
335
|
-
const connection = await testPool.getConnection()
|
|
336
|
-
await connection.beginTransaction()
|
|
337
|
-
// Store connection for rollback
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
afterEach(async () => {
|
|
341
|
-
// Rollback transaction
|
|
342
|
-
})
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### Health Checks
|
|
346
|
-
```typescript
|
|
347
|
-
async function checkDatabaseHealth(): Promise<boolean> {
|
|
348
|
-
try {
|
|
349
|
-
const [rows] = await pool.execute('SELECT 1 as health')
|
|
350
|
-
return (rows as any[]).length > 0
|
|
351
|
-
} catch {
|
|
352
|
-
return false
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
<!-- MYSQL:END -->
|
|
358
|
-
|
|
1
|
+
<!-- MYSQL:START -->
|
|
2
|
+
# MySQL Database Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Use MySQL for relational data storage with high performance, replication, and wide ecosystem support.
|
|
5
|
+
|
|
6
|
+
## Core Features
|
|
7
|
+
|
|
8
|
+
### Connection
|
|
9
|
+
```typescript
|
|
10
|
+
// Using mysql2 (Node.js)
|
|
11
|
+
import mysql from 'mysql2/promise'
|
|
12
|
+
|
|
13
|
+
const pool = mysql.createPool({
|
|
14
|
+
host: process.env.DB_HOST,
|
|
15
|
+
port: parseInt(process.env.DB_PORT || '3306'),
|
|
16
|
+
database: process.env.DB_NAME,
|
|
17
|
+
user: process.env.DB_USER,
|
|
18
|
+
password: process.env.DB_PASSWORD,
|
|
19
|
+
waitForConnections: true,
|
|
20
|
+
connectionLimit: 10,
|
|
21
|
+
queueLimit: 0,
|
|
22
|
+
enableKeepAlive: true,
|
|
23
|
+
keepAliveInitialDelay: 0,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Using Prisma
|
|
27
|
+
import { PrismaClient } from '@prisma/client'
|
|
28
|
+
const prisma = new PrismaClient()
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Basic Queries
|
|
32
|
+
```typescript
|
|
33
|
+
// SELECT
|
|
34
|
+
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId])
|
|
35
|
+
const users = rows as User[]
|
|
36
|
+
|
|
37
|
+
// INSERT
|
|
38
|
+
const [result] = await pool.execute(
|
|
39
|
+
'INSERT INTO users (name, email) VALUES (?, ?)',
|
|
40
|
+
['John Doe', 'john@example.com']
|
|
41
|
+
)
|
|
42
|
+
const insertId = (result as any).insertId
|
|
43
|
+
|
|
44
|
+
// UPDATE
|
|
45
|
+
const [result] = await pool.execute(
|
|
46
|
+
'UPDATE users SET name = ? WHERE id = ?',
|
|
47
|
+
['Jane Doe', userId]
|
|
48
|
+
)
|
|
49
|
+
const affectedRows = (result as any).affectedRows
|
|
50
|
+
|
|
51
|
+
// DELETE
|
|
52
|
+
const [result] = await pool.execute('DELETE FROM users WHERE id = ?', [userId])
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Transactions
|
|
56
|
+
```typescript
|
|
57
|
+
const connection = await pool.getConnection()
|
|
58
|
+
try {
|
|
59
|
+
await connection.beginTransaction()
|
|
60
|
+
|
|
61
|
+
await connection.execute('INSERT INTO accounts (user_id, balance) VALUES (?, ?)', [userId, 1000])
|
|
62
|
+
await connection.execute('INSERT INTO transactions (account_id, amount) VALUES (?, ?)', [accountId, 1000])
|
|
63
|
+
|
|
64
|
+
await connection.commit()
|
|
65
|
+
} catch (error) {
|
|
66
|
+
await connection.rollback()
|
|
67
|
+
throw error
|
|
68
|
+
} finally {
|
|
69
|
+
connection.release()
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Advanced Features
|
|
74
|
+
```typescript
|
|
75
|
+
// JSON queries (MySQL 5.7+)
|
|
76
|
+
const [rows] = await pool.execute(
|
|
77
|
+
"SELECT * FROM products WHERE JSON_EXTRACT(metadata, '$.category') = ?",
|
|
78
|
+
['electronics']
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
// Full-text search
|
|
82
|
+
const [rows] = await pool.execute(
|
|
83
|
+
"SELECT * FROM articles WHERE MATCH(title, content) AGAINST(? IN NATURAL LANGUAGE MODE)",
|
|
84
|
+
['search term']
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
// Window functions (MySQL 8.0+)
|
|
88
|
+
const [rows] = await pool.execute(`
|
|
89
|
+
SELECT
|
|
90
|
+
name,
|
|
91
|
+
salary,
|
|
92
|
+
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank
|
|
93
|
+
FROM employees
|
|
94
|
+
`)
|
|
95
|
+
|
|
96
|
+
// Common Table Expressions (CTE) (MySQL 8.0+)
|
|
97
|
+
const [rows] = await pool.execute(`
|
|
98
|
+
WITH RECURSIVE cte AS (
|
|
99
|
+
SELECT id, name, parent_id FROM categories WHERE parent_id IS NULL
|
|
100
|
+
UNION ALL
|
|
101
|
+
SELECT c.id, c.name, c.parent_id FROM categories c
|
|
102
|
+
INNER JOIN cte ON c.parent_id = cte.id
|
|
103
|
+
)
|
|
104
|
+
SELECT * FROM cte
|
|
105
|
+
`)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Common Patterns
|
|
109
|
+
|
|
110
|
+
### Connection Pooling
|
|
111
|
+
```typescript
|
|
112
|
+
// Reuse connection pool
|
|
113
|
+
let pool: mysql.Pool | null = null
|
|
114
|
+
|
|
115
|
+
export function getPool(): mysql.Pool {
|
|
116
|
+
if (!pool) {
|
|
117
|
+
pool = mysql.createPool({
|
|
118
|
+
// ... config
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
pool.on('connection', (connection) => {
|
|
122
|
+
connection.query('SET SESSION sql_mode = "STRICT_TRANS_TABLES"')
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
return pool
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Graceful shutdown
|
|
129
|
+
process.on('SIGINT', async () => {
|
|
130
|
+
if (pool) {
|
|
131
|
+
await pool.end()
|
|
132
|
+
}
|
|
133
|
+
process.exit(0)
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Prepared Statements
|
|
138
|
+
```typescript
|
|
139
|
+
// Always use parameterized queries (?) to prevent SQL injection
|
|
140
|
+
// ❌ WRONG
|
|
141
|
+
await pool.execute(`SELECT * FROM users WHERE email = '${email}'`)
|
|
142
|
+
|
|
143
|
+
// ✅ CORRECT
|
|
144
|
+
await pool.execute('SELECT * FROM users WHERE email = ?', [email])
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Error Handling
|
|
148
|
+
```typescript
|
|
149
|
+
try {
|
|
150
|
+
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId])
|
|
151
|
+
if ((rows as any[]).length === 0) {
|
|
152
|
+
throw new Error('User not found')
|
|
153
|
+
}
|
|
154
|
+
return rows[0]
|
|
155
|
+
} catch (error: any) {
|
|
156
|
+
if (error.code === 'ER_DUP_ENTRY') {
|
|
157
|
+
throw new Error('Duplicate entry')
|
|
158
|
+
}
|
|
159
|
+
if (error.code === 'ER_NO_REFERENCED_ROW_2') {
|
|
160
|
+
throw new Error('Referenced record does not exist')
|
|
161
|
+
}
|
|
162
|
+
throw error
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Migrations
|
|
167
|
+
```typescript
|
|
168
|
+
// Using db-migrate
|
|
169
|
+
import { migrate } from 'db-migrate'
|
|
170
|
+
|
|
171
|
+
await migrate({
|
|
172
|
+
config: {
|
|
173
|
+
dev: {
|
|
174
|
+
driver: 'mysql',
|
|
175
|
+
database: process.env.DB_NAME,
|
|
176
|
+
user: process.env.DB_USER,
|
|
177
|
+
password: process.env.DB_PASSWORD,
|
|
178
|
+
host: process.env.DB_HOST,
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
env: 'dev',
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Best Practices
|
|
186
|
+
|
|
187
|
+
✅ **DO:**
|
|
188
|
+
- Use connection pooling (10-20 connections typically)
|
|
189
|
+
- Always use parameterized queries (? placeholders)
|
|
190
|
+
- Use transactions for multi-step operations
|
|
191
|
+
- Create indexes on frequently queried columns
|
|
192
|
+
- Use EXPLAIN to optimize queries
|
|
193
|
+
- Enable query caching for read-heavy workloads
|
|
194
|
+
- Use InnoDB engine (ACID compliance)
|
|
195
|
+
- Set appropriate charset (utf8mb4 for full Unicode)
|
|
196
|
+
- Monitor slow query log
|
|
197
|
+
- Use prepared statements for repeated queries
|
|
198
|
+
|
|
199
|
+
❌ **DON'T:**
|
|
200
|
+
- Use string concatenation for queries (SQL injection risk)
|
|
201
|
+
- Create too many connections (exhaust pool)
|
|
202
|
+
- Skip error handling
|
|
203
|
+
- Ignore connection pool limits
|
|
204
|
+
- Use SELECT * in production (specify columns)
|
|
205
|
+
- Skip indexes on foreign keys
|
|
206
|
+
- Hardcode connection strings
|
|
207
|
+
- Use MyISAM engine (no transactions)
|
|
208
|
+
- Ignore query performance
|
|
209
|
+
- Use synchronous queries
|
|
210
|
+
|
|
211
|
+
## Configuration
|
|
212
|
+
|
|
213
|
+
### Environment Variables
|
|
214
|
+
```bash
|
|
215
|
+
DB_HOST=localhost
|
|
216
|
+
DB_PORT=3306
|
|
217
|
+
DB_NAME=myapp
|
|
218
|
+
DB_USER=myuser
|
|
219
|
+
DB_PASSWORD=securepassword
|
|
220
|
+
DATABASE_URL=mysql://user:password@host:port/database
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Docker Compose
|
|
224
|
+
```yaml
|
|
225
|
+
services:
|
|
226
|
+
mysql:
|
|
227
|
+
image: mysql:8.0
|
|
228
|
+
environment:
|
|
229
|
+
MYSQL_DATABASE: myapp
|
|
230
|
+
MYSQL_USER: myuser
|
|
231
|
+
MYSQL_PASSWORD: securepassword
|
|
232
|
+
MYSQL_ROOT_PASSWORD: rootpassword
|
|
233
|
+
ports:
|
|
234
|
+
- "3306:3306"
|
|
235
|
+
volumes:
|
|
236
|
+
- mysql_data:/var/lib/mysql
|
|
237
|
+
command: --default-authentication-plugin=mysql_native_password
|
|
238
|
+
healthcheck:
|
|
239
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
240
|
+
interval: 10s
|
|
241
|
+
timeout: 5s
|
|
242
|
+
retries: 5
|
|
243
|
+
|
|
244
|
+
volumes:
|
|
245
|
+
mysql_data:
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Prisma Schema
|
|
249
|
+
```prisma
|
|
250
|
+
datasource db {
|
|
251
|
+
provider = "mysql"
|
|
252
|
+
url = env("DATABASE_URL")
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
model User {
|
|
256
|
+
id Int @id @default(autoincrement())
|
|
257
|
+
email String @unique @db.VarChar(255)
|
|
258
|
+
name String? @db.VarChar(255)
|
|
259
|
+
createdAt DateTime @default(now()) @db.Timestamp(6)
|
|
260
|
+
posts Post[]
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
model Post {
|
|
264
|
+
id Int @id @default(autoincrement())
|
|
265
|
+
title String @db.VarChar(255)
|
|
266
|
+
content String? @db.Text
|
|
267
|
+
authorId Int
|
|
268
|
+
author User @relation(fields: [authorId], references: [id])
|
|
269
|
+
createdAt DateTime @default(now()) @db.Timestamp(6)
|
|
270
|
+
|
|
271
|
+
@@index([authorId, createdAt(sort: Desc)])
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Performance Optimization
|
|
276
|
+
|
|
277
|
+
### Indexing
|
|
278
|
+
```sql
|
|
279
|
+
-- Single column index
|
|
280
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
281
|
+
|
|
282
|
+
-- Composite index
|
|
283
|
+
CREATE INDEX idx_posts_author_created ON posts(author_id, created_at DESC);
|
|
284
|
+
|
|
285
|
+
-- Full-text index
|
|
286
|
+
CREATE FULLTEXT INDEX idx_articles_content ON articles(title, content);
|
|
287
|
+
|
|
288
|
+
-- Prefix index (for long strings)
|
|
289
|
+
CREATE INDEX idx_users_name_prefix ON users(name(10));
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Query Optimization
|
|
293
|
+
```typescript
|
|
294
|
+
// Use LIMIT for pagination
|
|
295
|
+
const [rows] = await pool.execute(
|
|
296
|
+
'SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?',
|
|
297
|
+
[limit, offset]
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
// Use EXISTS instead of COUNT
|
|
301
|
+
const [rows] = await pool.execute(
|
|
302
|
+
'SELECT EXISTS(SELECT 1 FROM users WHERE email = ?) as exists',
|
|
303
|
+
[email]
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
// Use JOIN instead of subqueries when possible
|
|
307
|
+
const [rows] = await pool.execute(`
|
|
308
|
+
SELECT u.*, COUNT(p.id) as post_count
|
|
309
|
+
FROM users u
|
|
310
|
+
LEFT JOIN posts p ON u.id = p.author_id
|
|
311
|
+
GROUP BY u.id
|
|
312
|
+
`)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Integration with Development
|
|
316
|
+
|
|
317
|
+
### Testing
|
|
318
|
+
```typescript
|
|
319
|
+
// Use test database
|
|
320
|
+
const testPool = mysql.createPool({
|
|
321
|
+
database: 'myapp_test',
|
|
322
|
+
// ... config
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
// Clean up after tests
|
|
326
|
+
afterEach(async () => {
|
|
327
|
+
await testPool.execute('SET FOREIGN_KEY_CHECKS = 0')
|
|
328
|
+
await testPool.execute('TRUNCATE TABLE users')
|
|
329
|
+
await testPool.execute('TRUNCATE TABLE posts')
|
|
330
|
+
await testPool.execute('SET FOREIGN_KEY_CHECKS = 1')
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
// Use transactions for test isolation
|
|
334
|
+
beforeEach(async () => {
|
|
335
|
+
const connection = await testPool.getConnection()
|
|
336
|
+
await connection.beginTransaction()
|
|
337
|
+
// Store connection for rollback
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
afterEach(async () => {
|
|
341
|
+
// Rollback transaction
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Health Checks
|
|
346
|
+
```typescript
|
|
347
|
+
async function checkDatabaseHealth(): Promise<boolean> {
|
|
348
|
+
try {
|
|
349
|
+
const [rows] = await pool.execute('SELECT 1 as health')
|
|
350
|
+
return (rows as any[]).length > 0
|
|
351
|
+
} catch {
|
|
352
|
+
return false
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
<!-- MYSQL:END -->
|
|
358
|
+
|