feat: make Kafka projector the Workbench realtime authority
This commit is contained in:
@@ -4,7 +4,8 @@ import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import {
|
||||
CLOUD_CORE_MIGRATION_ID,
|
||||
CLOUD_CORE_MIGRATIONS,
|
||||
CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
|
||||
CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE,
|
||||
CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE_COLUMNS,
|
||||
@@ -25,7 +26,8 @@ import { ENVIRONMENT_DEV } from "../../internal/protocol/index.mjs";
|
||||
import { ensureNotRepoReportsPath, tempReportPath } from "./report-paths.mjs";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
||||
const migrationPath = "internal/db/migrations/0001_cloud_core_skeleton.sql";
|
||||
const migrationPaths = CLOUD_CORE_MIGRATIONS.map((migration) => migration.path);
|
||||
const latestMigrationPath = migrationPaths.at(-1);
|
||||
const defaultReportPath = tempReportPath("dev-runtime-migration-report.json");
|
||||
const issue = "pikasTech/HWLAB#164";
|
||||
|
||||
@@ -55,7 +57,11 @@ export async function buildDevRuntimeMigrationReport(args = {}, options = {}) {
|
||||
const env = options.env ?? process.env;
|
||||
const now = options.now ?? (() => new Date().toISOString());
|
||||
const root = options.repoRoot ?? repoRoot;
|
||||
const sql = await readFile(path.join(root, migrationPath), "utf8");
|
||||
const migrationSources = await Promise.all(migrationPaths.map(async (migrationPath) => ({
|
||||
path: migrationPath,
|
||||
sql: await readFile(path.join(root, migrationPath), "utf8")
|
||||
})));
|
||||
const sql = migrationSources.map((migration) => migration.sql).join("\n");
|
||||
const sourceCheck = validateMigrationSource(sql);
|
||||
const db = summarizeDbEnv(env);
|
||||
const report = {
|
||||
@@ -71,8 +77,9 @@ export async function buildDevRuntimeMigrationReport(args = {}, options = {}) {
|
||||
dbEndpointAuthority: DEV_DB_ENV_CONTRACT.endpointAuthority.source
|
||||
},
|
||||
migration: {
|
||||
id: CLOUD_CORE_MIGRATION_ID,
|
||||
path: migrationPath,
|
||||
id: CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
path: latestMigrationPath,
|
||||
paths: migrationPaths,
|
||||
sha256: sha256(sql),
|
||||
schemaVersion: CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
|
||||
ledgerTable: CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE,
|
||||
@@ -195,7 +202,9 @@ export function validateMigrationSource(sql) {
|
||||
continue;
|
||||
}
|
||||
for (const column of columns) {
|
||||
if (!new RegExp(`\\b${column}\\b`, "u").test(tableMatch[1])) {
|
||||
const created = new RegExp(`\\b${column}\\b`, "u").test(tableMatch[1]);
|
||||
const added = new RegExp(`ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS ${column}\\b`, "u").test(sql);
|
||||
if (!created && !added) {
|
||||
missing.push(`column:${table}.${column}`);
|
||||
}
|
||||
}
|
||||
@@ -214,8 +223,8 @@ export function validateMigrationSource(sql) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!new RegExp(`'${CLOUD_CORE_MIGRATION_ID}'`, "u").test(sql)) {
|
||||
missing.push(`ledger-id:${CLOUD_CORE_MIGRATION_ID}`);
|
||||
if (!new RegExp(`'${CLOUD_RUNTIME_DURABLE_MIGRATION_ID}'`, "u").test(sql)) {
|
||||
missing.push(`ledger-id:${CLOUD_RUNTIME_DURABLE_MIGRATION_ID}`);
|
||||
}
|
||||
if (!new RegExp(`'${CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION}'`, "u").test(sql)) {
|
||||
missing.push(`schema-version:${CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION}`);
|
||||
@@ -227,8 +236,9 @@ export function validateMigrationSource(sql) {
|
||||
return {
|
||||
ready: missing.length === 0,
|
||||
checked: true,
|
||||
migrationPath,
|
||||
requiredMigrationId: CLOUD_CORE_MIGRATION_ID,
|
||||
migrationPath: latestMigrationPath,
|
||||
migrationPaths,
|
||||
requiredMigrationId: CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
requiredSchemaVersion: CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
|
||||
requiredTables: Object.keys(CLOUD_RUNTIME_DURABLE_TABLE_COLUMNS),
|
||||
requiredLedgerTable: CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE,
|
||||
@@ -456,7 +466,7 @@ function summarizeRuntimeMigration(migration = {}) {
|
||||
checked: Boolean(migration.checked),
|
||||
ready: Boolean(migration.ready),
|
||||
table: migration.table ?? CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE,
|
||||
requiredMigrationId: migration.requiredMigrationId ?? CLOUD_CORE_MIGRATION_ID,
|
||||
requiredMigrationId: migration.requiredMigrationId ?? CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
requiredSchemaVersion: migration.requiredSchemaVersion ?? CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
|
||||
appliedMigrationId: migration.appliedMigrationId ?? null,
|
||||
appliedSchemaVersion: migration.appliedSchemaVersion ?? null,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
parseArgs
|
||||
} from "./dev-runtime-migration.mjs";
|
||||
import {
|
||||
CLOUD_CORE_MIGRATION_ID,
|
||||
CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
|
||||
CLOUD_RUNTIME_DURABLE_TABLE_COLUMNS
|
||||
} from "../../internal/db/schema.ts";
|
||||
@@ -60,7 +60,7 @@ test("cloud-api image migration entrypoint exposes the same non-secret source ch
|
||||
assert.equal(report.actions.liveDbWriteAttempted, false);
|
||||
assert.equal(report.safety.printsSecretValues, false);
|
||||
assert.equal(report.safety.dbUrlValueRedacted, true);
|
||||
assert.equal(report.migration.id, CLOUD_CORE_MIGRATION_ID);
|
||||
assert.equal(report.migration.id, CLOUD_RUNTIME_DURABLE_MIGRATION_ID);
|
||||
assert.equal(JSON.stringify(report).includes("secret-password"), false);
|
||||
assert.equal(JSON.stringify(report).includes("db.example.test"), false);
|
||||
});
|
||||
@@ -306,7 +306,7 @@ test("apply mode records ledger and verifies durable runtime readiness", async (
|
||||
assert.equal(report.gates.schema.status, "ready");
|
||||
assert.equal(report.gates.migration.status, "ready");
|
||||
assert.equal(report.gates.readiness.status, "ready");
|
||||
assert.equal(report.runtime.migration.appliedMigrationId, CLOUD_CORE_MIGRATION_ID);
|
||||
assert.equal(report.runtime.migration.appliedMigrationId, CLOUD_RUNTIME_DURABLE_MIGRATION_ID);
|
||||
assert.equal(report.runtime.migration.appliedSchemaVersion, CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION);
|
||||
assert.ok(queryClient.calls.some((call) => call.sql === "BEGIN"));
|
||||
assert.ok(queryClient.calls.some((call) => call.sql.includes("INSERT INTO hwlab_schema_migrations")));
|
||||
@@ -448,7 +448,7 @@ function createFakeQueryClient({ migrationReady, countErrorCode = null, migratio
|
||||
rows: state.migrationReady
|
||||
? [
|
||||
{
|
||||
id: CLOUD_CORE_MIGRATION_ID,
|
||||
id: CLOUD_RUNTIME_DURABLE_MIGRATION_ID,
|
||||
schema_version: CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user