From 39542f5e154cb822490a1a47cead0ac9f76ba5b6 Mon Sep 17 00:00:00 2001 From: iridite Date: Mon, 25 May 2026 10:47:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(uta):=20export=20utaConfigSchema=20from=20u?= =?UTF-8?q?ta-protocol=20=E2=80=94=20unbreaks=20test-connection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UTA service's `/test-connection` endpoint (routes-trading.ts:191) imports `utaConfigSchema` from `@traderalice/uta-protocol`, but the schema was only defined in Alice's `src/core/config.ts` and never exported from the protocol package. This caused a TypeError: Cannot read properties of undefined (reading 'parse') …on every "Test " action in the New UTA flow (affects all exchanges, not just Bitget). Fix: define `utaConfigSchema` + `guardConfigSchema` in the protocol package (`packages/uta-protocol/src/schemas/index.ts`) and re-export from `src/core/config.ts` to keep the existing public API intact. Co-Authored-By: Claude Opus 4.6 --- packages/uta-protocol/src/schemas/index.ts | 22 ++++++++++++- src/core/config.ts | 38 ++-------------------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/packages/uta-protocol/src/schemas/index.ts b/packages/uta-protocol/src/schemas/index.ts index 9e3cd60e3..38cdec863 100644 --- a/packages/uta-protocol/src/schemas/index.ts +++ b/packages/uta-protocol/src/schemas/index.ts @@ -7,5 +7,25 @@ * lifts each route. */ -export {} +import { z } from 'zod' + +const guardConfigSchema = z.object({ + type: z.string(), + options: z.record(z.string(), z.unknown()).default({}), +}) + +export const utaConfigSchema = z.object({ + id: z.string(), + label: z.string().optional(), + presetId: z.string(), + enabled: z.boolean().default(true), + guards: z.array(guardConfigSchema).default([]), + presetConfig: z.record(z.string(), z.unknown()).default({}), + ephemeral: z.boolean().optional(), +}).refine((u) => u.ephemeral !== true || u.presetId === 'mock-simulator', { + message: 'ephemeral: true is only allowed on mock-simulator UTAs (would destroy real broker history at next boot)', + path: ['ephemeral'], +}) + +export type UTAConfig = z.infer diff --git a/src/core/config.ts b/src/core/config.ts index 32d71ec4c..b1a70e626 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -315,45 +315,11 @@ export type WebChannel = z.infer // ==================== UTA Config ==================== -const guardConfigSchema = z.object({ - type: z.string(), - options: z.record(z.string(), z.unknown()).default({}), -}) - -/** - * One Unified Trading Account. The user-facing concept — one preset - * (OKX, Bybit, IBKR, …) plus credentials, guards, and an enabled flag. - * - * Distinct from `AccountInfo` (which is broker-side: cash, equity, - * margin returned by `IBroker.getAccount()`). Two different "account"s. - */ -export const utaConfigSchema = z.object({ - id: z.string(), - label: z.string().optional(), - /** Broker preset id — resolves to engine + form schema via BROKER_PRESET_CATALOG. */ - presetId: z.string(), - enabled: z.boolean().default(true), - guards: z.array(guardConfigSchema).default([]), - /** User-filled form values, validated against the preset's own zodSchema. */ - presetConfig: z.record(z.string(), z.unknown()).default({}), - /** - * Test/throwaway UTA — purged at every server startup (config entry - * removed + `data/trading//` wiped) and dropped immediately when - * deleted via the UTA-config DELETE endpoint. For fixture-based testing: - * each session starts from a clean slate, no cross-session cost-basis - * pollution. Only allowed on `mock-simulator` preset; setting it on a - * real broker would silently destroy account history on next boot. - */ - ephemeral: z.boolean().optional(), -}).refine((u) => u.ephemeral !== true || u.presetId === 'mock-simulator', { - message: 'ephemeral: true is only allowed on mock-simulator UTAs (would destroy real broker history at next boot)', - path: ['ephemeral'], -}) +import { utaConfigSchema, type UTAConfig } from '@traderalice/uta-protocol' +export { utaConfigSchema, UTAConfig } export const utasFileSchema = z.array(utaConfigSchema) -export type UTAConfig = z.infer - // ==================== Unified Config Type ==================== export type Config = {