import type { ConnectorDefinition } from "@market-atlas/connector-sdk"; import { CONNECTORS, SOURCES } from "@market-atlas/connectors"; import { config } from "../config.js"; import { pool } from "../db/pool.js"; import { logger } from "../logger.js"; import { connectorManager } from "./connector-manager.js"; import { instruments } from "./instruments.js"; /** Syncs code-defined sources/connectors into the DB (metadata is code; runtime flags are DB) and registers them. */ export async function syncRegistry(): Promise { for (const s of SOURCES) { await pool.query( `insert into sources (id, name, organization, source_type, homepage, jurisdiction, rights_status, realtime_status, family, category, enabled) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) on conflict (id) do update set name = excluded.name, organization = excluded.organization, source_type = excluded.source_type, homepage = excluded.homepage, jurisdiction = excluded.jurisdiction, rights_status = excluded.rights_status, realtime_status = excluded.realtime_status, family = excluded.family, category = excluded.category, updated_at = now()`, [s.id, s.name, s.organization, s.sourceType, s.homepage, s.jurisdiction, s.rightsStatus, s.realtimeStatus, s.family, s.category, s.enabled], ); } const registered: ConnectorDefinition[] = []; for (const def of CONNECTORS) { const m = def.metadata; const enabled = m.enabled && !config.disabledConnectors.has(m.id); await pool.query( `insert into connectors (id, source_id, name, version, source_type, rights_status, realtime_status, enabled, metadata) values ($1,$2,$3,$4,$5,$6,$7,$8,$9) on conflict (id) do update set source_id = excluded.source_id, name = excluded.name, version = excluded.version, source_type = excluded.source_type, rights_status = excluded.rights_status, realtime_status = excluded.realtime_status, enabled = excluded.enabled, metadata = excluded.metadata, updated_at = now()`, [m.id, m.sourceId, m.name, m.version, m.sourceType, m.rightsStatus, m.realtimeStatus, enabled, JSON.stringify(m)], ); await pool.query(`insert into connector_versions (connector_id, version, metadata) values ($1,$2,$3) on conflict do nothing`, [m.id, m.version, JSON.stringify({ description: m.description })]); const row = (await pool.query<{ paused: boolean; state: Record; schema_fingerprints: Record }>("select paused, state, schema_fingerprints from connectors where id = $1", [m.id])).rows[0]!; if (!enabled) { logger.info({ connector: m.id }, "connector disabled"); continue; } // Seed static instruments declared by the connector. for (const seed of def.seeds ?? []) { const inst = await instruments.resolveOrCreate(seed.symbol, m.sourceId, seed.hint); if (inst) for (const a of seed.aliases ?? []) await instruments.addAlias(a, "*", inst.id); } await connectorManager.register(def, { paused: row.paused, state: row.state ?? {}, fingerprints: row.schema_fingerprints ?? {} }); registered.push(def); } logger.info({ connectors: registered.length, sources: SOURCES.length }, "registry synced"); return registered; }