feat: 沉淀 Workbench Kafka 隔离重放探针

This commit is contained in:
Codex
2026-07-10 13:51:05 +02:00
parent ea7bc0f444
commit 93abd9ba88
18 changed files with 490 additions and 10 deletions
+29
View File
@@ -154,6 +154,14 @@ export interface HwlabRuntimeWebProbeSpec {
readonly browserFreezePolicy?: HwlabRuntimeWebProbeBrowserFreezePolicySpec;
readonly projectManagement?: HwlabRuntimeWebProbeProjectManagementSpec;
readonly realtimeFanoutProfiles?: Readonly<Record<string, HwlabRuntimeWebProbeRealtimeFanoutProfileSpec>>;
readonly workbenchKafkaDebugReplay?: HwlabRuntimeWebProbeWorkbenchKafkaDebugReplaySpec;
}
export interface HwlabRuntimeWebProbeWorkbenchKafkaDebugReplaySpec {
readonly enabled: boolean;
readonly topic: string;
readonly groupPrefix: string;
readonly completionTimeoutMs: number;
}
export interface HwlabRuntimeWebProbeRealtimeFanoutProfileSpec {
@@ -1298,6 +1306,27 @@ function webProbeConfig(value: unknown, path: string): HwlabRuntimeWebProbeSpec
...(raw.browserFreezePolicy === undefined ? {} : { browserFreezePolicy: webProbeBrowserFreezePolicyConfig(raw.browserFreezePolicy, `${path}.browserFreezePolicy`) }),
...(raw.projectManagement === undefined ? {} : { projectManagement: webProbeProjectManagementConfig(raw.projectManagement, `${path}.projectManagement`) }),
...(raw.realtimeFanoutProfiles === undefined ? {} : { realtimeFanoutProfiles: webProbeRealtimeFanoutProfilesConfig(raw.realtimeFanoutProfiles, `${path}.realtimeFanoutProfiles`) }),
...(raw.workbenchKafkaDebugReplay === undefined
? {}
: { workbenchKafkaDebugReplay: webProbeWorkbenchKafkaDebugReplayConfig(raw.workbenchKafkaDebugReplay, `${path}.workbenchKafkaDebugReplay`) }),
};
}
function webProbeWorkbenchKafkaDebugReplayConfig(value: unknown, path: string): HwlabRuntimeWebProbeWorkbenchKafkaDebugReplaySpec {
const raw = asRecord(value, path);
const topic = stringField(raw, "topic", path);
const groupPrefix = stringField(raw, "groupPrefix", path);
const completionTimeoutMs = numberField(raw, "completionTimeoutMs", path);
if (!/^[A-Za-z0-9._-]+$/u.test(topic)) throw new Error(`${path}.topic must use Kafka topic identifier characters`);
if (!/^[A-Za-z0-9._-]+$/u.test(groupPrefix)) throw new Error(`${path}.groupPrefix must use Kafka consumer group identifier characters`);
if (!Number.isInteger(completionTimeoutMs) || completionTimeoutMs < 1000 || completionTimeoutMs > 120000) {
throw new Error(`${path}.completionTimeoutMs must be an integer between 1000 and 120000`);
}
return {
enabled: booleanField(raw, "enabled", path),
topic,
groupPrefix,
completionTimeoutMs,
};
}