@carllee1983/dbcli 0.5.0-beta → 1.1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,138 @@ All notable changes to dbcli are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] - 2026-03-30
9
+
10
+ ### Changed
11
+
12
+ - **Adapter `execute()` 回傳型別重構**: 從 `T[]` 改為 `ExecutionResult<T>`,包含 `rows`、`affectedRows`、`lastInsertId` 欄位,DML 操作(INSERT/UPDATE/DELETE)現在回傳正確的 affected rows 計數
13
+ - **Export 覆寫確認**: `export --output` 寫入已存在檔案時會提示確認,可用 `--force` 跳過
14
+ - **`ExecutionResult<T>` 介面**: 新增統一的查詢結果型別定義於 `src/adapters/types.ts`
15
+
16
+ ---
17
+
18
+ ## [1.0.0] - 2026-03-28
19
+
20
+ ### Stable Release
21
+
22
+ dbcli v1.0.0 is the first stable release. All three milestones are complete:
23
+ - **M1 (v0.6.0):** Smart REPL — interactive shell with SQL + dbcli commands
24
+ - **M2 (v0.8.0):** Schema DDL — CREATE/DROP/ALTER TABLE, INDEX, CONSTRAINT, ENUM
25
+ - **M3 (v1.0.0):** Stabilization — documentation, permission matrix, known limitations update
26
+
27
+ ### Added
28
+
29
+ - **`dbcli migrate` command group** (12 subcommands): Full DDL operations with cross-database support
30
+ - `migrate create <table>` — CREATE TABLE with `--column` spec format (`"id:serial:pk"`)
31
+ - `migrate drop <table>` — DROP TABLE with double confirmation (`--execute --force`)
32
+ - `migrate add-column` / `drop-column` / `alter-column` — Column management
33
+ - `migrate add-index` / `drop-index` — Index management (MySQL `--table` option for DROP)
34
+ - `migrate add-constraint` / `drop-constraint` — FK, UNIQUE, CHECK constraints
35
+ - `migrate add-enum` / `alter-enum` / `drop-enum` — PostgreSQL native ENUM support
36
+ - **DDLGenerator interface** with PostgreSQL and MySQL/MariaDB dialect implementations
37
+ - PostgreSQL: SERIAL, native ENUM types, ALTER COLUMN TYPE, double-quote identifiers
38
+ - MySQL: AUTO_INCREMENT, inline ENUM, MODIFY COLUMN, backtick identifiers
39
+ - **DDLExecutor**: Unified execution pipeline — admin permission check → blacklist protection → SQL generation → dry-run/execute → schema cache auto-refresh
40
+ - **Default dry-run for DDL**: All `migrate` commands preview SQL without `--execute`. Destructive operations also require `--force`
41
+ - **142 new tests**: column-parser (17), PG DDL (35), MySQL DDL (25), factory (5), DDL executor (22), schema cache DDL (6), CLI migrate (26), live-db migrate lifecycle (6)
42
+
43
+ ### Fixed
44
+
45
+ - **Schema comment encoding**: Fixed double-encoded UTF-8 comments from MySQL/MariaDB `information_schema` (e.g., `帳號` → `帳號`)
46
+ - **MySQL connection charset**: Added `charset: utf8mb4` and `SET NAMES utf8mb4`
47
+ - **DDL multi-line SQL execution**: Fixed statement splitting to use `;\n` instead of `\n`
48
+ - **MySQL DROP INDEX**: Added `--table` option (MariaDB requires `ON <table>`)
49
+
50
+ ### Changed
51
+
52
+ - **Permission model**: 4 levels — query-only, read-write, data-admin, admin (DDL requires admin)
53
+ - **Known Limitations**: Removed "Read-only schema" and "CLI-only" (both resolved). Added "No migration version tracking" as post-v1.0 item
54
+ - **Test infrastructure**: `docker-compose.test.yml` for MySQL 8 + PostgreSQL 16 integration testing
55
+ - **Package scripts**: Added `test:unit`, `test:integration`, `test:docker`
56
+ - **SKILL.md**: Updated with full `migrate` command reference and AI agent guidelines
57
+
58
+ ### Test Results (v1.0.0)
59
+
60
+ - Unit/Core: 1082 pass, 0 fail
61
+ - Live DB (MariaDB 10.11): 61 pass
62
+ - Docker Adapter (MySQL 8 + PG 16): 18 pass
63
+
64
+ ---
65
+
66
+ ## [0.6.1-beta] - 2026-03-28
67
+
68
+ ### Encoding Fix & Test Infrastructure
69
+
70
+ ### Fixed
71
+
72
+ - **Schema comment encoding**: Fixed double-encoded UTF-8 comments from MySQL/MariaDB `information_schema`. Comments stored through latin1 (cp1252) connections now correctly display CJK characters (e.g., `帳號` → `帳號`)
73
+ - **MySQL connection charset**: Added `charset: utf8mb4` and `SET NAMES utf8mb4` to MySQL adapter connections
74
+
75
+ ### Added
76
+
77
+ - **`fixDoubleEncodedUtf8()` utility** (`src/utils/encoding.ts`): Detects and reverses cp1252-to-UTF-8 double encoding with full cp1252 reverse mapping table. Applied to schema comments in both MySQL and PostgreSQL adapters
78
+ - **`docker-compose.test.yml`**: MySQL 8.4 (port 3307) + PostgreSQL 16 (port 5433) for integration testing, with health checks and tmpfs for fast ephemeral storage
79
+ - **Environment-driven adapter tests**: `mysql.test.ts` and `postgresql.test.ts` now read connection from `MYSQL_*` / `PG_*` env vars, falling back to docker-compose defaults. Auto-skip when DB is unreachable
80
+ - **`live-db.test.ts`**: 55 comprehensive CLI-level integration tests covering all commands against live MariaDB — list, schema, query, blacklist CRUD, insert/update/delete lifecycle, export, check, diff, status, doctor, shell, format validation, SQL injection protection
81
+ - **New test scripts**: `test:unit`, `test:integration`, `test:docker` in package.json
82
+
83
+ ### Test Results
84
+
85
+ - Unit/Core: 940 pass
86
+ - Live DB (MariaDB 10.11): 55 pass
87
+ - Adapter (Docker MySQL 8 + PG 16): 18 pass
88
+
89
+ ---
90
+
91
+ ## [0.6.0-beta] - 2026-03-28
92
+
93
+ ### Interactive Shell — Smart REPL
94
+
95
+ ### Added
96
+
97
+ - **`dbcli shell` command:** Interactive database shell with SQL execution and dbcli command dispatch
98
+ - **SQL-only mode:** `--sql` flag restricts to SQL statements only
99
+ - **Auto-completion (Tab):** Context-aware completion for SQL keywords, table names, column names, and dbcli commands
100
+ - **Multi-line SQL:** Accumulates input until `;` is found, with `...>` continuation prompt
101
+ - **SQL syntax highlighting:** Real-time colorization of keywords, strings, and numbers in verbose mode
102
+ - **Meta commands:** `.help`, `.quit`/`.exit`, `.clear`, `.format`, `.history`, `.timing`
103
+ - **Persistent history:** Stored in `~/.dbcli_history` (max 1000 entries), with up/down navigation and Ctrl+R search
104
+ - **Permission & blacklist integration:** Full enforcement within REPL session — SQL goes through PermissionGuard, query results go through blacklist filtering
105
+ - **Auto-reconnect:** Attempts to reconnect once on connection errors, then displays error without crashing the session
106
+ - **Error resilience:** SQL/permission/connection errors never crash the session
107
+ - **i18n support:** All shell messages available in English and Traditional Chinese
108
+ - **102 new tests:** input-classifier (25), multiline-buffer (10), meta-commands (15), completer (17), history-manager (8), command-dispatcher (12), repl-engine (12), shell-command (3)
109
+
110
+ ---
111
+
112
+ ## [0.5.2-beta] - 2026-03-27
113
+
114
+ ### Fixed
115
+
116
+ - **`init --use-env-refs` permission bug**: Interactive env-ref mode now correctly offers all 4 permission levels (was missing `data-admin`)
117
+ - **`init` i18n completeness**: All 10 hardcoded English messages replaced with i18n keys (supports en/zh-TW)
118
+ - **`init` duplicate code**: Extracted shared `.dbcli exists` overwrite check into `checkOverwrite()` helper
119
+ - **`--use-env-refs` help text**: Improved option description to clarify CI/CD and multi-env use case
120
+ - **Documentation**: Added `--use-env-refs` to README (en/zh-TW), CHANGELOG, and SKILL.md with AI agent guidance
121
+
122
+ ---
123
+
124
+ ## [0.5.1-beta] - 2026-03-27
125
+
126
+ ### Added
127
+
128
+ - **Database version check**: Warns on stderr when connected database version is below minimum supported (PostgreSQL 12+, MySQL 8.0+, MariaDB 10.5+). Non-blocking — connection proceeds normally.
129
+ - **`dbcli doctor` DB version check**: New "Database version" item in Connection & Data group.
130
+ - **`dbcli init --use-env-refs`**: Store environment variable references (`{"$env": "DB_HOST"}`) in config instead of actual values. Supports interactive and non-interactive modes with `--env-host`, `--env-port`, `--env-user`, `--env-password`, `--env-database` options. Suitable for CI/CD and multi-environment deployments.
131
+
132
+ ### Fixed
133
+
134
+ - **`init` permission bug**: Interactive env-ref mode now correctly offers all 4 permission levels (was missing `data-admin`)
135
+ - **`init` i18n**: All hardcoded English messages in init command replaced with i18n keys (10 messages)
136
+ - **`init` duplicate code**: Extracted shared `.dbcli exists` overwrite check into `checkOverwrite()` helper
137
+
138
+ ---
139
+
8
140
  ## [0.5.0-beta] - 2026-03-27
9
141
 
10
142
  ### UX & Developer Experience — Colors, Logging, Diagnostics, and Tooling
@@ -236,12 +368,11 @@ dbcli v0.1.0-beta is a complete, production-ready CLI tool enabling AI agents an
236
368
 
237
369
  ---
238
370
 
239
- ## Known Limitations (V1)
371
+ ## Known Limitations
240
372
 
241
- - **Single database per project:** Multi-connection support deferred to a future version
242
- - **No audit logging:** WHO/WHAT/WHEN tracking deferred to a future version
243
- - **Read-only schema:** No schema modification commands (ALTER TABLE, etc.) in V1
244
- - **CLI-only:** No visual schema designer, REPL, or interactive shell in V1
373
+ - **Single database per project:** Each directory uses one `.dbcli` config. For multi-database setups, use separate directories or `--config` flag. This is by design, not a technical limitation.
374
+ - **No audit logging:** WHO/WHAT/WHEN tracking deferred to post-v1.0
375
+ - **No migration version tracking:** `migrate` commands execute DDL directly without version history or rollback. The `migrate` namespace is reserved for future migration tracking support.
245
376
 
246
377
  ---
247
378
 
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carl Lee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -96,9 +96,27 @@ Initialize a new dbcli project with database connection configuration.
96
96
 
97
97
  **Usage:**
98
98
  ```bash
99
- dbcli init
99
+ dbcli init [OPTIONS]
100
100
  ```
101
101
 
102
+ **Options:**
103
+ - `--system <type>` — Database system: `postgresql`, `mysql`, `mariadb`
104
+ - `--host <host>` — Database host
105
+ - `--port <port>` — Database port
106
+ - `--user <user>` — Database user
107
+ - `--password <pass>` — Database password
108
+ - `--name <db>` — Database name
109
+ - `--permission <level>` — Permission level: `query-only`, `read-write`, `data-admin`, `admin`
110
+ - `--use-env-refs` — Store environment variable references instead of actual values in config
111
+ - `--env-host <var>` — Env var name for host (with `--use-env-refs`)
112
+ - `--env-port <var>` — Env var name for port (with `--use-env-refs`)
113
+ - `--env-user <var>` — Env var name for user (with `--use-env-refs`)
114
+ - `--env-password <var>` — Env var name for password (with `--use-env-refs`)
115
+ - `--env-database <var>` — Env var name for database (with `--use-env-refs`)
116
+ - `--skip-test` — Skip connection test
117
+ - `--no-interactive` — Non-interactive mode (requires all options)
118
+ - `--force` — Overwrite existing config without confirmation
119
+
102
120
  **Behavior:**
103
121
  - Reads `.env` file if present (auto-fills DATABASE_URL, DB_* variables)
104
122
  - Prompts for missing values (host, port, user, password, database name, permission level)
@@ -116,8 +134,20 @@ dbcli init
116
134
 
117
135
  # Specify permission level
118
136
  echo "PERMISSION_LEVEL=admin" >> .env && dbcli init
137
+
138
+ # Store env var references instead of values (interactive)
139
+ dbcli init --use-env-refs
140
+
141
+ # Store env var references (non-interactive)
142
+ dbcli init --use-env-refs --system mysql \
143
+ --env-host DB_HOST --env-port DB_PORT \
144
+ --env-user DB_USER --env-password DB_PASSWORD \
145
+ --env-database DB_DATABASE \
146
+ --no-interactive
119
147
  ```
120
148
 
149
+ > **`--use-env-refs`:** When enabled, the config stores environment variable names (e.g., `{"$env": "DB_HOST"}`) instead of actual values. This avoids writing sensitive credentials into the config file, making it suitable for multi-environment deployments and CI/CD pipelines. At connection time, dbcli automatically reads the actual values from the referenced environment variables.
150
+
121
151
  ---
122
152
 
123
153
  #### `dbcli list`
@@ -489,6 +519,72 @@ dbcli upgrade --check # Only check, do not upgrade
489
519
  **Options:** `--check` — check only, don't install
490
520
  **Background check:** dbcli silently checks npm registry once per 24 hours. If a newer version is found, a hint is shown after command output.
491
521
 
522
+ #### `dbcli shell`
523
+
524
+ Interactive database shell with SQL execution, auto-completion, and syntax highlighting.
525
+
526
+ **Usage:**
527
+ ```bash
528
+ dbcli shell # Interactive mode (SQL + dbcli commands)
529
+ dbcli shell --sql # SQL-only mode
530
+ ```
531
+
532
+ **Inside the shell:**
533
+ - Type SQL statements ending with `;` to execute queries
534
+ - Type dbcli commands without the `dbcli` prefix (e.g., `schema users`, `list`)
535
+ - Press Tab for context-aware auto-completion (SQL keywords, table/column names)
536
+ - Use `.help` for meta commands (`.quit`, `.clear`, `.format`, `.history`, `.timing`)
537
+ - Multi-line SQL: input accumulates until `;` is found
538
+ - History persists across sessions in `~/.dbcli_history`
539
+
540
+ **Permission:** Inherits from config. SQL and commands are fully permission/blacklist enforced.
541
+
542
+ #### `dbcli migrate`
543
+
544
+ Schema DDL operations. **All commands default to dry-run** — use `--execute` to actually run the SQL.
545
+
546
+ **Usage:**
547
+ ```bash
548
+ # Create table
549
+ dbcli migrate create posts \
550
+ --column "id:serial:pk" \
551
+ --column "title:varchar(200):not-null" \
552
+ --column "body:text" \
553
+ --column "created_at:timestamp:default=now()"
554
+
555
+ # Execute (actually run the SQL)
556
+ dbcli migrate create posts --column "id:serial:pk" --execute
557
+
558
+ # Drop table (destructive — requires --execute --force)
559
+ dbcli migrate drop posts --execute --force
560
+
561
+ # Column operations
562
+ dbcli migrate add-column users bio text --nullable --execute
563
+ dbcli migrate alter-column users name --type "varchar(200)" --execute
564
+ dbcli migrate alter-column users email --rename user_email --execute
565
+ dbcli migrate drop-column users temp_field --execute --force
566
+
567
+ # Index operations
568
+ dbcli migrate add-index users --columns email --unique --execute
569
+ dbcli migrate drop-index idx_users_email --table users --execute --force
570
+
571
+ # Constraint operations
572
+ dbcli migrate add-constraint orders --fk user_id --references users.id --on-delete cascade --execute
573
+ dbcli migrate add-constraint users --unique email --execute
574
+ dbcli migrate add-constraint users --check "age >= 0" --execute
575
+ dbcli migrate drop-constraint orders fk_orders_user_id --execute --force
576
+
577
+ # Enum (PostgreSQL only)
578
+ dbcli migrate add-enum status active inactive suspended --execute
579
+ dbcli migrate alter-enum status --add-value archived --execute
580
+ dbcli migrate drop-enum status --execute --force
581
+ ```
582
+
583
+ **Column spec format:** `name:type[:modifier...]` — Modifiers: `pk`, `not-null`, `unique`, `auto-increment`, `default=<value>`, `references=<table>.<column>`
584
+
585
+ **Options (all subcommands):** `--execute` (run SQL), `--force` (skip confirmation for DROP), `--config <path>`
586
+ **Permission:** admin only
587
+
492
588
  ---
493
589
 
494
590
  ## Global Options
@@ -512,9 +608,10 @@ dbcli implements a coarse-grained permission system with three levels. Permissio
512
608
 
513
609
  | Level | Allowed Commands | Blocked Commands | Use Case |
514
610
  |-------|------------------|------------------|----------|
515
- | **Query-only** | `init`, `list`, `schema`, `query`, `export` (limited to 1000 rows) | `insert`, `update`, `delete` | Read-only AI agents, data analysts, reporting |
516
- | **Read-Write** | + `insert`, `update` | `delete` | Application developers, content managers |
517
- | **Admin** | All commands | | Database administrators, schema modifications |
611
+ | **Query-only** | `init`, `list`, `schema`, `query`, `export` (limited to 1000 rows) | `insert`, `update`, `delete`, `migrate` | Read-only AI agents, data analysts, reporting |
612
+ | **Read-Write** | + `insert`, `update` | `delete`, `migrate` | Application developers, content managers |
613
+ | **Data-Admin** | + `delete` | `migrate` | Full DML access, no DDL |
614
+ | **Admin** | All commands including `migrate` (DDL) | — | Database administrators, schema modifications |
518
615
 
519
616
  ### Configuration
520
617
 
@@ -553,11 +650,12 @@ dbcli delete users --where "id=1" # ERROR: Admin only
553
650
 
554
651
  #### Admin Mode (Database Administrator)
555
652
  ```bash
556
- # Allowed: Everything
653
+ # Allowed: Everything including DDL
557
654
  dbcli query "SELECT * FROM users"
558
655
  dbcli insert users --data '{"name": "Eve"}'
559
656
  dbcli update users --where "id=1" --set '{"status": "active"}'
560
- dbcli delete users --where "id=1" --force # Only Admin can delete
657
+ dbcli delete users --where "id=1" --force # Data-Admin+ can delete
658
+ dbcli migrate create posts --column "id:serial:pk" --execute # Admin only
561
659
  ```
562
660
 
563
661
  ### Best Practices
package/README.zh-TW.md CHANGED
@@ -238,8 +238,19 @@ dbcli init
238
238
 
239
239
  dbcli init --host db.example.com --port 5432 --user admin --password secret --name prod_db --system postgresql
240
240
  # 非交互式初始化
241
+
242
+ dbcli init --use-env-refs
243
+ # 交互式:提示輸入環境變數名稱,config 中儲存 {"$env": "DB_HOST"} 而非實際值
244
+
245
+ dbcli init --use-env-refs --system mysql \
246
+ --env-host DB_HOST --env-port DB_PORT \
247
+ --env-user DB_USER --env-password DB_PASSWORD \
248
+ --env-database DB_DATABASE --no-interactive
249
+ # 非交互式環境變數參照模式,適合 CI/CD
241
250
  ```
242
251
 
252
+ > **`--use-env-refs` 說明:** 使用此選項時,config 中儲存的是環境變數名稱(如 `{"$env": "DB_HOST"}`)而非實際值。這樣可以避免將敏感資訊寫入 config 檔案,適合多環境部署或 CI/CD 場景。連線時 dbcli 會自動從環境變數讀取實際值。
253
+
243
254
  ### 列出表
244
255
 
245
256
  ```bash
package/assets/SKILL.md CHANGED
@@ -30,6 +30,8 @@ dbcli init --no-interactive --force # Non-interactive, skip overwrite confirmati
30
30
 
31
31
  **Key options:** `--system <postgresql|mysql|mariadb>`, `--permission <query-only|read-write|data-admin|admin>`, `--use-env-refs`, `--skip-test`, `--no-interactive`, `--force`
32
32
 
33
+ > **AI agent note on `--use-env-refs`:** If an existing `.dbcli` config contains `{"$env": "DB_HOST"}` style references, the connection values are read from environment variables at runtime. Do NOT re-run `init` to replace these references with actual values — the env-ref format is intentional for CI/CD and multi-environment setups.
34
+
33
35
  ### list
34
36
 
35
37
  List all tables.
@@ -114,10 +116,11 @@ Export query results to file or stdout.
114
116
 
115
117
  ```bash
116
118
  dbcli export "SELECT * FROM users" --format csv --output users.csv
119
+ dbcli export "SELECT * FROM users" --format csv --output users.csv --force # Skip overwrite confirmation
117
120
  dbcli export "SELECT * FROM users" --format json | jq '.[]'
118
121
  ```
119
122
 
120
- **Options:** `--format <json|csv>` (required), `--output <path>`
123
+ **Options:** `--format <json|csv>` (required), `--output <path>`, `--force`
121
124
  **Permission:** query-only+
122
125
 
123
126
  ### blacklist
@@ -220,6 +223,75 @@ dbcli upgrade --check # Only check, do not upgrade
220
223
 
221
224
  **Background check:** Every command silently checks the npm registry for a newer version (at most once per 24 hours, cached in `.dbcli/version-check.json`). If a newer version is found, a one-line hint is printed to stderr after the command completes. Pass `-q` / `--quiet` to suppress the hint.
222
225
 
226
+ ### `dbcli shell`
227
+
228
+ Start an interactive database shell.
229
+
230
+ ```bash
231
+ dbcli shell # Interactive mode with SQL + dbcli commands
232
+ dbcli shell --sql # SQL-only mode
233
+ ```
234
+
235
+ Inside the shell:
236
+ - Type SQL statements ending with `;` to execute
237
+ - Type dbcli commands without the `dbcli` prefix (e.g., `schema users`)
238
+ - Use Tab for auto-completion (SQL keywords, table names, column names)
239
+ - Type `.help` for meta commands (.quit, .clear, .format, .history, .timing)
240
+ - Multi-line SQL: keeps accumulating until `;` is found
241
+ - History persists across sessions (~/.dbcli_history)
242
+
243
+ ### migrate
244
+
245
+ Schema DDL operations. **All commands default to dry-run** — use `--execute` to actually run the SQL. Destructive operations (DROP) also require `--force`.
246
+
247
+ ```bash
248
+ # Create table
249
+ dbcli migrate create posts \
250
+ --column "id:serial:pk" \
251
+ --column "title:varchar(200):not-null" \
252
+ --column "body:text" \
253
+ --column "created_at:timestamp:default=now()"
254
+
255
+ # Drop table (dry-run by default)
256
+ dbcli migrate drop posts
257
+ dbcli migrate drop posts --execute --force # Actually drop
258
+
259
+ # Add/drop/alter column
260
+ dbcli migrate add-column users bio text --nullable
261
+ dbcli migrate drop-column users temp_field --execute --force
262
+ dbcli migrate alter-column users name --type "varchar(200)"
263
+ dbcli migrate alter-column users email --rename user_email
264
+ dbcli migrate alter-column users status --set-default "'active'"
265
+ dbcli migrate alter-column users bio --drop-default
266
+ dbcli migrate alter-column users bio --set-nullable
267
+ dbcli migrate alter-column users email --drop-nullable
268
+
269
+ # Index management
270
+ dbcli migrate add-index users --columns email --unique
271
+ dbcli migrate add-index users --columns "last_name,first_name" --name idx_fullname
272
+ dbcli migrate drop-index idx_fullname --execute --force
273
+
274
+ # Constraint management
275
+ dbcli migrate add-constraint orders --fk user_id --references users.id --on-delete cascade
276
+ dbcli migrate add-constraint users --unique email
277
+ dbcli migrate add-constraint users --check "age >= 0"
278
+ dbcli migrate drop-constraint orders fk_orders_user_id --execute --force
279
+
280
+ # Enum (PostgreSQL only — MySQL uses inline ENUM in column type)
281
+ dbcli migrate add-enum status active inactive suspended
282
+ dbcli migrate alter-enum status --add-value archived
283
+ dbcli migrate drop-enum status --execute --force
284
+ ```
285
+
286
+ **Column spec format:** `name:type[:modifier[:modifier...]]`
287
+ - Modifiers: `pk`, `not-null`, `unique`, `auto-increment`, `default=<value>`, `references=<table>.<column>`
288
+ - Serial types: `serial`, `bigserial`, `smallserial` (auto-expand per DB dialect)
289
+
290
+ **Options (all subcommands):** `--execute`, `--force`, `--config <path>`
291
+ **Permission:** admin
292
+
293
+ **AI agent note:** Always use dry-run first (no `--execute`) to preview generated SQL. Only add `--execute` after confirming the SQL is correct. For DROP operations, both `--execute` and `--force` are required.
294
+
223
295
  ## Permission Levels
224
296
 
225
297
  | Level | Allowed Operations |
@@ -227,7 +299,7 @@ dbcli upgrade --check # Only check, do not upgrade
227
299
  | query-only | SELECT, list, schema, export |
228
300
  | read-write | query-only + INSERT, UPDATE |
229
301
  | data-admin | read-write + DELETE (full DML, no DDL) |
230
- | admin | data-admin + DROP, ALTER, CREATE, TRUNCATE |
302
+ | admin | data-admin + DDL (migrate create/drop/alter, DROP, ALTER, CREATE, TRUNCATE) |
231
303
 
232
304
  Set via `dbcli init --permission <level>` or in `.dbcli` config.
233
305