db-model-router 1.0.3 → 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 (97) hide show
  1. package/README.md +283 -25
  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 +16 -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 +185 -0
  69. package/src/cli/commands/init.js +42 -14
  70. package/src/cli/commands/inspect.js +21 -3
  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-model.js +5 -4
  75. package/src/cli/generate-route.js +79 -45
  76. package/src/cli/init/dependencies.js +17 -5
  77. package/src/cli/init/generators.js +1073 -64
  78. package/src/cli/init/prompt.js +37 -5
  79. package/src/cli/init.js +148 -25
  80. package/src/cli/main.js +90 -10
  81. package/src/cockroachdb/db.js +90 -59
  82. package/src/commons/route.js +20 -20
  83. package/src/commons/validator.js +58 -1
  84. package/src/dynamodb/db.js +50 -27
  85. package/src/index.js +2 -0
  86. package/src/mongodb/db.js +1 -0
  87. package/src/mssql/db.js +89 -61
  88. package/src/mysql/db.js +1 -0
  89. package/src/oracle/db.js +1 -0
  90. package/src/postgres/db.js +61 -41
  91. package/src/redis/db.js +1 -0
  92. package/src/schema/schema-parser.js +43 -1
  93. package/src/schema/schema-printer.js +8 -5
  94. package/src/schema/schema-to-meta.js +4 -0
  95. package/src/schema/schema-validator.js +20 -1
  96. package/src/sqlite3/db.js +1 -0
  97. package/docs/SKILL.md +0 -374
@@ -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
+
package/demo/llms.txt ADDED
@@ -0,0 +1,70 @@
1
+ # db-model-router — LLM Quick Reference
2
+
3
+ ## Schema File: dbmr.schema.json
4
+ { "adapter": "<adapter>", "framework": "<framework>", "tables": { "<name>": { "columns": { "<col>": "<rule>" }, "pk": "<col>", "unique": ["<col>"], "softDelete": "<col>" } }, "relationships": [{ "parent": "<t>", "child": "<t>", "foreignKey": "<col>" }], "options": {} }
5
+
6
+ Adapters: mysql, postgres, sqlite3, mongodb, mssql, cockroachdb, oracle, redis, dynamodb
7
+ Frameworks: express, ultimate-express
8
+ Column rules: (required|)?(string|integer|numeric|boolean|object) e.g. "required|string"
9
+
10
+ ## Universal Flags
11
+ --yes --json --dry-run --no-install --help
12
+
13
+ ## Commands
14
+
15
+ ### init
16
+ Scaffold a new project.
17
+ --from <schema> Read config from schema file
18
+ --framework <fw> Framework (express|ultimate-express)
19
+ --database <db> Adapter name
20
+ Example: db-model-router init --from dbmr.schema.json --yes --no-install
21
+
22
+ ### inspect
23
+ Introspect a live database and produce a schema file.
24
+ --type <adapter> Database adapter
25
+ --env <path> Path to .env file
26
+ --out <path> Output path (default: dbmr.schema.json)
27
+ --tables <list> Comma-separated table filter
28
+ Example: db-model-router inspect --type sqlite3 --env .env --out schema.json
29
+
30
+ ### generate
31
+ Generate code artifacts from schema.
32
+ --from <schema> Schema file (default: dbmr.schema.json)
33
+ --models Generate model files only
34
+ --routes Generate route files only
35
+ --openapi Generate OpenAPI spec only
36
+ --tests Generate test files only
37
+ --llm-docs Generate LLM documentation only
38
+ Example: db-model-router generate --from dbmr.schema.json
39
+ Example: db-model-router generate --models --dry-run
40
+
41
+ ### doctor
42
+ Validate schema, check dependencies, verify file sync.
43
+ --from <schema> Schema file (default: dbmr.schema.json)
44
+ Example: db-model-router doctor --from dbmr.schema.json --json
45
+
46
+ ### diff
47
+ Preview changes between schema and generated files.
48
+ --from <schema> Schema file (default: dbmr.schema.json)
49
+ Example: db-model-router diff --from dbmr.schema.json
50
+
51
+ ## Route Contract (per table)
52
+ GET /api/<table>/ List (page, size, sort, select_columns)
53
+ POST /api/<table>/ Bulk insert
54
+ PUT /api/<table>/ Bulk update
55
+ DELETE /api/<table>/ Bulk delete
56
+ GET /api/<table>/:id Get by ID
57
+ POST /api/<table>/:id Insert one
58
+ PUT /api/<table>/:id Update one
59
+ PATCH /api/<table>/:id Partial update one
60
+ DELETE /api/<table>/:id Delete one
61
+
62
+ ## Generated Files
63
+ models/<table>.js Model with CRUD operations
64
+ routes/<table>.js Express route handlers
65
+ routes/<child>_child_of_<parent>.js Child route
66
+ routes/index.js Route mounting index
67
+ test/<table>.test.js CRUD endpoint tests
68
+ openapi.json OpenAPI 3.0 spec
69
+ llms.txt This file
70
+ docs/llm.md Full LLM reference
@@ -0,0 +1,67 @@
1
+ import winston from "winston";
2
+
3
+ /**
4
+ * Winston logger with Console transport.
5
+ * If LOKI_HOST is set in .env, adds a Loki transport for Grafana visualization.
6
+ */
7
+ const transports = [
8
+ new winston.transports.Console({
9
+ format: winston.format.combine(
10
+ winston.format.colorize(),
11
+ winston.format.printf(({ timestamp, level, message, ...meta }) => {
12
+ const metaStr = Object.keys(meta).length > 1
13
+ ? " " + JSON.stringify(meta)
14
+ : "";
15
+ return `[${timestamp}] [${level}] ${message}${metaStr}`;
16
+ }),
17
+ ),
18
+ }),
19
+ ];
20
+
21
+ // Add Loki transport only when LOKI_HOST is configured
22
+ if (process.env.LOKI_HOST) {
23
+ const { default: LokiTransport } = await import("winston-loki");
24
+ transports.push(
25
+ new LokiTransport({
26
+ host: process.env.LOKI_HOST,
27
+ labels: { app: process.env.APP_NAME || "app" },
28
+ json: true,
29
+ onConnectionError: (err) => console.error("Loki connection error:", err),
30
+ }),
31
+ );
32
+ }
33
+
34
+ const logger = winston.createLogger({
35
+ level: process.env.LOG_LEVEL || "info",
36
+ format: winston.format.combine(
37
+ winston.format.timestamp(),
38
+ winston.format.json(),
39
+ ),
40
+ defaultMeta: { service: process.env.APP_NAME || "app" },
41
+ transports,
42
+ });
43
+
44
+ /**
45
+ * Express middleware that logs every request/response.
46
+ */
47
+ function requestLogger(req, res, next) {
48
+ const start = Date.now();
49
+
50
+ res.on("finish", () => {
51
+ const duration = Date.now() - start;
52
+ const level = res.statusCode >= 400 ? "warn" : "info";
53
+ logger.log({
54
+ level,
55
+ message: `${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`,
56
+ method: req.method,
57
+ url: req.originalUrl,
58
+ status: res.statusCode,
59
+ duration,
60
+ });
61
+ });
62
+
63
+ next();
64
+ }
65
+
66
+ requestLogger.logger = logger;
67
+ export default requestLogger;
@@ -0,0 +1,6 @@
1
+ CREATE TABLE IF NOT EXISTS _migrations (
2
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
3
+ filename VARCHAR(255) NOT NULL UNIQUE,
4
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
5
+ checksum VARCHAR(64) NOT NULL
6
+ );