feat(FEAT-DS-001): 接入AKTools超短行情补充数据源

This commit is contained in:
2026-08-24 21:40:22 +08:00
parent 81c48af8cc
commit 6e8a05114e
42 changed files with 1449 additions and 36 deletions
+39
View File
@@ -41,6 +41,13 @@ export interface TdxRuntimeConfig {
timeoutMs: number;
}
/** AKTools 仅作为本机内网补充源,启用时固定回环地址和端口。 */
export interface AktoolsRuntimeConfig {
enabled: boolean;
baseUrl: string;
timeoutMs: number;
}
/** RocketMQ 公共寻址配置;实际生产/消费参数由相应进程扩展。 */
export interface RocketMqRuntimeConfig {
enabled: boolean;
@@ -61,6 +68,7 @@ export interface ApiRuntimeConfig extends CommonRuntimeConfig {
processName: 'api';
api: Readonly<{ host: string; port: number }>;
tdx: Readonly<TdxRuntimeConfig>;
aktools: Readonly<AktoolsRuntimeConfig>;
mysql: MysqlRuntimeConfig;
ai: AiRuntimeConfig;
}
@@ -227,6 +235,35 @@ function loadTdxConfig(env: EnvironmentSource): TdxRuntimeConfig {
};
}
function loadAktoolsConfig(env: EnvironmentSource): AktoolsRuntimeConfig {
const enabled = env.AKTOOLS_ENABLED === undefined ? false : parseBoolean(env, 'AKTOOLS_ENABLED');
const baseUrl = optionalText(env, 'AKTOOLS_BASE_URL') || 'http://127.0.0.1:8080';
let parsed: URL;
try {
parsed = new URL(baseUrl);
} catch {
throw new Error('AKTOOLS_BASE_URL 必须为有效 URL');
}
if (parsed.protocol !== 'http:') throw new Error('AKTOOLS_BASE_URL 必须使用 http 协议');
if (parsed.hostname !== '127.0.0.1') {
throw new Error('AKTOOLS_BASE_URL 必须指向本机回环地址');
}
if (parsed.port !== '8080') throw new Error('AKTOOLS_BASE_URL 必须使用 8080 端口');
if (parsed.pathname !== '' && parsed.pathname !== '/') {
throw new Error('AKTOOLS_BASE_URL 不得包含额外路径');
}
return {
enabled,
baseUrl: parsed.toString().replace(/\/$/, ''),
timeoutMs:
env.AKTOOLS_TIMEOUT_MS === undefined
? 10_000
: parseInteger(env, 'AKTOOLS_TIMEOUT_MS', { min: 100, max: 30_000 }),
};
}
function loadRocketMqConfig(env: EnvironmentSource): RocketMqRuntimeConfig {
const enabled = parseBoolean(env, 'ROCKETMQ_ENABLED');
const nameServerAddress = optionalText(env, 'ROCKETMQ_NAMESRV_ADDR');
@@ -257,6 +294,7 @@ export function loadApiConfig(env: EnvironmentSource): ApiRuntimeConfig {
port: parseInteger(env, 'API_PORT', { min: 1, max: 65_535 }),
},
tdx: loadTdxConfig(env),
aktools: loadAktoolsConfig(env),
redis: loadRedisConfig(env),
mysql: loadMysqlConfig(env),
ai: loadAiConfig(env),
@@ -335,6 +373,7 @@ export function toSafeRuntimeSummary(config: RuntimeConfig): Readonly<Record<str
};
if (config.processName === 'api') summary.api = config.api;
if (config.processName === 'api') summary.aktools = { enabled: config.aktools.enabled };
if (config.processName === 'scheduler') summary.scheduler = config.scheduler;
if (config.processName === 'worker') summary.marketData = { mode: config.marketData.mode };