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%
2.1 KB · 56 lines typescript
Raw Blame History
1import type { Database } from '@cancerindex/database';2import { computeTrialIntelligence } from './trial-intelligence.js';3import { computeTrialSiteCounts } from './trial-sites.js';4import { computeDrugPipeline } from './drug-pipeline.js';5import { computeResearchGap } from './research-gap.js';67export interface IntelligenceResult {8  trialIntelligenceRows: number;9  trialSiteCountryRows: number;10  drugPipelineRows: number;11  researchGapRows: number;12  ms: number;13}1415/**16 * Derived "intelligence" layer (SPEC §10-11, §15, §34): recomputed after counters, before rankings.17 * Each part is independent and deterministic; a failure in one part is reported, not hidden, and18 * does not prevent the others from running.19 */20export async function computeIntelligence(db: Database, log: (msg: string, extra?: Record<string, unknown>) => void = () => {}): Promise<IntelligenceResult> {21  const t0 = Date.now();22  const out: IntelligenceResult = { trialIntelligenceRows: 0, trialSiteCountryRows: 0, drugPipelineRows: 0, researchGapRows: 0, ms: 0 };23  const errors: string[] = [];24  try {25    const r = await computeTrialIntelligence(db);26    out.trialIntelligenceRows = r.rows;27    log('trial intelligence computed', { ...r });28  } catch (e) {29    errors.push(`trial-intelligence: ${(e as Error).message}`);30  }31  try {32    const r = await computeTrialSiteCounts(db);33    out.trialSiteCountryRows = r.rows;34    log('trial site country counts computed', { ...r });35  } catch (e) {36    errors.push(`trial-sites: ${(e as Error).message}`);37  }38  try {39    const r = await computeDrugPipeline(db);40    out.drugPipelineRows = r.rows;41    log('drug pipeline computed', { ...r });42  } catch (e) {43    errors.push(`drug-pipeline: ${(e as Error).message}`);44  }45  try {46    const r = await computeResearchGap(db);47    out.researchGapRows = r.rows;48    log('research gap components computed', { ...r });49  } catch (e) {50    errors.push(`research-gap: ${(e as Error).message}`);51  }52  out.ms = Date.now() - t0;53  if (errors.length) throw new Error(`intelligence partially failed: ${errors.join(' | ')}`);54  return out;55}56