@cosmicdrift/kumiko-dev-server 0.4.1 → 0.5.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @cosmicdrift/kumiko-dev-server
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7ff69ab: feat(es-ops): Phase 1 — file-based seed-migrations
8
+
9
+ Neues first-class Operations-Pattern fürs Framework. Liefert `seed-migrations`
10
+ als drizzle-migrate-equivalent für Event-Sourcing-Aggregate-Updates die
11
+ idempotent-Seeder nicht erfassen können (z.B. „Member hat schon eine
12
+ Rolle, aber jetzt soll noch eine dazukommen").
13
+
14
+ Public-API:
15
+
16
+ - `runProdApp({ seedsDir })` — Auto-apply pending Migrations beim Boot
17
+ - `SeedMigration`-Interface (default-Export einer `seeds/<id>.ts`-File)
18
+ - `SeedMigrationContext` mit `systemWriteAs` (ruft existing write-handler
19
+ als System-User) + Read-Helpers (`findUserByEmail`,
20
+ `findMembershipsOfUser`, `findTenants`)
21
+ - CLI: `bunx kumiko ops seed:new|status|apply`
22
+ - Tracking-Table `kumiko_es_operations` mit `operation_type`-Discriminator
23
+ (vorbereitet auf Phase 2+ Operations: projection-rebuild, event-replay,
24
+ stream-migration, ...)
25
+ - Env-Flags: `KUMIKO_SKIP_ES_OPS=1` (alle skippen für Recovery),
26
+ `KUMIKO_SKIP_ES_OPS_<ID>=1` (einzelne kaputte skippen)
27
+
28
+ Garantien: single-run via tracking, atomic via per-migration-Tx,
29
+ chronological order via filename-prefix, fail-stop bei Failure (kein
30
+ Partial-Apply), ES-konform via Handler-Dispatch.
31
+
32
+ Sub-path-Export: `@cosmicdrift/kumiko-framework/es-ops`
33
+
34
+ Plan-Doc: `kumiko-platform/docs/plans/features/es-ops.md`
35
+ Recipe: `samples/recipes/seed-migration/`
36
+ Driver-Use-Case: publicstatus admin-roles-drift (parallel-Branch
37
+ `feat/es-ops-driver-admin-roles`).
38
+
39
+ Phase 2+ skizziert + offen markiert — Implementation pro Use-Case.
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [7ff69ab]
44
+ - @cosmicdrift/kumiko-framework@0.5.0
45
+ - @cosmicdrift/kumiko-bundled-features@0.5.0
46
+
3
47
  ## 0.4.1
4
48
 
5
49
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Development server bootstrap for Kumiko apps. Bundles the client, mints dev-JWTs, injects the resolved AppSchema, and seeds an admin. Not for production.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -48,8 +48,8 @@
48
48
  "kumiko-dev": "./bin/kumiko-dev.ts"
49
49
  },
50
50
  "dependencies": {
51
- "@cosmicdrift/kumiko-bundled-features": "0.4.1",
52
- "@cosmicdrift/kumiko-framework": "0.4.1"
51
+ "@cosmicdrift/kumiko-bundled-features": "0.5.0",
52
+ "@cosmicdrift/kumiko-framework": "0.5.0"
53
53
  },
54
54
  "publishConfig": {
55
55
  "registry": "https://registry.npmjs.org",
@@ -42,7 +42,7 @@ import { createSessionCallbacks } from "@cosmicdrift/kumiko-bundled-features/ses
42
42
  import { TenantQueries } from "@cosmicdrift/kumiko-bundled-features/tenant";
43
43
  import { UserQueries } from "@cosmicdrift/kumiko-bundled-features/user";
44
44
  import { createSseBroker, type SseBroker } from "@cosmicdrift/kumiko-framework/api";
45
- import { createDbConnection } from "@cosmicdrift/kumiko-framework/db";
45
+ import { createDbConnection, type DbRunner } from "@cosmicdrift/kumiko-framework/db";
46
46
  import {
47
47
  buildAppSchema,
48
48
  createRegistry,
@@ -58,8 +58,14 @@ import {
58
58
  type ApiEntrypointOptions,
59
59
  createApiEntrypoint,
60
60
  } from "@cosmicdrift/kumiko-framework/entrypoint";
61
+ import {
62
+ createEsOperationsTable,
63
+ createSeedMigrationContext,
64
+ runPendingSeedMigrations,
65
+ } from "@cosmicdrift/kumiko-framework/es-ops";
61
66
  import { assertSchemaCurrent, SchemaDriftError } from "@cosmicdrift/kumiko-framework/migrations";
62
67
  import {
68
+ createDispatcher,
63
69
  createEntityCache,
64
70
  createEventDedup,
65
71
  createIdempotencyGuard,
@@ -275,6 +281,12 @@ export type RunProdAppOptions = {
275
281
  readonly auth?: RunProdAppAuthOptions;
276
282
  /** Custom seed functions, run after the admin seed (when auth-mode). */
277
283
  readonly seeds?: readonly ProdSeedFn[];
284
+ /** Pfad zum seeds-Directory für ES-Operations / Seed-Migrations
285
+ * (file-basiert wie drizzle-migrate). Wenn gesetzt + KUMIKO_SKIP_ES_OPS
286
+ * != "1": runProdApp scannt das Verzeichnis nach `<id>.ts` Files,
287
+ * diff vs kumiko_es_operations-Table, läuft pending in Tx.
288
+ * Plan: kumiko-platform/docs/plans/features/es-ops.md */
289
+ readonly seedsDir?: string;
278
290
  /** Anonymous-access for public endpoints (same shape as runDevApp).
279
291
  * Akzeptiert entweder einen statischen Config-Object ODER eine
280
292
  * Factory `({db, redis, registry}) => Config` — die Factory wird
@@ -603,6 +615,29 @@ export async function runProdApp(options: RunProdAppOptions): Promise<ProdAppHan
603
615
  await seed({ db });
604
616
  }
605
617
 
618
+ // ES-Operations / Seed-Migrations (Phase 1). Läuft NACH applyBootSeeds +
619
+ // existing seeds-array — die deklarativen Seeds sind die "always-insert-
620
+ // if-missing"-Schicht; seed-migrations sind die "diff-and-update"-
621
+ // Schicht für Drift den existing Seeds nicht erfassen können (z.B.
622
+ // Membership-Roles-Change nach initialer Seed-Erstellung).
623
+ if (options.seedsDir !== undefined && process.env["KUMIKO_SKIP_ES_OPS"] !== "1") {
624
+ await createEsOperationsTable(db);
625
+ const seedDispatcher = createDispatcher(registry, {
626
+ db,
627
+ redis,
628
+ entityCache,
629
+ registry,
630
+ ...extraContext,
631
+ });
632
+ await runPendingSeedMigrations({
633
+ db,
634
+ seedsDir: options.seedsDir,
635
+ appliedBy: "boot",
636
+ createContext: (dbRunner: DbRunner) =>
637
+ createSeedMigrationContext({ dispatcher: seedDispatcher, dbRunner }),
638
+ });
639
+ }
640
+
606
641
  await entrypoint.start();
607
642
 
608
643
  // 10. App-eigene HTTP-Routes mounten — vor dem static-fallback. Hono