fix: 固定 Workbench transactional 投影

This commit is contained in:
root
2026-07-14 03:55:47 +02:00
parent b513a565bd
commit 3e03e94e35
13 changed files with 254 additions and 246 deletions
@@ -1,5 +1,5 @@
import assert from "node:assert/strict";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { createServer } from "node:http";
import { connect } from "node:net";
import os from "node:os";
@@ -16,7 +16,25 @@ test("cloud web classifies Bun client disconnect ECONNRESET as non-fatal", () =>
assert.equal(isClientDisconnectError(new Error("database migration failed")), false);
});
test("serveCloudWeb rejects a missing refresh replay capability without opening health or SPA routes", async () => {
test("repo feature schema owns one unique key per product feature", async () => {
const schema = JSON.parse(await readFile(new URL("../../config/feature-config.schema.json", import.meta.url), "utf8"));
assert.equal(schema.$schema, "https://json-schema.org/draft/2020-12/schema");
assert.deepEqual(Object.keys(schema.properties), ["tracePanel", "rawEvents", "debugReplay", "views"]);
const features = Object.values(schema.properties).map((property) => property["x-unidesk-feature"]);
assert.equal(features.every((feature) => typeof feature === "string" && feature.length > 0), true);
assert.equal(new Set(features).size, features.length);
const encoded = JSON.stringify(schema);
for (const architectureEnv of [
"HWLAB_KAFKA_DIRECT_PUBLISH_ENABLED",
"HWLAB_WORKBENCH_LIVE_KAFKA_SSE_ENABLED",
"HWLAB_WORKBENCH_KAFKA_REFRESH_REPLAY_ENABLED",
"HWLAB_KAFKA_TRANSACTIONAL_PROJECTOR_ENABLED",
"HWLAB_KAFKA_PROJECTION_OUTBOX_RELAY_ENABLED",
"HWLAB_WORKBENCH_PROJECTION_REALTIME_ENABLED"
]) assert.equal(encoded.includes(architectureEnv), false);
});
test("serveCloudWeb starts without obsolete architecture capabilities", async () => {
const restoreEnv = withEnv({
HWLAB_CLOUD_WEB_DISPLAY_TIME_ZONE: "Asia/Shanghai",
HWLAB_CLOUD_WEB_DISPLAY_TIME_LOCALE: "zh-CN",
@@ -29,19 +47,21 @@ test("serveCloudWeb rejects a missing refresh replay capability without opening
HWLAB_WORKBENCH_RAW_HWLAB_EVENT_WINDOW_MAX_ENTRIES: "200",
HWLAB_WORKBENCH_RAW_HWLAB_EVENT_WINDOW_MAX_RETAINED_BYTES: "1048576"
});
delete process.env.HWLAB_WORKBENCH_KAFKA_REFRESH_REPLAY_ENABLED;
const port = await unusedPort();
let server = null;
try {
await assert.rejects(serveCloudWeb({
server = await serveCloudWeb({
port,
serviceId: "hwlab-cloud-web",
healthPayload: () => ({ status: "ok" }),
sendJson() {
assert.fail("missing runtime configuration must fail before serving any response");
sendJson(response, statusCode, body) {
response.writeHead(statusCode, { "content-type": "application/json" });
response.end(JSON.stringify(body));
}
}), /HWLAB_WORKBENCH_KAFKA_REFRESH_REPLAY_ENABLED/u);
assert.equal(await canConnect(port), false, "serveCloudWeb must not bind before runtime configuration is valid");
});
assert.equal(await canConnect(port), true);
} finally {
if (server) await close(server);
restoreEnv();
}
});
@@ -497,7 +517,7 @@ test("cloud web serves client deep links through the Vue shell", async () => {
const html = await response.text();
assert.match(html, /<div id="root"><\/div>/u, route);
assert.match(html, /HWLAB_CLOUD_WEB_CONFIG/u, route);
assert.match(html, /"realtimeFeatures":\{"liveKafkaSse":true,"kafkaRefreshReplay":true,"projectionRealtime":false\}/u, route);
assert.doesNotMatch(html, /realtimeFeatures|liveKafkaSse|kafkaRefreshReplay|projectionRealtime/u, route);
assert.match(html, /"debugCapabilities":\{"isolatedKafka":true,"rawHwlabEventWindow":\{"enabled":true,"maxEntries":200,"maxRetainedBytes":1048576\}\}/u, route);
}