spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import 'server-only';2import { run, sql, safe } from '@/lib/db';3import type { ProvenanceInfo } from '@/components/ui/source-badge';45export interface ProvRow {6 id: number;7 source_id: string;8 source_slug: string;9 source_name: string;10 source_url: string | null;11 dataset: string | null;12 dataset_version: string | null;13 retrieved_at: Date;14 evidence_type: string;15 license: string | null;16 pmid: string | null;17 ingest_run_id: string | null;18 source_record_id: string | null;19 methodology: string | null;20 population: string | null;21 geography: string | null;22}2324/** Load provenance rows (joined with the source) for a set of ids, keyed by id. */25export async function loadProvenance(ids: Array<number | null | undefined>): Promise<Map<number, ProvRow>> {26 const uniq = [...new Set(ids.filter((i): i is number => typeof i === 'number' && Number.isFinite(i)))];27 if (uniq.length === 0) return new Map();28 const rows = await safe(29 () =>30 run<ProvRow>(sql`31 SELECT p.id, p.source_id, s.slug AS source_slug, s.name AS source_name, p.source_url, p.dataset, p.dataset_version,32 p.retrieved_at, p.evidence_type, coalesce(p.license, s.license) AS license, p.pmid, p.ingest_run_id, p.source_record_id,33 p.methodology, p.population, p.geography34 FROM provenance p JOIN sources s ON s.id = p.source_id35 WHERE p.id IN ${sql`(${sql.join(uniq.map((i) => sql`${i}`), sql`, `)})`}`),36 [] as ProvRow[],37 );38 return new Map(rows.map((r) => [Number(r.id), r]));39}4041export function toInfo(p: ProvRow | undefined, layer: ProvenanceInfo['layer'] = 'normalized'): ProvenanceInfo | null {42 if (!p) return null;43 return {44 sourceSlug: p.source_slug,45 sourceName: p.source_name,46 dataset: p.dataset,47 datasetVersion: p.dataset_version,48 retrievedAt: p.retrieved_at,49 sourceUrl: p.source_url,50 layer,51 license: p.license,52 evidenceType: p.evidence_type,53 pmid: p.pmid,54 ingestRunId: p.ingest_run_id,55 };56}5758/** Minimal source lookup for badges when only a source_id is known. */59export async function sourceInfoById(ids: Array<string | null | undefined>): Promise<Map<string, { slug: string; name: string; license: string | null }>> {60 const uniq = [...new Set(ids.filter((i): i is string => !!i))];61 if (uniq.length === 0) return new Map();62 const rows = await safe(63 () => run<{ id: string; slug: string; name: string; license: string | null }>(sql`SELECT id, slug, name, license FROM sources WHERE id IN (${sql.join(uniq.map((i) => sql`${i}`), sql`, `)})`),64 [] as Array<{ id: string; slug: string; name: string; license: string | null }>,65 );66 return new Map(rows.map((r) => [r.id, { slug: r.slug, name: r.name, license: r.license }]));67}68