@hivehub/rulebook 5.5.1 → 5.7.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/rulebook-learn-capture.md +41 -48
- package/.claude/commands/rulebook-learn-list.md +13 -13
- package/README.md +332 -394
- package/dist/cli/commands/context-intelligence.d.ts +0 -1
- package/dist/cli/commands/context-intelligence.d.ts.map +1 -1
- package/dist/cli/commands/context-intelligence.js +12 -33
- package/dist/cli/commands/context-intelligence.js.map +1 -1
- package/dist/cli/commands/index.d.ts +4 -7
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +4 -7
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +40 -81
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +0 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +1 -7
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/memory.d.ts +7 -1
- package/dist/cli/commands/memory.d.ts.map +1 -1
- package/dist/cli/commands/memory.js +51 -57
- package/dist/cli/commands/memory.js.map +1 -1
- package/dist/cli/commands/misc.d.ts +1 -15
- package/dist/cli/commands/misc.d.ts.map +1 -1
- package/dist/cli/commands/misc.js +36 -215
- package/dist/cli/commands/misc.js.map +1 -1
- package/dist/cli/commands/plans.d.ts +0 -6
- package/dist/cli/commands/plans.d.ts.map +1 -1
- package/dist/cli/commands/plans.js +9 -77
- package/dist/cli/commands/plans.js.map +1 -1
- package/dist/cli/commands/skills.js +6 -6
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/task.js +4 -4
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +122 -52
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/prompts.d.ts.map +1 -1
- package/dist/cli/prompts.js +1 -78
- package/dist/cli/prompts.js.map +1 -1
- package/dist/core/claude/claude-mcp.d.ts +59 -0
- package/dist/core/claude/claude-mcp.d.ts.map +1 -0
- package/dist/core/claude/claude-mcp.js +220 -0
- package/dist/core/claude/claude-mcp.js.map +1 -0
- package/dist/core/claude/claude-md-generator.d.ts +52 -0
- package/dist/core/claude/claude-md-generator.d.ts.map +1 -0
- package/dist/core/claude/claude-md-generator.js +104 -0
- package/dist/core/claude/claude-md-generator.js.map +1 -0
- package/dist/core/claude/claude-settings-manager.d.ts +44 -0
- package/dist/core/claude/claude-settings-manager.d.ts.map +1 -0
- package/dist/core/claude/claude-settings-manager.js +194 -0
- package/dist/core/claude/claude-settings-manager.js.map +1 -0
- package/dist/core/claude-settings-manager.d.ts.map +1 -1
- package/dist/core/claude-settings-manager.js +9 -3
- package/dist/core/claude-settings-manager.js.map +1 -1
- package/dist/core/console/cli-bridge.d.ts +113 -0
- package/dist/core/console/cli-bridge.d.ts.map +1 -0
- package/dist/core/console/cli-bridge.js +1094 -0
- package/dist/core/console/cli-bridge.js.map +1 -0
- package/dist/core/detect/detector.d.ts +35 -0
- package/dist/core/detect/detector.d.ts.map +1 -0
- package/dist/core/detect/detector.js +541 -0
- package/dist/core/detect/detector.js.map +1 -0
- package/dist/core/docs/docs-generator.d.ts +9 -0
- package/dist/core/docs/docs-generator.d.ts.map +1 -0
- package/dist/core/docs/docs-generator.js +531 -0
- package/dist/core/docs/docs-generator.js.map +1 -0
- package/dist/core/docs/mcp-reference-generator.d.ts +13 -0
- package/dist/core/docs/mcp-reference-generator.d.ts.map +1 -0
- package/dist/core/docs/mcp-reference-generator.js +66 -0
- package/dist/core/docs/mcp-reference-generator.js.map +1 -0
- package/dist/core/generators/generator.d.ts +54 -0
- package/dist/core/generators/generator.d.ts.map +1 -0
- package/dist/core/generators/generator.js +1041 -0
- package/dist/core/generators/generator.js.map +1 -0
- package/dist/core/generators/gitignore-generator.d.ts +13 -0
- package/dist/core/generators/gitignore-generator.d.ts.map +1 -0
- package/dist/core/generators/gitignore-generator.js +307 -0
- package/dist/core/generators/gitignore-generator.js.map +1 -0
- package/dist/core/generators/minimal-scaffolder.d.ts +8 -0
- package/dist/core/generators/minimal-scaffolder.d.ts.map +1 -0
- package/dist/core/generators/minimal-scaffolder.js +51 -0
- package/dist/core/generators/minimal-scaffolder.js.map +1 -0
- package/dist/core/generators/rules-generator.d.ts +73 -0
- package/dist/core/generators/rules-generator.d.ts.map +1 -0
- package/dist/core/generators/rules-generator.js +202 -0
- package/dist/core/generators/rules-generator.js.map +1 -0
- package/dist/core/generators/workflow-generator.d.ts +15 -0
- package/dist/core/generators/workflow-generator.d.ts.map +1 -0
- package/dist/core/generators/workflow-generator.js +390 -0
- package/dist/core/generators/workflow-generator.js.map +1 -0
- package/dist/core/ide/multi-tool-generator.d.ts +59 -0
- package/dist/core/ide/multi-tool-generator.d.ts.map +1 -0
- package/dist/core/ide/multi-tool-generator.js +157 -0
- package/dist/core/ide/multi-tool-generator.js.map +1 -0
- package/dist/core/ide/opencode-generator.d.ts +72 -0
- package/dist/core/ide/opencode-generator.d.ts.map +1 -0
- package/dist/core/ide/opencode-generator.js +450 -0
- package/dist/core/ide/opencode-generator.js.map +1 -0
- package/dist/core/merger.d.ts +1 -1
- package/dist/core/merger.d.ts.map +1 -1
- package/dist/core/merger.js +5 -5
- package/dist/core/merger.js.map +1 -1
- package/dist/core/migrator.d.ts +0 -1
- package/dist/core/migrator.d.ts.map +1 -1
- package/dist/core/migrator.js +4 -29
- package/dist/core/migrator.js.map +1 -1
- package/dist/core/quality/coverage-checker.d.ts +14 -0
- package/dist/core/quality/coverage-checker.d.ts.map +1 -0
- package/dist/core/quality/coverage-checker.js +176 -0
- package/dist/core/quality/coverage-checker.js.map +1 -0
- package/dist/core/quality/dependency-checker.d.ts +21 -0
- package/dist/core/quality/dependency-checker.d.ts.map +1 -0
- package/dist/core/quality/dependency-checker.js +247 -0
- package/dist/core/quality/dependency-checker.js.map +1 -0
- package/dist/core/quality/doctor.d.ts +19 -0
- package/dist/core/quality/doctor.d.ts.map +1 -0
- package/dist/core/quality/doctor.js +163 -0
- package/dist/core/quality/doctor.js.map +1 -0
- package/dist/core/quality/validator.d.ts +21 -0
- package/dist/core/quality/validator.d.ts.map +1 -0
- package/dist/core/quality/validator.js +177 -0
- package/dist/core/quality/validator.js.map +1 -0
- package/dist/core/ralph-scripts.d.ts.map +1 -1
- package/dist/core/ralph-scripts.js +7 -6
- package/dist/core/ralph-scripts.js.map +1 -1
- package/dist/core/skills/skills-manager.d.ts +126 -0
- package/dist/core/skills/skills-manager.d.ts.map +1 -0
- package/dist/core/skills/skills-manager.js +630 -0
- package/dist/core/skills/skills-manager.js.map +1 -0
- package/dist/core/state/config-manager.d.ts +86 -0
- package/dist/core/state/config-manager.d.ts.map +1 -0
- package/dist/core/state/config-manager.js +562 -0
- package/dist/core/state/config-manager.js.map +1 -0
- package/dist/core/state/override-manager.d.ts +23 -0
- package/dist/core/state/override-manager.d.ts.map +1 -0
- package/dist/core/state/override-manager.js +82 -0
- package/dist/core/state/override-manager.js.map +1 -0
- package/dist/core/state/state-writer.d.ts +34 -0
- package/dist/core/state/state-writer.d.ts.map +1 -0
- package/dist/core/state/state-writer.js +78 -0
- package/dist/core/state/state-writer.js.map +1 -0
- package/dist/core/state/version-bumper.d.ts +19 -0
- package/dist/core/state/version-bumper.d.ts.map +1 -0
- package/dist/core/state/version-bumper.js +180 -0
- package/dist/core/state/version-bumper.js.map +1 -0
- package/dist/core/tasks/decision-manager.d.ts +25 -0
- package/dist/core/tasks/decision-manager.d.ts.map +1 -0
- package/dist/core/tasks/decision-manager.js +183 -0
- package/dist/core/tasks/decision-manager.js.map +1 -0
- package/dist/core/tasks/knowledge-manager.d.ts +24 -0
- package/dist/core/tasks/knowledge-manager.d.ts.map +1 -0
- package/dist/core/tasks/knowledge-manager.js +173 -0
- package/dist/core/tasks/knowledge-manager.js.map +1 -0
- package/dist/core/tasks/learn-manager.d.ts +27 -0
- package/dist/core/tasks/learn-manager.d.ts.map +1 -0
- package/dist/core/tasks/learn-manager.js +121 -0
- package/dist/core/tasks/learn-manager.js.map +1 -0
- package/dist/core/tasks/plans-manager.d.ts +46 -0
- package/dist/core/tasks/plans-manager.d.ts.map +1 -0
- package/dist/core/tasks/plans-manager.js +158 -0
- package/dist/core/tasks/plans-manager.js.map +1 -0
- package/dist/core/tasks/task-manager.d.ts +127 -0
- package/dist/core/tasks/task-manager.d.ts.map +1 -0
- package/dist/core/tasks/task-manager.js +607 -0
- package/dist/core/tasks/task-manager.js.map +1 -0
- package/dist/core/workspace/project-worker.d.ts +6 -6
- package/dist/core/workspace/project-worker.d.ts.map +1 -1
- package/dist/core/workspace/project-worker.js +6 -6
- package/dist/core/workspace/project-worker.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -176
- package/dist/index.js.map +1 -1
- package/dist/mcp/rulebook-server.d.ts.map +1 -1
- package/dist/mcp/rulebook-server.js +16 -960
- package/dist/mcp/rulebook-server.js.map +1 -1
- package/dist/memory/file-search.d.ts +43 -0
- package/dist/memory/file-search.d.ts.map +1 -0
- package/dist/memory/file-search.js +228 -0
- package/dist/memory/file-search.js.map +1 -0
- package/dist/memory/file-store.d.ts +99 -0
- package/dist/memory/file-store.d.ts.map +1 -0
- package/dist/memory/file-store.js +615 -0
- package/dist/memory/file-store.js.map +1 -0
- package/dist/memory/legacy-migrator.d.ts +27 -0
- package/dist/memory/legacy-migrator.d.ts.map +1 -0
- package/dist/memory/legacy-migrator.js +185 -0
- package/dist/memory/legacy-migrator.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +25 -24
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +97 -140
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/memory-types.d.ts +1 -1
- package/dist/memory/memory-types.d.ts.map +1 -1
- package/dist/types.d.ts +8 -119
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/file-system.d.ts +22 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +31 -0
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/git-hooks.d.ts.map +1 -1
- package/dist/utils/git-hooks.js +3 -2
- package/dist/utils/git-hooks.js.map +1 -1
- package/package.json +2 -6
- package/templates/agents/context-intelligence.md +50 -52
- package/templates/cli/OPENCODE.md +85 -18
- package/templates/commands/rulebook-learn-capture.md +41 -48
- package/templates/commands/rulebook-learn-list.md +13 -13
- package/templates/core/AGENTS_LEAN.md +0 -14
- package/templates/hooks/check-context-and-handoff.sh +74 -76
- package/templates/hooks/enforce-pre-tool.sh +70 -0
- package/templates/hooks/enforce-team-for-background-agents.sh +55 -55
- package/templates/hooks/on-compact-reinject.sh +34 -34
- package/templates/hooks/resume-from-handoff.sh +61 -61
- package/templates/hooks/terse-activate.sh +197 -197
- package/templates/hooks/terse-mode-tracker.sh +190 -187
- package/templates/ides/OPENCODE.md +63 -0
- package/templates/skills/cli/opencode/SKILL.md +82 -28
- package/.claude/commands/ralph-config.md +0 -112
- package/.claude/commands/ralph-history.md +0 -110
- package/.claude/commands/ralph-init.md +0 -72
- package/.claude/commands/ralph-pause-resume.md +0 -105
- package/.claude/commands/ralph-run.md +0 -101
- package/.claude/commands/ralph-status.md +0 -76
- package/templates/core/RALPH.md +0 -471
- package/templates/frameworks/ANGULAR.md +0 -36
- package/templates/frameworks/DJANGO.md +0 -83
- package/templates/frameworks/ELECTRON.md +0 -147
- package/templates/frameworks/FLASK.md +0 -38
- package/templates/frameworks/FLUTTER.md +0 -55
- package/templates/frameworks/JQUERY.md +0 -32
- package/templates/frameworks/LARAVEL.md +0 -38
- package/templates/frameworks/NESTJS.md +0 -43
- package/templates/frameworks/NEXTJS.md +0 -127
- package/templates/frameworks/NUXT.md +0 -40
- package/templates/frameworks/RAILS.md +0 -66
- package/templates/frameworks/REACT.md +0 -38
- package/templates/frameworks/REACT_NATIVE.md +0 -47
- package/templates/frameworks/SPRING.md +0 -39
- package/templates/frameworks/SYMFONY.md +0 -36
- package/templates/frameworks/VUE.md +0 -36
- package/templates/frameworks/ZEND.md +0 -35
- package/templates/hooks/enforce-mcp-for-tasks.sh +0 -31
- package/templates/hooks/enforce-no-deferred.sh +0 -21
- package/templates/hooks/enforce-no-shortcuts.sh +0 -31
- package/templates/ides/COPILOT.md +0 -37
- package/templates/ides/CURSOR.md +0 -43
- package/templates/ides/JETBRAINS_AI.md +0 -35
- package/templates/ides/REPLIT.md +0 -36
- package/templates/ides/TABNINE.md +0 -29
- package/templates/ides/VSCODE.md +0 -40
- package/templates/ides/WINDSURF.md +0 -36
- package/templates/ides/ZED.md +0 -32
- package/templates/ides/cursor-mdc/go.mdc +0 -24
- package/templates/ides/cursor-mdc/python.mdc +0 -24
- package/templates/ides/cursor-mdc/quality.mdc +0 -25
- package/templates/ides/cursor-mdc/ralph.mdc +0 -39
- package/templates/ides/cursor-mdc/rulebook.mdc +0 -38
- package/templates/ides/cursor-mdc/rust.mdc +0 -24
- package/templates/ides/cursor-mdc/typescript.mdc +0 -25
- package/templates/ralph/ralph-history.bat +0 -4
- package/templates/ralph/ralph-history.sh +0 -5
- package/templates/ralph/ralph-init.bat +0 -5
- package/templates/ralph/ralph-init.sh +0 -5
- package/templates/ralph/ralph-pause.bat +0 -5
- package/templates/ralph/ralph-pause.sh +0 -5
- package/templates/ralph/ralph-run.bat +0 -5
- package/templates/ralph/ralph-run.sh +0 -5
- package/templates/ralph/ralph-status.bat +0 -4
- package/templates/ralph/ralph-status.sh +0 -5
- package/templates/services/AZURE_BLOB.md +0 -184
- package/templates/services/CASSANDRA.md +0 -239
- package/templates/services/DATADOG.md +0 -26
- package/templates/services/DOCKER.md +0 -124
- package/templates/services/DOCKER_COMPOSE.md +0 -168
- package/templates/services/DYNAMODB.md +0 -308
- package/templates/services/ELASTICSEARCH.md +0 -347
- package/templates/services/GCS.md +0 -178
- package/templates/services/HELM.md +0 -194
- package/templates/services/INFLUXDB.md +0 -265
- package/templates/services/KAFKA.md +0 -341
- package/templates/services/KUBERNETES.md +0 -208
- package/templates/services/MARIADB.md +0 -183
- package/templates/services/MEMCACHED.md +0 -242
- package/templates/services/MINIO.md +0 -201
- package/templates/services/MONGODB.md +0 -268
- package/templates/services/MYSQL.md +0 -358
- package/templates/services/NEO4J.md +0 -247
- package/templates/services/OPENTELEMETRY.md +0 -25
- package/templates/services/ORACLE.md +0 -290
- package/templates/services/PINO.md +0 -24
- package/templates/services/POSTGRESQL.md +0 -326
- package/templates/services/PROMETHEUS.md +0 -33
- package/templates/services/RABBITMQ.md +0 -286
- package/templates/services/REDIS.md +0 -292
- package/templates/services/S3.md +0 -298
- package/templates/services/SENTRY.md +0 -23
- package/templates/services/SQLITE.md +0 -294
- package/templates/services/SQLSERVER.md +0 -294
- package/templates/services/WINSTON.md +0 -30
- package/templates/skills/frameworks/angular/SKILL.md +0 -46
- package/templates/skills/frameworks/django/SKILL.md +0 -93
- package/templates/skills/frameworks/electron/SKILL.md +0 -157
- package/templates/skills/frameworks/flask/SKILL.md +0 -48
- package/templates/skills/frameworks/flutter/SKILL.md +0 -65
- package/templates/skills/frameworks/jquery/SKILL.md +0 -42
- package/templates/skills/frameworks/laravel/SKILL.md +0 -48
- package/templates/skills/frameworks/nestjs/SKILL.md +0 -53
- package/templates/skills/frameworks/nextjs/SKILL.md +0 -137
- package/templates/skills/frameworks/nuxt/SKILL.md +0 -50
- package/templates/skills/frameworks/rails/SKILL.md +0 -76
- package/templates/skills/frameworks/react/SKILL.md +0 -48
- package/templates/skills/frameworks/react-native/SKILL.md +0 -57
- package/templates/skills/frameworks/spring/SKILL.md +0 -49
- package/templates/skills/frameworks/symfony/SKILL.md +0 -46
- package/templates/skills/frameworks/vue/SKILL.md +0 -46
- package/templates/skills/frameworks/zend/SKILL.md +0 -45
- package/templates/skills/services/azure-blob/SKILL.md +0 -194
- package/templates/skills/services/cassandra/SKILL.md +0 -249
- package/templates/skills/services/dynamodb/SKILL.md +0 -318
- package/templates/skills/services/elasticsearch/SKILL.md +0 -357
- package/templates/skills/services/gcs/SKILL.md +0 -188
- package/templates/skills/services/influxdb/SKILL.md +0 -275
- package/templates/skills/services/kafka/SKILL.md +0 -351
- package/templates/skills/services/mariadb/SKILL.md +0 -193
- package/templates/skills/services/memcached/SKILL.md +0 -252
- package/templates/skills/services/minio/SKILL.md +0 -211
- package/templates/skills/services/mongodb/SKILL.md +0 -278
- package/templates/skills/services/mysql/SKILL.md +0 -368
- package/templates/skills/services/neo4j/SKILL.md +0 -257
- package/templates/skills/services/oracle/SKILL.md +0 -300
- package/templates/skills/services/postgresql/SKILL.md +0 -336
- package/templates/skills/services/rabbitmq/SKILL.md +0 -296
- package/templates/skills/services/redis/SKILL.md +0 -302
- package/templates/skills/services/s3/SKILL.md +0 -308
- package/templates/skills/services/sqlite/SKILL.md +0 -304
- package/templates/skills/services/sqlserver/SKILL.md +0 -304
- package/templates/skills/workflows/ralph/SETUP.md +0 -228
- package/templates/skills/workflows/ralph/SKILL.md +0 -309
- package/templates/skills/workflows/ralph/install.sh +0 -87
- package/templates/skills/workflows/ralph/manifest.json +0 -158
package/templates/services/S3.md
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
<!-- S3:START -->
|
|
2
|
-
# AWS S3 Storage Instructions
|
|
3
|
-
|
|
4
|
-
**CRITICAL**: Use AWS S3 for object storage, file uploads, static assets, and backup storage with high availability.
|
|
5
|
-
|
|
6
|
-
## Core Features
|
|
7
|
-
|
|
8
|
-
### Connection
|
|
9
|
-
```typescript
|
|
10
|
-
// Using @aws-sdk/client-s3
|
|
11
|
-
import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
|
12
|
-
|
|
13
|
-
const s3Client = new S3Client({
|
|
14
|
-
region: process.env.AWS_REGION || 'us-east-1',
|
|
15
|
-
credentials: {
|
|
16
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
|
|
17
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
|
|
18
|
-
},
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
// Using AWS SDK v2
|
|
22
|
-
import AWS from 'aws-sdk'
|
|
23
|
-
|
|
24
|
-
const s3 = new AWS.S3({
|
|
25
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
26
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
27
|
-
region: process.env.AWS_REGION || 'us-east-1',
|
|
28
|
-
})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Basic Operations
|
|
32
|
-
```typescript
|
|
33
|
-
// Upload file
|
|
34
|
-
const uploadParams = {
|
|
35
|
-
Bucket: process.env.S3_BUCKET || 'my-bucket',
|
|
36
|
-
Key: 'path/to/file.jpg',
|
|
37
|
-
Body: fileBuffer,
|
|
38
|
-
ContentType: 'image/jpeg',
|
|
39
|
-
ACL: 'private', // or 'public-read'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
await s3Client.send(new PutObjectCommand(uploadParams))
|
|
43
|
-
|
|
44
|
-
// Upload with metadata
|
|
45
|
-
await s3Client.send(new PutObjectCommand({
|
|
46
|
-
...uploadParams,
|
|
47
|
-
Metadata: {
|
|
48
|
-
userId: '123',
|
|
49
|
-
originalName: 'photo.jpg',
|
|
50
|
-
},
|
|
51
|
-
TagSet: [
|
|
52
|
-
{ Key: 'category', Value: 'profile' },
|
|
53
|
-
],
|
|
54
|
-
}))
|
|
55
|
-
|
|
56
|
-
// Get file
|
|
57
|
-
const getParams = {
|
|
58
|
-
Bucket: process.env.S3_BUCKET,
|
|
59
|
-
Key: 'path/to/file.jpg',
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const response = await s3Client.send(new GetObjectCommand(getParams))
|
|
63
|
-
const fileContent = await response.Body?.transformToByteArray()
|
|
64
|
-
|
|
65
|
-
// Delete file
|
|
66
|
-
await s3Client.send(new DeleteObjectCommand({
|
|
67
|
-
Bucket: process.env.S3_BUCKET,
|
|
68
|
-
Key: 'path/to/file.jpg',
|
|
69
|
-
}))
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Advanced Features
|
|
73
|
-
```typescript
|
|
74
|
-
// Presigned URL for upload
|
|
75
|
-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
|
|
76
|
-
|
|
77
|
-
const command = new PutObjectCommand({
|
|
78
|
-
Bucket: process.env.S3_BUCKET,
|
|
79
|
-
Key: 'uploads/file.jpg',
|
|
80
|
-
ContentType: 'image/jpeg',
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 })
|
|
84
|
-
|
|
85
|
-
// Presigned URL for download
|
|
86
|
-
const getCommand = new GetObjectCommand({
|
|
87
|
-
Bucket: process.env.S3_BUCKET,
|
|
88
|
-
Key: 'path/to/file.jpg',
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
const downloadUrl = await getSignedUrl(s3Client, getCommand, { expiresIn: 3600 })
|
|
92
|
-
|
|
93
|
-
// Multipart upload (for large files)
|
|
94
|
-
import { CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand } from '@aws-sdk/client-s3'
|
|
95
|
-
|
|
96
|
-
const createCommand = new CreateMultipartUploadCommand({
|
|
97
|
-
Bucket: process.env.S3_BUCKET,
|
|
98
|
-
Key: 'large-file.zip',
|
|
99
|
-
ContentType: 'application/zip',
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
const { UploadId } = await s3Client.send(createCommand)
|
|
103
|
-
|
|
104
|
-
// Upload parts
|
|
105
|
-
const part1 = await s3Client.send(new UploadPartCommand({
|
|
106
|
-
Bucket: process.env.S3_BUCKET,
|
|
107
|
-
Key: 'large-file.zip',
|
|
108
|
-
PartNumber: 1,
|
|
109
|
-
UploadId,
|
|
110
|
-
Body: part1Buffer,
|
|
111
|
-
}))
|
|
112
|
-
|
|
113
|
-
// Complete upload
|
|
114
|
-
await s3Client.send(new CompleteMultipartUploadCommand({
|
|
115
|
-
Bucket: process.env.S3_BUCKET,
|
|
116
|
-
Key: 'large-file.zip',
|
|
117
|
-
UploadId,
|
|
118
|
-
MultipartUpload: {
|
|
119
|
-
Parts: [
|
|
120
|
-
{ PartNumber: 1, ETag: part1.ETag },
|
|
121
|
-
],
|
|
122
|
-
},
|
|
123
|
-
}))
|
|
124
|
-
|
|
125
|
-
// List objects
|
|
126
|
-
import { ListObjectsV2Command } from '@aws-sdk/client-s3'
|
|
127
|
-
|
|
128
|
-
const listCommand = new ListObjectsV2Command({
|
|
129
|
-
Bucket: process.env.S3_BUCKET,
|
|
130
|
-
Prefix: 'uploads/',
|
|
131
|
-
MaxKeys: 100,
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
const { Contents } = await s3Client.send(listCommand)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Common Patterns
|
|
138
|
-
|
|
139
|
-
### File Upload Handler
|
|
140
|
-
```typescript
|
|
141
|
-
async function uploadFile(file: Buffer, filename: string, userId: string) {
|
|
142
|
-
const key = `users/${userId}/${Date.now()}-${filename}`
|
|
143
|
-
|
|
144
|
-
await s3Client.send(new PutObjectCommand({
|
|
145
|
-
Bucket: process.env.S3_BUCKET,
|
|
146
|
-
Key: key,
|
|
147
|
-
Body: file,
|
|
148
|
-
ContentType: getContentType(filename),
|
|
149
|
-
Metadata: {
|
|
150
|
-
userId,
|
|
151
|
-
originalName: filename,
|
|
152
|
-
uploadedAt: new Date().toISOString(),
|
|
153
|
-
},
|
|
154
|
-
}))
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
key,
|
|
158
|
-
url: `https://${process.env.S3_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${key}`,
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Temporary File Access
|
|
164
|
-
```typescript
|
|
165
|
-
async function generateTemporaryDownloadUrl(key: string, expiresIn: number = 3600) {
|
|
166
|
-
const command = new GetObjectCommand({
|
|
167
|
-
Bucket: process.env.S3_BUCKET,
|
|
168
|
-
Key: key,
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
return await getSignedUrl(s3Client, command, { expiresIn })
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### File Cleanup
|
|
176
|
-
```typescript
|
|
177
|
-
async function deleteFilesByPrefix(prefix: string) {
|
|
178
|
-
const listCommand = new ListObjectsV2Command({
|
|
179
|
-
Bucket: process.env.S3_BUCKET,
|
|
180
|
-
Prefix: prefix,
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
let continuationToken: string | undefined
|
|
184
|
-
|
|
185
|
-
do {
|
|
186
|
-
const response = await s3Client.send({
|
|
187
|
-
...listCommand,
|
|
188
|
-
ContinuationToken: continuationToken,
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
if (response.Contents) {
|
|
192
|
-
for (const object of response.Contents) {
|
|
193
|
-
if (object.Key) {
|
|
194
|
-
await s3Client.send(new DeleteObjectCommand({
|
|
195
|
-
Bucket: process.env.S3_BUCKET,
|
|
196
|
-
Key: object.Key,
|
|
197
|
-
}))
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
continuationToken = response.NextContinuationToken
|
|
203
|
-
} while (continuationToken)
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Best Practices
|
|
208
|
-
|
|
209
|
-
✅ **DO:**
|
|
210
|
-
- Use presigned URLs for client uploads
|
|
211
|
-
- Set appropriate Content-Type headers
|
|
212
|
-
- Use versioning for important files
|
|
213
|
-
- Implement lifecycle policies for cleanup
|
|
214
|
-
- Use multipart upload for files > 5MB
|
|
215
|
-
- Enable encryption (SSE-S3 or SSE-KMS)
|
|
216
|
-
- Use appropriate storage classes (Standard, IA, Glacier)
|
|
217
|
-
- Implement proper error handling
|
|
218
|
-
- Use bucket policies for access control
|
|
219
|
-
- Monitor bucket usage and costs
|
|
220
|
-
|
|
221
|
-
❌ **DON'T:**
|
|
222
|
-
- Store sensitive data without encryption
|
|
223
|
-
- Use public-read ACL unnecessarily
|
|
224
|
-
- Hardcode credentials
|
|
225
|
-
- Ignore error handling
|
|
226
|
-
- Skip content-type validation
|
|
227
|
-
- Store large files without multipart upload
|
|
228
|
-
- Ignore lifecycle policies
|
|
229
|
-
- Skip access logging
|
|
230
|
-
- Use default bucket policies
|
|
231
|
-
- Ignore cost optimization
|
|
232
|
-
|
|
233
|
-
## Configuration
|
|
234
|
-
|
|
235
|
-
### Environment Variables
|
|
236
|
-
```bash
|
|
237
|
-
AWS_REGION=us-east-1
|
|
238
|
-
AWS_ACCESS_KEY_ID=your-access-key
|
|
239
|
-
AWS_SECRET_ACCESS_KEY=your-secret-key
|
|
240
|
-
S3_BUCKET=my-bucket
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### IAM Policy
|
|
244
|
-
```json
|
|
245
|
-
{
|
|
246
|
-
"Version": "2012-10-17",
|
|
247
|
-
"Statement": [
|
|
248
|
-
{
|
|
249
|
-
"Effect": "Allow",
|
|
250
|
-
"Action": [
|
|
251
|
-
"s3:PutObject",
|
|
252
|
-
"s3:GetObject",
|
|
253
|
-
"s3:DeleteObject"
|
|
254
|
-
],
|
|
255
|
-
"Resource": "arn:aws:s3:::my-bucket/*"
|
|
256
|
-
}
|
|
257
|
-
]
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Integration with Development
|
|
262
|
-
|
|
263
|
-
### Testing
|
|
264
|
-
```typescript
|
|
265
|
-
// Use test bucket or LocalStack
|
|
266
|
-
const testS3Client = new S3Client({
|
|
267
|
-
endpoint: 'http://localhost:4566', // LocalStack
|
|
268
|
-
region: 'us-east-1',
|
|
269
|
-
credentials: {
|
|
270
|
-
accessKeyId: 'test',
|
|
271
|
-
secretAccessKey: 'test',
|
|
272
|
-
},
|
|
273
|
-
forcePathStyle: true,
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
// Clean up after tests
|
|
277
|
-
afterEach(async () => {
|
|
278
|
-
// Delete test files
|
|
279
|
-
})
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### Health Checks
|
|
283
|
-
```typescript
|
|
284
|
-
async function checkS3Health(): Promise<boolean> {
|
|
285
|
-
try {
|
|
286
|
-
await s3Client.send(new ListObjectsV2Command({
|
|
287
|
-
Bucket: process.env.S3_BUCKET,
|
|
288
|
-
MaxKeys: 1,
|
|
289
|
-
}))
|
|
290
|
-
return true
|
|
291
|
-
} catch {
|
|
292
|
-
return false
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
<!-- S3:END -->
|
|
298
|
-
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<!-- SENTRY:START -->
|
|
2
|
-
# Sentry — Error Tracking
|
|
3
|
-
|
|
4
|
-
## Configuration
|
|
5
|
-
- Initialize Sentry at application entry point BEFORE other imports
|
|
6
|
-
- Set `dsn` from environment variable: `process.env.SENTRY_DSN`
|
|
7
|
-
- Configure `environment` from `NODE_ENV`
|
|
8
|
-
- Enable `tracesSampleRate: 0.1` in production (not 1.0)
|
|
9
|
-
|
|
10
|
-
## Error Capture
|
|
11
|
-
- Wrap route handlers with Sentry error middleware
|
|
12
|
-
- Use `Sentry.captureException(err)` in catch blocks for unexpected errors
|
|
13
|
-
- Add custom context: `Sentry.setContext('user', { id, email })`
|
|
14
|
-
- Never log sensitive data (passwords, tokens) in Sentry context
|
|
15
|
-
|
|
16
|
-
## Release Tracking
|
|
17
|
-
- Set `release` using git commit SHA: `process.env.SENTRY_RELEASE`
|
|
18
|
-
- Run `sentry-cli releases` in CI to associate commits with releases
|
|
19
|
-
|
|
20
|
-
## Performance
|
|
21
|
-
- Use `Sentry.startTransaction()` for tracking custom operations
|
|
22
|
-
- Add distributed tracing headers to internal service calls
|
|
23
|
-
<!-- SENTRY:END -->
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
<!-- SQLITE:START -->
|
|
2
|
-
# SQLite Database Instructions
|
|
3
|
-
|
|
4
|
-
**CRITICAL**: Use SQLite for embedded databases, local storage, development, and small-scale applications with zero configuration.
|
|
5
|
-
|
|
6
|
-
## Core Features
|
|
7
|
-
|
|
8
|
-
### Connection
|
|
9
|
-
```typescript
|
|
10
|
-
// Using better-sqlite3 (synchronous, faster)
|
|
11
|
-
import Database from 'better-sqlite3'
|
|
12
|
-
|
|
13
|
-
const db = new Database(process.env.DB_PATH || './database.db', {
|
|
14
|
-
verbose: process.env.NODE_ENV === 'development' ? console.log : undefined,
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
// Using sqlite3 (asynchronous)
|
|
18
|
-
import sqlite3 from 'sqlite3'
|
|
19
|
-
|
|
20
|
-
const db = new sqlite3.Database(process.env.DB_PATH || './database.db', (err) => {
|
|
21
|
-
if (err) {
|
|
22
|
-
console.error('Error opening database', err)
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Using better-sqlite3 with WAL mode (recommended)
|
|
27
|
-
const db = new Database('./database.db')
|
|
28
|
-
db.pragma('journal_mode = WAL') // Write-Ahead Logging
|
|
29
|
-
db.pragma('foreign_keys = ON') // Enable foreign keys
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Basic Queries
|
|
33
|
-
```typescript
|
|
34
|
-
// Using better-sqlite3 (synchronous)
|
|
35
|
-
// SELECT
|
|
36
|
-
const stmt = db.prepare('SELECT * FROM users WHERE id = ?')
|
|
37
|
-
const user = stmt.get(userId)
|
|
38
|
-
|
|
39
|
-
// INSERT
|
|
40
|
-
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
|
|
41
|
-
const info = insert.run('John Doe', 'john@example.com')
|
|
42
|
-
const newId = info.lastInsertRowid
|
|
43
|
-
|
|
44
|
-
// UPDATE
|
|
45
|
-
const update = db.prepare('UPDATE users SET name = ? WHERE id = ?')
|
|
46
|
-
update.run('Jane Doe', userId)
|
|
47
|
-
|
|
48
|
-
// DELETE
|
|
49
|
-
const del = db.prepare('DELETE FROM users WHERE id = ?')
|
|
50
|
-
del.run(userId)
|
|
51
|
-
|
|
52
|
-
// Using sqlite3 (asynchronous)
|
|
53
|
-
db.get('SELECT * FROM users WHERE id = ?', [userId], (err, row) => {
|
|
54
|
-
if (err) throw err
|
|
55
|
-
console.log(row)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
db.run('INSERT INTO users (name, email) VALUES (?, ?)', ['John Doe', 'john@example.com'], function(err) {
|
|
59
|
-
if (err) throw err
|
|
60
|
-
console.log('Inserted with ID:', this.lastID)
|
|
61
|
-
})
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Transactions
|
|
65
|
-
```typescript
|
|
66
|
-
// Using better-sqlite3
|
|
67
|
-
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
|
|
68
|
-
const insertPost = db.prepare('INSERT INTO posts (user_id, title) VALUES (?, ?)')
|
|
69
|
-
|
|
70
|
-
const insertUserAndPost = db.transaction((userName, userEmail, postTitle) => {
|
|
71
|
-
const userInfo = insertUser.run(userName, userEmail)
|
|
72
|
-
const userId = userInfo.lastInsertRowid
|
|
73
|
-
insertPost.run(userId, postTitle)
|
|
74
|
-
return userId
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
const userId = insertUserAndPost('John Doe', 'john@example.com', 'First Post')
|
|
78
|
-
|
|
79
|
-
// Using sqlite3
|
|
80
|
-
db.serialize(() => {
|
|
81
|
-
db.run('BEGIN TRANSACTION')
|
|
82
|
-
db.run('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com'], function(err) {
|
|
83
|
-
if (err) {
|
|
84
|
-
db.run('ROLLBACK')
|
|
85
|
-
throw err
|
|
86
|
-
}
|
|
87
|
-
const userId = this.lastID
|
|
88
|
-
db.run('INSERT INTO posts (user_id, title) VALUES (?, ?)', [userId, 'Post'], (err) => {
|
|
89
|
-
if (err) {
|
|
90
|
-
db.run('ROLLBACK')
|
|
91
|
-
throw err
|
|
92
|
-
}
|
|
93
|
-
db.run('COMMIT')
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Advanced Features
|
|
100
|
-
```typescript
|
|
101
|
-
// JSON operations (SQLite 3.38+)
|
|
102
|
-
const result = db.prepare(`
|
|
103
|
-
SELECT
|
|
104
|
-
id,
|
|
105
|
-
name,
|
|
106
|
-
json_extract(metadata, '$.category') AS category
|
|
107
|
-
FROM products
|
|
108
|
-
WHERE json_extract(metadata, '$.category') = ?
|
|
109
|
-
`).get('electronics')
|
|
110
|
-
|
|
111
|
-
// Full-text search (FTS5)
|
|
112
|
-
db.exec(`
|
|
113
|
-
CREATE VIRTUAL TABLE articles_fts USING fts5(
|
|
114
|
-
title,
|
|
115
|
-
content,
|
|
116
|
-
content_rowid=id
|
|
117
|
-
)
|
|
118
|
-
`)
|
|
119
|
-
|
|
120
|
-
const results = db.prepare(`
|
|
121
|
-
SELECT * FROM articles_fts
|
|
122
|
-
WHERE articles_fts MATCH ?
|
|
123
|
-
`).all('search term')
|
|
124
|
-
|
|
125
|
-
// Window functions (SQLite 3.25+)
|
|
126
|
-
const result = db.prepare(`
|
|
127
|
-
SELECT
|
|
128
|
-
name,
|
|
129
|
-
salary,
|
|
130
|
-
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
|
|
131
|
-
FROM employees
|
|
132
|
-
`).all()
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Common Patterns
|
|
136
|
-
|
|
137
|
-
### Prepared Statements
|
|
138
|
-
```typescript
|
|
139
|
-
// Reuse prepared statements for better performance
|
|
140
|
-
const getUserById = db.prepare('SELECT * FROM users WHERE id = ?')
|
|
141
|
-
const getUserByEmail = db.prepare('SELECT * FROM users WHERE email = ?')
|
|
142
|
-
|
|
143
|
-
// Use in functions
|
|
144
|
-
function getUser(id: number) {
|
|
145
|
-
return getUserById.get(id)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function findUserByEmail(email: string) {
|
|
149
|
-
return getUserByEmail.get(email)
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Batch Operations
|
|
154
|
-
```typescript
|
|
155
|
-
// Insert multiple rows efficiently
|
|
156
|
-
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
|
|
157
|
-
const insertMany = db.transaction((users) => {
|
|
158
|
-
for (const user of users) {
|
|
159
|
-
insert.run(user.name, user.email)
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
insertMany([
|
|
164
|
-
{ name: 'User 1', email: 'user1@example.com' },
|
|
165
|
-
{ name: 'User 2', email: 'user2@example.com' },
|
|
166
|
-
])
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Migrations
|
|
170
|
-
```typescript
|
|
171
|
-
// Simple migration system
|
|
172
|
-
const migrations = [
|
|
173
|
-
`CREATE TABLE IF NOT EXISTS users (
|
|
174
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
175
|
-
name TEXT NOT NULL,
|
|
176
|
-
email TEXT UNIQUE NOT NULL,
|
|
177
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
178
|
-
)`,
|
|
179
|
-
`CREATE TABLE IF NOT EXISTS posts (
|
|
180
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
181
|
-
user_id INTEGER NOT NULL,
|
|
182
|
-
title TEXT NOT NULL,
|
|
183
|
-
content TEXT,
|
|
184
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
185
|
-
FOREIGN KEY (user_id) REFERENCES users(id)
|
|
186
|
-
)`,
|
|
187
|
-
]
|
|
188
|
-
|
|
189
|
-
db.exec('BEGIN TRANSACTION')
|
|
190
|
-
try {
|
|
191
|
-
for (const migration of migrations) {
|
|
192
|
-
db.exec(migration)
|
|
193
|
-
}
|
|
194
|
-
db.exec('COMMIT')
|
|
195
|
-
} catch (error) {
|
|
196
|
-
db.exec('ROLLBACK')
|
|
197
|
-
throw error
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Best Practices
|
|
202
|
-
|
|
203
|
-
✅ **DO:**
|
|
204
|
-
- Use WAL mode for better concurrency
|
|
205
|
-
- Enable foreign keys
|
|
206
|
-
- Use prepared statements
|
|
207
|
-
- Use transactions for multiple operations
|
|
208
|
-
- Create indexes on frequently queried columns
|
|
209
|
-
- Use appropriate data types (TEXT, INTEGER, REAL, BLOB)
|
|
210
|
-
- Backup database regularly
|
|
211
|
-
- Use connection pooling (better-sqlite3 handles this)
|
|
212
|
-
- Monitor database size
|
|
213
|
-
- Use VACUUM periodically
|
|
214
|
-
|
|
215
|
-
❌ **DON'T:**
|
|
216
|
-
- Use for high-concurrency write scenarios
|
|
217
|
-
- Store large binary data (use external storage)
|
|
218
|
-
- Skip error handling
|
|
219
|
-
- Use string concatenation for queries
|
|
220
|
-
- Ignore database size limits
|
|
221
|
-
- Skip indexes on foreign keys
|
|
222
|
-
- Hardcode database paths
|
|
223
|
-
- Ignore transaction boundaries
|
|
224
|
-
- Use synchronous operations in async contexts (better-sqlite3 is fine)
|
|
225
|
-
- Skip backups
|
|
226
|
-
|
|
227
|
-
## Configuration
|
|
228
|
-
|
|
229
|
-
### Environment Variables
|
|
230
|
-
```bash
|
|
231
|
-
DB_PATH=./database.db
|
|
232
|
-
DB_PATH=/var/lib/myapp/database.db
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Initialization
|
|
236
|
-
```typescript
|
|
237
|
-
// Initialize database with schema
|
|
238
|
-
const db = new Database('./database.db')
|
|
239
|
-
|
|
240
|
-
db.pragma('journal_mode = WAL')
|
|
241
|
-
db.pragma('foreign_keys = ON')
|
|
242
|
-
db.pragma('synchronous = NORMAL')
|
|
243
|
-
db.pragma('cache_size = 10000')
|
|
244
|
-
db.pragma('temp_store = MEMORY')
|
|
245
|
-
|
|
246
|
-
// Create tables
|
|
247
|
-
db.exec(`
|
|
248
|
-
CREATE TABLE IF NOT EXISTS users (
|
|
249
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
250
|
-
name TEXT NOT NULL,
|
|
251
|
-
email TEXT UNIQUE NOT NULL,
|
|
252
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email)
|
|
256
|
-
`)
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
## Integration with Development
|
|
260
|
-
|
|
261
|
-
### Testing
|
|
262
|
-
```typescript
|
|
263
|
-
// Use in-memory database for tests
|
|
264
|
-
const testDb = new Database(':memory:')
|
|
265
|
-
|
|
266
|
-
// Or use separate test database
|
|
267
|
-
const testDb = new Database('./test.db')
|
|
268
|
-
|
|
269
|
-
// Clean up after tests
|
|
270
|
-
afterEach(() => {
|
|
271
|
-
testDb.exec('DELETE FROM users')
|
|
272
|
-
testDb.exec('DELETE FROM posts')
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
afterAll(() => {
|
|
276
|
-
testDb.close()
|
|
277
|
-
// Optionally delete test database file
|
|
278
|
-
})
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Health Checks
|
|
282
|
-
```typescript
|
|
283
|
-
function checkDatabaseHealth(): boolean {
|
|
284
|
-
try {
|
|
285
|
-
db.prepare('SELECT 1').get()
|
|
286
|
-
return true
|
|
287
|
-
} catch {
|
|
288
|
-
return false
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
<!-- SQLITE:END -->
|
|
294
|
-
|