@jskit-ai/agent-docs 0.1.98 → 0.1.99
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.
|
@@ -613,6 +613,7 @@ const dialectId = resolveDatabaseClientFromEnvironment(process.env);
|
|
|
613
613
|
const client = toKnexClientId(dialectId);
|
|
614
614
|
const defaultPort = dialectId === "pg" ? 5432 : 3306;
|
|
615
615
|
const migrationsDirectory = path.resolve(appRoot, normalizeText(process.env.DB_MIGRATIONS_DIR) || "migrations");
|
|
616
|
+
const deferredConstraintsDirectory = path.join(migrationsDirectory, "constraints");
|
|
616
617
|
|
|
617
618
|
export default {
|
|
618
619
|
client,
|
|
@@ -622,8 +623,9 @@ export default {
|
|
|
622
623
|
context: "knex migrations"
|
|
623
624
|
}),
|
|
624
625
|
migrations: {
|
|
625
|
-
directory: migrationsDirectory,
|
|
626
|
-
extension: "cjs"
|
|
626
|
+
directory: [migrationsDirectory, deferredConstraintsDirectory],
|
|
627
|
+
extension: "cjs",
|
|
628
|
+
sortDirsSeparately: true
|
|
627
629
|
}
|
|
628
630
|
};
|
|
629
631
|
```
|
|
@@ -643,6 +645,14 @@ So there are really two separate database entry points:
|
|
|
643
645
|
|
|
644
646
|
That separation is good. It keeps the operational CLI workflow and the app runtime wiring clear.
|
|
645
647
|
|
|
648
|
+
The two migration directories are one ordered migration plan. Knex completes
|
|
649
|
+
the ordinary `migrations/` files before it reads
|
|
650
|
+
`migrations/constraints/`. CRUD scaffolding uses that second phase for foreign
|
|
651
|
+
keys, so two tables may validly reference one another without either
|
|
652
|
+
table-creation migration depending on a table that has not been created yet.
|
|
653
|
+
Rollback reverses the order and removes those constraints before dropping
|
|
654
|
+
tables.
|
|
655
|
+
|
|
646
656
|
### The MySQL package registers the driver, and the generic runtime builds the Knex client
|
|
647
657
|
|
|
648
658
|
On the server side, the two installed packages split responsibilities very deliberately.
|
|
@@ -248,6 +248,13 @@ needs a different persistence model, record the durable decision in
|
|
|
248
248
|
`.jskit/APP_BLUEPRINT.md` and use the explicit table-ownership exception path
|
|
249
249
|
instead of modifying generated CRUD files.
|
|
250
250
|
|
|
251
|
+
Mutual foreign keys are valid when each side still follows that key contract.
|
|
252
|
+
The server generator keeps table creation and foreign-key installation in
|
|
253
|
+
separate migration phases: every ordinary migration creates its table first,
|
|
254
|
+
then migrations under `migrations/constraints/` add the constraints. Do not
|
|
255
|
+
move those constraints back into the table-creation migrations or disable
|
|
256
|
+
foreign-key checks to work around ordering.
|
|
257
|
+
|
|
251
258
|
## Example 1: `contacts`
|
|
252
259
|
|
|
253
260
|
This is the baseline pattern. If you understand this example, the rest of the chapter becomes much easier.
|
package/package.json
CHANGED
|
@@ -51,6 +51,10 @@ Rules:
|
|
|
51
51
|
- If the table should already be CRUD-owned but should not expose public CRUD HTTP routes yet, scaffold it with `jskit generate crud-server-generator scaffold ... --internal` instead of dropping to direct knex or a hand-built pseudo-repository.
|
|
52
52
|
- Create the real table directly in the database before scaffolding. `crud-server-generator` reads the live table shape.
|
|
53
53
|
- If `crud-server-generator` is going to own the CRUD, do not hand-write a separate CRUD migration for that table. The generator installs and manages the CRUD migration scaffold itself.
|
|
54
|
+
- Keep generated table creation in `migrations/` and generated foreign keys in
|
|
55
|
+
`migrations/constraints/`. The database runtime deliberately runs those
|
|
56
|
+
phases in that order so valid mutual foreign keys rebuild cleanly without
|
|
57
|
+
disabling constraint checks.
|
|
54
58
|
- Do not scaffold CRUD UI, hand-build CRUD routes, or hand-build CRUD endpoints before the server CRUD package and shared resource file exist.
|
|
55
59
|
- Treat the generated shared resource file as the canonical CRUD contract for later UI scaffolding and CRUD behavior changes.
|
|
56
60
|
- Treat the exact columns `workspace_id` and `user_id` as reserved JSKIT ownership columns. They are the only standard columns used for generated ownership filtering and create-time owner stamping.
|
|
@@ -78,6 +78,8 @@ Local functions
|
|
|
78
78
|
- `renderMigrationIndexLines(snapshot)`
|
|
79
79
|
- `renderMigrationForeignKeyLine(foreignKey = {})`
|
|
80
80
|
- `renderMigrationForeignKeyLines(snapshot)`
|
|
81
|
+
- `renderMigrationDropForeignKeyLine(foreignKey = {})`
|
|
82
|
+
- `renderMigrationDropForeignKeyLines(snapshot)`
|
|
81
83
|
- `renderMigrationCheckConstraintLines(snapshot)`
|
|
82
84
|
- `mergeFieldMetaEntries(...entryGroups)`
|
|
83
85
|
- `resolveLookupNamespaceFromTableName(tableName = "")`
|
|
@@ -157,6 +159,10 @@ Exports
|
|
|
157
159
|
|
|
158
160
|
### templates
|
|
159
161
|
|
|
162
|
+
### `templates/migrations/crud_foreign_keys.cjs`
|
|
163
|
+
Exports
|
|
164
|
+
- None
|
|
165
|
+
|
|
160
166
|
### `templates/migrations/crud_initial.cjs`
|
|
161
167
|
Exports
|
|
162
168
|
- None
|
|
@@ -582,7 +582,9 @@ Exports
|
|
|
582
582
|
### `src/server/commandHandlers/appCommands/updatePackages.js`
|
|
583
583
|
Exports
|
|
584
584
|
- `collectChangedInstalledPackageIds(lock = {}, latestVersions = new Map())`
|
|
585
|
+
- `findRangeIntersectionVersion(ranges = [])`
|
|
585
586
|
- `formatElapsedTime(elapsedMilliseconds = 0)`
|
|
587
|
+
- `resolveRequiredDirectPeerUpdates({ createCliError, packageJson = {}, packageManifests = new Map() } = {})`
|
|
586
588
|
- `reapplyChangedInstalledPackages({ appRoot, createCliError, dryRun, latestVersions, loadLockFile, stderr, stdout })`
|
|
587
589
|
- `runAppUpdatePackagesCommand(ctx = {}, { appRoot = "", options = {}, stdout, stderr })`
|
|
588
590
|
- `runWithProgress(task, { activity, progressIntervalMs = PROGRESS_INTERVAL_MS, stdout, step } = {})`
|
|
@@ -593,6 +595,9 @@ Local functions
|
|
|
593
595
|
- `resolveMajorRange(packageName = "", version = "", createCliError)`
|
|
594
596
|
- `resolveRegistryArgs(registryUrl = "")`
|
|
595
597
|
- `resolveInstallSpecs(packageNames = [], latestVersions = new Map())`
|
|
598
|
+
- `parseRegistryPackageManifest(rawValue, packageName, createCliError)`
|
|
599
|
+
- `resolveRegistryPackageManifests(packageNames = [], latestVersions = new Map(), { appRoot, createCliError, registryArgs, stderr, stdout })`
|
|
600
|
+
- `resolveDeclaredDependencySection(packageJson = {}, packageName = "")`
|
|
596
601
|
- `hasNpmWorkspaces(packageJson = {})`
|
|
597
602
|
- `readJson(filePath)`
|
|
598
603
|
- `readOptionalFile(filePath)`
|