diff --git a/lib/firm-catalog.ts b/lib/firm-catalog.ts index 5d74992..716a094 100644 --- a/lib/firm-catalog.ts +++ b/lib/firm-catalog.ts @@ -104,6 +104,10 @@ export function getCatalogMeta(): { export function getTradableFirms(): (CatalogFirm & { username: string; password: string })[] { const result: (CatalogFirm & { username: string; password: string })[] = []; for (const firm of getCachedCatalog()) { + // Only Tradovate has a client. A TopstepX firm in the catalog is + // config-only for now; handing it to the Tradovate login would just + // burn attempts against the wrong platform. + if (firm.platform !== 'tradovate') continue; const creds = getCredentials(firm.id); if (creds) result.push({ ...firm, ...creds }); } @@ -156,6 +160,10 @@ function validatePayload(raw: unknown): FirmCatalogPayload { return { id: firm.id, name: firm.name, + // Lenient on purpose: a master from before the platform field (or + // with a platform this build doesn't know) must not fail the whole + // sync, and 'tradovate' is what every firm was until then. + platform: firm.platform === 'topstepx' ? 'topstepx' : 'tradovate', bannedSymbols: Array.isArray(firm.bannedSymbols) ? (firm.bannedSymbols as string[]) : [], accountTypes, updatedAt: typeof firm.updatedAt === 'string' ? firm.updatedAt : new Date(0).toISOString(), diff --git a/lib/master-protocol.ts b/lib/master-protocol.ts index 07e6ce7..733e985 100644 --- a/lib/master-protocol.ts +++ b/lib/master-protocol.ts @@ -78,6 +78,10 @@ export interface CatalogAccountType { export interface CatalogFirm { id: string; name: string; + /** Which platform the firm's accounts trade on. Only 'tradovate' firms get + * a client here; anything else is synced but sits idle until its trading + * logic exists. Older masters omit the field — treated as 'tradovate'. */ + platform: 'tradovate' | 'topstepx'; bannedSymbols: string[]; accountTypes: CatalogAccountType[]; updatedAt: string;