spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1# ADR-004 — CancerIndex public identifiers23Status: accepted (2026-09-08)45## Context67Entities come from many sources with their own identifiers (NCIt codes, DOIDs, OncoTree codes,8HGNC ids, NCT ids, PMIDs, CIViC ids, ChEMBL ids…). CancerIndex needs stable public identifiers that9survive merges, renames and source changes, are safe in URLs and JSON, and never leak database10internals (spec §6, §347).1112## Decision1314Public identifiers have the form `CI-<NS>-<n>` where `NS` is one of the namespaces in15`packages/shared/src/ids.ts` (`CAN`, `GENE`, `VAR`, `DRUG`, `TRIAL`, `PUB`, `BIO`, `STUDY`, `METRIC`,16`SOURCE`, `ORG`, `TRT`, `ANAT`, `GEO`, `PROV`, `EDGE`, `RANK`) and `n` is a zero-padded integer of at17least 8 digits. They are minted by `mintId(db, ns)` from per-namespace counters in `id_sequences`18(atomic upsert-increment), are never reused and never re-numbered.1920Rules:21221. Database auto-increment integers (`bigserial` keys of aliases, observations, edges…) are internal23 and never exposed as entity references. The API resolver refuses bare integers except PMIDs.242. Every upstream identifier is kept in a searchable column or in `*_codes` tables with its system25 and `match_type` — never only inside a JSON blob.263. A merged entity keeps its id with `status = merged` and `merged_into`; the API follows the pointer27 so old links keep working. Deprecated entities keep their id and a `deprecated_reason`.284. Slugs (`cancers.slug`, `drugs.slug`, `variants.slug`) are human-friendly aliases for URLs; they are29 unique but may change, and the `CI-*` id remains the canonical reference.305. Ingest runs use `ING-<CONNECTOR>-YYYYMMDD-<seq>`; provenance rows get a `CI-PROV-*` public id only31 when exposed.3233## Consequences3435- Identifiers are stable across re-ingestion: connectors look entities up by upstream code or36 alias and reuse the existing `CI-*` id; only genuinely new concepts mint new ids.37- URLs are permanent: `/cancers/CI-CAN-00000364` and `/cancers/lung-adenocarcinoma` both resolve.38- Sharding or re-numbering would break the contract; the namespace counter is a deliberate single39 point of coordination (one database, ADR-001).40