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

# ADR-004 — CancerIndex public identifiers

Status: accepted (2026-09-08)

# Context

Entities come from many sources with their own identifiers (NCIt codes, DOIDs, OncoTree codes, HGNC ids, NCT ids, PMIDs, CIViC ids, ChEMBL ids…). CancerIndex needs stable public identifiers that survive merges, renames and source changes, are safe in URLs and JSON, and never leak database internals (spec §6, §347).

# Decision

Public identifiers have the form CI-<NS>-<n> where NS is one of the namespaces in packages/shared/src/ids.ts (CAN, GENE, VAR, DRUG, TRIAL, PUB, BIO, STUDY, METRIC, SOURCE, ORG, TRT, ANAT, GEO, PROV, EDGE, RANK) and n is a zero-padded integer of at least 8 digits. They are minted by mintId(db, ns) from per-namespace counters in id_sequences (atomic upsert-increment), are never reused and never re-numbered.

Rules:

  1. Database auto-increment integers (bigserial keys of aliases, observations, edges…) are internal and never exposed as entity references. The API resolver refuses bare integers except PMIDs.
  2. Every upstream identifier is kept in a searchable column or in *_codes tables with its system and match_type — never only inside a JSON blob.
  3. A merged entity keeps its id with status = merged and merged_into; the API follows the pointer so old links keep working. Deprecated entities keep their id and a deprecated_reason.
  4. Slugs (cancers.slug, drugs.slug, variants.slug) are human-friendly aliases for URLs; they are unique but may change, and the CI-* id remains the canonical reference.
  5. Ingest runs use ING-<CONNECTOR>-YYYYMMDD-<seq>; provenance rows get a CI-PROV-* public id only when exposed.

# Consequences

  • Identifiers are stable across re-ingestion: connectors look entities up by upstream code or alias and reuse the existing CI-* id; only genuinely new concepts mint new ids.
  • URLs are permanent: /cancers/CI-CAN-00000364 and /cancers/lung-adenocarcinoma both resolve.
  • Sharding or re-numbering would break the contract; the namespace counter is a deliberate single point of coordination (one database, ADR-001).