import { eq } from 'drizzle-orm'; import { type Database, sources, mintId } from '@cancerindex/database'; import { CONNECTORS } from './registry.js'; import type { ConnectorManifest } from './sdk/manifest.js'; /** Sync connector manifests into the `sources` registry (CLAUDE.md §95, §142, §307). Idempotent. */ export async function syncSources(db: Database, extra: ConnectorManifest[] = []): Promise<{ created: number; updated: number }> { let created = 0; let updated = 0; const manifests = [...CONNECTORS.map((c) => c.manifest), ...extra]; for (const m of manifests) { const values = { slug: m.id, name: m.name, organization: m.organization, category: m.category, description: m.description, homepage: m.homepage, docsUrl: m.docsUrl ?? null, termsUrl: m.termsUrl ?? null, accessType: m.access.type, accessAuth: m.access.auth, license: m.license, licenseStatus: m.licenseStatus, commercialUse: m.commercialUse, redistribution: m.redistribution, attribution: m.attribution ?? null, licenseReviewedAt: m.termsReviewedAt ? new Date(m.termsReviewedAt) : null, approvedForProduction: m.licenseStatus === 'approved', updateFrequency: m.updateFrequency, supportsIncremental: m.supportsIncrementalSync, entities: m.entities, metrics: m.metrics, rateLimit: m.rateLimits.requestsPerSecond ? `${m.rateLimits.requestsPerSecond} req/s` : m.rateLimits.requestsPerMinute ? `${m.rateLimits.requestsPerMinute} req/min` : null, tier: m.tier, manifest: m as unknown as Record, updatedAt: new Date(), }; const [existing] = await db.select({ id: sources.id, status: sources.status }).from(sources).where(eq(sources.slug, m.id)).limit(1); if (existing) { // Keep runtime status (active/degraded) unless manifest declares a gating status. const gating = ['awaiting_credentials', 'review', 'retired', 'paused'].includes(m.status); await db.update(sources).set({ ...values, ...(gating ? { status: m.status } : {}) }).where(eq(sources.id, existing.id)); updated++; } else { await db.insert(sources).values({ id: await mintId(db, 'SOURCE'), ...values, status: m.status }); created++; } } return { created, updated }; }