db-model-router 1.0.4 → 1.0.5

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 (92) hide show
  1. package/README.md +110 -16
  2. package/TODO.md +14 -0
  3. package/dbmr.schema.json +333 -0
  4. package/demo/.dockerignore +7 -0
  5. package/demo/.env.example +13 -0
  6. package/demo/Dockerfile +20 -0
  7. package/demo/app.js +37 -0
  8. package/demo/commons/add_migration.js +43 -0
  9. package/demo/commons/db.js +17 -0
  10. package/demo/commons/migrate.js +65 -0
  11. package/demo/commons/security.js +30 -0
  12. package/demo/commons/session.js +13 -0
  13. package/demo/dbmr.schema.json +362 -0
  14. package/demo/docs/llm.md +197 -0
  15. package/demo/llms.txt +70 -0
  16. package/demo/middleware/logger.js +67 -0
  17. package/demo/migrations/20260430155808_create_migrations_table.sql +6 -0
  18. package/demo/migrations/20260430155809_create_tables.sql +207 -0
  19. package/demo/models/addresses.js +22 -0
  20. package/demo/models/cart_items.js +18 -0
  21. package/demo/models/carts.js +16 -0
  22. package/demo/models/categories.js +20 -0
  23. package/demo/models/coupons.js +23 -0
  24. package/demo/models/order_items.js +21 -0
  25. package/demo/models/orders.js +25 -0
  26. package/demo/models/payments.js +21 -0
  27. package/demo/models/product_images.js +18 -0
  28. package/demo/models/product_reviews.js +20 -0
  29. package/demo/models/product_variants.js +20 -0
  30. package/demo/models/products.js +30 -0
  31. package/demo/models/shipments.js +19 -0
  32. package/demo/models/users.js +19 -0
  33. package/demo/models/wishlists.js +15 -0
  34. package/demo/openapi.json +5872 -0
  35. package/demo/package-lock.json +2810 -0
  36. package/demo/package.json +34 -0
  37. package/demo/routes/addresses.js +6 -0
  38. package/demo/routes/carts/cart_items.js +7 -0
  39. package/demo/routes/carts.js +6 -0
  40. package/demo/routes/categories.js +6 -0
  41. package/demo/routes/coupons.js +6 -0
  42. package/demo/routes/docs.js +18 -0
  43. package/demo/routes/health.js +35 -0
  44. package/demo/routes/index.js +39 -0
  45. package/demo/routes/orders/order_items.js +7 -0
  46. package/demo/routes/orders/payments.js +7 -0
  47. package/demo/routes/orders/shipments.js +7 -0
  48. package/demo/routes/orders.js +6 -0
  49. package/demo/routes/products/product_images.js +7 -0
  50. package/demo/routes/products/product_reviews.js +7 -0
  51. package/demo/routes/products/product_variants.js +7 -0
  52. package/demo/routes/products.js +6 -0
  53. package/demo/routes/users.js +6 -0
  54. package/demo/routes/wishlists.js +6 -0
  55. package/docker-compose.yml +1 -1
  56. package/package.json +8 -7
  57. package/scripts/demo-create.js +47 -0
  58. package/skill/SKILL.md +464 -0
  59. package/skill/references/cockroachdb.md +49 -0
  60. package/skill/references/dynamodb.md +53 -0
  61. package/skill/references/mongodb.md +56 -0
  62. package/skill/references/mssql.md +55 -0
  63. package/skill/references/oracle.md +52 -0
  64. package/skill/references/postgres.md +50 -0
  65. package/skill/references/redis.md +53 -0
  66. package/skill/references/sqlite3.md +43 -0
  67. package/src/cli/commands/generate.js +58 -17
  68. package/src/cli/commands/help.js +11 -6
  69. package/src/cli/commands/init.js +2 -2
  70. package/src/cli/commands/inspect.js +1 -0
  71. package/src/cli/diff-engine.js +52 -22
  72. package/src/cli/generate-docs-route.js +31 -0
  73. package/src/cli/generate-migration.js +356 -0
  74. package/src/cli/generate-route.js +52 -24
  75. package/src/cli/init/dependencies.js +3 -0
  76. package/src/cli/init/generators.js +1 -1
  77. package/src/cli/init.js +8 -8
  78. package/src/cockroachdb/db.js +90 -59
  79. package/src/commons/route.js +20 -20
  80. package/src/commons/validator.js +58 -1
  81. package/src/dynamodb/db.js +50 -27
  82. package/src/mongodb/db.js +1 -0
  83. package/src/mssql/db.js +89 -61
  84. package/src/mysql/db.js +1 -0
  85. package/src/oracle/db.js +1 -0
  86. package/src/postgres/db.js +61 -41
  87. package/src/redis/db.js +1 -0
  88. package/src/schema/schema-parser.js +43 -1
  89. package/src/schema/schema-printer.js +7 -0
  90. package/src/schema/schema-validator.js +17 -0
  91. package/src/sqlite3/db.js +1 -0
  92. package/docs/SKILL.md +0 -419
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import crypto from "crypto";
5
+ import { fileURLToPath } from "url";
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ /**
10
+ * Run all pending SQL migrations from the migrations directory.
11
+ * @param {object} db - db-model-router db instance
12
+ * @param {string} migrationsDir - absolute path to migrations folder
13
+ */
14
+ export default async function runMigrations(db, migrationsDir) {
15
+ const files = fs.readdirSync(migrationsDir)
16
+ .filter(f => f.endsWith(".sql"))
17
+ .sort();
18
+
19
+ let executed;
20
+ try {
21
+ const result = await db.query("SELECT filename FROM _migrations");
22
+ executed = new Set((result || []).map(r => r.filename));
23
+ } catch (e) {
24
+ executed = new Set();
25
+ }
26
+
27
+ let ran = 0;
28
+ for (const file of files) {
29
+ if (executed.has(file)) {
30
+ console.log(` Skipping (already executed): ${file}`);
31
+ continue;
32
+ }
33
+ const filePath = path.join(migrationsDir, file);
34
+ const content = fs.readFileSync(filePath, "utf8");
35
+ const checksum = crypto.createHash("md5").update(content).digest("hex");
36
+
37
+ console.log(` Running migration: ${file}`);
38
+ await db.query(content);
39
+ await db.query(
40
+ "INSERT INTO _migrations (filename, checksum) VALUES (?, ?)",
41
+ [file, checksum]
42
+ );
43
+ console.log(` Completed: ${file}`);
44
+ ran++;
45
+ }
46
+
47
+ if (ran === 0) {
48
+ console.log("No pending migrations.");
49
+ } else {
50
+ console.log(`\n${ran} migration(s) complete.`);
51
+ }
52
+ }
53
+
54
+ // Run as standalone script
55
+ const isMain = process.argv[1] && fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
56
+ if (isMain) {
57
+ await import("dotenv/config");
58
+ const pkg = await import("db-model-router");
59
+ const mod = pkg.default || pkg;
60
+ mod.init("sqlite3");
61
+ const migrationsDir = path.join(__dirname, "../migrations");
62
+ runMigrations(mod.db, migrationsDir)
63
+ .then(() => process.exit(0))
64
+ .catch(err => { console.error("Migration failed:", err); process.exit(1); });
65
+ }
@@ -0,0 +1,30 @@
1
+ import helmet from "helmet";
2
+ import rateLimit from "express-rate-limit";
3
+
4
+ /**
5
+ * Apply security middleware to the Express app.
6
+ * Includes: Helmet, rate limiting, custom security headers.
7
+ * @param {import("express").Application} app
8
+ */
9
+ export default function applySecurity(app) {
10
+ // Helmet — sets various HTTP headers for security
11
+ app.use(helmet());
12
+
13
+ // Rate limiting
14
+ app.use(rateLimit({
15
+ windowMs: 15 * 60 * 1000,
16
+ max: 100,
17
+ standardHeaders: true,
18
+ legacyHeaders: false,
19
+ }));
20
+
21
+ // Custom security headers (override or extend as needed)
22
+ app.use((req, res, next) => {
23
+ res.setHeader("X-Content-Type-Options", "nosniff");
24
+ res.setHeader("X-Frame-Options", "DENY");
25
+ res.setHeader("X-XSS-Protection", "1; mode=block");
26
+ res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
27
+ res.removeHeader("X-Powered-By");
28
+ next();
29
+ });
30
+ }
@@ -0,0 +1,13 @@
1
+ import session from "express-session";
2
+
3
+ /**
4
+ * Configure and return session middleware.
5
+ * Session store: memory
6
+ */
7
+ export default function configureSession() {
8
+ return session({
9
+ secret: process.env.SESSION_SECRET || "change-me",
10
+ resave: false,
11
+ saveUninitialized: false,
12
+ });
13
+ }
@@ -0,0 +1,362 @@
1
+ {
2
+ "adapter": "sqlite3",
3
+ "framework": "express",
4
+ "options": {
5
+ "rateLimiting": true,
6
+ "helmet": true,
7
+ "logger": true
8
+ },
9
+ "tables": {
10
+ "users": {
11
+ "columns": {
12
+ "user_id": "auto_increment",
13
+ "name": "required|string",
14
+ "email": "required|string",
15
+ "password_hash": "required|string",
16
+ "phone": "string",
17
+ "avatar_url": "string",
18
+ "role": "required|string",
19
+ "is_deleted": "boolean",
20
+ "created_at": "datetime",
21
+ "updated_at": "datetime"
22
+ },
23
+ "pk": "user_id",
24
+ "unique": [
25
+ "email"
26
+ ],
27
+ "softDelete": "is_deleted",
28
+ "timestamps": {
29
+ "created_at": "created_at",
30
+ "modified_at": "updated_at"
31
+ },
32
+ "parent": null
33
+ },
34
+ "addresses": {
35
+ "columns": {
36
+ "address_id": "auto_increment",
37
+ "user_id": "required|integer",
38
+ "label": "string",
39
+ "line1": "required|string",
40
+ "line2": "string",
41
+ "city": "required|string",
42
+ "state": "required|string",
43
+ "postal_code": "required|string",
44
+ "country": "required|string",
45
+ "is_default": "boolean",
46
+ "created_at": "datetime",
47
+ "updated_at": "datetime"
48
+ },
49
+ "pk": "address_id",
50
+ "unique": [
51
+ "address_id"
52
+ ],
53
+ "timestamps": {
54
+ "created_at": "created_at",
55
+ "modified_at": "updated_at"
56
+ },
57
+ "parent": null
58
+ },
59
+ "categories": {
60
+ "columns": {
61
+ "category_id": "auto_increment",
62
+ "name": "required|string",
63
+ "slug": "required|string",
64
+ "description": "string",
65
+ "parent_category_id": "integer",
66
+ "image_url": "string",
67
+ "sort_order": "integer",
68
+ "is_active": "boolean",
69
+ "created_at": "datetime",
70
+ "updated_at": "datetime"
71
+ },
72
+ "pk": "category_id",
73
+ "unique": [
74
+ "slug"
75
+ ],
76
+ "timestamps": {
77
+ "created_at": "created_at",
78
+ "modified_at": "updated_at"
79
+ },
80
+ "parent": null
81
+ },
82
+ "products": {
83
+ "columns": {
84
+ "product_id": "auto_increment",
85
+ "category_id": "required|integer",
86
+ "name": "required|string",
87
+ "slug": "required|string",
88
+ "description": "string",
89
+ "short_description": "string",
90
+ "sku": "required|string",
91
+ "price": "required|numeric",
92
+ "compare_at_price": "numeric",
93
+ "cost_price": "numeric",
94
+ "currency": "required|string",
95
+ "stock_quantity": "required|integer",
96
+ "low_stock_threshold": "integer",
97
+ "weight": "numeric",
98
+ "weight_unit": "string",
99
+ "is_active": "boolean",
100
+ "is_featured": "boolean",
101
+ "is_deleted": "boolean",
102
+ "meta": "object",
103
+ "created_at": "datetime",
104
+ "updated_at": "datetime"
105
+ },
106
+ "pk": "product_id",
107
+ "unique": [
108
+ "sku",
109
+ "slug"
110
+ ],
111
+ "softDelete": "is_deleted",
112
+ "timestamps": {
113
+ "created_at": "created_at",
114
+ "modified_at": "updated_at"
115
+ },
116
+ "parent": null
117
+ },
118
+ "product_images": {
119
+ "columns": {
120
+ "product_image_id": "auto_increment",
121
+ "product_id": "required|integer",
122
+ "url": "required|string",
123
+ "alt_text": "string",
124
+ "sort_order": "integer",
125
+ "is_primary": "boolean",
126
+ "created_at": "datetime"
127
+ },
128
+ "pk": "product_image_id",
129
+ "unique": [
130
+ "product_image_id"
131
+ ],
132
+ "timestamps": {
133
+ "created_at": "created_at"
134
+ },
135
+ "parent": "products"
136
+ },
137
+ "product_variants": {
138
+ "columns": {
139
+ "variant_id": "auto_increment",
140
+ "product_id": "required|integer",
141
+ "name": "required|string",
142
+ "sku": "required|string",
143
+ "price": "required|numeric",
144
+ "stock_quantity": "required|integer",
145
+ "attributes": "object",
146
+ "is_active": "boolean",
147
+ "created_at": "datetime",
148
+ "updated_at": "datetime"
149
+ },
150
+ "pk": "variant_id",
151
+ "unique": [
152
+ "sku"
153
+ ],
154
+ "timestamps": {
155
+ "created_at": "created_at",
156
+ "modified_at": "updated_at"
157
+ },
158
+ "parent": "products"
159
+ },
160
+ "product_reviews": {
161
+ "columns": {
162
+ "review_id": "auto_increment",
163
+ "product_id": "required|integer",
164
+ "user_id": "required|integer",
165
+ "rating": "required|integer",
166
+ "title": "string",
167
+ "body": "string",
168
+ "is_verified": "boolean",
169
+ "is_approved": "boolean",
170
+ "created_at": "datetime",
171
+ "updated_at": "datetime"
172
+ },
173
+ "pk": "review_id",
174
+ "unique": [
175
+ "review_id"
176
+ ],
177
+ "timestamps": {
178
+ "created_at": "created_at",
179
+ "modified_at": "updated_at"
180
+ },
181
+ "parent": "products"
182
+ },
183
+ "carts": {
184
+ "columns": {
185
+ "cart_id": "auto_increment",
186
+ "user_id": "integer",
187
+ "session_id": "string",
188
+ "currency": "required|string",
189
+ "created_at": "datetime",
190
+ "updated_at": "datetime"
191
+ },
192
+ "pk": "cart_id",
193
+ "unique": [
194
+ "cart_id"
195
+ ],
196
+ "timestamps": {
197
+ "created_at": "created_at",
198
+ "modified_at": "updated_at"
199
+ },
200
+ "parent": null
201
+ },
202
+ "cart_items": {
203
+ "columns": {
204
+ "cart_item_id": "auto_increment",
205
+ "cart_id": "required|integer",
206
+ "product_id": "required|integer",
207
+ "variant_id": "integer",
208
+ "quantity": "required|integer",
209
+ "unit_price": "required|numeric",
210
+ "created_at": "datetime",
211
+ "updated_at": "datetime"
212
+ },
213
+ "pk": "cart_item_id",
214
+ "unique": [
215
+ "cart_item_id"
216
+ ],
217
+ "timestamps": {
218
+ "created_at": "created_at",
219
+ "modified_at": "updated_at"
220
+ },
221
+ "parent": "carts"
222
+ },
223
+ "orders": {
224
+ "columns": {
225
+ "order_id": "auto_increment",
226
+ "user_id": "required|integer",
227
+ "order_number": "required|string",
228
+ "status": "required|string",
229
+ "subtotal": "required|numeric",
230
+ "tax_amount": "required|numeric",
231
+ "shipping_amount": "required|numeric",
232
+ "discount_amount": "numeric",
233
+ "total": "required|numeric",
234
+ "currency": "required|string",
235
+ "shipping_address_id": "integer",
236
+ "billing_address_id": "integer",
237
+ "notes": "string",
238
+ "created_at": "datetime",
239
+ "updated_at": "datetime"
240
+ },
241
+ "pk": "order_id",
242
+ "unique": [
243
+ "order_number"
244
+ ],
245
+ "timestamps": {
246
+ "created_at": "created_at",
247
+ "modified_at": "updated_at"
248
+ },
249
+ "parent": null
250
+ },
251
+ "order_items": {
252
+ "columns": {
253
+ "order_item_id": "auto_increment",
254
+ "order_id": "required|integer",
255
+ "product_id": "required|integer",
256
+ "variant_id": "integer",
257
+ "product_name": "required|string",
258
+ "sku": "required|string",
259
+ "quantity": "required|integer",
260
+ "unit_price": "required|numeric",
261
+ "total_price": "required|numeric",
262
+ "created_at": "datetime"
263
+ },
264
+ "pk": "order_item_id",
265
+ "unique": [
266
+ "order_item_id"
267
+ ],
268
+ "timestamps": {
269
+ "created_at": "created_at"
270
+ },
271
+ "parent": "orders"
272
+ },
273
+ "payments": {
274
+ "columns": {
275
+ "payment_id": "auto_increment",
276
+ "order_id": "required|integer",
277
+ "method": "required|string",
278
+ "provider": "string",
279
+ "provider_transaction_id": "string",
280
+ "amount": "required|numeric",
281
+ "currency": "required|string",
282
+ "status": "required|string",
283
+ "paid_at": "datetime",
284
+ "created_at": "datetime",
285
+ "updated_at": "datetime"
286
+ },
287
+ "pk": "payment_id",
288
+ "unique": [
289
+ "payment_id"
290
+ ],
291
+ "timestamps": {
292
+ "created_at": "created_at",
293
+ "modified_at": "updated_at"
294
+ },
295
+ "parent": "orders"
296
+ },
297
+ "shipments": {
298
+ "columns": {
299
+ "shipment_id": "auto_increment",
300
+ "order_id": "required|integer",
301
+ "carrier": "required|string",
302
+ "tracking_number": "string",
303
+ "status": "required|string",
304
+ "shipped_at": "datetime",
305
+ "delivered_at": "datetime",
306
+ "created_at": "datetime",
307
+ "updated_at": "datetime"
308
+ },
309
+ "pk": "shipment_id",
310
+ "unique": [
311
+ "shipment_id"
312
+ ],
313
+ "timestamps": {
314
+ "created_at": "created_at",
315
+ "modified_at": "updated_at"
316
+ },
317
+ "parent": "orders"
318
+ },
319
+ "coupons": {
320
+ "columns": {
321
+ "coupon_id": "auto_increment",
322
+ "code": "required|string",
323
+ "description": "string",
324
+ "discount_type": "required|string",
325
+ "discount_value": "required|numeric",
326
+ "min_order_amount": "numeric",
327
+ "max_uses": "integer",
328
+ "used_count": "integer",
329
+ "starts_at": "datetime",
330
+ "expires_at": "datetime",
331
+ "is_active": "boolean",
332
+ "created_at": "datetime",
333
+ "updated_at": "datetime"
334
+ },
335
+ "pk": "coupon_id",
336
+ "unique": [
337
+ "code"
338
+ ],
339
+ "timestamps": {
340
+ "created_at": "created_at",
341
+ "modified_at": "updated_at"
342
+ },
343
+ "parent": null
344
+ },
345
+ "wishlists": {
346
+ "columns": {
347
+ "wishlist_id": "auto_increment",
348
+ "user_id": "required|integer",
349
+ "product_id": "required|integer",
350
+ "created_at": "datetime"
351
+ },
352
+ "pk": "wishlist_id",
353
+ "unique": [
354
+ "wishlist_id"
355
+ ],
356
+ "timestamps": {
357
+ "created_at": "created_at"
358
+ },
359
+ "parent": null
360
+ }
361
+ }
362
+ }
@@ -0,0 +1,197 @@
1
+ # db-model-router — LLM Reference
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ npm install db-model-router
7
+ ```
8
+
9
+ ## Canonical Schema-Driven Workflow
10
+
11
+ 1. Create or inspect a `dbmr.schema.json` schema file
12
+ 2. Run `db-model-router generate --from dbmr.schema.json` to generate all artifacts
13
+ 3. Run `db-model-router doctor` to validate schema and check sync
14
+ 4. Run `db-model-router diff` to preview changes before regenerating
15
+ 5. Edit the schema file and repeat from step 2
16
+
17
+ ## Schema Definition
18
+
19
+ The `dbmr.schema.json` file is the single source of truth for your project.
20
+
21
+ ```json
22
+ {
23
+ "adapter": "<adapter>",
24
+ "framework": "<framework>",
25
+ "tables": {
26
+ "<table_name>": {
27
+ "columns": {
28
+ "<column_name>": "<column_rule>"
29
+ },
30
+ "pk": "<primary_key_column>",
31
+ "unique": [
32
+ "<column_name>"
33
+ ],
34
+ "softDelete": "<column_name>",
35
+ "timestamps": {
36
+ "created_at": "<column_name>",
37
+ "modified_at": "<column_name>"
38
+ }
39
+ }
40
+ },
41
+ "relationships": [
42
+ {
43
+ "parent": "<table>",
44
+ "child": "<table>",
45
+ "foreignKey": "<column>"
46
+ }
47
+ ],
48
+ "options": {}
49
+ }
50
+ ```
51
+
52
+ ### Adapters
53
+
54
+ | Adapter | Description |
55
+ |---------|-------------|
56
+ | mysql | mysql database adapter |
57
+ | postgres | postgres database adapter |
58
+ | sqlite3 | sqlite3 database adapter |
59
+ | mongodb | mongodb database adapter |
60
+ | mssql | mssql database adapter |
61
+ | cockroachdb | cockroachdb database adapter |
62
+ | oracle | oracle database adapter |
63
+ | redis | redis database adapter |
64
+ | dynamodb | dynamodb database adapter |
65
+
66
+ ### Frameworks
67
+
68
+ | Framework | Description |
69
+ |-----------|-------------|
70
+ | express | express HTTP framework |
71
+ | ultimate-express | ultimate-express HTTP framework |
72
+
73
+ ### Column Rules
74
+
75
+ Column rules use pipe-delimited tokens: `(required|)?(string|integer|numeric|boolean|object)`
76
+
77
+ Examples: `"required|string"`, `"integer"`, `"required|boolean"`, `"object"`
78
+
79
+ ## CLI Commands
80
+
81
+ All commands support universal flags: `--yes`, `--json`, `--dry-run`, `--no-install`, `--help`
82
+
83
+ ### init
84
+
85
+ Scaffold a new project from a schema file or interactively.
86
+
87
+ ```bash
88
+ # From schema file, non-interactive
89
+ db-model-router init --from dbmr.schema.json --yes --no-install
90
+
91
+ # Interactive with defaults
92
+ db-model-router init --framework express --database sqlite3 --yes
93
+
94
+ # Dry run to preview
95
+ db-model-router init --from dbmr.schema.json --dry-run
96
+ ```
97
+
98
+ | Flag | Description |
99
+ |------|-------------|
100
+ | `--from <path>` | Read config from schema file |
101
+ | `--framework <fw>` | Framework: express, ultimate-express |
102
+ | `--database <db>` | Adapter name |
103
+
104
+ ### inspect
105
+
106
+ Introspect a live database and produce a schema file.
107
+
108
+ ```bash
109
+ db-model-router inspect --type postgres --env .env --out dbmr.schema.json
110
+ db-model-router inspect --type sqlite3 --tables users,posts --json
111
+ ```
112
+
113
+ | Flag | Description |
114
+ |------|-------------|
115
+ | `--type <adapter>` | Database adapter to use |
116
+ | `--env <path>` | Path to .env file |
117
+ | `--out <path>` | Output file (default: dbmr.schema.json) |
118
+ | `--tables <list>` | Comma-separated table filter |
119
+
120
+ ### generate
121
+
122
+ Generate code artifacts from the schema file.
123
+
124
+ ```bash
125
+ # Generate all artifacts
126
+ db-model-router generate --from dbmr.schema.json
127
+
128
+ # Generate only models
129
+ db-model-router generate --models
130
+
131
+ # Generate only routes
132
+ db-model-router generate --routes
133
+
134
+ # Preview with dry-run
135
+ db-model-router generate --dry-run --json
136
+
137
+ # Generate LLM docs only
138
+ db-model-router generate --llm-docs
139
+ ```
140
+
141
+ | Flag | Description |
142
+ |------|-------------|
143
+ | `--from <path>` | Schema file (default: dbmr.schema.json) |
144
+ | `--models` | Generate model files only |
145
+ | `--routes` | Generate route files only |
146
+ | `--openapi` | Generate OpenAPI spec only |
147
+ | `--tests` | Generate test files only |
148
+ | `--llm-docs` | Generate LLM documentation only |
149
+
150
+ ### doctor
151
+
152
+ Validate schema, check dependencies, and verify generated files are in sync.
153
+
154
+ ```bash
155
+ db-model-router doctor --from dbmr.schema.json
156
+ db-model-router doctor --json
157
+ ```
158
+
159
+ ### diff
160
+
161
+ Preview changes between the schema and currently generated files.
162
+
163
+ ```bash
164
+ db-model-router diff --from dbmr.schema.json
165
+ db-model-router diff --json
166
+ ```
167
+
168
+ ## Route Contract
169
+
170
+ Each table generates 9 endpoints:
171
+
172
+ | Method | Path | Description |
173
+ |--------|------|-------------|
174
+ | GET | `/api/<table>/` | List with pagination (page, size, sort, select_columns) |
175
+ | POST | `/api/<table>/` | Bulk insert |
176
+ | PUT | `/api/<table>/` | Bulk update |
177
+ | DELETE | `/api/<table>/` | Bulk delete |
178
+ | GET | `/api/<table>/:id` | Get single record by primary key |
179
+ | POST | `/api/<table>/:id` | Insert single record |
180
+ | PUT | `/api/<table>/:id` | Update single record |
181
+ | PATCH | `/api/<table>/:id` | Partial update single record |
182
+ | DELETE | `/api/<table>/:id` | Delete single record |
183
+
184
+ ## Adapter Capability Matrix
185
+
186
+ | Adapter | SQL | Transactions | Migrations | Streaming |
187
+ |---------|-----|--------------|------------|-----------|
188
+ | mysql | Yes | Yes | Yes | No |
189
+ | postgres | Yes | Yes | Yes | No |
190
+ | sqlite3 | Yes | Yes | Yes | No |
191
+ | mongodb | No | No | No | No |
192
+ | mssql | Yes | Yes | Yes | No |
193
+ | cockroachdb | Yes | Yes | Yes | No |
194
+ | oracle | Yes | Yes | Yes | No |
195
+ | redis | No | No | No | No |
196
+ | dynamodb | No | No | No | No |
197
+