@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/agent-docs",
3
- "version": "0.1.98",
3
+ "version": "0.1.99",
4
4
  "description": "Distributed JSKIT agent references, prompts, guides, and generated reference maps.",
5
5
  "type": "module",
6
6
  "files": [
@@ -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)`