@nockdev/awf 6.2.6 → 6.2.7
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/.agent/config.yaml +2 -2
- package/.agent/core/AGENT_BEHAVIOR.md +1 -1
- package/.agent/core/AUDIT_POLICY.md +1 -1
- package/.agent/core/CACHE.md +1 -1
- package/.agent/core/DATA_SAFETY.md +1 -1
- package/.agent/core/MEMORY_PATHS.yaml +2 -2
- package/.agent/core/PERMISSIONS.md +1 -1
- package/.agent/core/README.md +1 -1
- package/.agent/core/VERSION.yaml +4 -4
- package/.agent/core/archive/ACTIVE_MEMORY.yaml +2 -2
- package/.agent/core/archive/CHECKPOINT.yaml +2 -2
- package/.agent/core/archive/CLEANUP_ENGINE.yaml +2 -2
- package/.agent/core/archive/CONTEXT_INJECTOR.yaml +2 -2
- package/.agent/core/archive/CONTEXT_LOADER.yaml +1 -1
- package/.agent/core/archive/CONTEXT_OPTIMIZATION.yaml +1 -1
- package/.agent/core/archive/CONTEXT_PRIORITY.yaml +2 -2
- package/.agent/core/archive/FLOW_ENGINE.yaml +1 -1
- package/.agent/core/archive/GRAPH_MEMORY.yaml +1 -1
- package/.agent/core/archive/HYBRID_ROUTER.yaml +1 -1
- package/.agent/core/archive/INTENT_DETECTION.yaml +1 -1
- package/.agent/core/archive/MEMORY_CONSOLIDATION.yaml +3 -3
- package/.agent/core/archive/MEMORY_ENGINE.yaml +2 -2
- package/.agent/core/archive/MEMORY_UTILS.yaml +1 -1
- package/.agent/core/archive/REFLECTION_ENGINE.yaml +1 -1
- package/.agent/core/archive/ROUTER.yaml +4 -4
- package/.agent/core/archive/SCORING_FORMULA.yaml +2 -2
- package/.agent/core/archive/SEMANTIC_ENGINE.yaml +1 -1
- package/.agent/core/archive/SKILLS_FLOW.yaml +1 -1
- package/.agent/core/archive/STATE_MACHINE.yaml +1 -1
- package/.agent/core/archive/SUMMARIZATION_ENGINE.yaml +2 -2
- package/.agent/core/archive/TOKEN_BUDGETS.yaml +2 -2
- package/.agent/core/archive/TOKEN_LOADING.yaml +2 -2
- package/.agent/core/archive/TOKEN_SUMMARY.yaml +2 -2
- package/.agent/core/reference/CODING_STYLES.yaml +1 -1
- package/.agent/core/reference/LIBRARY_REGISTRY.yaml +1 -1
- package/.agent/core/reference/MCP_TOOLS.yaml +2 -2
- package/.agent/core/reference/PATTERNS.yaml +1 -1
- package/.agent/core/reference/SKILL_SCHEMA.yaml +1 -1
- package/.agent/i18n/en.yaml +6 -6
- package/.agent/i18n/vi.yaml +6 -6
- package/.agent/ide/README.md +1 -1
- package/.agent/ide/amazonq.json +1 -1
- package/.agent/ide/amp.json +1 -1
- package/.agent/ide/antigravity.json +1 -1
- package/.agent/ide/augment.json +1 -1
- package/.agent/ide/claude.json +1 -1
- package/.agent/ide/cline.json +1 -1
- package/.agent/ide/cody.json +1 -1
- package/.agent/ide/continue.json +1 -1
- package/.agent/ide/cursor.json +1 -1
- package/.agent/ide/gemini.json +1 -1
- package/.agent/ide/jetbrains.json +1 -1
- package/.agent/ide/kiro.json +1 -1
- package/.agent/ide/opencode.json +1 -1
- package/.agent/ide/roo.json +1 -1
- package/.agent/ide/tabnine.json +1 -1
- package/.agent/ide/trae.json +1 -1
- package/.agent/ide/vscode.json +1 -1
- package/.agent/ide/windsurf.json +1 -1
- package/.agent/ide/zed.json +1 -1
- package/.agent/manifest.yaml +1 -1
- package/.agent/personas/README.md +1 -1
- package/.agent/personas/architect.md +1 -1
- package/.agent/personas/auditor.md +1 -1
- package/.agent/personas/debugger.md +1 -1
- package/.agent/personas/developer.md +1 -1
- package/.agent/personas/devops.md +1 -1
- package/.agent/personas/documenter.md +1 -1
- package/.agent/personas/orchestrator.md +1 -1
- package/.agent/personas/persona.schema.yaml +1 -1
- package/.agent/personas/planner.md +1 -1
- package/.agent/personas/researcher.md +1 -1
- package/.agent/personas/security.md +1 -1
- package/.agent/personas/tester.md +1 -1
- package/.agent/rules/README.md +1 -1
- package/.agent/rules/archive/constitutional/tier-0-core.yaml +5 -5
- package/.agent/rules/archive/constitutional/tier-1-safety.yaml +5 -5
- package/.agent/rules/archive/constitutional/tier-2-execution.yaml +6 -6
- package/.agent/rules/archive/context-management.yaml +1 -1
- package/.agent/rules/archive/duplication-prevention.md +1 -1
- package/.agent/rules/archive/evidence.yaml +1 -1
- package/.agent/rules/archive/project-detection.md +1 -1
- package/.agent/rules/archive/reflection.yaml +1 -1
- package/.agent/rules/archive/versioning.yaml +5 -5
- package/.agent/rules/data/build-systems.yaml +2 -2
- package/.agent/rules/modules/agent-delegation.yaml +2 -2
- package/.agent/rules/modules/edit-verification.yaml +1 -1
- package/.agent/rules/modules/git-workflow.yaml +1 -1
- package/.agent/rules/modules/language.yaml +1 -1
- package/.agent/rules/modules/online-research.yaml +1 -1
- package/.agent/rules/modules/performance-optimization.yaml +2 -2
- package/.agent/rules/modules/quality.yaml +1 -1
- package/.agent/rules/modules/stop-conditions.yaml +1 -1
- package/.agent/rules/modules/terminal-safety.yaml +1 -1
- package/.agent/rules/modules/yagni.yaml +1 -1
- package/.agent/rules/validation-framework.md +1 -1
- package/.agent/skills/README.md +1 -1
- package/.agent/skills/_categories.yaml +2 -2
- package/.agent/skills/ai-ml/rag-patterns/META.yaml +2 -0
- package/.agent/skills/core/api-design/META.yaml +1 -1
- package/.agent/skills/core/authentication/META.yaml +1 -1
- package/.agent/skills/core/error-handling/META.yaml +1 -1
- package/.agent/skills/core/logging/META.yaml +1 -1
- package/.agent/skills/core/observability/META.yaml +1 -1
- package/.agent/skills/core/security/META.yaml +1 -1
- package/.agent/skills/core/security/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/accessibility/META.yaml +1 -1
- package/.agent/skills/cross-cutting/audit-pro/META.yaml +9 -1
- package/.agent/skills/cross-cutting/audit-pro/SKILL.md +61 -5
- package/.agent/skills/cross-cutting/bun/META.yaml +17 -8
- package/.agent/skills/cross-cutting/bun/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/coding-rules/META.yaml +1 -1
- package/.agent/skills/cross-cutting/database/META.yaml +42 -1
- package/.agent/skills/cross-cutting/database/SKILL.md +44 -628
- package/.agent/skills/cross-cutting/database/references/nosql-patterns.md +194 -0
- package/.agent/skills/cross-cutting/database/references/orms-patterns.md +278 -0
- package/.agent/skills/cross-cutting/database/references/postgresql.md +144 -0
- package/.agent/skills/cross-cutting/deno/META.yaml +19 -10
- package/.agent/skills/cross-cutting/deno/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/domyh-design/META.yaml +1 -1
- package/.agent/skills/cross-cutting/domyh-design/data/desktop-colors.yaml +1 -1
- package/.agent/skills/cross-cutting/electron/SKILL.md +15 -616
- package/.agent/skills/cross-cutting/electron/references/ipc-testing.md +114 -0
- package/.agent/skills/cross-cutting/electron/references/native-integrations.md +216 -0
- package/.agent/skills/cross-cutting/electron/references/performance-accessibility.md +118 -0
- package/.agent/skills/cross-cutting/electron/references/updates-persistence.md +165 -0
- package/.agent/skills/cross-cutting/seo/META.yaml +1 -1
- package/.agent/skills/cross-cutting/skill-creator/META.yaml +37 -0
- package/.agent/skills/cross-cutting/skill-creator/SKILL.md +163 -0
- package/.agent/skills/cross-cutting/skill-creator/references/patterns.md +58 -0
- package/.agent/skills/cross-cutting/skill-creator/references/schema-v2.md +44 -0
- package/.agent/skills/cross-cutting/sql/META.yaml +1 -1
- package/.agent/skills/cross-cutting/sql/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/tailwind/META.yaml +1 -1
- package/.agent/skills/cross-cutting/tailwind/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/tdd-workflow/META.yaml +1 -1
- package/.agent/skills/cross-cutting/testing/META.yaml +7 -1
- package/.agent/skills/cross-cutting/testing/SKILL.md +1 -1
- package/.agent/skills/cross-cutting/testing/data/frameworks.yaml +1 -1
- package/.agent/skills/cross-cutting/web-perf/META.yaml +1 -1
- package/.agent/skills/cross-cutting/web-perf/SKILL.md +1 -1
- package/.agent/skills/devops/aws/META.yaml +1 -1
- package/.agent/skills/devops/aws/SKILL.md +101 -16
- package/.agent/skills/devops/azure/SKILL.md +96 -30
- package/.agent/skills/devops/ci-cd/META.yaml +1 -1
- package/.agent/skills/devops/ci-cd/SKILL.md +114 -8
- package/.agent/skills/devops/docker/META.yaml +1 -1
- package/.agent/skills/devops/docker/SKILL.md +96 -8
- package/.agent/skills/devops/gcp/SKILL.md +106 -30
- package/.agent/skills/devops/kubernetes/META.yaml +1 -1
- package/.agent/skills/devops/kubernetes/SKILL.md +125 -8
- package/.agent/skills/frameworks/angular/META.yaml +1 -1
- package/.agent/skills/frameworks/angular/SKILL.md +1 -1
- package/.agent/skills/frameworks/flutter/META.yaml +1 -1
- package/.agent/skills/frameworks/flutter/SKILL.md +1 -1
- package/.agent/skills/frameworks/nextjs/META.yaml +1 -1
- package/.agent/skills/frameworks/nextjs/SKILL.md +1 -1
- package/.agent/skills/frameworks/nuxt/META.yaml +1 -1
- package/.agent/skills/frameworks/nuxt/SKILL.md +1 -1
- package/.agent/skills/frameworks/react/META.yaml +1 -1
- package/.agent/skills/frameworks/react/SKILL.md +24 -1
- package/.agent/skills/frameworks/react-native/META.yaml +1 -1
- package/.agent/skills/frameworks/react-native/SKILL.md +1 -1
- package/.agent/skills/frameworks/svelte/META.yaml +1 -1
- package/.agent/skills/frameworks/svelte/SKILL.md +1 -1
- package/.agent/skills/frameworks/vue/META.yaml +1 -1
- package/.agent/skills/frameworks/vue/SKILL.md +1 -1
- package/.agent/skills/index.json +2 -2
- package/.agent/skills/languages/asm/META.yaml +1 -1
- package/.agent/skills/languages/asm/SKILL.md +27 -436
- package/.agent/skills/languages/asm/references/advanced-architectures.md +191 -0
- package/.agent/skills/languages/asm/references/build-structure.md +150 -0
- package/.agent/skills/languages/asm/references/simd-programming.md +92 -0
- package/.agent/skills/languages/c/META.yaml +1 -1
- package/.agent/skills/languages/c/SKILL.md +14 -356
- package/.agent/skills/languages/c/references/data-structures.md +63 -0
- package/.agent/skills/languages/c/references/memory-management.md +74 -0
- package/.agent/skills/languages/c/references/platform-headers.md +230 -0
- package/.agent/skills/languages/clojure/META.yaml +1 -1
- package/.agent/skills/languages/clojure/SKILL.md +1 -1
- package/.agent/skills/languages/cpp/META.yaml +1 -1
- package/.agent/skills/languages/cpp/SKILL.md +22 -753
- package/.agent/skills/languages/cpp/references/headers-optimization.md +229 -0
- package/.agent/skills/languages/cpp/references/memory-concurrency.md +85 -0
- package/.agent/skills/languages/cpp/references/modern-cpp-features.md +126 -0
- package/.agent/skills/languages/cpp/references/platform-headers.md +202 -0
- package/.agent/skills/languages/cpp/references/stl-containers.md +57 -0
- package/.agent/skills/languages/crystal/META.yaml +1 -1
- package/.agent/skills/languages/crystal/SKILL.md +1 -1
- package/.agent/skills/languages/csharp/META.yaml +1 -1
- package/.agent/skills/languages/csharp/SKILL.md +1 -1
- package/.agent/skills/languages/elixir/META.yaml +1 -1
- package/.agent/skills/languages/elixir/SKILL.md +1 -1
- package/.agent/skills/languages/fsharp/META.yaml +1 -1
- package/.agent/skills/languages/fsharp/SKILL.md +1 -1
- package/.agent/skills/languages/go/META.yaml +1 -1
- package/.agent/skills/languages/go/SKILL.md +1 -1
- package/.agent/skills/languages/haskell/META.yaml +1 -1
- package/.agent/skills/languages/haskell/SKILL.md +1 -1
- package/.agent/skills/languages/java/META.yaml +1 -1
- package/.agent/skills/languages/java/SKILL.md +1 -1
- package/.agent/skills/languages/javascript/META.yaml +1 -1
- package/.agent/skills/languages/javascript/SKILL.md +1 -1
- package/.agent/skills/languages/julia/META.yaml +1 -1
- package/.agent/skills/languages/julia/SKILL.md +1 -1
- package/.agent/skills/languages/kotlin/META.yaml +1 -1
- package/.agent/skills/languages/kotlin/SKILL.md +1 -1
- package/.agent/skills/languages/lua/META.yaml +1 -1
- package/.agent/skills/languages/lua/SKILL.md +3 -3
- package/.agent/skills/languages/nim/META.yaml +1 -1
- package/.agent/skills/languages/nim/SKILL.md +1 -1
- package/.agent/skills/languages/ocaml/META.yaml +1 -1
- package/.agent/skills/languages/ocaml/SKILL.md +1 -1
- package/.agent/skills/languages/perl/META.yaml +1 -1
- package/.agent/skills/languages/perl/SKILL.md +1 -1
- package/.agent/skills/languages/php/META.yaml +1 -1
- package/.agent/skills/languages/php/SKILL.md +1 -1
- package/.agent/skills/languages/python/META.yaml +1 -1
- package/.agent/skills/languages/python/SKILL.md +1 -1
- package/.agent/skills/languages/r/META.yaml +1 -1
- package/.agent/skills/languages/r/SKILL.md +1 -1
- package/.agent/skills/languages/ruby/META.yaml +1 -1
- package/.agent/skills/languages/ruby/SKILL.md +1 -1
- package/.agent/skills/languages/rust/META.yaml +1 -1
- package/.agent/skills/languages/rust/SKILL.md +1 -1
- package/.agent/skills/languages/scala/META.yaml +1 -1
- package/.agent/skills/languages/scala/SKILL.md +1 -1
- package/.agent/skills/languages/solidity/META.yaml +1 -1
- package/.agent/skills/languages/solidity/SKILL.md +1 -1
- package/.agent/skills/languages/swift/META.yaml +1 -1
- package/.agent/skills/languages/swift/SKILL.md +1 -1
- package/.agent/skills/languages/typescript/META.yaml +19 -1
- package/.agent/skills/languages/typescript/SKILL.md +23 -1
- package/.agent/skills/languages/zig/META.yaml +1 -1
- package/.agent/skills/languages/zig/SKILL.md +1 -1
- package/.agent/templates/README.md +2 -2
- package/.agent/templates/chains/feature/step1-requirements.md +76 -0
- package/.agent/templates/chains/feature/step2-design.md +75 -0
- package/.agent/templates/chains/feature/step3-planning.md +81 -0
- package/.agent/templates/chains/feature/step4-implementation.md +74 -0
- package/.agent/templates/chains/feature/step5-testing.md +81 -0
- package/.agent/templates/debug-report.md +1 -1
- package/.agent/templates/deploy-plan.md +1 -1
- package/.agent/templates/doc-template.md +1 -1
- package/.agent/templates/feature-lifecycle.md +53 -0
- package/.agent/templates/index.yaml +53 -2
- package/.agent/templates/migrate-plan.md +1 -1
- package/.agent/templates/phase-template.md +1 -1
- package/.agent/templates/tasks/audit.yaml +1 -1
- package/.agent/templates/tasks/bug_fix.yaml +1 -1
- package/.agent/templates/tasks/code_implementation.yaml +1 -1
- package/.agent/templates/tasks/feature_development.yaml +89 -0
- package/.agent/templates/tasks/refactor.yaml +1 -1
- package/.agent/templates/test-report.md +1 -1
- package/.agent/workflows/doctor.md +124 -0
- package/.agent/workflows/feature.md +130 -0
- package/.agent/workflows/help.md +7 -5
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/package.json +2 -2
|
@@ -1,15 +1,37 @@
|
|
|
1
|
-
---
|
|
1
|
+
---
|
|
2
2
|
name: database
|
|
3
3
|
detect:
|
|
4
4
|
["*.sql", "schema.prisma", "drizzle/", "migrations/", "*.db", "*.sqlite"]
|
|
5
|
-
version: "6.2.
|
|
5
|
+
version: "6.2.7"
|
|
6
6
|
category: infrastructure
|
|
7
7
|
tier: 1
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Database Patterns
|
|
10
|
+
# Database Patterns DOMYH Awesome Code
|
|
11
|
+
|
|
12
|
+
> SQL + NoSQL Patterns PostgreSQL 18, MySQL 9.4, MongoDB 8, Redis 8 2025-2026
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
## Decision Tree
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Task → What database need?
|
|
18
|
+
├─ Structured data with relationships
|
|
19
|
+
│ ├─ Complex queries → PostgreSQL (JSON + full-text + GIS)
|
|
20
|
+
│ ├─ Simple reads → MySQL (fast, reliable)
|
|
21
|
+
│ └─ Global distribution → CockroachDB / TiDB
|
|
22
|
+
├─ Flexible schema
|
|
23
|
+
│ ├─ Document model → MongoDB
|
|
24
|
+
│ └─ Time-series → InfluxDB / TimescaleDB
|
|
25
|
+
├─ Caching / sessions
|
|
26
|
+
│ └─ Redis (sub-ms, TTL, pub/sub)
|
|
27
|
+
├─ Search
|
|
28
|
+
│ ├─ Full-text → PostgreSQL GIN or Elasticsearch
|
|
29
|
+
│ └─ Vector → pgvector / Redis VectorSet
|
|
30
|
+
└─ ORM selection
|
|
31
|
+
├─ Type-safe → Prisma (schema-first)
|
|
32
|
+
├─ SQL-first → Drizzle (lightweight)
|
|
33
|
+
└─ Legacy → TypeORM / Sequelize
|
|
34
|
+
```
|
|
13
35
|
|
|
14
36
|
---
|
|
15
37
|
|
|
@@ -122,635 +144,29 @@ nosql_indicators:
|
|
|
122
144
|
### Polyglot Persistence (Recommended Pattern)
|
|
123
145
|
|
|
124
146
|
```
|
|
125
|
-
|
|
126
|
-
│
|
|
127
|
-
|
|
128
|
-
│
|
|
129
|
-
│
|
|
130
|
-
│
|
|
131
|
-
│
|
|
132
|
-
│
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 🐘 PostgreSQL 17/18 (2024-2025)
|
|
139
|
-
|
|
140
|
-
### Version Comparison
|
|
141
|
-
|
|
142
|
-
| Feature | PG 17 (2024) | PG 18 (2025) |
|
|
143
|
-
| ------------------------- | ------------ | ------------ |
|
|
144
|
-
| JSON_TABLE() | ✅ | ✅ |
|
|
145
|
-
| Incremental Backup | ✅ | ✅ |
|
|
146
|
-
| MERGE + RETURNING | ✅ | ✅ |
|
|
147
|
-
| Asynchronous I/O (AIO) | ❌ | ✅ NEW |
|
|
148
|
-
| Skip Scan (B-tree) | ❌ | ✅ NEW |
|
|
149
|
-
| RETURNING OLD/NEW | ❌ | ✅ NEW |
|
|
150
|
-
| UUIDv7 | ❌ | ✅ NEW |
|
|
151
|
-
| Virtual Generated Columns | ❌ | ✅ NEW |
|
|
152
|
-
| NOT NULL (NOT VALID) | ❌ | ✅ NEW |
|
|
153
|
-
|
|
154
|
-
### PostgreSQL Core Patterns
|
|
155
|
-
|
|
156
|
-
```sql
|
|
157
|
-
-- ✅ Parameterized queries (prevent SQL injection)
|
|
158
|
-
SELECT id, name, email FROM users WHERE id = $1;
|
|
159
|
-
|
|
160
|
-
-- ✅ Indexes (critical for performance)
|
|
161
|
-
CREATE INDEX idx_users_email ON users(email);
|
|
162
|
-
CREATE INDEX idx_orders_user_created
|
|
163
|
-
ON orders(user_id, created_at DESC);
|
|
164
|
-
|
|
165
|
-
-- ✅ Partial index (index subset of rows)
|
|
166
|
-
CREATE INDEX idx_active_users ON users(email)
|
|
167
|
-
WHERE active = true;
|
|
168
|
-
|
|
169
|
-
-- ✅ Covering index (include columns to avoid table lookup)
|
|
170
|
-
CREATE INDEX idx_orders_covering
|
|
171
|
-
ON orders(user_id) INCLUDE (status, total);
|
|
172
|
-
|
|
173
|
-
-- ✅ BRIN index (for large time-series tables)
|
|
174
|
-
CREATE INDEX idx_events_created
|
|
175
|
-
ON events USING BRIN(created_at);
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### PostgreSQL 18 New Features
|
|
179
|
-
|
|
180
|
-
```sql
|
|
181
|
-
-- ✅ PG 18: RETURNING OLD and NEW values
|
|
182
|
-
UPDATE products SET price = price * 1.1
|
|
183
|
-
RETURNING OLD.price AS old_price, NEW.price AS new_price;
|
|
184
|
-
|
|
185
|
-
DELETE FROM users WHERE inactive = true
|
|
186
|
-
RETURNING OLD.*;
|
|
187
|
-
|
|
188
|
-
-- ✅ PG 18: UUIDv7 (time-ordered, better for indexes)
|
|
189
|
-
SELECT uuidv7(); -- e.g., 019445a0-c000-7000-8000-000000000001
|
|
190
|
-
|
|
191
|
-
-- ✅ PG 18: NOT NULL constraint without full scan
|
|
192
|
-
ALTER TABLE large_table
|
|
193
|
-
ADD CONSTRAINT col_not_null
|
|
194
|
-
CHECK (col IS NOT NULL) NOT VALID;
|
|
195
|
-
-- Validate later without ACCESS EXCLUSIVE lock
|
|
196
|
-
ALTER TABLE large_table
|
|
197
|
-
VALIDATE CONSTRAINT col_not_null;
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### PostgreSQL JSON Operations
|
|
201
|
-
|
|
202
|
-
```sql
|
|
203
|
-
-- ✅ JSONB storage and querying
|
|
204
|
-
CREATE TABLE events (
|
|
205
|
-
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
206
|
-
data JSONB NOT NULL,
|
|
207
|
-
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
-- GIN index for JSONB
|
|
211
|
-
CREATE INDEX idx_events_data ON events USING GIN(data);
|
|
212
|
-
|
|
213
|
-
-- Query JSONB
|
|
214
|
-
SELECT * FROM events
|
|
215
|
-
WHERE data @> '{"type": "purchase"}';
|
|
216
|
-
|
|
217
|
-
SELECT data->>'user_id' AS user_id,
|
|
218
|
-
(data->>'amount')::NUMERIC AS amount
|
|
219
|
-
FROM events
|
|
220
|
-
WHERE data->>'type' = 'purchase';
|
|
221
|
-
|
|
222
|
-
-- ✅ PG 17: JSON_TABLE (convert JSON to rows)
|
|
223
|
-
SELECT jt.*
|
|
224
|
-
FROM events,
|
|
225
|
-
JSON_TABLE(
|
|
226
|
-
data,
|
|
227
|
-
'$.items[*]'
|
|
228
|
-
COLUMNS (
|
|
229
|
-
product_id INT PATH '$.product_id',
|
|
230
|
-
quantity INT PATH '$.qty',
|
|
231
|
-
price NUMERIC PATH '$.price'
|
|
232
|
-
)
|
|
233
|
-
) AS jt;
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### PostgreSQL Transactions & Locking
|
|
237
|
-
|
|
238
|
-
```sql
|
|
239
|
-
-- ✅ Transaction with proper isolation
|
|
240
|
-
BEGIN;
|
|
241
|
-
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
|
242
|
-
|
|
243
|
-
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
|
|
244
|
-
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
|
|
245
|
-
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
|
|
246
|
-
|
|
247
|
-
COMMIT;
|
|
248
|
-
|
|
249
|
-
-- ✅ Advisory locks (application-level)
|
|
250
|
-
SELECT pg_advisory_lock(12345); -- Acquire
|
|
251
|
-
-- Do work...
|
|
252
|
-
SELECT pg_advisory_unlock(12345); -- Release
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### PostgreSQL Configuration (Performance)
|
|
256
|
-
|
|
257
|
-
```sql
|
|
258
|
-
-- Key parameters for performance tuning
|
|
259
|
-
-- postgresql.conf
|
|
260
|
-
|
|
261
|
-
-- Memory (adjust based on RAM)
|
|
262
|
-
shared_buffers = '4GB' -- 25% of RAM
|
|
263
|
-
effective_cache_size = '12GB' -- 75% of RAM
|
|
264
|
-
work_mem = '256MB' -- Per operation
|
|
265
|
-
maintenance_work_mem = '1GB' -- For VACUUM, CREATE INDEX
|
|
266
|
-
|
|
267
|
-
-- WAL
|
|
268
|
-
wal_buffers = '64MB'
|
|
269
|
-
checkpoint_timeout = '15min'
|
|
270
|
-
max_wal_size = '4GB'
|
|
271
|
-
|
|
272
|
-
-- Connections
|
|
273
|
-
max_connections = 200
|
|
274
|
-
-- Use PgBouncer for connection pooling!
|
|
275
|
-
|
|
276
|
-
-- Queries
|
|
277
|
-
statement_timeout = '30s' -- Prevent long queries
|
|
278
|
-
lock_timeout = '10s' -- Prevent lock waiting
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## 🐬 MySQL 8.x
|
|
284
|
-
|
|
285
|
-
### MySQL Core Patterns
|
|
286
|
-
|
|
287
|
-
```sql
|
|
288
|
-
-- ✅ Parameterized queries (use ? placeholder)
|
|
289
|
-
SELECT id, name FROM users WHERE id = ?;
|
|
290
|
-
|
|
291
|
-
-- ✅ Indexes
|
|
292
|
-
CREATE INDEX idx_users_email ON users(email);
|
|
293
|
-
|
|
294
|
-
-- ✅ Full-text search
|
|
295
|
-
CREATE FULLTEXT INDEX idx_products_search
|
|
296
|
-
ON products(name, description);
|
|
297
|
-
|
|
298
|
-
SELECT * FROM products
|
|
299
|
-
WHERE MATCH(name, description) AGAINST('laptop' IN NATURAL LANGUAGE MODE);
|
|
300
|
-
|
|
301
|
-
-- ✅ Window functions
|
|
302
|
-
SELECT id, name, price,
|
|
303
|
-
ROW_NUMBER() OVER (ORDER BY price DESC) AS rank,
|
|
304
|
-
AVG(price) OVER () AS avg_price
|
|
305
|
-
FROM products;
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### MySQL vs PostgreSQL
|
|
309
|
-
|
|
310
|
-
| Feature | PostgreSQL | MySQL |
|
|
311
|
-
| ---------------- | ----------------------- | ----------------- |
|
|
312
|
-
| JSON Support | JSONB (binary, indexed) | JSON (text-based) |
|
|
313
|
-
| Full-text Search | Built-in tsquery | FULLTEXT index |
|
|
314
|
-
| CTEs | Optimized | Less optimized |
|
|
315
|
-
| Arrays | Native | JSON workaround |
|
|
316
|
-
| Enums | Native | Limited |
|
|
317
|
-
| Partitioning | Declarative | Hash, Range, List |
|
|
318
|
-
| Replication | Logical + Physical | Group Replication |
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## 📦 ORMs Comparison (2025)
|
|
323
|
-
|
|
324
|
-
### Node.js/TypeScript
|
|
325
|
-
|
|
326
|
-
| ORM | Type Safety | Performance | Bundle Size | Best For |
|
|
327
|
-
| ------------- | ----------- | ----------- | ----------- | --------------------- |
|
|
328
|
-
| **Prisma 7** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 90% smaller | Type-safe, Next.js |
|
|
329
|
-
| **Drizzle** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ~7.4kb | Serverless, SQL-first |
|
|
330
|
-
| **TypeORM** | ⭐⭐⭐⭐ | ⭐⭐⭐ | Medium | NestJS, Enterprise |
|
|
331
|
-
| **Sequelize** | ⭐⭐⭐ | ⭐⭐⭐ | Medium | Legacy, Beginner |
|
|
332
|
-
| **Kysely** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | Tiny | Type-safe SQL builder |
|
|
333
|
-
|
|
334
|
-
### Python
|
|
335
|
-
|
|
336
|
-
| ORM | Use Case |
|
|
337
|
-
| ------------------ | -------------------------------- |
|
|
338
|
-
| **SQLAlchemy 2.0** | Industry standard, async support |
|
|
339
|
-
| **Tortoise ORM** | Async-first, Django-like |
|
|
340
|
-
| **SQLModel** | Pydantic + SQLAlchemy |
|
|
341
|
-
|
|
342
|
-
### Go
|
|
343
|
-
|
|
344
|
-
| Library | Use Case |
|
|
345
|
-
| -------- | --------------------------- |
|
|
346
|
-
| **GORM** | Full-featured ORM |
|
|
347
|
-
| **sqlc** | Code generation from SQL |
|
|
348
|
-
| **sqlx** | Extensions for database/sql |
|
|
349
|
-
| **pgx** | PostgreSQL driver |
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
## 🔷 Prisma Patterns
|
|
354
|
-
|
|
355
|
-
### Schema Definition
|
|
356
|
-
|
|
357
|
-
```prisma
|
|
358
|
-
// schema.prisma
|
|
359
|
-
generator client {
|
|
360
|
-
provider = "prisma-client-js"
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
datasource db {
|
|
364
|
-
provider = "postgresql"
|
|
365
|
-
url = env("DATABASE_URL")
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
model User {
|
|
369
|
-
id String @id @default(cuid())
|
|
370
|
-
email String @unique
|
|
371
|
-
name String?
|
|
372
|
-
role Role @default(USER)
|
|
373
|
-
posts Post[]
|
|
374
|
-
profile Profile?
|
|
375
|
-
createdAt DateTime @default(now())
|
|
376
|
-
updatedAt DateTime @updatedAt
|
|
377
|
-
|
|
378
|
-
@@index([email])
|
|
379
|
-
@@index([createdAt])
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
model Post {
|
|
383
|
-
id String @id @default(cuid())
|
|
384
|
-
title String
|
|
385
|
-
content String?
|
|
386
|
-
published Boolean @default(false)
|
|
387
|
-
author User @relation(fields: [authorId], references: [id])
|
|
388
|
-
authorId String
|
|
389
|
-
tags Tag[]
|
|
390
|
-
createdAt DateTime @default(now())
|
|
391
|
-
|
|
392
|
-
@@index([authorId])
|
|
393
|
-
@@index([published, createdAt])
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
enum Role {
|
|
397
|
-
USER
|
|
398
|
-
ADMIN
|
|
399
|
-
MODERATOR
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
### Prisma Queries
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
import { PrismaClient } from "@prisma/client";
|
|
407
|
-
|
|
408
|
-
const prisma = new PrismaClient();
|
|
409
|
-
|
|
410
|
-
// ✅ Find with relations
|
|
411
|
-
const users = await prisma.user.findMany({
|
|
412
|
-
where: { role: "ADMIN" },
|
|
413
|
-
include: { posts: { where: { published: true } } },
|
|
414
|
-
orderBy: { createdAt: "desc" },
|
|
415
|
-
take: 10,
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
// ✅ Create with nested relations
|
|
419
|
-
const user = await prisma.user.create({
|
|
420
|
-
data: {
|
|
421
|
-
email: "alice@example.com",
|
|
422
|
-
name: "Alice",
|
|
423
|
-
posts: {
|
|
424
|
-
create: [{ title: "Hello World", content: "First post!" }],
|
|
425
|
-
},
|
|
426
|
-
},
|
|
427
|
-
include: { posts: true },
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
// ✅ Transaction (atomic operations)
|
|
431
|
-
const [updatedUser, newPost] = await prisma.$transaction([
|
|
432
|
-
prisma.user.update({
|
|
433
|
-
where: { id: userId },
|
|
434
|
-
data: { postCount: { increment: 1 } },
|
|
435
|
-
}),
|
|
436
|
-
prisma.post.create({
|
|
437
|
-
data: { title: "New Post", authorId: userId },
|
|
438
|
-
}),
|
|
439
|
-
]);
|
|
440
|
-
|
|
441
|
-
// ✅ Interactive transaction
|
|
442
|
-
await prisma.$transaction(async (tx) => {
|
|
443
|
-
const balance = await tx.account.findUnique({
|
|
444
|
-
where: { id: fromAccountId },
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
if (balance.amount < transferAmount) {
|
|
448
|
-
throw new Error("Insufficient funds");
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
await tx.account.update({
|
|
452
|
-
where: { id: fromAccountId },
|
|
453
|
-
data: { amount: { decrement: transferAmount } },
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
await tx.account.update({
|
|
457
|
-
where: { id: toAccountId },
|
|
458
|
-
data: { amount: { increment: transferAmount } },
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
---
|
|
464
|
-
|
|
465
|
-
## 🔶 Drizzle Patterns
|
|
466
|
-
|
|
467
|
-
### Schema Definition
|
|
468
|
-
|
|
469
|
-
```typescript
|
|
470
|
-
// schema.ts
|
|
471
|
-
import { pgTable, text, timestamp, boolean, index } from "drizzle-orm/pg-core";
|
|
472
|
-
import { relations } from "drizzle-orm";
|
|
473
|
-
|
|
474
|
-
export const users = pgTable(
|
|
475
|
-
"users",
|
|
476
|
-
{
|
|
477
|
-
id: text("id")
|
|
478
|
-
.primaryKey()
|
|
479
|
-
.$defaultFn(() => crypto.randomUUID()),
|
|
480
|
-
email: text("email").notNull().unique(),
|
|
481
|
-
name: text("name"),
|
|
482
|
-
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
483
|
-
},
|
|
484
|
-
(table) => ({
|
|
485
|
-
emailIdx: index("users_email_idx").on(table.email),
|
|
486
|
-
}),
|
|
487
|
-
);
|
|
488
|
-
|
|
489
|
-
export const posts = pgTable(
|
|
490
|
-
"posts",
|
|
491
|
-
{
|
|
492
|
-
id: text("id")
|
|
493
|
-
.primaryKey()
|
|
494
|
-
.$defaultFn(() => crypto.randomUUID()),
|
|
495
|
-
title: text("title").notNull(),
|
|
496
|
-
content: text("content"),
|
|
497
|
-
published: boolean("published").default(false),
|
|
498
|
-
authorId: text("author_id")
|
|
499
|
-
.notNull()
|
|
500
|
-
.references(() => users.id),
|
|
501
|
-
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
502
|
-
},
|
|
503
|
-
(table) => ({
|
|
504
|
-
authorIdx: index("posts_author_idx").on(table.authorId),
|
|
505
|
-
}),
|
|
506
|
-
);
|
|
507
|
-
|
|
508
|
-
export const usersRelations = relations(users, ({ many }) => ({
|
|
509
|
-
posts: many(posts),
|
|
510
|
-
}));
|
|
511
|
-
|
|
512
|
-
export const postsRelations = relations(posts, ({ one }) => ({
|
|
513
|
-
author: one(users, {
|
|
514
|
-
fields: [posts.authorId],
|
|
515
|
-
references: [users.id],
|
|
516
|
-
}),
|
|
517
|
-
}));
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
### Drizzle Queries
|
|
521
|
-
|
|
522
|
-
```typescript
|
|
523
|
-
import { drizzle } from "drizzle-orm/node-postgres";
|
|
524
|
-
import { eq, and, desc } from "drizzle-orm";
|
|
525
|
-
import * as schema from "./schema";
|
|
526
|
-
|
|
527
|
-
const db = drizzle(pool, { schema });
|
|
528
|
-
|
|
529
|
-
// ✅ SQL-like query API
|
|
530
|
-
const activeUsers = await db
|
|
531
|
-
.select()
|
|
532
|
-
.from(schema.users)
|
|
533
|
-
.where(eq(schema.users.active, true))
|
|
534
|
-
.orderBy(desc(schema.users.createdAt))
|
|
535
|
-
.limit(10);
|
|
536
|
-
|
|
537
|
-
// ✅ Relational query API
|
|
538
|
-
const usersWithPosts = await db.query.users.findMany({
|
|
539
|
-
with: {
|
|
540
|
-
posts: {
|
|
541
|
-
where: eq(schema.posts.published, true),
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
// ✅ Transaction
|
|
547
|
-
await db.transaction(async (tx) => {
|
|
548
|
-
await tx
|
|
549
|
-
.update(schema.accounts)
|
|
550
|
-
.set({ balance: sql`balance - 100` })
|
|
551
|
-
.where(eq(schema.accounts.id, 1));
|
|
552
|
-
|
|
553
|
-
await tx
|
|
554
|
-
.update(schema.accounts)
|
|
555
|
-
.set({ balance: sql`balance + 100` })
|
|
556
|
-
.where(eq(schema.accounts.id, 2));
|
|
557
|
-
});
|
|
147
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
148
|
+
│ Application │
|
|
149
|
+
├──────────────┬────────────┬───────────┬─────────────────────┤
|
|
150
|
+
│ PostgreSQL │ MongoDB │ Redis │ Elasticsearch │
|
|
151
|
+
│ (Primary) │ (Flexible) │ (Cache) │ (Search) │
|
|
152
|
+
│ Users │ Logs │ Sessions │ Products │
|
|
153
|
+
│ Orders │ Events │ Rate Limit│ Full-text │
|
|
154
|
+
│ Payments │ Analytics │ Leaderboard│ │
|
|
155
|
+
└──────────────┴────────────┴───────────┴─────────────────────┘
|
|
558
156
|
```
|
|
559
157
|
|
|
560
158
|
---
|
|
561
159
|
|
|
562
|
-
##
|
|
563
|
-
|
|
564
|
-
### When to Use MongoDB
|
|
565
|
-
|
|
566
|
-
| ✅ Good For | ❌ Not Good For |
|
|
567
|
-
| ------------------------ | ----------------------------- |
|
|
568
|
-
| Flexible/evolving schema | Complex joins |
|
|
569
|
-
| JSON-like documents | ACID transactions (multi-doc) |
|
|
570
|
-
| Rapid prototyping | Strong consistency |
|
|
571
|
-
| Content management | Financial data |
|
|
572
|
-
| IoT data ingestion | Complex queries |
|
|
573
|
-
| Real-time analytics | Relational data |
|
|
574
|
-
|
|
575
|
-
### MongoDB Node.js Patterns
|
|
576
|
-
|
|
577
|
-
```typescript
|
|
578
|
-
import { MongoClient, ObjectId } from "mongodb";
|
|
160
|
+
## 📚 Deep-Dive References
|
|
579
161
|
|
|
580
|
-
|
|
581
|
-
|
|
162
|
+
- **PostgreSQL 17/18** — Table partitioning, JSONB, full-text search, performance tuning
|
|
163
|
+
→ See [references/postgresql.md](references/postgresql.md)
|
|
582
164
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
email: "alice@example.com",
|
|
586
|
-
name: "Alice",
|
|
587
|
-
metadata: { lastLogin: new Date(), preferences: { theme: "dark" } },
|
|
588
|
-
createdAt: new Date(),
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
// ✅ Find with projection
|
|
592
|
-
const user = await db.collection("users").findOne(
|
|
593
|
-
{ email: "alice@example.com" },
|
|
594
|
-
{ projection: { password: 0 } }, // Exclude password
|
|
595
|
-
);
|
|
596
|
-
|
|
597
|
-
// ✅ Aggregation pipeline
|
|
598
|
-
const results = await db
|
|
599
|
-
.collection("orders")
|
|
600
|
-
.aggregate([
|
|
601
|
-
{ $match: { status: "completed" } },
|
|
602
|
-
{
|
|
603
|
-
$group: {
|
|
604
|
-
_id: "$userId",
|
|
605
|
-
totalAmount: { $sum: "$amount" },
|
|
606
|
-
orderCount: { $sum: 1 },
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
{ $sort: { totalAmount: -1 } },
|
|
610
|
-
{ $limit: 10 },
|
|
611
|
-
])
|
|
612
|
-
.toArray();
|
|
613
|
-
|
|
614
|
-
// ✅ Indexes
|
|
615
|
-
await db.collection("users").createIndex({ email: 1 }, { unique: true });
|
|
616
|
-
await db
|
|
617
|
-
.collection("events")
|
|
618
|
-
.createIndex({ createdAt: 1 }, { expireAfterSeconds: 86400 });
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
---
|
|
165
|
+
- **ORMs Comparison & Patterns** — MySQL, Prisma, Drizzle, TypeORM patterns
|
|
166
|
+
→ See [references/orms-patterns.md](references/orms-patterns.md)
|
|
622
167
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
### Redis Use Cases
|
|
626
|
-
|
|
627
|
-
| Pattern | Use Case | TTL |
|
|
628
|
-
| --------------- | -------------------- | ---------- |
|
|
629
|
-
| **Cache** | Database query cache | 5-60 min |
|
|
630
|
-
| **Session** | User sessions | 24h |
|
|
631
|
-
| **Rate Limit** | API throttling | 1 min |
|
|
632
|
-
| **Leaderboard** | Sorted sets | Persistent |
|
|
633
|
-
| **Pub/Sub** | Real-time events | N/A |
|
|
634
|
-
| **Queue** | Job queue (List) | N/A |
|
|
635
|
-
| **Lock** | Distributed lock | 30s |
|
|
636
|
-
|
|
637
|
-
### Redis Node.js Patterns
|
|
638
|
-
|
|
639
|
-
```typescript
|
|
640
|
-
import Redis from "ioredis";
|
|
641
|
-
|
|
642
|
-
const redis = new Redis(process.env.REDIS_URL);
|
|
643
|
-
|
|
644
|
-
// ✅ Cache pattern
|
|
645
|
-
async function getCachedUser(userId: string) {
|
|
646
|
-
const cacheKey = `user:${userId}`;
|
|
647
|
-
|
|
648
|
-
// Try cache first
|
|
649
|
-
const cached = await redis.get(cacheKey);
|
|
650
|
-
if (cached) return JSON.parse(cached);
|
|
651
|
-
|
|
652
|
-
// Cache miss - fetch from DB
|
|
653
|
-
const user = await db.users.findUnique({ where: { id: userId } });
|
|
654
|
-
|
|
655
|
-
// Store in cache with TTL
|
|
656
|
-
await redis.setex(cacheKey, 3600, JSON.stringify(user));
|
|
657
|
-
|
|
658
|
-
return user;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// ✅ Rate limiting (sliding window)
|
|
662
|
-
async function checkRateLimit(ip: string, limit = 100, windowSec = 60) {
|
|
663
|
-
const key = `ratelimit:${ip}`;
|
|
664
|
-
const current = await redis.incr(key);
|
|
665
|
-
|
|
666
|
-
if (current === 1) {
|
|
667
|
-
await redis.expire(key, windowSec);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
return current <= limit;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// ✅ Session storage
|
|
674
|
-
await redis.hset(`session:${sessionId}`, {
|
|
675
|
-
userId: user.id,
|
|
676
|
-
email: user.email,
|
|
677
|
-
loginAt: Date.now(),
|
|
678
|
-
});
|
|
679
|
-
await redis.expire(`session:${sessionId}`, 86400); // 24h
|
|
680
|
-
|
|
681
|
-
// ✅ Leaderboard
|
|
682
|
-
await redis.zadd("leaderboard", score, `user:${userId}`);
|
|
683
|
-
const top10 = await redis.zrevrange("leaderboard", 0, 9, "WITHSCORES");
|
|
684
|
-
|
|
685
|
-
// ✅ Pub/Sub
|
|
686
|
-
const subscriber = redis.duplicate();
|
|
687
|
-
await subscriber.subscribe("notifications");
|
|
688
|
-
subscriber.on("message", (channel, message) => {
|
|
689
|
-
console.log(`Received: ${message}`);
|
|
690
|
-
});
|
|
691
|
-
|
|
692
|
-
await redis.publish("notifications", JSON.stringify({ type: "new_order" }));
|
|
693
|
-
|
|
694
|
-
// ✅ Distributed lock
|
|
695
|
-
async function withLock<T>(key: string, fn: () => Promise<T>, ttlMs = 30000) {
|
|
696
|
-
const lockKey = `lock:${key}`;
|
|
697
|
-
const lockValue = crypto.randomUUID();
|
|
698
|
-
|
|
699
|
-
const acquired = await redis.set(lockKey, lockValue, "PX", ttlMs, "NX");
|
|
700
|
-
if (!acquired) throw new Error("Failed to acquire lock");
|
|
701
|
-
|
|
702
|
-
try {
|
|
703
|
-
return await fn();
|
|
704
|
-
} finally {
|
|
705
|
-
// Release only if we own the lock
|
|
706
|
-
const script = `
|
|
707
|
-
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
708
|
-
return redis.call("del", KEYS[1])
|
|
709
|
-
else
|
|
710
|
-
return 0
|
|
711
|
-
end
|
|
712
|
-
`;
|
|
713
|
-
await redis.eval(script, 1, lockKey, lockValue);
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
```
|
|
717
|
-
|
|
718
|
-
---
|
|
719
|
-
|
|
720
|
-
## 🛠️ Database Tools
|
|
721
|
-
|
|
722
|
-
### Migration Tools
|
|
723
|
-
|
|
724
|
-
| Tool | Language | Database |
|
|
725
|
-
| ------------------ | -------- | ---------- |
|
|
726
|
-
| **Prisma Migrate** | TS/JS | Multi |
|
|
727
|
-
| **Drizzle Kit** | TS/JS | Multi |
|
|
728
|
-
| **golang-migrate** | Go | Multi |
|
|
729
|
-
| **Alembic** | Python | SQLAlchemy |
|
|
730
|
-
| **Flyway** | Java/CLI | Multi |
|
|
731
|
-
| **Atlas** | Go | Multi |
|
|
732
|
-
|
|
733
|
-
### Monitoring & GUI
|
|
734
|
-
|
|
735
|
-
| Tool | Purpose |
|
|
736
|
-
| ------------------- | -------------- |
|
|
737
|
-
| **pgAdmin** | PostgreSQL GUI |
|
|
738
|
-
| **DBeaver** | Universal GUI |
|
|
739
|
-
| **TablePlus** | Multi-DB GUI |
|
|
740
|
-
| **Prisma Studio** | Prisma visual |
|
|
741
|
-
| **RedisInsight** | Redis GUI |
|
|
742
|
-
| **MongoDB Compass** | MongoDB GUI |
|
|
743
|
-
|
|
744
|
-
### Connection Pooling
|
|
745
|
-
|
|
746
|
-
| Tool | Database |
|
|
747
|
-
| ----------------- | ---------- |
|
|
748
|
-
| **PgBouncer** | PostgreSQL |
|
|
749
|
-
| **PgCat** | PostgreSQL |
|
|
750
|
-
| **ProxySQL** | MySQL |
|
|
751
|
-
| **Redis Cluster** | Redis |
|
|
752
|
-
|
|
753
|
-
---
|
|
168
|
+
- **NoSQL Patterns** — MongoDB aggregation, Redis caching, pub/sub, Streams
|
|
169
|
+
→ See [references/nosql-patterns.md](references/nosql-patterns.md)
|
|
754
170
|
|
|
755
171
|
## ✅ Production Checklist
|
|
756
172
|
|
|
@@ -789,7 +205,7 @@ async function withLock<T>(key: string, fn: () => Promise<T>, ttlMs = 30000) {
|
|
|
789
205
|
|
|
790
206
|
---
|
|
791
207
|
|
|
792
|
-
##
|
|
208
|
+
## 📌 HSA Integration
|
|
793
209
|
|
|
794
210
|
Data powered by HSA BM25 search engine across 6 database domains:
|
|
795
211
|
|
|
@@ -804,4 +220,4 @@ Data powered by HSA BM25 search engine across 6 database domains:
|
|
|
804
220
|
|
|
805
221
|
---
|
|
806
222
|
|
|
807
|
-
_DOMYH Awesome Code
|
|
223
|
+
_DOMYH Awesome Code Database Patterns HSA-Powered 2025-2026_
|