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%
5.1 KB · 90 lines typescript
Raw Blame History
1import { pgTable, text, integer, bigserial, index, uniqueIndex, boolean, jsonb, real, timestamp } from 'drizzle-orm/pg-core';2import { ciId, createdAt, updatedAt } from './_common.js';34/** Knowledge graph edge with mandatory context and provenance (CLAUDE.md §28-29, §244). */5export const knowledgeEdges = pgTable(6  'knowledge_edges',7  {8    id: bigserial('id', { mode: 'number' }).primaryKey(),9    sourceEntityType: text('source_entity_type').notNull(), // cancer | gene | variant | drug | biomarker | trial | publication | pathway | risk_factor10    sourceEntityId: text('source_entity_id').notNull(),11    targetEntityType: text('target_entity_type').notNull(),12    targetEntityId: text('target_entity_id').notNull(),13    relationshipType: text('relationship_type').notNull(), // HAS_SUBTYPE | OCCURS_IN | ASSOCIATED_WITH | HAS_VARIANT | HAS_BIOMARKER | TREATED_BY | STUDIED_IN | DESCRIBED_BY | TARGETS | APPROVED_FOR | INVESTIGATED_FOR | PREDICTS_RESPONSE_TO | CONFERS_RESISTANCE_TO | PREDISPOSES_TO | PROGNOSTIC_IN | DIAGNOSTIC_OF14    cancerContextIds: text('cancer_context_ids').array().notNull().default([]),15    predictive: boolean('predictive'),16    prognostic: boolean('prognostic'),17    diagnostic: boolean('diagnostic'),18    predisposing: boolean('predisposing'),19    direction: text('direction'), // supports | resistance | sensitivity | neutral | unknown20    evidenceLevel: text('evidence_level'), // source-native level (e.g. CIViC A-E) — never re-scaled silently21    evidenceScore: real('evidence_score'),22    evidenceCategory: text('evidence_category').notNull().default('curated_evidence'), // observed_data | published_evidence | curated_evidence | regulatory_status | clinical_guideline | computed_metric23    status: text('status').notNull().default('active'), // active | candidate | superseded | retracted_basis24    sourceId: ciId('source_id').notNull(),25    sourceRecordId: text('source_record_id'),26    provenanceIds: integer('provenance_ids').array().notNull().default([]),27    supportCount: integer('support_count').notNull().default(1),28    firstSeenAt: timestamp('first_seen_at', { withTimezone: true }).notNull().defaultNow(),29    lastSeenAt: timestamp('last_seen_at', { withTimezone: true }).notNull().defaultNow(),30  },31  (t) => [32    uniqueIndex('knowledge_edges_uq').on(t.sourceEntityType, t.sourceEntityId, t.targetEntityType, t.targetEntityId, t.relationshipType, t.sourceId, t.sourceRecordId),33    index('knowledge_edges_source_idx').on(t.sourceEntityType, t.sourceEntityId, t.relationshipType),34    index('knowledge_edges_target_idx').on(t.targetEntityType, t.targetEntityId, t.relationshipType),35  ],36);3738/** CIViC evidence items kept in their native structure (CLAUDE.md §10.9). */39export const civicEvidenceItems = pgTable(40  'civic_evidence_items',41  {42    id: bigserial('id', { mode: 'number' }).primaryKey(),43    civicId: integer('civic_id').notNull(),44    name: text('name'),45    molecularProfileId: integer('molecular_profile_id'),46    molecularProfileName: text('molecular_profile_name'),47    geneSymbols: text('gene_symbols').array().notNull().default([]),48    geneIds: text('gene_ids').array().notNull().default([]),49    variantIds: text('variant_ids').array().notNull().default([]),50    civicVariantIds: integer('civic_variant_ids').array().notNull().default([]),51    diseaseName: text('disease_name'),52    doid: text('doid'),53    cancerId: ciId('cancer_id'),54    cancerMatchType: text('cancer_match_type'),55    therapyNames: text('therapy_names').array().notNull().default([]),56    therapyIds: text('therapy_ids').array().notNull().default([]), // CI-DRUG-…57    therapyInteractionType: text('therapy_interaction_type'),58    evidenceType: text('evidence_type'), // PREDICTIVE | PROGNOSTIC | DIAGNOSTIC | PREDISPOSING | ONCOGENIC | FUNCTIONAL59    evidenceLevel: text('evidence_level'), // A-E60    evidenceDirection: text('evidence_direction'), // SUPPORTS | DOES_NOT_SUPPORT61    significance: text('significance'), // SENSITIVITYRESPONSE | RESISTANCE | …62    evidenceRating: integer('evidence_rating'),63    status: text('status'), // ACCEPTED | SUBMITTED | REJECTED64    description: text('description'),65    pmid: text('pmid'),66    sourceCitation: text('source_citation'),67    phenotypes: text('phenotypes').array().notNull().default([]),68    provenanceId: integer('provenance_id').notNull(),69    ingestRunId: text('ingest_run_id'),70    updatedAt: updatedAt(),71  },72  (t) => [uniqueIndex('civic_evidence_uq').on(t.civicId), index('civic_evidence_cancer_idx').on(t.cancerId), index('civic_evidence_gene_idx').on(t.geneSymbols)],73);7475/** Risk factors / carcinogens as first-class entities (CLAUDE.md §74, §133). */76export const riskFactors = pgTable(77  'risk_factors',78  {79    id: bigserial('id', { mode: 'number' }).primaryKey(),80    slug: text('slug').notNull(),81    name: text('name').notNull(),82    kind: text('kind').notNull(), // behavioral | infectious | environmental | occupational | genetic | hormonal | demographic | carcinogen83    classificationAuthority: text('classification_authority'),84    classification: text('classification'),85    description: text('description'),86    createdAt: createdAt(),87  },88  (t) => [uniqueIndex('risk_factors_slug_uq').on(t.slug)],89);90