@cosmicdrift/kumiko-framework 0.45.0 → 0.45.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-framework",
|
|
3
|
-
"version": "0.45.
|
|
3
|
+
"version": "0.45.1",
|
|
4
4
|
"description": "Framework core — engine, pipeline, API, DB, and every other bit that makes Kumiko go.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { type BunTestDb, createTestDb } from "../bun-db/__tests__/bun-test-db";
|
|
6
|
+
import { createDbConnection, tableExists } from "../db";
|
|
6
7
|
import { runSchemaCli, type SchemaCliOut } from "../schema-cli";
|
|
7
8
|
import { ensureTemporalPolyfill } from "../time/polyfill";
|
|
8
9
|
|
|
@@ -186,6 +187,33 @@ describe("runSchemaCli — DB-backed paths", () => {
|
|
|
186
187
|
rmSync(appCwd, { recursive: true, force: true });
|
|
187
188
|
});
|
|
188
189
|
|
|
190
|
+
test("apply creates the framework-infra tables on a greenfield DB", async () => {
|
|
191
|
+
// Regression-pin: a brand-new app (no legacy-drizzle cutover) only had its
|
|
192
|
+
// entity-read tables after `apply`, so runProdApp's first event-store access
|
|
193
|
+
// hit "relation kumiko_events does not exist". `apply` now ensures the
|
|
194
|
+
// framework-infra tables (idempotent) so a greenfield deploy boots.
|
|
195
|
+
const appCwd = freshAppCwd();
|
|
196
|
+
writeSchemaFile(appCwd, "tbl_infra");
|
|
197
|
+
await runSchemaCli(["generate", "infra_test"], appCwd, captureOut().out);
|
|
198
|
+
await runSchemaCli(["apply"], appCwd, captureOut().out);
|
|
199
|
+
|
|
200
|
+
const { db, close } = createDbConnection(dbUrl);
|
|
201
|
+
try {
|
|
202
|
+
for (const table of [
|
|
203
|
+
"public.kumiko_events",
|
|
204
|
+
"public.kumiko_snapshots",
|
|
205
|
+
"public.kumiko_archived_streams",
|
|
206
|
+
"public.kumiko_event_consumers",
|
|
207
|
+
"public.kumiko_projections",
|
|
208
|
+
]) {
|
|
209
|
+
expect(await tableExists(db, table)).toBe(true);
|
|
210
|
+
}
|
|
211
|
+
} finally {
|
|
212
|
+
await close();
|
|
213
|
+
}
|
|
214
|
+
rmSync(appCwd, { recursive: true, force: true });
|
|
215
|
+
});
|
|
216
|
+
|
|
189
217
|
test("status with pending migrations exits 1 (regression-pin: CI-gating signal)", async () => {
|
|
190
218
|
const appCwd = freshAppCwd();
|
|
191
219
|
writeSchemaFile(appCwd, "tbl_pending");
|
package/src/schema-cli.ts
CHANGED
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
writeRebuildMarker,
|
|
25
25
|
writeSnapshotJson,
|
|
26
26
|
} from "./db";
|
|
27
|
+
import { createEventsTable } from "./event-store";
|
|
28
|
+
import { createEventConsumerStateTable, createProjectionStateTable } from "./pipeline";
|
|
27
29
|
|
|
28
30
|
export type SchemaCliOut = {
|
|
29
31
|
readonly log: (line: string) => void;
|
|
@@ -143,6 +145,14 @@ export async function runSchemaCli(
|
|
|
143
145
|
const { db, close } = createDbConnection(dbUrl);
|
|
144
146
|
try {
|
|
145
147
|
const result = await runMigrationsFromDir(db, migrationsDir);
|
|
148
|
+
// Framework-Infra-Tabellen (event-store + pipeline-state) — die erfasst
|
|
149
|
+
// `generate` nicht (nur Entity-read-Tabellen). Bestehende DBs haben sie
|
|
150
|
+
// aus dem legacy-drizzle-Fundament; eine Greenfield-DB (erste App ohne
|
|
151
|
+
// Cutover) hätte sonst kein kumiko_events → runProdApp-Boot scheitert.
|
|
152
|
+
// Alle drei sind idempotent (tableExists-Gate), also no-op für Bestands-DBs.
|
|
153
|
+
await createEventsTable(db);
|
|
154
|
+
await createEventConsumerStateTable(db);
|
|
155
|
+
await createProjectionStateTable(db);
|
|
146
156
|
out.log("");
|
|
147
157
|
if (result.applied.length === 0) {
|
|
148
158
|
out.log(` ✓ All ${result.skipped.length} migrations already applied.`);
|