@hivehub/rulebook 4.2.1 → 4.3.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/.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-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 +70 -70
- 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 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +4 -4
- package/dist/cli/commands.js.map +1 -1
- package/dist/core/claude-mcp.d.ts +8 -1
- package/dist/core/claude-mcp.d.ts.map +1 -1
- package/dist/core/claude-mcp.js +32 -1
- package/dist/core/claude-mcp.js.map +1 -1
- package/dist/core/generator.d.ts +13 -0
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +283 -28
- package/dist/core/generator.js.map +1 -1
- package/dist/core/workspace/project-worker.d.ts.map +1 -1
- package/dist/core/workspace/project-worker.js +3 -0
- package/dist/core/workspace/project-worker.js.map +1 -1
- package/dist/core/workspace/workspace-manager.d.ts.map +1 -1
- package/dist/core/workspace/workspace-manager.js +2 -6
- package/dist/core/workspace/workspace-manager.js.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/rulebook-server.d.ts.map +1 -1
- package/dist/mcp/rulebook-server.js +6 -5
- package/dist/mcp/rulebook-server.js.map +1 -1
- package/package.json +21 -22
- package/templates/agents/accessibility-reviewer.md +43 -0
- package/templates/agents/api-designer.md +42 -0
- package/templates/agents/architect.md +51 -0
- package/templates/agents/build-engineer.md +36 -0
- package/templates/agents/code-reviewer.md +47 -0
- package/templates/agents/database-architect.md +41 -0
- package/templates/agents/devops-engineer.md +42 -0
- package/templates/agents/docs-writer.md +38 -0
- package/templates/agents/i18n-engineer.md +42 -0
- package/templates/agents/implementer.md +38 -35
- package/templates/agents/migration-engineer.md +42 -0
- package/templates/agents/performance-engineer.md +49 -0
- package/templates/agents/refactoring-agent.md +41 -0
- package/templates/agents/researcher.md +38 -34
- package/templates/agents/security-reviewer.md +40 -0
- package/templates/agents/team-lead.md +37 -34
- package/templates/agents/tester.md +45 -42
- package/templates/agents/ux-reviewer.md +43 -0
- 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-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 +288 -288
- package/templates/core/DAG.md +304 -304
- package/templates/core/DOCUMENTATION_RULES.md +36 -36
- 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 +1935 -1935
- 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 +1157 -1157
- 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/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 -0
- package/templates/skills/dev/api-design/SKILL.md +15 -0
- package/templates/skills/dev/architect/SKILL.md +17 -0
- package/templates/skills/dev/build-fix/SKILL.md +17 -0
- package/templates/skills/dev/db-design/SKILL.md +15 -0
- package/templates/skills/dev/debug/SKILL.md +16 -0
- package/templates/skills/dev/deploy/SKILL.md +17 -0
- package/templates/skills/dev/docs/SKILL.md +17 -0
- package/templates/skills/dev/migrate/SKILL.md +15 -0
- package/templates/skills/dev/perf/SKILL.md +17 -0
- package/templates/skills/dev/refactor/SKILL.md +17 -0
- package/templates/skills/dev/research/SKILL.md +14 -0
- package/templates/skills/dev/review/SKILL.md +18 -0
- package/templates/skills/dev/security-audit/SKILL.md +17 -0
- 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,290 +1,290 @@
|
|
|
1
|
-
<!-- ORACLE:START -->
|
|
2
|
-
# Oracle Database Instructions
|
|
3
|
-
|
|
4
|
-
**CRITICAL**: Use Oracle Database for enterprise relational data storage with advanced features, high availability, and comprehensive tooling.
|
|
5
|
-
|
|
6
|
-
## Core Features
|
|
7
|
-
|
|
8
|
-
### Connection
|
|
9
|
-
```typescript
|
|
10
|
-
// Using oracledb
|
|
11
|
-
import oracledb from 'oracledb'
|
|
12
|
-
|
|
13
|
-
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT
|
|
14
|
-
oracledb.autoCommit = false
|
|
15
|
-
|
|
16
|
-
const connection = await oracledb.getConnection({
|
|
17
|
-
user: process.env.DB_USER || 'system',
|
|
18
|
-
password: process.env.DB_PASSWORD,
|
|
19
|
-
connectString: `${process.env.DB_HOST || 'localhost'}:${process.env.DB_PORT || '1521'}/${process.env.DB_SERVICE || 'XE'}`,
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
// Connection pool
|
|
23
|
-
const pool = await oracledb.createPool({
|
|
24
|
-
user: process.env.DB_USER,
|
|
25
|
-
password: process.env.DB_PASSWORD,
|
|
26
|
-
connectString: `${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_SERVICE}`,
|
|
27
|
-
poolMin: 2,
|
|
28
|
-
poolMax: 10,
|
|
29
|
-
poolIncrement: 1,
|
|
30
|
-
poolTimeout: 60,
|
|
31
|
-
})
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Basic Queries
|
|
35
|
-
```typescript
|
|
36
|
-
// SELECT
|
|
37
|
-
const result = await connection.execute(
|
|
38
|
-
'SELECT * FROM Users WHERE Id = :id',
|
|
39
|
-
{ id: userId }
|
|
40
|
-
)
|
|
41
|
-
const users = result.rows
|
|
42
|
-
|
|
43
|
-
// INSERT with RETURNING
|
|
44
|
-
const result = await connection.execute(
|
|
45
|
-
`INSERT INTO Users (Name, Email)
|
|
46
|
-
VALUES (:name, :email)
|
|
47
|
-
RETURNING Id INTO :id`,
|
|
48
|
-
{
|
|
49
|
-
name: 'John Doe',
|
|
50
|
-
email: 'john@example.com',
|
|
51
|
-
id: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
|
|
52
|
-
}
|
|
53
|
-
)
|
|
54
|
-
const newId = result.outBinds.id[0]
|
|
55
|
-
|
|
56
|
-
// UPDATE
|
|
57
|
-
const result = await connection.execute(
|
|
58
|
-
'UPDATE Users SET Name = :name WHERE Id = :id',
|
|
59
|
-
{
|
|
60
|
-
name: 'Jane Doe',
|
|
61
|
-
id: userId,
|
|
62
|
-
}
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
// DELETE
|
|
66
|
-
await connection.execute(
|
|
67
|
-
'DELETE FROM Users WHERE Id = :id',
|
|
68
|
-
{ id: userId }
|
|
69
|
-
)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Transactions
|
|
73
|
-
```typescript
|
|
74
|
-
const connection = await pool.getConnection()
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
await connection.execute(
|
|
78
|
-
'INSERT INTO Accounts (UserId, Balance) VALUES (:userId, :balance)',
|
|
79
|
-
{ userId, balance: 1000 }
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
await connection.execute(
|
|
83
|
-
'INSERT INTO Transactions (AccountId, Amount) VALUES (:accountId, :amount)',
|
|
84
|
-
{ accountId, amount: 1000 }
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
await connection.commit()
|
|
88
|
-
} catch (error) {
|
|
89
|
-
await connection.rollback()
|
|
90
|
-
throw error
|
|
91
|
-
} finally {
|
|
92
|
-
await connection.close()
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Advanced Features
|
|
97
|
-
```typescript
|
|
98
|
-
// PL/SQL procedures
|
|
99
|
-
const result = await connection.execute(
|
|
100
|
-
`BEGIN
|
|
101
|
-
sp_GetUserDetails(:userId, :userData);
|
|
102
|
-
END;`,
|
|
103
|
-
{
|
|
104
|
-
userId,
|
|
105
|
-
userData: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
|
|
106
|
-
}
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
// JSON operations (Oracle 12c+)
|
|
110
|
-
const result = await connection.execute(
|
|
111
|
-
`SELECT
|
|
112
|
-
Id,
|
|
113
|
-
Name,
|
|
114
|
-
JSON_VALUE(Metadata, '$.category') AS Category
|
|
115
|
-
FROM Products
|
|
116
|
-
WHERE JSON_VALUE(Metadata, '$.category') = :category`,
|
|
117
|
-
{ category: 'electronics' }
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
// Full-text search (Oracle Text)
|
|
121
|
-
const result = await connection.execute(
|
|
122
|
-
`SELECT * FROM Articles
|
|
123
|
-
WHERE CONTAINS(Content, :searchTerm, 1) > 0`,
|
|
124
|
-
{ searchTerm: 'search term' }
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
// Window functions
|
|
128
|
-
const result = await connection.execute(
|
|
129
|
-
`SELECT
|
|
130
|
-
Name,
|
|
131
|
-
Salary,
|
|
132
|
-
ROW_NUMBER() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS Rank
|
|
133
|
-
FROM Employees`
|
|
134
|
-
)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Common Patterns
|
|
138
|
-
|
|
139
|
-
### Connection Pooling
|
|
140
|
-
```typescript
|
|
141
|
-
let pool: oracledb.Pool | null = null
|
|
142
|
-
|
|
143
|
-
export async function getPool(): Promise<oracledb.Pool> {
|
|
144
|
-
if (!pool) {
|
|
145
|
-
pool = await oracledb.createPool({
|
|
146
|
-
// ... config
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
return pool
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Graceful shutdown
|
|
153
|
-
process.on('SIGINT', async () => {
|
|
154
|
-
if (pool) {
|
|
155
|
-
await pool.close()
|
|
156
|
-
}
|
|
157
|
-
process.exit(0)
|
|
158
|
-
})
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Parameterized Queries
|
|
162
|
-
```typescript
|
|
163
|
-
// Always use bind variables (:param) to prevent SQL injection
|
|
164
|
-
// ❌ WRONG
|
|
165
|
-
await connection.execute(`SELECT * FROM Users WHERE Email = '${email}'`)
|
|
166
|
-
|
|
167
|
-
// ✅ CORRECT
|
|
168
|
-
await connection.execute(
|
|
169
|
-
'SELECT * FROM Users WHERE Email = :email',
|
|
170
|
-
{ email }
|
|
171
|
-
)
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Error Handling
|
|
175
|
-
```typescript
|
|
176
|
-
try {
|
|
177
|
-
const result = await connection.execute(
|
|
178
|
-
'SELECT * FROM Users WHERE Id = :id',
|
|
179
|
-
{ id: userId }
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
if (result.rows.length === 0) {
|
|
183
|
-
throw new Error('User not found')
|
|
184
|
-
}
|
|
185
|
-
return result.rows[0]
|
|
186
|
-
} catch (error: any) {
|
|
187
|
-
if (error.errorNum === 1) { // Unique constraint violation
|
|
188
|
-
throw new Error('Duplicate entry')
|
|
189
|
-
}
|
|
190
|
-
if (error.errorNum === 2291) { // Foreign key constraint violation
|
|
191
|
-
throw new Error('Referenced record does not exist')
|
|
192
|
-
}
|
|
193
|
-
throw error
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Best Practices
|
|
198
|
-
|
|
199
|
-
✅ **DO:**
|
|
200
|
-
- Use connection pooling (2-10 connections typically)
|
|
201
|
-
- Always use bind variables (:param)
|
|
202
|
-
- Use transactions for multi-step operations
|
|
203
|
-
- Create indexes on frequently queried columns
|
|
204
|
-
- Use appropriate data types
|
|
205
|
-
- Enable connection retry logic
|
|
206
|
-
- Use PL/SQL for complex operations
|
|
207
|
-
- Monitor connection pool usage
|
|
208
|
-
- Use appropriate fetch array sizes
|
|
209
|
-
- Implement proper error handling
|
|
210
|
-
|
|
211
|
-
❌ **DON'T:**
|
|
212
|
-
- Use string concatenation for queries (SQL injection risk)
|
|
213
|
-
- Create too many connections
|
|
214
|
-
- Skip error handling
|
|
215
|
-
- Ignore connection pool limits
|
|
216
|
-
- Use SELECT * in production
|
|
217
|
-
- Skip indexes on foreign keys
|
|
218
|
-
- Hardcode connection strings
|
|
219
|
-
- Skip transaction management
|
|
220
|
-
- Ignore query performance
|
|
221
|
-
- Use synchronous operations
|
|
222
|
-
|
|
223
|
-
## Configuration
|
|
224
|
-
|
|
225
|
-
### Environment Variables
|
|
226
|
-
```bash
|
|
227
|
-
DB_HOST=localhost
|
|
228
|
-
DB_PORT=1521
|
|
229
|
-
DB_SERVICE=XE
|
|
230
|
-
DB_USER=system
|
|
231
|
-
DB_PASSWORD=securepassword
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Docker Compose
|
|
235
|
-
```yaml
|
|
236
|
-
services:
|
|
237
|
-
oracle:
|
|
238
|
-
image: container-registry.oracle.com/database/express:21.3.0-xe
|
|
239
|
-
ports:
|
|
240
|
-
- "1521:1521"
|
|
241
|
-
- "5500:5500" # Enterprise Manager
|
|
242
|
-
environment:
|
|
243
|
-
ORACLE_PWD: securepassword
|
|
244
|
-
volumes:
|
|
245
|
-
- oracle_data:/opt/oracle/oradata
|
|
246
|
-
healthcheck:
|
|
247
|
-
test: ["CMD-SHELL", "sqlplus -S system/securepassword@localhost:1521/XE <<< 'SELECT 1 FROM DUAL;' || exit 1"]
|
|
248
|
-
interval: 30s
|
|
249
|
-
timeout: 10s
|
|
250
|
-
retries: 5
|
|
251
|
-
|
|
252
|
-
volumes:
|
|
253
|
-
oracle_data:
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## Integration with Development
|
|
257
|
-
|
|
258
|
-
### Testing
|
|
259
|
-
```typescript
|
|
260
|
-
// Use test database
|
|
261
|
-
const testPool = await oracledb.createPool({
|
|
262
|
-
connectString: 'localhost:1521/TEST',
|
|
263
|
-
// ... config
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
// Clean up after tests
|
|
267
|
-
afterEach(async () => {
|
|
268
|
-
const connection = await testPool.getConnection()
|
|
269
|
-
await connection.execute('DELETE FROM Users')
|
|
270
|
-
await connection.execute('DELETE FROM Posts')
|
|
271
|
-
await connection.close()
|
|
272
|
-
})
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Health Checks
|
|
276
|
-
```typescript
|
|
277
|
-
async function checkDatabaseHealth(): Promise<boolean> {
|
|
278
|
-
try {
|
|
279
|
-
const connection = await pool.getConnection()
|
|
280
|
-
const result = await connection.execute('SELECT 1 FROM DUAL')
|
|
281
|
-
await connection.close()
|
|
282
|
-
return result.rows.length > 0
|
|
283
|
-
} catch {
|
|
284
|
-
return false
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
<!-- ORACLE:END -->
|
|
290
|
-
|
|
1
|
+
<!-- ORACLE:START -->
|
|
2
|
+
# Oracle Database Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Use Oracle Database for enterprise relational data storage with advanced features, high availability, and comprehensive tooling.
|
|
5
|
+
|
|
6
|
+
## Core Features
|
|
7
|
+
|
|
8
|
+
### Connection
|
|
9
|
+
```typescript
|
|
10
|
+
// Using oracledb
|
|
11
|
+
import oracledb from 'oracledb'
|
|
12
|
+
|
|
13
|
+
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT
|
|
14
|
+
oracledb.autoCommit = false
|
|
15
|
+
|
|
16
|
+
const connection = await oracledb.getConnection({
|
|
17
|
+
user: process.env.DB_USER || 'system',
|
|
18
|
+
password: process.env.DB_PASSWORD,
|
|
19
|
+
connectString: `${process.env.DB_HOST || 'localhost'}:${process.env.DB_PORT || '1521'}/${process.env.DB_SERVICE || 'XE'}`,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
// Connection pool
|
|
23
|
+
const pool = await oracledb.createPool({
|
|
24
|
+
user: process.env.DB_USER,
|
|
25
|
+
password: process.env.DB_PASSWORD,
|
|
26
|
+
connectString: `${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_SERVICE}`,
|
|
27
|
+
poolMin: 2,
|
|
28
|
+
poolMax: 10,
|
|
29
|
+
poolIncrement: 1,
|
|
30
|
+
poolTimeout: 60,
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Basic Queries
|
|
35
|
+
```typescript
|
|
36
|
+
// SELECT
|
|
37
|
+
const result = await connection.execute(
|
|
38
|
+
'SELECT * FROM Users WHERE Id = :id',
|
|
39
|
+
{ id: userId }
|
|
40
|
+
)
|
|
41
|
+
const users = result.rows
|
|
42
|
+
|
|
43
|
+
// INSERT with RETURNING
|
|
44
|
+
const result = await connection.execute(
|
|
45
|
+
`INSERT INTO Users (Name, Email)
|
|
46
|
+
VALUES (:name, :email)
|
|
47
|
+
RETURNING Id INTO :id`,
|
|
48
|
+
{
|
|
49
|
+
name: 'John Doe',
|
|
50
|
+
email: 'john@example.com',
|
|
51
|
+
id: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
const newId = result.outBinds.id[0]
|
|
55
|
+
|
|
56
|
+
// UPDATE
|
|
57
|
+
const result = await connection.execute(
|
|
58
|
+
'UPDATE Users SET Name = :name WHERE Id = :id',
|
|
59
|
+
{
|
|
60
|
+
name: 'Jane Doe',
|
|
61
|
+
id: userId,
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
// DELETE
|
|
66
|
+
await connection.execute(
|
|
67
|
+
'DELETE FROM Users WHERE Id = :id',
|
|
68
|
+
{ id: userId }
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Transactions
|
|
73
|
+
```typescript
|
|
74
|
+
const connection = await pool.getConnection()
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
await connection.execute(
|
|
78
|
+
'INSERT INTO Accounts (UserId, Balance) VALUES (:userId, :balance)',
|
|
79
|
+
{ userId, balance: 1000 }
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
await connection.execute(
|
|
83
|
+
'INSERT INTO Transactions (AccountId, Amount) VALUES (:accountId, :amount)',
|
|
84
|
+
{ accountId, amount: 1000 }
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
await connection.commit()
|
|
88
|
+
} catch (error) {
|
|
89
|
+
await connection.rollback()
|
|
90
|
+
throw error
|
|
91
|
+
} finally {
|
|
92
|
+
await connection.close()
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Advanced Features
|
|
97
|
+
```typescript
|
|
98
|
+
// PL/SQL procedures
|
|
99
|
+
const result = await connection.execute(
|
|
100
|
+
`BEGIN
|
|
101
|
+
sp_GetUserDetails(:userId, :userData);
|
|
102
|
+
END;`,
|
|
103
|
+
{
|
|
104
|
+
userId,
|
|
105
|
+
userData: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// JSON operations (Oracle 12c+)
|
|
110
|
+
const result = await connection.execute(
|
|
111
|
+
`SELECT
|
|
112
|
+
Id,
|
|
113
|
+
Name,
|
|
114
|
+
JSON_VALUE(Metadata, '$.category') AS Category
|
|
115
|
+
FROM Products
|
|
116
|
+
WHERE JSON_VALUE(Metadata, '$.category') = :category`,
|
|
117
|
+
{ category: 'electronics' }
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
// Full-text search (Oracle Text)
|
|
121
|
+
const result = await connection.execute(
|
|
122
|
+
`SELECT * FROM Articles
|
|
123
|
+
WHERE CONTAINS(Content, :searchTerm, 1) > 0`,
|
|
124
|
+
{ searchTerm: 'search term' }
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
// Window functions
|
|
128
|
+
const result = await connection.execute(
|
|
129
|
+
`SELECT
|
|
130
|
+
Name,
|
|
131
|
+
Salary,
|
|
132
|
+
ROW_NUMBER() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS Rank
|
|
133
|
+
FROM Employees`
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Common Patterns
|
|
138
|
+
|
|
139
|
+
### Connection Pooling
|
|
140
|
+
```typescript
|
|
141
|
+
let pool: oracledb.Pool | null = null
|
|
142
|
+
|
|
143
|
+
export async function getPool(): Promise<oracledb.Pool> {
|
|
144
|
+
if (!pool) {
|
|
145
|
+
pool = await oracledb.createPool({
|
|
146
|
+
// ... config
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
return pool
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Graceful shutdown
|
|
153
|
+
process.on('SIGINT', async () => {
|
|
154
|
+
if (pool) {
|
|
155
|
+
await pool.close()
|
|
156
|
+
}
|
|
157
|
+
process.exit(0)
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Parameterized Queries
|
|
162
|
+
```typescript
|
|
163
|
+
// Always use bind variables (:param) to prevent SQL injection
|
|
164
|
+
// ❌ WRONG
|
|
165
|
+
await connection.execute(`SELECT * FROM Users WHERE Email = '${email}'`)
|
|
166
|
+
|
|
167
|
+
// ✅ CORRECT
|
|
168
|
+
await connection.execute(
|
|
169
|
+
'SELECT * FROM Users WHERE Email = :email',
|
|
170
|
+
{ email }
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Error Handling
|
|
175
|
+
```typescript
|
|
176
|
+
try {
|
|
177
|
+
const result = await connection.execute(
|
|
178
|
+
'SELECT * FROM Users WHERE Id = :id',
|
|
179
|
+
{ id: userId }
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
if (result.rows.length === 0) {
|
|
183
|
+
throw new Error('User not found')
|
|
184
|
+
}
|
|
185
|
+
return result.rows[0]
|
|
186
|
+
} catch (error: any) {
|
|
187
|
+
if (error.errorNum === 1) { // Unique constraint violation
|
|
188
|
+
throw new Error('Duplicate entry')
|
|
189
|
+
}
|
|
190
|
+
if (error.errorNum === 2291) { // Foreign key constraint violation
|
|
191
|
+
throw new Error('Referenced record does not exist')
|
|
192
|
+
}
|
|
193
|
+
throw error
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Best Practices
|
|
198
|
+
|
|
199
|
+
✅ **DO:**
|
|
200
|
+
- Use connection pooling (2-10 connections typically)
|
|
201
|
+
- Always use bind variables (:param)
|
|
202
|
+
- Use transactions for multi-step operations
|
|
203
|
+
- Create indexes on frequently queried columns
|
|
204
|
+
- Use appropriate data types
|
|
205
|
+
- Enable connection retry logic
|
|
206
|
+
- Use PL/SQL for complex operations
|
|
207
|
+
- Monitor connection pool usage
|
|
208
|
+
- Use appropriate fetch array sizes
|
|
209
|
+
- Implement proper error handling
|
|
210
|
+
|
|
211
|
+
❌ **DON'T:**
|
|
212
|
+
- Use string concatenation for queries (SQL injection risk)
|
|
213
|
+
- Create too many connections
|
|
214
|
+
- Skip error handling
|
|
215
|
+
- Ignore connection pool limits
|
|
216
|
+
- Use SELECT * in production
|
|
217
|
+
- Skip indexes on foreign keys
|
|
218
|
+
- Hardcode connection strings
|
|
219
|
+
- Skip transaction management
|
|
220
|
+
- Ignore query performance
|
|
221
|
+
- Use synchronous operations
|
|
222
|
+
|
|
223
|
+
## Configuration
|
|
224
|
+
|
|
225
|
+
### Environment Variables
|
|
226
|
+
```bash
|
|
227
|
+
DB_HOST=localhost
|
|
228
|
+
DB_PORT=1521
|
|
229
|
+
DB_SERVICE=XE
|
|
230
|
+
DB_USER=system
|
|
231
|
+
DB_PASSWORD=securepassword
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Docker Compose
|
|
235
|
+
```yaml
|
|
236
|
+
services:
|
|
237
|
+
oracle:
|
|
238
|
+
image: container-registry.oracle.com/database/express:21.3.0-xe
|
|
239
|
+
ports:
|
|
240
|
+
- "1521:1521"
|
|
241
|
+
- "5500:5500" # Enterprise Manager
|
|
242
|
+
environment:
|
|
243
|
+
ORACLE_PWD: securepassword
|
|
244
|
+
volumes:
|
|
245
|
+
- oracle_data:/opt/oracle/oradata
|
|
246
|
+
healthcheck:
|
|
247
|
+
test: ["CMD-SHELL", "sqlplus -S system/securepassword@localhost:1521/XE <<< 'SELECT 1 FROM DUAL;' || exit 1"]
|
|
248
|
+
interval: 30s
|
|
249
|
+
timeout: 10s
|
|
250
|
+
retries: 5
|
|
251
|
+
|
|
252
|
+
volumes:
|
|
253
|
+
oracle_data:
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Integration with Development
|
|
257
|
+
|
|
258
|
+
### Testing
|
|
259
|
+
```typescript
|
|
260
|
+
// Use test database
|
|
261
|
+
const testPool = await oracledb.createPool({
|
|
262
|
+
connectString: 'localhost:1521/TEST',
|
|
263
|
+
// ... config
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
// Clean up after tests
|
|
267
|
+
afterEach(async () => {
|
|
268
|
+
const connection = await testPool.getConnection()
|
|
269
|
+
await connection.execute('DELETE FROM Users')
|
|
270
|
+
await connection.execute('DELETE FROM Posts')
|
|
271
|
+
await connection.close()
|
|
272
|
+
})
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Health Checks
|
|
276
|
+
```typescript
|
|
277
|
+
async function checkDatabaseHealth(): Promise<boolean> {
|
|
278
|
+
try {
|
|
279
|
+
const connection = await pool.getConnection()
|
|
280
|
+
const result = await connection.execute('SELECT 1 FROM DUAL')
|
|
281
|
+
await connection.close()
|
|
282
|
+
return result.rows.length > 0
|
|
283
|
+
} catch {
|
|
284
|
+
return false
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
<!-- ORACLE:END -->
|
|
290
|
+
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
<!-- PINO:START -->
|
|
2
|
-
# Pino — Structured Logging
|
|
3
|
-
|
|
4
|
-
## Configuration
|
|
5
|
-
- Create singleton logger instance: `const logger = pino({ level: process.env.LOG_LEVEL || 'info' })`
|
|
6
|
-
- Use child loggers for request context: `req.log = logger.child({ requestId: req.id })`
|
|
7
|
-
- Configure pretty print for development only: `transport: { target: 'pino-pretty' }` (only when `NODE_ENV !== 'production'`)
|
|
8
|
-
|
|
9
|
-
## Log Levels
|
|
10
|
-
- `error`: Unexpected errors requiring immediate attention
|
|
11
|
-
- `warn`: Recoverable errors, deprecated usage, approaching limits
|
|
12
|
-
- `info`: Significant state changes, important business events
|
|
13
|
-
- `debug`: Detailed flow for troubleshooting (disabled in production)
|
|
14
|
-
- `trace`: High-frequency diagnostic data (never in production)
|
|
15
|
-
|
|
16
|
-
## Structured Fields
|
|
17
|
-
- Always include: `{ service, version, requestId, userId }` in request context
|
|
18
|
-
- Never log: passwords, tokens, credit cards, PII fields
|
|
19
|
-
- Log all outgoing HTTP calls with: `{ method, url, statusCode, duration }`
|
|
20
|
-
|
|
21
|
-
## Performance
|
|
22
|
-
- Avoid `JSON.stringify()` in log calls — pino handles serialization
|
|
23
|
-
- Use `logger.isLevelEnabled('debug')` before expensive debug computations
|
|
24
|
-
<!-- PINO:END -->
|
|
1
|
+
<!-- PINO:START -->
|
|
2
|
+
# Pino — Structured Logging
|
|
3
|
+
|
|
4
|
+
## Configuration
|
|
5
|
+
- Create singleton logger instance: `const logger = pino({ level: process.env.LOG_LEVEL || 'info' })`
|
|
6
|
+
- Use child loggers for request context: `req.log = logger.child({ requestId: req.id })`
|
|
7
|
+
- Configure pretty print for development only: `transport: { target: 'pino-pretty' }` (only when `NODE_ENV !== 'production'`)
|
|
8
|
+
|
|
9
|
+
## Log Levels
|
|
10
|
+
- `error`: Unexpected errors requiring immediate attention
|
|
11
|
+
- `warn`: Recoverable errors, deprecated usage, approaching limits
|
|
12
|
+
- `info`: Significant state changes, important business events
|
|
13
|
+
- `debug`: Detailed flow for troubleshooting (disabled in production)
|
|
14
|
+
- `trace`: High-frequency diagnostic data (never in production)
|
|
15
|
+
|
|
16
|
+
## Structured Fields
|
|
17
|
+
- Always include: `{ service, version, requestId, userId }` in request context
|
|
18
|
+
- Never log: passwords, tokens, credit cards, PII fields
|
|
19
|
+
- Log all outgoing HTTP calls with: `{ method, url, statusCode, duration }`
|
|
20
|
+
|
|
21
|
+
## Performance
|
|
22
|
+
- Avoid `JSON.stringify()` in log calls — pino handles serialization
|
|
23
|
+
- Use `logger.isLevelEnabled('debug')` before expensive debug computations
|
|
24
|
+
<!-- PINO:END -->
|