create-restforge-skills 0.2.0 → 0.4.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.
@@ -1,238 +1,245 @@
1
- # Reference: dbschema-kit Catalog
2
-
3
- > **Offline mirror.** This file mirrors `codegen_get_dbschema_catalog` from the
4
- > installed RESTForge platform. The live tool is authoritative — when this file
5
- > and the tool disagree, trust the tool, then update this file. Always re-ground
6
- > with the tool before defining SDF; do not rely on this mirror alone.
7
-
8
- Source: `codegen_get_dbschema_catalog` — installed platform version.
9
- Use as grounding before defining SDF.
10
- Schema version: 1.1.
11
-
12
- ---
13
-
14
- ## Table of Contents
15
-
16
- 1. [Field Types](#field-types)
17
- 2. [Shorthand Syntax](#shorthand-syntax)
18
- 3. [Constraints](#constraints)
19
- 4. [Relation Types](#relation-types)
20
- 5. [Referential Actions](#referential-actions)
21
- 6. [Check Operations](#check-operations)
22
- 7. [Audit Columns](#audit-columns)
23
- 8. [Soft-Delete Contract](#soft-delete-contract)
24
- 9. [Naming Rules](#naming-rules)
25
- 10. [Dialect Support](#dialect-support)
26
-
27
- ---
28
-
29
- ## Field Types
30
-
31
- 10 types available. `string` and `decimal` require a modifier.
32
-
33
- | Type | Modifier | Shorthand example | Notes |
34
- |---|---|---|---|
35
- | `string` | required: `:<length>` | `string:255` | VARCHAR, explicit length required |
36
- | `text` | none | `text` | TEXT/CLOB, no length limit |
37
- | `integer` | none | `integer` | INT 32-bit |
38
- | `bigint` | none | `bigint` | BIGINT 64-bit |
39
- | `decimal` | required: `:<precision>,<scale>` | `decimal:15,2` | Fixed-point |
40
- | `boolean` | none | `boolean` | Native BOOLEAN (PG), VARCHAR on others |
41
- | `date` | none | `date` | Date only |
42
- | `timestamp` | none | `timestamp` | Date + time |
43
- | `uuid` | none | `uuid` | Native UUID (PG), VARCHAR(36) on others |
44
- | `json` | none | `json` | JSONB (PG), JSON (MySQL), CLOB (Oracle) |
45
-
46
- ---
47
-
48
- ## Shorthand Syntax
49
-
50
- Format: `<type>[:<modifier>] [<constraint>[:<value>]]...`
51
-
52
- ```
53
- string:36 pk
54
- string:255 notnull
55
- decimal:15,2 notnull default:0
56
- boolean default:true
57
- string:100 default:'pending'
58
- timestamp default:now()
59
- string:36 fk:category.category_id
60
- string:64 index
61
- ```
62
-
63
- Rules:
64
- - Type must come first and must be from the field types list above.
65
- - Modifier is required for `string` (length) and `decimal` (precision,scale).
66
- - Standalone constraints have no value: `pk`, `notnull`, `unique`, `index`.
67
- - Value constraints require `constraint:value` format: `default`, `fk`.
68
- - String default: single-quoted `default:'value'`; numeric/boolean: raw `default:0`;
69
- SQL constant: bare identifier `default:current_date`; native function: `default:now()`.
70
- - FK uses dot notation: `fk:<table>.<column>`. `<column>` is the **actual
71
- column name** of the referenced field in the target table — normally that
72
- table's primary key column (e.g. `category.category_id`), NOT a literal `id`.
73
- RESTForge does not auto-resolve `.id` to the primary key; a reference to a
74
- column that does not exist is rejected. Bracket syntax is rejected by the parser.
75
- - `autoUpdate` is deprecated — no functional effect, parsed for backward compat only.
76
-
77
- ---
78
-
79
- ## Constraints
80
-
81
- 7 constraints available (excludes deprecated `autoUpdate`).
82
-
83
- | Constraint | Kind | Example | Notes |
84
- |---|---|---|---|
85
- | `pk` | standalone | `string:36 pk` | Primary key |
86
- | `notnull` | standalone | `string:255 notnull` | NOT NULL |
87
- | `unique` | standalone | `string:32 unique` | Single-column UNIQUE |
88
- | `index` | standalone | `string:64 index` | Single-column non-unique index |
89
- | `default` | value | `boolean default:true` | Default value |
90
- | `fk` | value | `string:36 fk:category.category_id` | FK + auto belongsTo relation; target is the actual PK column name |
91
-
92
- ---
93
-
94
- ## Relation Types
95
-
96
- 3 relation types. All use `type`, `localKey`, `references` (required),
97
- and `target`, `onDelete`, `onUpdate` (optional).
98
-
99
- | Type | Direction | DDL |
100
- |---|---|---|
101
- | `belongsTo` | Many-to-one, this table holds the FK | FK constraint generated |
102
- | `hasOne` | One-to-one inverse of belongsTo | No additional DDL |
103
- | `hasMany` | One-to-many inverse of belongsTo | No additional DDL |
104
-
105
- Example:
106
- ```js
107
- relations: {
108
- category: {
109
- type: "belongsTo",
110
- localKey: "category_id",
111
- references: "category_id",
112
- onDelete: "restrict"
113
- }
114
- }
115
- ```
116
-
117
- ---
118
-
119
- ## Referential Actions
120
-
121
- 4 actions for `onDelete` and `onUpdate`:
122
-
123
- | Action | Behavior |
124
- |---|---|
125
- | `cascade` | Delete/update child rows |
126
- | `restrict` | Reject delete/update if child exists |
127
- | `setNull` | Set child FK to NULL (field must be nullable) |
128
- | `noAction` | Defer check (semantics similar to restrict in most dialects) |
129
-
130
- ---
131
-
132
- ## Check Operations
133
-
134
- 7 operators for the `checks` array. Format: `{ name?, field, <operator>: <value> }`.
135
-
136
- | Operator | Value type | Example |
137
- |---|---|---|
138
- | `in` | array | `{ field: "status", in: ["active", "inactive"] }` |
139
- | `eq` | scalar | `{ field: "type", eq: "user" }` |
140
- | `neq` | scalar | `{ field: "type", neq: "system" }` |
141
- | `gt` | numeric | `{ field: "qty", gt: 0 }` |
142
- | `gte` | numeric | `{ field: "qty", gte: 0 }` |
143
- | `lt` | numeric | `{ field: "discount", lt: 100 }` |
144
- | `lte` | numeric | `{ field: "discount", lte: 100 }` |
145
-
146
- > Case enforcement at the DB level (e.g. require `customer_name` to be stored
147
- > upper case) belongs here as a check, not in RDF `fieldValidation`. RDF
148
- > `uppercase` only normalizes the value at the API layer.
149
-
150
- ---
151
-
152
- ## Audit Columns
153
-
154
- 4 standard columns for tables managed by RESTForge. Emitted automatically by
155
- `codegen_dbschema_init`. Lookup/system tables may remove them manually.
156
-
157
- | Column | SDF shorthand | Notes |
158
- |---|---|---|
159
- | `created_at` | `timestamp default:now()` | Set via DEFAULT now() on INSERT |
160
- | `created_by` | `string:100` | Set by application layer on INSERT, nullable |
161
- | `updated_at` | `timestamp` | Auto-updated via RDF runtime (not an SDF marker) |
162
- | `updated_by` | `string:100` | Set by application layer on UPDATE, nullable |
163
-
164
- All 4 columns are nullable. Drift between SDF (audit columns absent) and RDF
165
- (assumes audit columns exist) causes runtime errors.
166
-
167
- ---
168
-
169
- ## Soft-Delete Contract
170
-
171
- Declare with `softDelete: { enabled: true }` in `defineModel`. The three
172
- contract columns must be present in `fields` with the correct types.
173
-
174
- | Column | Required shorthand | Nullable |
175
- |---|---|---|
176
- | `is_deleted` | `boolean notnull default:false` | no |
177
- | `deleted_at` | `timestamp` | yes |
178
- | `deleted_by` | `string:70` | yes |
179
-
180
- ### Biconditional rules
181
-
182
- - `enabled: true` + all three columns present with correct types → valid.
183
- - `enabled: true` + missing columns → ERROR (missing columns listed).
184
- - Contract columns present but `enabled` not true → ERROR.
185
- - Wrong column type → ERROR.
186
- - `is_deleted`, `deleted_at`, `deleted_by` are reserved names — cannot be used
187
- as regular columns in a RESTForge table.
188
-
189
- ### Reusable (UNIQUE column values freed after soft-delete)
190
-
191
- Fields whose unique values should be freed after soft-delete must be declared
192
- in `softDelete.reusable: [{ field, length }]`. Requirements:
193
- - Field must exist in `fields`.
194
- - Field type must be `string` or `text`.
195
- - Field must have a single-column UNIQUE constraint.
196
- - `length` = maximum input length. Physical length = `length + 38`
197
- (38 = "##" + UUID v7).
198
-
199
- ### Generated DDL
200
-
201
- - CHECK constraint: `chk_<table>_soft_delete_consistency` — enforces consistency
202
- across the three contract columns.
203
- - Non-unique indexes become PostgreSQL partial indexes:
204
- `WHERE is_deleted = FALSE`.
205
- - UNIQUE constraints are NOT made partial; column values are freed via
206
- suffix mutation (not a partial unique index).
207
-
208
- ### Unique eligibility gate
209
-
210
- When `enabled: true`, all UNIQUE constraints on the table are checked:
211
- - Composite UNIQUE is rejected — suffix mutation cannot free composite columns.
212
- - Single-column UNIQUE on a non-string type is rejected — suffix mutation only
213
- works for `string`/`text`.
214
-
215
- ### Dialect support
216
-
217
- Phase 1: PostgreSQL only. Other dialects produce an explicit error.
218
-
219
- ---
220
-
221
- ## Naming Rules
222
-
223
- - Table names: `snake_case`, lowercase, digits, underscores.
224
- - Field/column names: `snake_case`.
225
- - Constraint names: auto-generated with prefixes `pk_`, `fk_`, `idx_`, `uq_`,
226
- `ck_`. When exceeding the dialect's maximum length, falls back to an 8-character
227
- MD5 suffix.
228
-
229
- ---
230
-
231
- ## Dialect Support
232
-
233
- | Dialect | Driver | Boolean storage |
234
- |---|---|---|
235
- | `postgres` | pg | Native BOOLEAN |
236
- | `mysql` | mysql2 | VARCHAR ("true"/"false") |
237
- | `oracle` | oracledb | VARCHAR2 + CHECK constraint |
238
- | `sqlite` | better-sqlite3 | TEXT |
1
+ # Reference: dbschema-kit Catalog
2
+
3
+ > **Offline mirror.** This file mirrors `codegen_get_dbschema_catalog` from the
4
+ > installed RESTForge platform. The live tool is authoritative — when this file
5
+ > and the tool disagree, trust the tool, then update this file. Always re-ground
6
+ > with the tool before defining SDF; do not rely on this mirror alone.
7
+
8
+ Source: `codegen_get_dbschema_catalog` — installed platform version.
9
+ Use as grounding before defining SDF.
10
+ Schema version: 1.1.
11
+
12
+ ---
13
+
14
+ ## Table of Contents
15
+
16
+ 1. [Field Types](#field-types)
17
+ 2. [Shorthand Syntax](#shorthand-syntax)
18
+ 3. [Constraints](#constraints)
19
+ 4. [Relation Types](#relation-types)
20
+ 5. [Referential Actions](#referential-actions)
21
+ 6. [Check Operations](#check-operations)
22
+ 7. [Audit Columns](#audit-columns)
23
+ 8. [Soft-Delete Contract](#soft-delete-contract)
24
+ 9. [Naming Rules](#naming-rules)
25
+ 10. [Dialect Support](#dialect-support)
26
+
27
+ ---
28
+
29
+ ## Field Types
30
+
31
+ 12 types available. `string` and `decimal` require a modifier.
32
+
33
+ | Type | Modifier | Shorthand example | Notes |
34
+ |---|---|---|---|
35
+ | `string` | required: `:<length>` | `string:255` | VARCHAR, explicit length required |
36
+ | `text` | none | `text` | TEXT/CLOB, no length limit |
37
+ | `integer` | none | `integer` | INT 32-bit |
38
+ | `bigint` | none | `bigint` | BIGINT 64-bit |
39
+ | `decimal` | required: `:<precision>,<scale>` | `decimal:15,2` | Fixed-point |
40
+ | `boolean` | none | `boolean` | Native BOOLEAN (PG), VARCHAR on others |
41
+ | `date` | none | `date` | Date only |
42
+ | `time` | none | `time` | Time of day without date (TIME). Not affected by `TIMEZONE`/`DATEFORMAT`/`DATETIMEFORMAT`. **Rejected on Oracle** (no native TIME; use `timestamp`) |
43
+ | `timestamp` | none | `timestamp` | Date + time **without** time zone: wall-clock of `TIMEZONE`, millisecond precision. PG `TIMESTAMP`, MySQL `DATETIME(3)`, Oracle `TIMESTAMP`, SQLite text |
44
+ | `timestamptz` | none | `timestamptz` | Date + time **with** time zone, an absolute moment (stored as UTC, returned as ISO UTC). **PostgreSQL only**; rejected on MySQL, Oracle, SQLite with no silent fallback |
45
+ | `uuid` | none | `uuid` | Native UUID (PG), VARCHAR(36) on others |
46
+ | `json` | none | `json` | JSONB (PG), JSON (MySQL), CLOB (Oracle) |
47
+
48
+ ---
49
+
50
+ ## Shorthand Syntax
51
+
52
+ Format: `<type>[:<modifier>] [<constraint>[:<value>]]...`
53
+
54
+ ```
55
+ string:36 pk
56
+ string:255 notnull
57
+ decimal:15,2 notnull default:0
58
+ boolean default:true
59
+ string:100 default:'pending'
60
+ timestamp default:now()
61
+ string:36 fk:category.category_id
62
+ string:64 index
63
+ ```
64
+
65
+ Rules:
66
+ - Type must come first and must be from the field types list above.
67
+ - Modifier is required for `string` (length) and `decimal` (precision,scale).
68
+ - Standalone constraints have no value: `pk`, `notnull`, `unique`, `index`.
69
+ - Value constraints require `constraint:value` format: `default`, `fk`.
70
+ - String default: single-quoted `default:'value'`; numeric/boolean: raw `default:0`;
71
+ SQL constant: bare identifier `default:current_date`; native function: `default:now()`.
72
+ - FK uses dot notation: `fk:<table>.<column>`. `<column>` is the **actual
73
+ column name** of the referenced field in the target table — normally that
74
+ table's primary key column (e.g. `category.category_id`), NOT a literal `id`.
75
+ RESTForge does not auto-resolve `.id` to the primary key; a reference to a
76
+ column that does not exist is rejected. Bracket syntax is rejected by the parser.
77
+ - `autoUpdate` is deprecated — no functional effect, parsed for backward compat only.
78
+
79
+ ---
80
+
81
+ ## Constraints
82
+
83
+ 6 active constraints. The catalog counts 7 because it also lists the deprecated
84
+ `autoUpdate` (parsed for backward compatibility, no effect on DDL or runtime).
85
+
86
+ | Constraint | Kind | Example | Notes |
87
+ |---|---|---|---|
88
+ | `pk` | standalone | `string:36 pk` | Primary key |
89
+ | `notnull` | standalone | `string:255 notnull` | NOT NULL |
90
+ | `unique` | standalone | `string:32 unique` | Single-column UNIQUE |
91
+ | `index` | standalone | `string:64 index` | Single-column non-unique index |
92
+ | `default` | value | `boolean default:true` | Default value |
93
+ | `fk` | value | `string:36 fk:category.category_id` | FK + auto belongsTo relation; target is the actual PK column name |
94
+
95
+ ---
96
+
97
+ ## Relation Types
98
+
99
+ 3 relation types. All use `type`, `localKey`, `references` (required),
100
+ and `target`, `onDelete`, `onUpdate` (optional).
101
+
102
+ | Type | Direction | DDL |
103
+ |---|---|---|
104
+ | `belongsTo` | Many-to-one, this table holds the FK | FK constraint generated |
105
+ | `hasOne` | One-to-one inverse of belongsTo | No additional DDL |
106
+ | `hasMany` | One-to-many inverse of belongsTo | No additional DDL |
107
+
108
+ Example:
109
+ ```js
110
+ relations: {
111
+ category: {
112
+ type: "belongsTo",
113
+ localKey: "category_id",
114
+ references: "category_id",
115
+ onDelete: "restrict"
116
+ }
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Referential Actions
123
+
124
+ 4 actions for `onDelete` and `onUpdate`:
125
+
126
+ | Action | Behavior |
127
+ |---|---|
128
+ | `cascade` | Delete/update child rows |
129
+ | `restrict` | Reject delete/update if child exists |
130
+ | `setNull` | Set child FK to NULL (field must be nullable) |
131
+ | `noAction` | Defer check (semantics similar to restrict in most dialects) |
132
+
133
+ Oracle writes `restrict` and `noAction` without an `ON DELETE` clause, which
134
+ Oracle enforces the same way. `codegen_dbschema_diff` treats `noAction` and
135
+ `restrict` as equal, so switching between them is not reported as drift.
136
+
137
+ ---
138
+
139
+ ## Check Operations
140
+
141
+ 7 operators for the `checks` array. Format: `{ name?, field, <operator>: <value> }`.
142
+
143
+ | Operator | Value type | Example |
144
+ |---|---|---|
145
+ | `in` | array | `{ field: "status", in: ["active", "inactive"] }` |
146
+ | `eq` | scalar | `{ field: "type", eq: "user" }` |
147
+ | `neq` | scalar | `{ field: "type", neq: "system" }` |
148
+ | `gt` | numeric | `{ field: "qty", gt: 0 }` |
149
+ | `gte` | numeric | `{ field: "qty", gte: 0 }` |
150
+ | `lt` | numeric | `{ field: "discount", lt: 100 }` |
151
+ | `lte` | numeric | `{ field: "discount", lte: 100 }` |
152
+
153
+ > Case enforcement at the DB level (e.g. require `customer_name` to be stored
154
+ > upper case) belongs here as a check, not in RDF `fieldValidation`. RDF
155
+ > `uppercase` only normalizes the value at the API layer.
156
+
157
+ ---
158
+
159
+ ## Audit Columns
160
+
161
+ 4 standard columns for tables managed by RESTForge. Emitted automatically by
162
+ `codegen_dbschema_init`. Lookup/system tables may remove them manually.
163
+
164
+ | Column | SDF shorthand | Notes |
165
+ |---|---|---|
166
+ | `created_at` | `timestamp default:now()` | Set via DEFAULT now() on INSERT |
167
+ | `created_by` | `string:100` | Set by application layer on INSERT, nullable |
168
+ | `updated_at` | `timestamp` | Auto-updated via RDF runtime (not an SDF marker) |
169
+ | `updated_by` | `string:100` | Set by application layer on UPDATE, nullable |
170
+
171
+ All 4 columns are nullable. Drift between SDF (audit columns absent) and RDF
172
+ (assumes audit columns exist) causes runtime errors.
173
+
174
+ ---
175
+
176
+ ## Soft-Delete Contract
177
+
178
+ Declare with `softDelete: { enabled: true }` in `defineModel`. The three
179
+ contract columns must be present in `fields` with the correct types.
180
+
181
+ | Column | Required shorthand | Nullable |
182
+ |---|---|---|
183
+ | `is_deleted` | `boolean notnull default:false` | no |
184
+ | `deleted_at` | `timestamp` | yes |
185
+ | `deleted_by` | `string:70` | yes |
186
+
187
+ ### Biconditional rules
188
+
189
+ - `enabled: true` + all three columns present with correct types → valid.
190
+ - `enabled: true` + missing columns → ERROR (missing columns listed).
191
+ - Contract columns present but `enabled` not true → ERROR.
192
+ - Wrong column type → ERROR.
193
+ - `is_deleted`, `deleted_at`, `deleted_by` are reserved names — cannot be used
194
+ as regular columns in a RESTForge table.
195
+
196
+ ### Reusable (UNIQUE column values freed after soft-delete)
197
+
198
+ Fields whose unique values should be freed after soft-delete must be declared
199
+ in `softDelete.reusable: [{ field, length }]`. Requirements:
200
+ - Field must exist in `fields`.
201
+ - Field type must be `string` or `text`.
202
+ - Field must have a single-column UNIQUE constraint.
203
+ - `length` = maximum input length. Physical length = `length + 38`
204
+ (38 = "##" + UUID v7).
205
+
206
+ ### Generated DDL
207
+
208
+ - CHECK constraint: `chk_<table>_soft_delete_consistency` — enforces consistency
209
+ across the three contract columns.
210
+ - Non-unique indexes become PostgreSQL partial indexes:
211
+ `WHERE is_deleted = FALSE`.
212
+ - UNIQUE constraints are NOT made partial; column values are freed via
213
+ suffix mutation (not a partial unique index).
214
+
215
+ ### Unique eligibility gate
216
+
217
+ When `enabled: true`, all UNIQUE constraints on the table are checked:
218
+ - Composite UNIQUE is rejected — suffix mutation cannot free composite columns.
219
+ - Single-column UNIQUE on a non-string type is rejected — suffix mutation only
220
+ works for `string`/`text`.
221
+
222
+ ### Dialect support
223
+
224
+ Phase 1: PostgreSQL only. Other dialects produce an explicit error.
225
+
226
+ ---
227
+
228
+ ## Naming Rules
229
+
230
+ - Table names: `snake_case`, lowercase, digits, underscores.
231
+ - Field/column names: `snake_case`.
232
+ - Constraint names: auto-generated with prefixes `pk_`, `fk_`, `idx_`, `uq_`,
233
+ `ck_`. When exceeding the dialect's maximum length, falls back to an 8-character
234
+ MD5 suffix.
235
+
236
+ ---
237
+
238
+ ## Dialect Support
239
+
240
+ | Dialect | Driver | Boolean storage |
241
+ |---|---|---|
242
+ | `postgres` | pg | Native BOOLEAN |
243
+ | `mysql` | mysql2 | VARCHAR ("true"/"false") |
244
+ | `oracle` | oracledb | VARCHAR2 + CHECK constraint |
245
+ | `sqlite` | better-sqlite3 | TEXT |