sherryyyyang/FDA_endpoint_tracking
GitHub: sherryyyyang/FDA_endpoint_tracking
通过追踪FDA终点变化在161个适应症中寻找药物研发资产机会的搜索与可构建性评分工具。
Stars: 4 | Forks: 0
# 终点演进图谱 (Endpoint Evolution Atlas)
**一款寻找药物研发资产机会的搜索工具——通过追踪 FDA 改变临床试验规则来实现。** 当 FDA 更改*申办方必须证明什么、在哪些人群中证明以及需要多长时间*时,它实质上重写了该适应症下每一项关键性试验的成本、规模和持续时间——而迫使这一改变发生的研究联盟通常在监管机构采取行动的 **1 到 5 年前**就已经清晰可见。我开发这个工具是为了让任何人都能搜索这一领域:选择一种疾病或终点,查看试验范式是如何转移的,并评估在何处让*宽松的*终点遇上*一片空白*的竞争领域——这正是建立新项目成本最低的空间。

## 功能
在 **涵盖 15 个治疗领域的 161 种适应症** 中搜索正在发生转移的主要终点,然后沿着问题链找到一份按可行性排序的机会清单:
- **搜索任何内容** —— 疾病、终点(`EASI-75`、`MRD`、`ctDNA`)或治疗领域 —— 查看终点的新旧交替、谁发出了信号,以及 FDA 何时采取了行动。**每次搜索都是一个可分享的链接** —— 查询、过滤器和排序都保存在 URL 中,因此任何视图都可以被加入书签或发送给同事。
- **按机会排序** —— Whitespace Explorer 会根据*可构建性*对每种适应症进行打分:即让试验规模/周期大幅缩短的宽松终点,遇上活跃项目极少的空白竞争领域。
- **结合真实试验查看** —— 每个适应症都直接链接到 ClinicalTrials.gov 上经过其新终点过滤的实时试验列表,并且每批次都包含了从 ClinicalTrials.gov API 提取的关键阶段试验活动的带日期快照。
- **抢占先机** —— Signal Tracker 根据 15 个活跃的联盟项目距离 FDA 行动的接近程度对其进行阶段划分,让你能够在市场*提前消化*这些变化之前发现趋势。
## 技术栈
- **TypeScript + Vite**,无 UI 框架 —— 纯 DOM 渲染、hash 路由和内联 SVG。该应用以 **~40 KB 的 gzip 压缩包形式发布,零运行时依赖**(无 Web 字体,无 CDN);主题配图是自托管的矢量图,而非库存图片。
- **数据与渲染分离。** 数据集以 JSON 格式存放在 [`data/`](data/) 中,并作为唯一的真实来源;UI (`app/`) 和领域逻辑 (`lib/`) 会导入它们。只需添加一条数据,所有展示界面都会自动重新计算。
- **靠代码而非文字来强制执行规范。** 数据验证器(引用完整性、无 NaN、来源追溯)会对构建进行把关并在 CI 中运行;写入保护钩子会阻止对流水线生成的数据进行手动编辑;不受信任的引用文本会被 HTML 转义,并且链接协议会被加入白名单。
## 在本地运行
```
git clone https://github.com//FDA_endpoint_tracking.git
cd FDA_endpoint_tracking
npm install
npm run dev # http://localhost:5173
```
无需注册,无需 API key,无需后端 —— 克隆并打开即可。然后浏览四个界面,每个界面都在回答上一个界面提出的“*那又怎样?*”:
1. **进入图谱。** 搜索疾病或终点,或选择一个治疗领域。每一泳道都会展示变化(旧 → 新终点)、联盟、FDA 行动及日期,以及它们之间的**前置时间**。
2. **打开适应症。** 点击任意泳道以查看完整的证据链 —— 包括变化、联盟信号、监管路径、注意事项、来源、值得发掘的目标、试验负担评估,以及流行病学与市场规模面板。
3. **对领域进行排序。** 跳转至 **Whitespace Explorer**,按构建机会对每个已打分的适应症进行排序,按罕见病等级进行筛选,并在平衡策略与罕见病基金策略之间进行切换。
4. **展望未来。** **Signal Tracker** 根据距离 FDA 行动的远近程度,将 15 个前向信号划分为 1→4 个阶段 —— 阶段 1–2 属于 Alpha(超额收益)区间。
其他脚本:
```
npm run build # validate data → typecheck → bundle to dist/
npm run validate # referential integrity + no-NaN + provenance report
npm test # scoring, render smoke (jsdom), and data-integrity suites
npm run research:status # per-layer research coverage + citation-hardening queue
```
## 机会评分 —— 核心差异化优势

大多数市场格局工具是对*当前已经拥挤*的领域进行排序。而本图谱是对**可构建性**进行排序:它是以下三者的交汇点 a) 能够大幅缩短试验规模和周期的**宽松终点**,b) **一片空白的竞争领域**,以及 c) **适用于罕见病监管路径的人群**。代码中强制执行了三项信任准则:
- **评分会报告自身的覆盖率,并会诚实降级。** 当输入缺失时,`buildScore` 会对可用项重新进行归一化计算,并返回一个 `coverage`(覆盖率)百分比以及缺失的维度——它目前在**公式的 65%**上运行,并且会在每个评分旁边如实显示。
- **评分映射采用对数标尺。** 计数值范围从 8 跨越到 1,028,患病率从 0.25 跨越到 48,000(每 10 万人);线性映射会将稀缺的长尾部分——这正是空白市场理论的核心所在——压缩到一个桶里。
- **拥挤阈值是绝对的,绝不会基于样本进行重置。**
盲区被明确展示出来而非被隐藏:由于占比最大的权重项(未满足的需求,25%)尚未加载,一种几乎已被解决的疾病可能会浮现在顶部——因此警告会直接渲染在 **Explorer** 中紧挨着具有误导性的排名。
## 实时临床试验链接

每种适应症的深度分析都在回答:*“真的有人在开展这种试验吗?”* 这 161 种适应症中的每一个都带有一个指向当前正在招募的 ClinicalTrials.gov 列表的**实时深层链接**,该列表经过其新终点过滤——始终保持最新,且无运行时依赖。同时,每批次也附带一份**带有日期的快照**([`data/trials.json`](data/trials.json)),该快照从 ClinicalTrials.gov API v2 提取:统计在该疾病状态下正在招募的关键性(Phase 3)试验数量——这是一项可作为 Convoke 项目计数补充的竞争密度解读——以及带有申办方、阶段和入组人数的试验示例。快照计数会标注其提取日期;而链接才是始终准确的真理来源。
## 架构
| 路径 | 作用 |
|------|------|
| `app/main.ts` | 入口 —— 加载样式,启动路由器 |
| `app/router.ts` | hash 路由器(路由 + 重绘) |
| `app/components.ts` | 渲染器、格式化器、`esc` / `htmlEscape` / `safeHref` |
| `app/views/atlas.ts` | 搜索、过滤、排序、手风琴式时间轴 |
| `app/views/indication.ts` | 针对单一疾病的证据链 |
| `app/views/whitespace.ts` | 可构建性排序表 |
| `app/views/tracker.ts` | 前向信号追踪器 |
| `app/styles/globals.css` + `hero.svg` | 设计令牌、布局、矢量主题图 |
| `lib/data.ts` | 加载 JSON 数据集及派生常量 |
| `lib/scoring.ts` | `pipScore` · `preScore` · `buildScore` · `crowdLabel` …… |
| `lib/validate.ts` · `lib/types.ts` | 不变量(在 CI 中镜像执行) · 共享接口 |
| `data/*.json` | 数据集 —— 唯一的真实来源(终点、Convoke、流行病学、信号、**试验**) |
| `scripts/pull_convoke.py` | Convoke 流水线(项目计数) |
| `scripts/validate_data.mjs` | CI 数据门禁 |
| `scripts/research_status.mjs` | 研究覆盖率报告 |
| `.claude/hooks/` · `.github/workflows/` | 写入保护 · 构建并部署至 Pages |
在 `data/*.json` 中更改任意一条数据,所有界面都会重新计算;在 `lib/scoring.ts` 中更改阈值,该阈值将全面生效。
## 数据完整性 —— 强制执行,而非纸上谈兵
- **验证器**(`npm run validate`,同时也是 `npm run build` 的第一步):每一个 `area`/`signal`/`convoke`/`epi`/`signal-indication` ID 都必须能被解析,评分字段中绝对不能有 NaN 泄漏,并且每一个经验证的项目计数都必须带有其 Convoke 实体 ID(Tier-1 来源)。它还会报告 Tier-3 患病率数据层中有多少已具备来源依据。
- **CI**([`.github/workflows/deploy.yml`](.github/workflows/deploy.yml))在每次推送时都会运行验证器、类型检查、测试和构建 —— 从而确保“已验证,无 NaN 泄漏”的状态得以持续保持。
- **写入保护钩子**([`.claude/hooks/guard_data_writes.py`](.claude/hooks/guard_data_writes.py))阻止对 `data/convoke.json` 及其映射表的手动编辑;计数的更改只能通过 `scripts/pull_convoke.py` 进行,从而确保它们始终与其 `entity_resolution`(实体解析)来源保持绑定。
- **不受信任的输入已被净化。** 由于该仓库鼓励通过 Fork/PR 提交新数据,因此引用文本会被 HTML 转义,并且链接的 `href` 协议会被限制在白名单内(`http/https/mailto`)—— `javascript:` URL 绝不会被转化为可点击执行的链接。
## 数据来源 —— 三个信任等级
1. **Tier 1 —— 已验证。** 来自 Convoke Program Tracker 的活跃临床阶段项目计数(涵盖 154 个可评分适应症中的 53 个),每一条都记录了实体 ID,并经过人工与解析器核对无误。
2. **Tier 2 —— 基于规则重建。** PIP 和 PRE 评分,使用 Convoke 公开的方法论,基于 Tier-1 计数和 Tier-3 患病率进行对数映射得出。
3. **Tier 3 —— 估算数据。** 全部 154 个适应症的患病率,数据来源于一般流行病学文献,**尚未经过严格的引用加固**(由验证器的来源报告进行追踪)。
## 部署到 GitHub Pages
CI 会自动进行构建和部署。在 **Settings → Pages** 中,将 **Source** 设置为 **GitHub Actions**,然后推送到 `main` 分支 —— [`.github/workflows/deploy.yml`](.github/workflows/deploy.yml) 将会进行验证、构建并发布 `dist/`。该站点采用 hash 路由,因此无需任何服务器重写规则。
## 构建过程
我与 Claude 合作实现了该项目的端到端开发,并且这一过程被记录得像代码一样具有可复现性:
- **[`docs/BUILD-STORY.md`](docs/BUILD-STORY.md)** —— 完整的叙述:包括问题定义、数据结构化、构建评分引擎、提炼洞察,以及从单一文件重构为当前模块化目录结构的过程。
- **[`docs/RESEARCH-METHOD.md`](docs/RESEARCH-METHOD.md)** —— 如何借助 Claude 研究 161 个适应症的终点数据集:包括研究指令、每次搜索需填写的记录契约、诚实反映各层级覆盖率的来源评级机制,以及重新运行的配方。运行 `npm run research:status` 可报告覆盖率并列出待引用加固的队列。
它们共同涵盖了流水线的两大部分:**工具调用** 数据(Convoke 计数,通过 [`scripts/pull_convoke.py`](scripts/pull_convoke.py))和 **研究扫描** 数据(终点变化)—— 每一部分都有明确的输入、定义良好的输出结构,以及拒绝格式错误数据的 CI 门禁。
## 贡献
Fork 并重新定向它:替换 `data/` 中的 JSON,保留 `lib/` 和 `app/` 即可。欢迎添加新的适应症、更正患病率(需附带 `src`)或补充新信号 —— 如果有 ID 无法解析,验证器会提示你。
## 许可证
MIT —— 详见 [`LICENSE`](LICENSE)。
标签:FDA合规分析, TypeScript, Vite, 医疗数据挖掘, 安全插件, 自动化攻击, 药物研发, 逆向工具