dbdock 1.1.15 → 1.1.17

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.
Files changed (43) hide show
  1. package/README.md +473 -580
  2. package/dist/cli/commands/analyze.d.ts +1 -0
  3. package/dist/cli/commands/analyze.js +135 -0
  4. package/dist/cli/commands/analyze.js.map +1 -0
  5. package/dist/cli/commands/cross-migrate.d.ts +11 -0
  6. package/dist/cli/commands/cross-migrate.js +307 -0
  7. package/dist/cli/commands/cross-migrate.js.map +1 -0
  8. package/dist/cli/index.js +20 -0
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/migration/analyzers/mongodb.analyzer.d.ts +3 -0
  11. package/dist/migration/analyzers/mongodb.analyzer.js +208 -0
  12. package/dist/migration/analyzers/mongodb.analyzer.js.map +1 -0
  13. package/dist/migration/analyzers/postgres.analyzer.d.ts +3 -0
  14. package/dist/migration/analyzers/postgres.analyzer.js +176 -0
  15. package/dist/migration/analyzers/postgres.analyzer.js.map +1 -0
  16. package/dist/migration/config.manager.d.ts +3 -0
  17. package/dist/migration/config.manager.js +80 -0
  18. package/dist/migration/config.manager.js.map +1 -0
  19. package/dist/migration/engines/migration.engine.d.ts +6 -0
  20. package/dist/migration/engines/migration.engine.js +62 -0
  21. package/dist/migration/engines/migration.engine.js.map +1 -0
  22. package/dist/migration/engines/mongo-to-postgres.engine.d.ts +2 -0
  23. package/dist/migration/engines/mongo-to-postgres.engine.js +409 -0
  24. package/dist/migration/engines/mongo-to-postgres.engine.js.map +1 -0
  25. package/dist/migration/engines/postgres-to-mongo.engine.d.ts +2 -0
  26. package/dist/migration/engines/postgres-to-mongo.engine.js +192 -0
  27. package/dist/migration/engines/postgres-to-mongo.engine.js.map +1 -0
  28. package/dist/migration/mappers/mongo-to-postgres.mapper.d.ts +2 -0
  29. package/dist/migration/mappers/mongo-to-postgres.mapper.js +263 -0
  30. package/dist/migration/mappers/mongo-to-postgres.mapper.js.map +1 -0
  31. package/dist/migration/mappers/postgres-to-mongo.mapper.d.ts +2 -0
  32. package/dist/migration/mappers/postgres-to-mongo.mapper.js +174 -0
  33. package/dist/migration/mappers/postgres-to-mongo.mapper.js.map +1 -0
  34. package/dist/migration/reference.detector.d.ts +2 -0
  35. package/dist/migration/reference.detector.js +57 -0
  36. package/dist/migration/reference.detector.js.map +1 -0
  37. package/dist/migration/type.mapper.d.ts +12 -0
  38. package/dist/migration/type.mapper.js +197 -0
  39. package/dist/migration/type.mapper.js.map +1 -0
  40. package/dist/migration/types.d.ts +183 -0
  41. package/dist/migration/types.js +11 -0
  42. package/dist/migration/types.js.map +1 -0
  43. package/package.json +11 -2
package/README.md CHANGED
@@ -1,116 +1,117 @@
1
1
  # DBDock
2
2
 
3
- Enterprise-grade PostgreSQL backup and restore. Beautiful CLI with real-time progress tracking.
3
+ Stop writing backup scripts. Stop losing sleep over database migrations. DBDock handles PostgreSQL backups, restores, database copies, and cross-database migrations between MongoDB and PostgreSQL in one command.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/dbdock.svg)](https://www.npmjs.com/package/dbdock)
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
7
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
8
8
  [![Documentation](https://img.shields.io/badge/docs-dbdock.mintlify.app-blue)](https://dbdock.mintlify.app)
9
9
 
10
- 📚 **[Full Documentation](https://dbdock.mintlify.app)** | 💬 **[Discussions](https://github.com/naheemolaide/dbdock-support/discussions)** | 🐛 **[Issues](https://github.com/naheemolaide/dbdock-support/issues)**
10
+ [Full Docs](https://dbdock.mintlify.app) [Discussions](https://github.com/naheemolaide/dbdock-support/discussions) [Report a Bug](https://github.com/naheemolaide/dbdock-support/issues)
11
11
 
12
- ## Quick Start
12
+ ---
13
+
14
+ ## The Problem
15
+
16
+ Every time you need to backup a database, copy it to staging, or restore before a migration — it's the same boring steps. Connect, dump, upload, move files around, remember the right flags. Sure, you could ask AI to write you a script. But then you're maintaining that script, handling errors, adding encryption, switching storage providers, doing it again next week.
17
+
18
+ It's not hard. It's just repetitive. And repetitive stuff should be one command.
19
+
20
+ ## The Fix
13
21
 
14
22
  ```bash
15
- npx dbdock init # Interactive setup
16
- npx dbdock backup # Create backup
17
- npx dbdock restore # Restore backup
23
+ npx dbdock init # One-time setup (takes 30 seconds)
24
+ npx dbdock backup # Backup with encryption + compression
25
+ npx dbdock restore # Restore from any backup
26
+ npx dbdock copydb "db_url_1" "db_url_2" # Copy entire database, zero config
27
+ npx dbdock migrate "mongo_url" "postgres_url" # Cross-database migration
18
28
  ```
19
29
 
20
- ## Features
30
+ That's it. No shell scripts. No manual uploads. No throwaway migration code.
21
31
 
22
- - **Beautiful CLI** - Real-time progress bars, speed tracking, smart filtering
23
- - **Multiple Storage** - Local, AWS S3, Cloudflare R2, Cloudinary
24
- - **Security First** - Hybrid config (env vars for secrets), AES-256 encryption, credential masking, .pgpass support
25
- - **Retention Policies** - Automatic cleanup by count/age with safety nets
26
- - **Smart UX** - Intelligent filtering for 100+ backups, clear error messages
27
- - **Alerts** - Email (SMTP) and Slack notifications for backups (CLI & Programmatic)
28
- - **TypeScript Native** - Full type safety for programmatic usage
29
- - **Automation** - Cron schedules, auto-cleanup after backups
30
- - **Migration Tool** - One command to migrate legacy configs to secure env vars
32
+ ---
31
33
 
32
- ## Installation
34
+ ## Install
33
35
 
34
- **Global Installation (Recommended):**
36
+ **Use directly with npx (no install needed):**
35
37
 
36
38
  ```bash
37
- npm install -g dbdock
38
-
39
- dbdock init # Use directly
40
- dbdock backup
41
- dbdock status
39
+ npx dbdock backup
42
40
  ```
43
41
 
44
- **Or use with npx (No installation needed):**
42
+ **Or install globally:**
45
43
 
46
44
  ```bash
47
- npx dbdock init
48
- npx dbdock backup
49
- npx dbdock status
45
+ npm install -g dbdock
50
46
  ```
51
47
 
52
- ## CLI Commands
48
+ **Prerequisites:** Node.js 18+ and PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`).
53
49
 
54
- ### `dbdock init`
50
+ ```bash
51
+ # macOS
52
+ brew install postgresql
55
53
 
56
- Interactive setup wizard that creates secure configuration:
54
+ # Ubuntu/Debian
55
+ sudo apt-get install postgresql-client
56
+ ```
57
57
 
58
- - Database connection (host, port, credentials)
59
- - Storage provider (Local, S3, R2, Cloudinary)
60
- - Encryption/compression settings
61
- - Email and Slack alerts (optional)
58
+ ---
62
59
 
63
- **Security-first approach:**
64
- - Saves non-sensitive config to `dbdock.config.json` (safe for git)
65
- - Saves secrets to `.env` (automatically gitignored)
66
- - Auto-updates `.gitignore` to exclude sensitive files
60
+ ## Commands
67
61
 
68
- ### `dbdock migrate-config`
62
+ ### `dbdock init` — Set up in 30 seconds
69
63
 
70
- Migrate existing configurations with embedded secrets:
64
+ Run once. It walks you through everything interactively:
71
65
 
72
66
  ```bash
73
- npx dbdock migrate-config
67
+ npx dbdock init
74
68
  ```
75
69
 
76
- Extracts secrets from `dbdock.config.json`, creates `.env`, and updates your config to use environment variables.
70
+ It asks for your database connection, picks your storage (Local, S3, R2, Cloudinary), sets up encryption if you want it, and optionally configures Slack/Email alerts.
71
+
72
+ **What happens under the hood:**
73
+ - Config (safe stuff) goes to `dbdock.config.json` — commit this
74
+ - Secrets go to `.env` — never committed, `.gitignore` updated automatically
77
75
 
78
- ### `npx dbdock backup`
76
+ ---
79
77
 
80
- Creates database backup with real-time progress tracking:
78
+ ### `dbdock backup` One command, full backup
81
79
 
80
+ ```bash
81
+ npx dbdock backup
82
82
  ```
83
- ████████████████████ | 100% | 45.23/100 MB | Speed: 12.50 MB/s | ETA: 0s | Uploading to S3
83
+
84
+ ```
85
+ ████████████████████ | 100% | 45.23 MB | Speed: 12.50 MB/s | Uploading to S3
84
86
  ✔ Backup completed successfully
85
87
  ```
86
88
 
87
- **Options:**
89
+ Real-time progress. Streams directly to your storage provider. Done.
88
90
 
89
- ```bash
90
- npx dbdock backup --encrypt --compress --compression-level 9
91
- ```
91
+ **Options:**
92
92
 
93
- - `--encrypt` / `--no-encrypt` - Toggle encryption
94
- - `--compress` / `--no-compress` - Toggle compression
95
- - `--encryption-key <key>` - 64-char hex key (must be exactly 64 hexadecimal characters)
96
- - `--compression-level <1-11>` - Compression level (default: 6)
93
+ | Flag | What it does |
94
+ |------|------|
95
+ | `--encrypt` / `--no-encrypt` | Toggle AES-256 encryption |
96
+ | `--compress` / `--no-compress` | Toggle Brotli compression |
97
+ | `--encryption-key <key>` | Custom 64-char hex key |
98
+ | `--compression-level <1-11>` | Compression intensity (default: 6) |
97
99
 
98
- **Generate encryption key:**
100
+ **Need an encryption key?**
99
101
 
100
102
  ```bash
101
103
  node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
102
104
  ```
103
105
 
104
- **Backup Formats:**
106
+ **Backup formats:** `custom` (default binary), `plain` (SQL text), `directory`, `tar`
105
107
 
106
- - `custom` (default) - PostgreSQL custom binary format (.sql)
107
- - `plain` - Plain SQL text format (.sql)
108
- - `directory` - Directory format (.dir)
109
- - `tar` - Tar archive format (.tar)
108
+ ---
110
109
 
111
- ### `npx dbdock restore`
110
+ ### `dbdock restore` — Interactive restore with smart filtering
112
111
 
113
- Interactive restore with smart filtering and multi-step progress:
112
+ ```bash
113
+ npx dbdock restore
114
+ ```
114
115
 
115
116
  ```
116
117
  Progress:
@@ -123,282 +124,385 @@ Progress:
123
124
  ✔ All steps completed in 8.42s
124
125
  ```
125
126
 
126
- **Smart filtering** (auto-enabled for 20+ backups):
127
+ Got 200+ backups? It auto-enables smart filtering — search by date, keyword, or just grab the most recent ones. No scrolling through walls of text.
128
+
129
+ You can also restore to a completely different database. Pick "New Database Instance (Migrate)" when prompted and enter the target connection details.
130
+
131
+ ---
132
+
133
+ ### `dbdock copydb` — Copy a database with just two URLs
134
+
135
+ This is the one people love. No config files. No setup. Just paste two PostgreSQL URLs:
136
+
137
+ ```bash
138
+ npx dbdock copydb "postgresql://user:pass@source:5432/mydb" "postgresql://user:pass@target:5432/mydb"
139
+ ```
140
+
141
+ It tests both connections, shows you the source DB size and table count, warns you if the target has existing data, and asks for confirmation before doing anything. Then it streams `pg_dump` directly into `pg_restore` — no temp files, no waiting.
142
+
143
+ **Options:**
144
+
145
+ | Flag | What it does |
146
+ |------|------|
147
+ | `--schema-only` | Copy tables, indexes, constraints — no data |
148
+ | `--data-only` | Copy data only (schema must exist on target) |
149
+ | `--verbose` | Show detailed pg_dump/pg_restore output |
150
+
151
+ ```bash
152
+ npx dbdock copydb --schema-only "source_url" "target_url"
153
+ npx dbdock copydb --data-only "source_url" "target_url"
154
+ ```
155
+
156
+ **Perfect for:**
157
+ - Moving between Neon, Supabase, Railway, RDS, or any Postgres host
158
+ - Migrating cloud providers without the headache
127
159
 
128
- - Show recent (last 10)
129
- - Date range (24h, 7d, 30d, 90d, custom)
130
- - Search by keyword/ID
160
+ **Environment consolidation:**
131
161
 
132
- **Migration Support:**
162
+ ```bash
163
+ # Refresh staging with production data
164
+ npx dbdock copydb "prod_url" "staging_url"
133
165
 
134
- You can choose to restore to a **New Database Instance** during the restore process. This is perfect for migrating data between servers (e.g., from staging to production or local to cloud).
166
+ # Promote staging to production
167
+ npx dbdock copydb "staging_url" "prod_url"
135
168
 
136
- 1. Run `npx dbdock restore`
137
- 2. Select a backup
138
- 3. Choose "New Database Instance (Migrate)"
139
- 4. Enter connection details for the target database
169
+ # Pull production to local for debugging
170
+ npx dbdock copydb "prod_url" "postgresql://postgres:pass@localhost:5432/myapp"
140
171
 
141
- Shows database stats and requires confirmation before restore.
172
+ # Align schema across environments without touching data
173
+ npx dbdock copydb --schema-only "prod_url" "staging_url"
174
+ ```
142
175
 
143
- ### `npx dbdock list`
176
+ ---
144
177
 
145
- View backups with smart filtering:
178
+ ### `dbdock list` See all your backups
146
179
 
147
180
  ```bash
148
- npx dbdock list # All backups
181
+ npx dbdock list # Everything
149
182
  npx dbdock list --recent 10 # Last 10
150
- npx dbdock list --search keyword # Search
183
+ npx dbdock list --search keyword # Find specific backup
151
184
  npx dbdock list --days 7 # Last 7 days
152
185
  ```
153
186
 
154
- **Auto-filtering** for 50+ backups with interactive prompts.
187
+ Auto-filters when you have 50+ backups so the output stays clean.
155
188
 
156
- ### `npx dbdock delete`
189
+ ---
157
190
 
158
- Delete backups interactively or by key:
191
+ ### `dbdock delete` Remove backups
159
192
 
160
193
  ```bash
161
- npx dbdock delete # Interactive
162
- npx dbdock delete --key <id> # Specific backup
163
- npx dbdock delete --all # All (with confirmation)
194
+ npx dbdock delete # Interactive picker
195
+ npx dbdock delete --key <id> # Delete specific backup
196
+ npx dbdock delete --all # Nuke everything (with confirmation)
164
197
  ```
165
198
 
166
- ### `npx dbdock cleanup`
199
+ ---
167
200
 
168
- Clean up old backups based on retention policy:
201
+ ### `dbdock cleanup` Auto-clean old backups
169
202
 
170
203
  ```bash
171
204
  npx dbdock cleanup # Interactive with preview
172
- npx dbdock cleanup --dry-run # Preview only
205
+ npx dbdock cleanup --dry-run # See what would be deleted
173
206
  npx dbdock cleanup --force # Skip confirmation
174
207
  ```
175
208
 
176
- Shows detailed preview of what will be deleted and space to reclaim.
209
+ Shows you exactly what gets deleted and how much space you reclaim before doing anything.
177
210
 
178
- ### `dbdock status`
211
+ ---
179
212
 
180
- Quick view of all schedules and service status:
213
+ ### `dbdock status` Check schedules and service health
181
214
 
182
215
  ```bash
183
- dbdock status
216
+ npx dbdock status
184
217
  ```
185
218
 
186
- **Output:**
187
-
188
219
  ```
189
- 📅 Scheduled Backups:
190
-
191
220
  ┌─────┬──────────────┬─────────────────┬──────────┐
192
221
  │ # │ Name │ Cron Expression │ Status │
193
222
  ├─────┼──────────────┼─────────────────┼──────────┤
194
223
  │ 1 │ daily │ 0 * * * * │ ✓ Active │
195
224
  │ 2 │ weekly │ 0 0 * * 0 │ ✗ Paused │
196
225
  └─────┴──────────────┴─────────────────┴──────────┘
226
+ ```
197
227
 
198
- Total: 2 schedule(s) - 1 active, 1 paused
228
+ ---
199
229
 
200
- 🚀 Service Status:
230
+ ### `dbdock schedule` — Manage cron schedules
201
231
 
202
- 🟢 Running (PM2)
203
- PID: 12345
204
- Uptime: 2d 5h
205
- Memory: 45.23 MB
232
+ ```bash
233
+ npx dbdock schedule
206
234
  ```
207
235
 
208
- ### `dbdock test`
236
+ Add, remove, or toggle backup schedules. Comes with presets (hourly, daily at midnight, daily at 2 AM, weekly, monthly) or use a custom cron expression.
209
237
 
210
- Validates database, storage, and email configuration.
238
+ **Heads up:** Schedules only run when DBDock is integrated into your Node.js app (see [Programmatic Usage](#programmatic-usage) below). The CLI just manages the config.
211
239
 
212
- ### `dbdock schedule`
240
+ ---
213
241
 
214
- Manage backup schedules in configuration:
242
+ ### `dbdock test` Verify everything works
215
243
 
216
244
  ```bash
217
- dbdock schedule
245
+ npx dbdock test
218
246
  ```
219
247
 
220
- **Features:**
248
+ Tests your database connection, storage provider, and alert config. Run this first if something feels off.
221
249
 
222
- - View current schedules with status
223
- - Add new schedule with cron expression presets
224
- - Remove or toggle (enable/disable) schedules
225
- - Saves to `dbdock.config.json`
250
+ ---
226
251
 
227
- **Schedule Presets:**
252
+ ### `dbdock migrate-config` — Fix legacy configs
228
253
 
229
- - Every hour: `0 * * * *`
230
- - Every day at midnight: `0 0 * * *`
231
- - Every day at 2 AM: `0 2 * * *`
232
- - Every week (Sunday): `0 0 * * 0`
233
- - Every month (1st): `0 0 1 * *`
234
- - Custom cron expression
254
+ ```bash
255
+ npx dbdock migrate-config
256
+ ```
235
257
 
236
- **⚠️ Important:** Schedules only execute when DBDock is integrated into your Node.js application (see Programmatic Usage below). The CLI is for configuration only.
258
+ Got secrets sitting in `dbdock.config.json` from an older version? This extracts them to `.env`, cleans up your config, and updates `.gitignore`. One command, done.
237
259
 
238
- ## Security Best Practices
260
+ ---
239
261
 
240
- ### Secure Configuration Management
262
+ ## Cross-Database Migration (MongoDB ↔ PostgreSQL)
241
263
 
242
- DBDock uses a **hybrid configuration approach** to keep your secrets safe:
264
+ Move your data between MongoDB and PostgreSQL without writing throwaway scripts. DBDock analyzes the source, proposes a schema mapping, lets you review it, and handles the transfer.
243
265
 
244
- - **Non-sensitive settings** → `dbdock.config.json` (safe for version control)
245
- - **Sensitive secrets** → Environment variables (NEVER commit to git)
266
+ ### `dbdock analyze` Understand your database first
246
267
 
247
- When you run `npx dbdock init`, DBDock automatically:
248
- - Saves credentials to `.env` (not committed)
249
- - Saves only non-sensitive config to `dbdock.config.json`
250
- - Updates `.gitignore` to exclude `.env`
268
+ ```bash
269
+ npx dbdock analyze "mongodb://localhost:27017/myapp"
270
+ npx dbdock analyze "postgresql://user:pass@localhost:5432/myapp"
271
+ ```
251
272
 
252
- **Note:** DBDock reads environment variables from both `.env` and `.env.local` files (with `.env.local` taking priority for local overrides). You can use either file depending on your workflow.
273
+ Scans the source database and shows you everything collections/tables, field types, nested structures, inconsistencies (like a `price` field that's a string in 200 docs and a number in 15,000), and missing fields.
253
274
 
254
- ### Environment Variables
275
+ ```
276
+ DBDock - Database Analysis
277
+ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
278
+
279
+ ℹ Database: MongoDB — myapp
280
+ ℹ Host: localhost:27017
281
+
282
+ ✓ Analysis complete
283
+
284
+ Found 4 collections, 57.2K total documents
255
285
 
256
- Set these environment variables for secure credential management:
286
+ users (45K docs)
287
+ ├─ _id (objectId)
288
+ ├─ name (string)
289
+ ├─ email (string)
290
+ ├─ address (object)
291
+ │ ├─ street (string)
292
+ │ ├─ city (string)
293
+ │ └─ zip (string)
294
+ ├─ phone (string) [62% present]
295
+ └─ orders (array: object)
296
+
297
+ products (12K docs)
298
+ ├─ _id (objectId)
299
+ ├─ title (string)
300
+ ├─ price (string(203), number(11797)) ⚠ mixed types
301
+ ├─ tags (array: string)
302
+ └─ meta (object)
303
+ ```
304
+
305
+ ---
306
+
307
+ ### `dbdock migrate` — Cross-database migration
257
308
 
258
309
  ```bash
259
- # Database password (Required)
260
- DBDOCK_DB_PASSWORD=your-database-password
310
+ npx dbdock migrate "mongodb://localhost:27017/myapp" "postgresql://user:pass@localhost:5432/myapp"
311
+ ```
261
312
 
262
- # Storage credentials (Required for cloud storage)
263
- DBDOCK_STORAGE_ACCESS_KEY=your-access-key
264
- DBDOCK_STORAGE_SECRET_KEY=your-secret-key
313
+ DBDock analyzes the source, generates a schema mapping proposal, and presents it for review before touching anything:
265
314
 
266
- # Encryption key (Required if encryption enabled)
267
- # Generate with: openssl rand -hex 32
268
- DBDOCK_ENCRYPTION_SECRET=64-char-hex-string
315
+ ```
316
+ DBDock - Cross-Database Migration
317
+ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
269
318
 
270
- # Email alerts (Optional)
271
- DBDOCK_SMTP_USER=your-email@example.com
272
- DBDOCK_SMTP_PASS=your-app-password
319
+ Source: MongoDB — myapp
320
+ ℹ Target: PostgreSQL — myapp
273
321
 
274
- # Slack alerts (Optional)
275
- DBDOCK_SLACK_WEBHOOK=https://hooks.slack.com/services/...
322
+ Source analyzed: 4 collections, 57.2K documents
323
+
324
+ Proposed Schema Mapping:
325
+
326
+ users → users
327
+ ├─ _id → (uuid_from_objectid) users.id (uuid) PK
328
+ ├─ name → users.name (text)
329
+ ├─ email → users.email (text)
330
+ ├─ address {} → user_addresses (1:1 relation)
331
+ │ ├─ street → street (text)
332
+ │ ├─ city → city (text)
333
+ │ └─ zip → zip (text)
334
+ ├─ orders [] → user_orders child table
335
+
336
+ products → products
337
+ ├─ _id → (uuid_from_objectid) products.id (uuid) PK
338
+ ├─ title → products.title (text)
339
+ ├─ price → products.price (numeric) nullable
340
+ ├─ tags [] → product_tags text[]
341
+ ├─ meta {} → products.meta (jsonb)
342
+
343
+ ⚠ Conflicts Found:
344
+
345
+ • products.price: string in 203 docs, number in 11797 docs
346
+ → Suggestion: cast to numeric, log failures
347
+
348
+ • users.phone: missing in 38.0% of documents
349
+ → Suggestion: nullable column
350
+
351
+ ? Accept mapping? (Y / export / cancel)
276
352
  ```
277
353
 
278
- ### Migration from Legacy Config
354
+ You review the mapping, then choose: execute it, export it as a config file to tweak, or cancel.
355
+
356
+ ---
357
+
358
+ ### What it handles
279
359
 
280
- If you have an existing configuration with secrets in `dbdock.config.json`:
360
+ | Scenario | How DBDock handles it |
361
+ |---|---|
362
+ | **Nested objects** | Consistent shape → flattened to a related table. Varying/messy → kept as `jsonb` column |
363
+ | **Arrays of primitives** | `tags: ["a", "b"]` → PostgreSQL array column or junction table |
364
+ | **Arrays of objects** | `orders: [{item, qty}]` → child table with foreign key back to parent |
365
+ | **Missing fields** | Detects frequency across all documents, makes sparse fields nullable |
366
+ | **Type mismatches** | Same field with different types → casts to majority type, logs failures to `_migration_errors` |
367
+ | **ObjectId references** | Auto-detects `userId: ObjectId(...)` patterns → creates proper foreign keys |
368
+ | **Deep nesting** | Flattens up to configurable depth (default: 2), stores deeper levels as `jsonb` |
369
+ | **Postgres → Mongo** | 1:1 joins → embedded objects. Small 1:many → embedded arrays. Large 1:many → separate collections with refs |
370
+ | **Many-to-many** | Junction tables → arrays of values in the document |
371
+
372
+ ---
373
+
374
+ ### The reverse — PostgreSQL to MongoDB
281
375
 
282
376
  ```bash
283
- npx dbdock migrate-config
377
+ npx dbdock migrate "postgresql://user:pass@localhost:5432/myapp" "mongodb://localhost:27017/myapp"
378
+ ```
379
+
380
+ DBDock detects table relationships and proposes embedding vs referencing strategies:
381
+
382
+ ```
383
+ Proposed Document Mapping:
384
+
385
+ users → users collection
386
+ ├─ id → _id
387
+ ├─ name → name
388
+ ├─ email → email
389
+ ├─ addresses → embed object as address
390
+ ├─ orders → embed array as orders (< 1000 rows)
391
+
392
+ products → products collection
393
+ ├─ id → _id
394
+ ├─ title → title
395
+ ├─ price → price
396
+ ├─ product_tags → embed as tags array
284
397
  ```
285
398
 
286
- This command will:
287
- 1. Extract all secrets from your config file
288
- 2. Create/update `.env` with the secrets
289
- 3. Remove secrets from `dbdock.config.json`
290
- 4. Update `.gitignore` automatically
399
+ Small 1:1 and 1:many relations get embedded. Large 1:many relations stay as separate collections with reference fields. You can override per table.
291
400
 
292
- ### Using .pgpass for PostgreSQL
401
+ ---
293
402
 
294
- For enhanced security, use `.pgpass` instead of environment variables:
403
+ ### Dry run & validation
295
404
 
296
405
  ```bash
297
- # Create the file
298
- touch ~/.pgpass
299
- chmod 600 ~/.pgpass
406
+ npx dbdock migrate --dry-run "mongodb://..." "postgresql://..."
407
+ ```
408
+
409
+ Runs the full migration into a temporary schema, validates counts and referential integrity, then cleans up. Nothing touches the real target:
300
410
 
301
- # Add your connection (format: host:port:database:username:password)
302
- echo "localhost:5432:myapp:postgres:my-secure-password" >> ~/.pgpass
303
411
  ```
412
+ Dry Run Results:
413
+ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
414
+ ✔ users: 45,000 → 45,000
415
+ ✔ addresses: 45,000 → 44,998 (2 failed)
416
+ ✔ orders: 312,400 → 312,400
417
+ ✔ products: 12,000 → 12,000
418
+ ✔ product_tags: 38,200 → 38,200
304
419
 
305
- DBDock will automatically use `.pgpass` when available, which is more secure than `PGPASSWORD` environment variables.
420
+ 2 rows failed (see _migration_errors)
421
+ ✓ All foreign keys valid — dry run passed
422
+ ```
306
423
 
307
- ### Security Features
424
+ ---
308
425
 
309
- - **Automatic credential masking** - All passwords and keys are masked in logs
310
- - **File permission checking** - Warns about insecure config file permissions
311
- - **Encryption at rest** - AES-256-GCM encryption for backups
312
- - **Strict mode** - Optional enforcement of env-only secrets (`DBDOCK_STRICT_MODE=true`)
426
+ ### Incremental / delta migration
313
427
 
314
- 📖 **[Read the full Security Guide](SECURITY.md)** for deployment best practices, compliance guidelines, and incident response procedures.
428
+ Already migrated once but your app is still running on the old database? Sync only new or changed data:
315
429
 
316
- ## Configuration
430
+ ```bash
431
+ npx dbdock migrate --incremental --since "2026-03-10" "mongodb://..." "postgresql://..."
432
+ ```
317
433
 
318
- After running `npx dbdock init`, a `dbdock.config.json` file is created (without sensitive data):
434
+ Uses `createdAt`/`updatedAt` timestamps to only transfer new and changed documents. Existing rows in the target are upserted.
319
435
 
320
- ```json
321
- {
322
- "_comment": "Secrets (passwords, keys) are set via environment variables",
323
- "database": {
324
- "type": "postgres",
325
- "host": "localhost",
326
- "port": 5432,
327
- "username": "postgres",
328
- "database": "myapp"
329
- },
330
- "storage": {
331
- "provider": "s3",
332
- "s3": {
333
- "bucket": "my-backups",
334
- "region": "us-east-1"
335
- }
336
- },
337
- "backup": {
338
- "format": "custom",
339
- "compression": {
340
- "enabled": true,
341
- "level": 6
342
- },
343
- "encryption": {
344
- "enabled": true
345
- },
346
- "retention": {
347
- "enabled": true,
348
- "maxBackups": 100,
349
- "maxAgeDays": 30,
350
- "minBackups": 5,
351
- "runAfterBackup": true
352
- }
353
- },
354
- "alerts": {
355
- "email": {
356
- "enabled": true,
357
- "smtp": {
358
- "host": "smtp.gmail.com",
359
- "port": 587,
360
- "secure": false
361
- },
362
- "from": "backups@yourapp.com",
363
- "to": ["admin@yourapp.com"]
364
- }
365
- }
366
- }
436
+ ---
437
+
438
+ ### Save & reuse config
439
+
440
+ Export the mapping for your team to use reproducibly:
441
+
442
+ ```bash
443
+ npx dbdock migrate --export-config ./migration.yaml "mongodb://..." "postgresql://..."
367
444
  ```
368
445
 
369
- **Note:** SMTP credentials (`user`, `pass`) and storage secrets are set via environment variables for security.
446
+ Then anyone runs the same migration:
447
+
448
+ ```bash
449
+ npx dbdock migrate --config ./migration.yaml "mongodb://..." "postgresql://..."
450
+ ```
451
+
452
+ Tweak the YAML/JSON config to adjust type mappings, embedding strategies, or rename target tables — then re-run.
453
+
454
+ ---
455
+
456
+ ### Migration options
457
+
458
+ | Flag | What it does |
459
+ |---|---|
460
+ | `--dry-run` | Migrate into temp schema, validate, clean up |
461
+ | `--incremental` | Only sync new/changed data |
462
+ | `--since <date>` | Cutoff date for incremental mode (ISO format) |
463
+ | `--config <path>` | Load a saved migration config (YAML or JSON) |
464
+ | `--export-config <path>` | Save migration plan to file without executing |
465
+ | `--batch-size <n>` | Documents per batch (default: 1000) |
466
+ | `--max-depth <n>` | Max nesting depth before storing as jsonb (default: 2) |
467
+
468
+ ### Core principles
469
+
470
+ - **Never lose data** — failed rows go to `_migration_errors`, never silently dropped
471
+ - **Never surprise the user** — full mapping shown before execution, conflicts flagged
472
+ - **Always let you review** — nothing executes without explicit confirmation
473
+ - **Reproducible** — export/import configs for team-wide consistency
474
+
475
+ ---
370
476
 
371
- ### Storage Providers
477
+ ## Storage Providers
372
478
 
373
- **Local:**
479
+ Pick your storage during `dbdock init`, or set it in `dbdock.config.json`:
480
+
481
+ ### Local
374
482
 
375
483
  ```json
376
484
  { "storage": { "provider": "local", "local": { "path": "./backups" } } }
377
485
  ```
378
486
 
379
- **AWS S3:**
487
+ ### AWS S3
380
488
 
381
489
  ```json
382
490
  {
383
491
  "storage": {
384
492
  "provider": "s3",
385
- "s3": {
386
- "bucket": "my-backups",
387
- "region": "us-east-1"
388
- }
493
+ "s3": { "bucket": "my-backups", "region": "us-east-1" }
389
494
  }
390
495
  }
391
496
  ```
392
497
 
393
- Set credentials via environment variables:
394
498
  ```bash
395
499
  DBDOCK_STORAGE_ACCESS_KEY=your-access-key
396
500
  DBDOCK_STORAGE_SECRET_KEY=your-secret-key
397
501
  ```
398
502
 
399
- Required IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
503
+ Needs IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
400
504
 
401
- **Cloudflare R2:**
505
+ ### Cloudflare R2
402
506
 
403
507
  ```json
404
508
  {
@@ -413,32 +517,70 @@ Required IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:D
413
517
  }
414
518
  ```
415
519
 
416
- Set credentials via environment variables (same as S3 above).
520
+ Same env vars as S3 above.
417
521
 
418
- **Cloudinary:**
522
+ ### Cloudinary
419
523
 
420
524
  ```json
421
525
  {
422
526
  "storage": {
423
527
  "provider": "cloudinary",
424
- "cloudinary": {
425
- "cloudName": "your-cloud"
426
- }
528
+ "cloudinary": { "cloudName": "your-cloud" }
427
529
  }
428
530
  }
429
531
  ```
430
532
 
431
- Set credentials via environment variables:
432
533
  ```bash
433
534
  DBDOCK_CLOUDINARY_API_KEY=your-api-key
434
535
  DBDOCK_CLOUDINARY_API_SECRET=your-api-secret
435
536
  ```
436
537
 
437
- All cloud backups stored in `dbdock_backups/` folder with format: `backup-YYYY-MM-DD-HH-MM-SS-BACKUPID.sql`
538
+ ---
539
+
540
+ ## Security
541
+
542
+ DBDock splits your config into two parts by design:
543
+
544
+ | What | Where | Git safe? |
545
+ |------|-------|-----------|
546
+ | Host, port, bucket names, settings | `dbdock.config.json` | Yes |
547
+ | Passwords, API keys, secrets | `.env` | No (auto-gitignored) |
548
+
549
+ ### Environment Variables
550
+
551
+ ```bash
552
+ DBDOCK_DB_PASSWORD=your-database-password # Required
553
+ DBDOCK_STORAGE_ACCESS_KEY=your-access-key # For cloud storage
554
+ DBDOCK_STORAGE_SECRET_KEY=your-secret-key # For cloud storage
555
+ DBDOCK_ENCRYPTION_SECRET=64-char-hex-string # If encryption enabled
556
+ DBDOCK_SMTP_USER=your-email@example.com # For email alerts
557
+ DBDOCK_SMTP_PASS=your-app-password # For email alerts
558
+ DBDOCK_SLACK_WEBHOOK=https://hooks.slack.com/... # For Slack alerts
559
+ ```
560
+
561
+ Reads from both `.env` and `.env.local` (`.env.local` takes priority).
438
562
 
439
- ### Retention Policy
563
+ ### .pgpass Support
440
564
 
441
- Automatic cleanup to prevent storage bloat from frequent backups:
565
+ If you prefer `.pgpass` over env vars for the database password, DBDock detects and uses it automatically:
566
+
567
+ ```bash
568
+ touch ~/.pgpass && chmod 600 ~/.pgpass
569
+ echo "localhost:5432:myapp:postgres:my-secure-password" >> ~/.pgpass
570
+ ```
571
+
572
+ ### What's Built In
573
+
574
+ - AES-256 encryption at rest
575
+ - Automatic credential masking in all logs
576
+ - File permission warnings for insecure configs
577
+ - Strict mode (`DBDOCK_STRICT_MODE=true`) — enforces env-only secrets
578
+
579
+ ---
580
+
581
+ ## Retention Policy
582
+
583
+ Backups pile up fast. Retention handles it automatically:
442
584
 
443
585
  ```json
444
586
  {
@@ -454,449 +596,200 @@ Automatic cleanup to prevent storage bloat from frequent backups:
454
596
  }
455
597
  ```
456
598
 
457
- **How it works:**
599
+ - Keeps at least `minBackups` recent backups (safety net — these never get deleted)
600
+ - Removes anything over `maxBackups` (oldest first)
601
+ - Removes anything older than `maxAgeDays`
602
+ - Runs automatically after each backup if `runAfterBackup` is on
603
+ - Or run manually: `npx dbdock cleanup`
458
604
 
459
- - Keeps most recent `minBackups` (safety net, never deleted)
460
- - Deletes backups exceeding `maxBackups` limit (oldest first)
461
- - Deletes backups older than `maxAgeDays` (respecting minBackups)
462
- - Runs automatically after each backup (if `runAfterBackup: true`)
463
- - Manual cleanup: `npx dbdock cleanup`
605
+ ---
464
606
 
465
- **Safety features:**
607
+ ## Alerts
466
608
 
467
- - Always preserves `minBackups` most recent backups
468
- - Shows preview before deletion
469
- - Detailed logging of what was deleted
470
- - Error handling for failed deletions
609
+ Get notified on Slack or Email when backups succeed or fail. Set it up during `dbdock init` or add to your config:
471
610
 
472
- ## Programmatic Usage
611
+ ```json
612
+ {
613
+ "alerts": {
614
+ "email": {
615
+ "enabled": true,
616
+ "smtp": {
617
+ "host": "smtp.gmail.com",
618
+ "port": 587,
619
+ "secure": false
620
+ },
621
+ "from": "backups@yourapp.com",
622
+ "to": ["admin@yourapp.com"]
623
+ },
624
+ "slack": {
625
+ "enabled": true,
626
+ "webhookUrl": "https://hooks.slack.com/services/..."
627
+ }
628
+ }
629
+ }
630
+ ```
473
631
 
474
- Use DBDock in your Node.js application to create backups programmatically. You don't need to understand NestJS internals - DBDock provides a simple API that works with any Node.js backend.
632
+ SMTP credentials go in env vars (`DBDOCK_SMTP_USER`, `DBDOCK_SMTP_PASS`).
475
633
 
476
- ### Basic Setup
634
+ **Works with:** Gmail, SendGrid, AWS SES, Mailgun — anything that speaks SMTP.
477
635
 
478
- First, install DBDock:
636
+ > For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833), not your regular password.
479
637
 
480
- ```bash
481
- npm install dbdock
482
- ```
638
+ Alerts fire automatically on both CLI and programmatic backups. They include backup ID, database name, size, duration, and storage location. Failure alerts include the error message and troubleshooting tips.
483
639
 
484
- Make sure you have `dbdock.config.json` configured (run `npx dbdock init` first). DBDock reads all configuration from this file automatically.
640
+ ---
485
641
 
486
- ### How It Works
642
+ ## Programmatic Usage
487
643
 
488
- DBDock uses a simple initialization pattern:
644
+ Don't just use the CLI — drop DBDock into your Node.js app and trigger backups from code. Works with any backend (Express, Fastify, NestJS, whatever).
489
645
 
490
- 1. Call `createDBDock()` to initialize DBDock (reads from `dbdock.config.json`)
491
- 2. Get the `BackupService` from the returned context using `.get(BackupService)`
492
- 3. Use the service methods to create backups, list backups, etc.
646
+ ```bash
647
+ npm install dbdock
648
+ ```
493
649
 
494
- Think of `createDBDock()` as a factory function that sets up everything for you based on your config file.
650
+ Make sure `dbdock.config.json` exists (run `npx dbdock init` first).
495
651
 
496
- ### Creating Backups
652
+ ### Create a Backup
497
653
 
498
654
  ```javascript
499
655
  const { createDBDock, BackupService } = require('dbdock');
500
656
 
501
- async function createBackup() {
657
+ async function backup() {
502
658
  const dbdock = await createDBDock();
503
659
  const backupService = dbdock.get(BackupService);
504
660
 
505
661
  const result = await backupService.createBackup({
506
- format: 'plain', // 'custom' (binary), 'plain' (sql), 'directory', 'tar'
662
+ format: 'plain',
507
663
  compress: true,
508
664
  encrypt: true,
509
665
  });
510
666
 
511
- console.log(`Backup created: ${result.metadata.id}`);
512
- console.log(`Size: ${result.metadata.formattedSize}`); // e.g. "108.3 KB"
513
- console.log(`Path: ${result.storageKey}`);
514
-
515
- return result;
667
+ console.log(`Done: ${result.metadata.id} (${result.metadata.formattedSize})`);
516
668
  }
517
669
 
518
- createBackup().catch(console.error);
670
+ backup();
519
671
  ```
520
672
 
521
- **Backup Options:**
673
+ **Options:** `compress`, `encrypt`, `format` (`'custom'` | `'plain'` | `'directory'` | `'tar'`), `type` (`'full'` | `'schema'` | `'data'`)
522
674
 
523
- - `compress` - Enable/disable compression (default: from config)
524
- - `encrypt` - Enable/disable encryption (default: from config)
525
- - `format` - Backup format: `'custom'` (default), `'plain'`, `'directory'`, `'tar'`
526
- - `type` - Backup type: `'full'` (default), `'schema'`, `'data'`
527
-
528
- ### Listing Backups
675
+ ### List Backups
529
676
 
530
677
  ```javascript
531
678
  const { createDBDock, BackupService } = require('dbdock');
532
679
 
533
- async function listBackups() {
680
+ async function list() {
534
681
  const dbdock = await createDBDock();
535
- const backupService = dbdock.get(BackupService);
536
-
537
- const backups = await backupService.listBackups();
538
-
539
- console.log(`Found ${backups.length} backups:`);
540
- backups.forEach(
541
- (backup: {
542
- id: string;
543
- formattedSize: string;
544
- startTime: string | Date;
545
- }) => {
546
- console.log(
547
- `- ${backup.id} (${backup.formattedSize}, created: ${backup.startTime})`
548
- );
549
- }
550
- );
551
-
552
- return backups;
682
+ const backups = await dbdock.get(BackupService).listBackups();
683
+ backups.forEach(b => console.log(`${b.id} — ${b.formattedSize} — ${b.startTime}`));
553
684
  }
554
685
 
555
- listBackups().catch(console.error);
686
+ list();
556
687
  ```
557
688
 
558
- ### Getting Backup Metadata
689
+ ### Get Backup Info
559
690
 
560
691
  ```javascript
561
692
  const { createDBDock, BackupService } = require('dbdock');
562
693
 
563
- async function getBackupInfo(backupId) {
694
+ async function info(id) {
564
695
  const dbdock = await createDBDock();
565
- const backupService = dbdock.get(BackupService);
566
-
567
- const metadata = await backupService.getBackupMetadata(backupId);
568
-
569
- if (!metadata) {
570
- console.log('Backup not found');
571
- return null;
572
- }
573
-
574
- console.log('Backup details:', {
575
- id: metadata.id,
576
- size: metadata.size,
577
- created: metadata.startTime,
578
- encrypted: !!metadata.encryption,
579
- compressed: metadata.compression.enabled,
580
- });
581
-
582
- return metadata;
696
+ const metadata = await dbdock.get(BackupService).getBackupMetadata(id);
697
+ if (!metadata) return console.log('Not found');
698
+ console.log({ id: metadata.id, size: metadata.size, encrypted: !!metadata.encryption });
583
699
  }
584
700
 
585
- getBackupInfo('your-backup-id').catch(console.error);
701
+ info('your-backup-id');
586
702
  ```
587
703
 
588
- **Note:** Restore functionality is currently only available via CLI (`npx dbdock restore`). Programmatic restore will be available in a future release.
704
+ Restore is CLI-only for now (`npx dbdock restore`). Programmatic restore is coming.
589
705
 
590
- ### Scheduling Backups
706
+ ### Schedule Backups with node-cron
591
707
 
592
- DBDock doesn't include a built-in scheduler (to keep the package lightweight), but it's easy to schedule backups using `node-cron`.
593
-
594
- First, install `node-cron`:
708
+ DBDock stays lightweight no built-in daemon. Use `node-cron` to schedule:
595
709
 
596
710
  ```bash
597
711
  npm install node-cron
598
- npm install --save-dev @types/node-cron
599
712
  ```
600
713
 
601
- Then create a scheduler script (e.g., `scheduler.ts`):
602
-
603
714
  ```typescript
604
715
  import { createDBDock, BackupService } from 'dbdock';
605
716
  import * as cron from 'node-cron';
606
717
 
607
- async function startScheduler() {
608
- // Initialize DBDock
718
+ async function start() {
609
719
  const dbdock = await createDBDock();
610
720
  const backupService = dbdock.get(BackupService);
611
721
 
612
- console.log('🚀 Backup scheduler started. Running every minute...');
613
-
614
- // Schedule task to run every minute ('* * * * *')
615
- // For every 5 minutes use: '*/5 * * * *'
616
- // For every hour use: '0 * * * *'
617
- cron.schedule('* * * * *', async () => {
618
- try {
619
- console.log('\n⏳ Starting scheduled backup...');
620
-
621
- const result = await backupService.createBackup({
622
- format: 'plain', // Use 'plain' for SQL text, 'custom' for binary
623
- compress: true,
624
- encrypt: true,
625
- });
626
-
627
- console.log(`✅ Backup successful: ${result.metadata.id}`);
628
- console.log(`📦 Size: ${result.metadata.formattedSize}`);
629
- console.log(`📂 Path: ${result.storageKey}`);
630
- } catch (error) {
631
- console.error('❌ Backup failed:', error);
632
- }
722
+ cron.schedule('0 2 * * *', async () => {
723
+ const result = await backupService.createBackup({ compress: true, encrypt: true });
724
+ console.log(`Backup done: ${result.metadata.id}`);
633
725
  });
726
+
727
+ console.log('Scheduler running — daily at 2 AM');
634
728
  }
635
729
 
636
- startScheduler().catch(console.error);
730
+ start();
637
731
  ```
638
732
 
639
- **Note:** The CLI `dbdock schedule` command manages configuration for external schedulers but does not run a daemon itself. Using `node-cron` as shown above is the recommended way to run scheduled backups programmatically.
733
+ ---
640
734
 
641
- ### Alerts
642
-
643
- DBDock can send notifications when backups complete (success or failure) via Email and Slack. Alerts work with both **programmatic usage** and **CLI commands**.
644
-
645
- **Configuration in `dbdock.config.json`:**
646
-
647
- ```json
648
- {
649
- "database": { ... },
650
- "storage": { ... },
651
- "backup": { ... },
652
- "alerts": {
653
- "email": {
654
- "enabled": true,
655
- "smtp": {
656
- "host": "smtp.gmail.com",
657
- "port": 587,
658
- "secure": false,
659
- "auth": {
660
- "user": "your-email@gmail.com",
661
- "pass": "your-app-password"
662
- }
663
- },
664
- "from": "backups@yourapp.com",
665
- "to": ["admin@yourapp.com", "devops@yourapp.com"]
666
- },
667
- "slack": {
668
- "enabled": true,
669
- "webhookUrl": "https://hooks.slack.com/services/..."
670
- }
671
- }
672
- }
673
- ```
674
-
675
- **Slack Configuration:**
676
-
677
- 1. Create a Slack App or use an existing one.
678
- 2. Enable "Incoming Webhooks".
679
- 3. Create a new Webhook URL for your channel.
680
- 4. Run `npx dbdock init` and paste the URL when prompted.
681
-
682
- **SMTP Provider Examples:**
683
-
684
- _Gmail:_
685
- ```json
686
- {
687
- "smtp": {
688
- "host": "smtp.gmail.com",
689
- "port": 587,
690
- "secure": false,
691
- "auth": {
692
- "user": "your-email@gmail.com",
693
- "pass": "your-app-password"
694
- }
695
- }
696
- }
697
- ```
698
-
699
- > **Note:** For Gmail, you need to [create an App Password](https://support.google.com/accounts/answer/185833) instead of using your regular password.
700
-
701
- _SendGrid:_
702
- ```json
703
- {
704
- "smtp": {
705
- "host": "smtp.sendgrid.net",
706
- "port": 587,
707
- "secure": false,
708
- "auth": {
709
- "user": "apikey",
710
- "pass": "YOUR_SENDGRID_API_KEY"
711
- }
712
- }
713
- }
714
- ```
715
-
716
- _AWS SES:_
717
- ```json
718
- {
719
- "smtp": {
720
- "host": "email-smtp.us-east-1.amazonaws.com",
721
- "port": 587,
722
- "secure": false,
723
- "auth": {
724
- "user": "YOUR_SMTP_USERNAME",
725
- "pass": "YOUR_SMTP_PASSWORD"
726
- }
727
- }
728
- }
729
- ```
730
-
731
- _Mailgun:_
732
- ```json
733
- {
734
- "smtp": {
735
- "host": "smtp.mailgun.org",
736
- "port": 587,
737
- "secure": false,
738
- "auth": {
739
- "user": "postmaster@your-domain.mailgun.org",
740
- "pass": "YOUR_MAILGUN_SMTP_PASSWORD"
741
- }
742
- }
743
- }
744
- ```
745
-
746
- **Using Alerts Programmatically:**
747
-
748
- Once configured in `dbdock.config.json`, alerts are sent automatically when you create backups programmatically:
749
-
750
- ```javascript
751
- const { createDBDock, BackupService } = require('dbdock');
752
-
753
- async function createBackupWithAlerts() {
754
- const dbdock = await createDBDock();
755
- const backupService = dbdock.get(BackupService);
756
-
757
- // Alerts will be sent automatically after backup completes
758
- const result = await backupService.createBackup({
759
- compress: true,
760
- encrypt: true,
761
- });
762
-
763
- console.log(`Backup created: ${result.metadata.id}`);
764
- // Alerts sent to configured channels
765
- }
766
-
767
- createBackupWithAlerts().catch(console.error);
768
- ```
769
-
770
- **Alert Content:**
771
-
772
- Success alerts include:
773
- - Backup ID
774
- - Database name
775
- - Size (original and compressed)
776
- - Duration
777
- - Storage location
778
- - Encryption status
779
-
780
- Failure alerts include:
781
- - Error message
782
- - Database details
783
- - Timestamp
784
- - Helpful troubleshooting tips
785
-
786
- **Testing Alert Configuration:**
787
-
788
- Run `npx dbdock test` to validate your configuration without creating a backup.
789
-
790
- **Important Notes:**
791
-
792
- - ✅ Alerts work with programmatic usage (`createBackup()`)
793
- - ✅ Alerts work with scheduled backups (cron jobs in your app)
794
- - ✅ Alerts work with CLI commands (`npx dbdock backup`)
795
- - Configuration is read from `dbdock.config.json` automatically
796
- - Multiple recipients supported in the `to` array for email
797
- - Alerts are sent asynchronously (won't block backup completion)
798
-
799
- ## Requirements
800
-
801
- - Node.js 18 or higher
802
- - PostgreSQL 12+
803
- - PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`)
804
-
805
- **Installing PostgreSQL client tools:**
806
-
807
- ```bash
808
- # macOS
809
- brew install postgresql
735
+ ## Troubleshooting
810
736
 
811
- # Ubuntu/Debian
812
- sudo apt-get install postgresql-client
737
+ **First step, always:**
813
738
 
814
- # Windows
815
- # Download from https://www.postgresql.org/download/windows/
739
+ ```bash
740
+ npx dbdock test
816
741
  ```
817
742
 
818
- ## Troubleshooting
819
-
820
- Run `npx dbdock test` to verify your configuration.
743
+ This tests your database, storage, and alert config in one go.
821
744
 
822
- ### Common Issues
745
+ ### pg_dump / pg_restore / psql not found
823
746
 
824
- **pg_dump not found:**
747
+ You need PostgreSQL client tools installed:
825
748
 
826
749
  ```bash
827
- # macOS
828
- brew install postgresql
829
-
830
- # Ubuntu/Debian
831
- sudo apt-get install postgresql-client
750
+ brew install postgresql # macOS
751
+ sudo apt-get install postgresql-client # Ubuntu/Debian
832
752
  ```
833
753
 
834
- **Database connection errors:**
835
-
836
- - Verify `host`, `port`, `username`, `password`, `database` in config
837
- - Test connection: `psql -h HOST -p PORT -U USERNAME -d DATABASE`
838
- - Check PostgreSQL server is running
839
- - Verify network/firewall allows connection
754
+ ### Can't connect to database
840
755
 
841
- **Storage errors:**
756
+ - Double-check `host`, `port`, `username`, `password`, `database` in config
757
+ - Test manually: `psql -h HOST -p PORT -U USERNAME -d DATABASE`
758
+ - Make sure the PostgreSQL server is actually running
759
+ - Check firewalls / security groups if it's a remote database
842
760
 
843
- _AWS S3:_
761
+ ### Storage errors
844
762
 
845
- - Verify credentials are correct
846
- - Ensure IAM user has permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
847
- - Check bucket name and region
763
+ **S3:** Check credentials, bucket name, region. IAM user needs `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`.
848
764
 
849
- _Cloudflare R2:_
765
+ **R2:** Check endpoint format (`https://ACCOUNT_ID.r2.cloudflarestorage.com`), verify API token and bucket exist.
850
766
 
851
- - Verify API token is correct
852
- - Check endpoint URL format: `https://ACCOUNT_ID.r2.cloudflarestorage.com`
853
- - Ensure bucket exists and is accessible
854
- - Verify R2 credentials have read/write permissions
767
+ **Cloudinary:** Verify cloud name, API key, API secret. Make sure the account is active.
855
768
 
856
- _Cloudinary:_
769
+ ### Encryption key issues
857
770
 
858
- - Verify cloud name, API key, and secret are correct
859
- - Check your Cloudinary account is active
860
- - Ensure API credentials have media library access
861
-
862
- **Encryption key errors:**
771
+ Key must be exactly 64 hex characters. Generate a valid one:
863
772
 
864
773
  ```bash
865
- # Generate a valid 64-character hex key
866
774
  node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
867
-
868
- # Must be exactly 64 hexadecimal characters (0-9, a-f, A-F)
869
775
  ```
870
776
 
871
- **R2 restore not working:**
872
-
873
- - Ensure backups are in `dbdock_backups/` folder
874
- - Verify backup files are named with `.sql` extension
875
- - Check endpoint configuration matches R2 account ID
876
-
877
- **No backups found:**
878
-
879
- - Local: Check files exist in configured path
880
- - S3/R2: Verify files are in `dbdock_backups/` folder
881
- - Cloudinary: Check Media Library for `dbdock_backups` folder
882
- - Ensure files match pattern: `backup-*.sql`
883
-
884
- DBDock shows clear, actionable error messages for all issues with specific troubleshooting steps.
885
-
886
- ## Documentation
887
-
888
- 📚 **[Full Documentation](https://dbdock.mintlify.app)** - Comprehensive guides, API reference, and examples
777
+ ### No backups found during restore
889
778
 
890
- ## Support
779
+ - **Local:** Check the configured path has files
780
+ - **S3/R2:** Files should be in `dbdock_backups/` folder
781
+ - **Cloudinary:** Check Media Library for `dbdock_backups` folder
782
+ - Files should match: `backup-*.sql`
891
783
 
892
- - 💬 **[Discussions](https://github.com/naheemolaide/dbdock-support/discussions)** - Ask questions and share ideas
893
- - 🐛 **[Issues](https://github.com/naheemolaide/dbdock-support/issues)** - Report bugs and request features
784
+ ---
894
785
 
895
786
  ## Links
896
787
 
897
- - 📦 **[npm Package](https://www.npmjs.com/package/dbdock)**
898
- - 📖 **[Documentation](https://dbdock.mintlify.app)**
899
- - 💻 **[GitHub Repository](https://github.com/naheemolaide/dbdock-support)**
788
+ - [npm Package](https://www.npmjs.com/package/dbdock)
789
+ - [Full Documentation](https://dbdock.mintlify.app)
790
+ - [GitHub](https://github.com/naheemolaide/dbdock-support)
791
+ - [Discussions](https://github.com/naheemolaide/dbdock-support/discussions)
792
+ - [Report Issues](https://github.com/naheemolaide/dbdock-support/issues)
900
793
 
901
794
  ## License
902
795