SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
3.2 KB · 68 lines typescript
Raw Blame History
1import { z } from 'zod';23/** Connector manifest (CLAUDE.md §9). Seeds the `sources` table; drives the public /source pages. */4export const ConnectorManifest = z.object({5  id: z.string().regex(/^[a-z0-9-]+$/),6  name: z.string(),7  organization: z.string(),8  category: z.enum(['terminology', 'genes', 'genomics', 'variants', 'epidemiology', 'trials', 'literature', 'drugs', 'regulatory', 'evidence', 'pathways', 'funding', 'guidelines']),9  tier: z.number().int().min(0).max(11),10  description: z.string(),11  homepage: z.string().url(),12  docsUrl: z.string().url().optional(),13  termsUrl: z.string().url().optional(),14  access: z.object({15    type: z.enum(['api', 'bulk', 'rss', 'ftp', 'graphql', 'rest', 'scrape', 'manual']),16    auth: z.enum(['none', 'api_key', 'oauth', 'account', 'controlled']),17    baseUrl: z.string().url().optional(),18  }),19  license: z.string(),20  licenseStatus: z.enum(['review', 'approved', 'restricted', 'blocked']),21  commercialUse: z.enum(['allowed', 'restricted', 'prohibited', 'unknown']),22  redistribution: z.enum(['allowed', 'attribution', 'restricted', 'prohibited', 'unknown']),23  attribution: z.string().optional(),24  termsReviewedAt: z.string().optional(), // YYYY-MM-DD, human review date25  termsNotes: z.string().optional(),26  updateFrequency: z.string(),27  expectedLatency: z.string().optional(),28  supportsIncrementalSync: z.boolean(),29  entities: z.array(z.string()),30  metrics: z.array(z.string()).default([]),31  rateLimits: z.object({32    requestsPerSecond: z.number().positive().optional(),33    requestsPerMinute: z.number().positive().optional(),34    maxConcurrency: z.number().int().positive().default(1),35    notes: z.string().optional(),36  }),37  retryPolicy: z38    .object({39      maxRetries: z.number().int().min(0).default(4),40      baseDelayMs: z.number().int().min(0).default(500),41      maxDelayMs: z.number().int().min(0).default(30_000),42    })43    .default({ maxRetries: 4, baseDelayMs: 500, maxDelayMs: 30_000 }),44  rawRetention: z.enum(['full', 'summary', 'none']).default('full'),45  schemaVersion: z.string().default('1'),46  documentationVerifiedAt: z.string(), // YYYY-MM-DD, the date official docs were checked (CLAUDE.md §224-225)47  owner: z.string().default('cancerindex'),48  status: z.enum(['planned', 'active', 'paused', 'awaiting_credentials', 'review', 'retired']),49  schedule: z.string().optional(), // cron expression for the worker scheduler50  anomalyGuard: z51    .object({52      /** Refuse to mark records source_missing when the fetched count drops below this ratio of the previous run. */53      minRatioOfPrevious: z.number().min(0).max(1).default(0.5),54    })55    .default({ minRatioOfPrevious: 0.5 }),56  /**57   * Mid-run cursor checkpoint (CLAUDE.md §90): `connector_cursors.cursor` is persisted after this many58   * upserted records (or every 60 s) whenever `ctx.cursor` changed, so a killed run resumes from the59   * last completed page instead of from the start of the run. See docs/connectors/README.md.60   */61  checkpointEvery: z.number().int().positive().default(2000),62});63export type ConnectorManifest = z.infer<typeof ConnectorManifest>;6465export function defineManifest(m: z.input<typeof ConnectorManifest>): ConnectorManifest {66  return ConnectorManifest.parse(m);67}68