/** * Metric catalog (CLAUDE.md §250-252, §352). Every derived number shown on the site references * one of these definitions by slug; the formula text and version are displayed on /methodology. * * Composite scores (CI-IMPACT etc.) are intentionally absent from Phase 1 (§353). */ export interface MetricSeed { slug: string; name: string; description: string; formula: string; formulaVersion: string; unit: string; higherIsWorse: boolean | null; aggregation: string | null; validDimensions: string[]; sourceSlugs: string[]; category: string; eligibility: Record; experimental: boolean; } export const METRIC_CATALOG: MetricSeed[] = [ // --- Burden (epidemiology observations) --- { slug: 'incidence_count', name: 'Annual new cases', description: 'Number of new cases diagnosed in the reference year for the population scope. Registry counts are observed; national/global figures may be estimates and are labeled as such.', formula: 'epidemiology_observations.value WHERE metric = incidence_count', formulaVersion: 'ci-incidence-count-v1', unit: 'count', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'sex', 'age_group', 'year'], sourceSlugs: ['cdc-wonder', 'seer', 'iarc-globocan'], category: 'burden', eligibility: { requires: ['incidence_count'], entityLevel: 'top' }, experimental: false, }, { slug: 'mortality_count', name: 'Annual deaths', description: 'Number of deaths with this cancer as underlying cause in the reference year for the population scope.', formula: 'epidemiology_observations.value WHERE metric = mortality_count', formulaVersion: 'ci-mortality-count-v1', unit: 'count', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'sex', 'age_group', 'year'], sourceSlugs: ['cdc-wonder', 'seer', 'iarc-globocan'], category: 'burden', eligibility: { requires: ['mortality_count'], entityLevel: 'top' }, experimental: false, }, { slug: 'as_incidence_rate', name: 'Age-standardized incidence rate', description: 'Incidence per 100,000 person-years, age-standardized to the standard population declared by the source. Rates standardized to different standard populations are never compared in one ranking.', formula: 'epidemiology_observations.value WHERE metric = as_incidence_rate (standard_population fixed per scope)', formulaVersion: 'ci-asir-v1', unit: 'per_100k', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'sex', 'year'], sourceSlugs: ['cdc-wonder', 'seer', 'iarc-globocan'], category: 'burden', eligibility: { requires: ['as_incidence_rate'], entityLevel: 'top' }, experimental: false, }, { slug: 'as_mortality_rate', name: 'Age-standardized mortality rate', description: 'Deaths per 100,000 person-years, age-standardized to the standard population declared by the source.', formula: 'epidemiology_observations.value WHERE metric = as_mortality_rate (standard_population fixed per scope)', formulaVersion: 'ci-asmr-v1', unit: 'per_100k', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'sex', 'year'], sourceSlugs: ['cdc-wonder', 'seer', 'iarc-globocan'], category: 'burden', eligibility: { requires: ['as_mortality_rate'], entityLevel: 'top' }, experimental: false, }, // --- Lethality --- { slug: 'mortality_incidence_ratio', name: 'Mortality-to-incidence ratio', description: 'Deaths divided by new cases in the same population, year and sex. A crude proxy of lethality; it is not a survival probability and is affected by incidence trends and registration completeness.', formula: 'mortality_count / incidence_count (same geography, year, sex, source family)', formulaVersion: 'ci-mir-v1', unit: 'ratio', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'sex', 'year'], sourceSlugs: ['cdc-wonder', 'seer', 'iarc-globocan'], category: 'lethality', eligibility: { requires: ['incidence_count', 'mortality_count'], minIncidence: 100, entityLevel: 'top' }, experimental: false, }, { slug: 'five_year_survival', name: '5-year relative survival', description: '5-year relative survival for the diagnosis period and population declared by the source. Population survival statistics do not predict an individual outcome.', formula: 'survival_observations.probability WHERE survival_type = relative AND duration_months = 60 AND stage IS NULL', formulaVersion: 'ci-5ys-v1', unit: 'probability', higherIsWorse: false, aggregation: 'none', validDimensions: ['geography', 'sex', 'diagnosis_period'], sourceSlugs: ['seer'], category: 'lethality', eligibility: { requires: ['five_year_relative_survival'], minCohort: 50, entityLevel: 'top' }, experimental: false, }, // --- Clinical research (ClinicalTrials.gov) --- { slug: 'active_trials', name: 'Active clinical trials', description: 'Interventional studies registered on ClinicalTrials.gov whose overall status is RECRUITING, NOT_YET_RECRUITING, ENROLLING_BY_INVITATION or ACTIVE_NOT_RECRUITING and whose conditions map to this cancer or one of its descendants in the NCIt hierarchy.', formula: 'COUNT(DISTINCT trial) FROM trial_conditions JOIN clinical_trials WHERE cancer_id IN descendants(cancer) AND study_type = INTERVENTIONAL AND overall_status IN (RECRUITING, NOT_YET_RECRUITING, ENROLLING_BY_INVITATION, ACTIVE_NOT_RECRUITING)', formulaVersion: 'ci-active-trials-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['clinicaltrials'], category: 'trials', eligibility: { entityLevel: 'any' }, experimental: false, }, { slug: 'recruiting_trials', name: 'Recruiting clinical trials', description: 'Interventional studies currently RECRUITING whose conditions map to this cancer or its descendants.', formula: 'COUNT(DISTINCT trial) … overall_status = RECRUITING AND study_type = INTERVENTIONAL', formulaVersion: 'ci-recruiting-trials-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['clinicaltrials'], category: 'trials', eligibility: { entityLevel: 'any' }, experimental: false, }, { slug: 'phase3_trials', name: 'Active Phase III trials', description: 'Active interventional studies with PHASE3 among their phases, mapped to this cancer or its descendants.', formula: 'COUNT(DISTINCT trial) … active statuses AND PHASE3 = ANY(phases)', formulaVersion: 'ci-phase3-trials-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['clinicaltrials'], category: 'trials', eligibility: { entityLevel: 'any' }, experimental: false, }, // --- Research activity (PubMed) --- { slug: 'publications_5y', name: 'Publications, last 5 years', description: 'PubMed records matching the cancer’s MeSH-anchored query (stored verbatim with the count) with a publication date in the last 5 full years plus the current year.', formula: 'literature_counts.count WHERE window_key = 5y (query stored per row)', formulaVersion: 'ci-pubs-5y-v1', unit: 'count', higherIsWorse: false, aggregation: 'none', validDimensions: ['entity_level'], sourceSlugs: ['pubmed'], category: 'research', eligibility: { entityLevel: 'any', requiresQuery: true }, experimental: false, }, { slug: 'publications_12m', name: 'Publications, last 12 months', description: 'PubMed records matching the cancer’s query with a publication date in the last 12 months.', formula: 'literature_counts.count WHERE window_key = 12m', formulaVersion: 'ci-pubs-12m-v1', unit: 'count', higherIsWorse: false, aggregation: 'none', validDimensions: ['entity_level'], sourceSlugs: ['pubmed'], category: 'research', eligibility: { entityLevel: 'any', requiresQuery: true }, experimental: false, }, { slug: 'publication_growth', name: 'Publication growth', description: 'Ratio of publications in the last 12 months to the average annual publications over the preceding 5-year window. Values above 1 indicate accelerating literature.', formula: 'publications_12m / (publications_5y_prior / 5)', formulaVersion: 'ci-pub-growth-v1', unit: 'ratio', higherIsWorse: null, aggregation: 'none', validDimensions: ['entity_level'], sourceSlugs: ['pubmed'], category: 'trend', eligibility: { entityLevel: 'any', minPublications5y: 50 }, experimental: false, }, // --- Molecular knowledge --- { slug: 'curated_evidence_items', name: 'Curated clinical evidence items', description: 'Accepted CIViC evidence items whose disease maps to this cancer or its descendants.', formula: 'COUNT(civic_evidence_items) WHERE status = ACCEPTED AND cancer_id IN descendants(cancer)', formulaVersion: 'ci-civic-evidence-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['civic'], category: 'molecular', eligibility: { entityLevel: 'any' }, experimental: false, }, { slug: 'associated_genes', name: 'Genes with curated or cohort evidence', description: 'Distinct genes linked to this cancer (or descendants) by an accepted CIViC evidence item or by a GDC cohort frequency of at least 5% with ≥ 20 affected cases.', formula: 'COUNT(DISTINCT gene) FROM (civic accepted evidence ∪ gdc frequency ≥ 0.05 AND cases_affected ≥ 20)', formulaVersion: 'ci-genes-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['civic', 'gdc'], category: 'molecular', eligibility: { entityLevel: 'any' }, experimental: false, }, { slug: 'genomic_cohorts', name: 'Public genomic cohorts', description: 'Open-access genomic studies (GDC projects) whose disease maps to this cancer or its descendants.', formula: 'COUNT(genomic_cohorts) WHERE cancer_id IN descendants(cancer)', formulaVersion: 'ci-cohorts-v1', unit: 'count', higherIsWorse: false, aggregation: 'descendants', validDimensions: ['entity_level'], sourceSlugs: ['gdc'], category: 'molecular', eligibility: { entityLevel: 'any' }, experimental: false, }, // --- Gap indexes (derived; require burden) --- { slug: 'trial_gap', name: 'Trial Gap Index', description: 'Burden percentile minus active-trial percentile within the same scope. Positive values flag cancers with high mortality burden but comparatively few active trials. A quantitative signal, not an accusation (CLAUDE.md §324). Caveat (Phase 1): trial counts aggregate a cancer and its NCIt descendants only; registrations phrased at a broader level (e.g. "colorectal cancer" for colon and rectal cancer) are attributed to the broader entity, which can overstate the gap of narrower top-level sites.', formula: 'percentile(mortality_count) − percentile(active_trials)', formulaVersion: 'ci-trial-gap-v1', unit: 'percentile_points', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'year'], sourceSlugs: ['clinicaltrials', 'cdc-wonder', 'seer', 'iarc-globocan'], category: 'unmet_need', eligibility: { requires: ['mortality_count', 'active_trials'], entityLevel: 'top' }, experimental: false, }, { slug: 'research_gap', name: 'Research Gap Index', description: 'Burden percentile minus research-activity percentile (publications, last 5 years) within the same scope. Positive values flag cancers with high mortality burden but comparatively little literature. Caveat (Phase 1): literature counts are query-based per entity (query stored on each row); they are not aggregated over descendants.', formula: 'percentile(mortality_count) − percentile(publications_5y)', formulaVersion: 'ci-research-gap-v1', unit: 'percentile_points', higherIsWorse: true, aggregation: 'none', validDimensions: ['geography', 'year'], sourceSlugs: ['pubmed', 'cdc-wonder', 'seer', 'iarc-globocan'], category: 'unmet_need', eligibility: { requires: ['mortality_count', 'publications_5y'], entityLevel: 'top' }, experimental: false, }, ];