Repository navigation
feat(associations): MEDIC + CTD drug-indications section + details modal (#1348) - #1357
kevinschaper wants to merge 16 commits into
Conversation
…1348) Enrich the association details modal (SectionAssociationDetails.vue) to surface the fields it previously hid: knowledge level, the nested retrieval-source provenance chain (e.g. MEDIC's infores:medic <- infores:dailymed/FDA), aggregator knowledge source, original predicate, qualifiers, frequency data, FDA adverse event level, and negated. Extract the sources JSON parsing into a tested util (parseRetrievalSources). Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
Replace the hidden single-category "Medical Action" mapping with a merged "drug_indications" section built on the flexible enabler: it combines MEDIC (biolink:treats) and CTD (biolink:treats_or_applied_or_studied_to_treat), which carry different association categories, via the multivalued category criterion (no ingest change needed). Shown as "Indications" on a drug/chemical page and "Treatments" on a disease/phenotype page. Merged filter verified vs api-beta (medic 6619 + ctd 19139 = 25758). Un-hid the section (cleared the now-stale HIDDEN_CATEGORIES entry, since sections key on `key` not category). Fixtures regenerated. The modal field enrichment rides along (cherry-picked). Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff for this PR (stacked on #1355). Overall this is a clean, well-scoped change — the new Backend (
|
Register monarch-initiative/medic-ingest so `make fetch-docs` generates the /Sources/medic/ page, fixing the association "Provided By" link for MEDIC edges (.../Sources/medic/), which 404s without a manifest entry. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
This PR clears HIDDEN_CATEGORIES to un-hide the drug-indications section, so the "filters out hidden categories" test (which asserted that category is hidden) no longer holds. Update it to assert the category now renders, keyed on `key`. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
Review: MEDIC + CTD drug-indications section + details modalReviewed against Summary
Correctness
Code quality / style
Test coverage
Security / performance
Nits
Nice work — this looks ready modulo the small optional test-coverage suggestion above, once #1355 lands and this is retargeted to |
The merged drug-indications section mixes biolink:treats (MEDIC/FDA) and biolink:treats_or_applied_or_studied_to_treat (CTD). Add a per-section "Filter by relationship" dropdown that scopes the table by predicate, mirroring the existing taxon filter: the table facets on predicate, emits the options, and selected predicates become filter_queries. Gated by predicateFilterConfig (currently just drug_indications) and shown only when >1 predicate is present. Verified: /entity/MONDO:0005148/drug_indications = 97, filtered to treats = 46, to treats_or_applied_or_studied_to_treat = 51. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff against Correctness
Test coverage
Minor/style
Security / performance
Nice work — this is a solid, low-risk stacked PR that reuses established patterns well. |
Add a watcher on predicateFilters (mirroring the taxonFilters watcher) so selecting a predicate in the drug-indications "Filter by relationship" dropdown re-runs the association query. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewNice PR — the "combine two categories under one section key" approach is clean, and the details-modal enrichment (provenance chain, knowledge level, qualifiers, frequency data) is a solid addition. I verified the diff ( Correctness
Code quality / style
Test coverage
Performance / security
Minor nit
Overall: solid, well-tested, and the multivalued-category enabler is used correctly end-to-end. Once #1355 merges and this is retargeted to |
…tional toggle The merged drug-indications section defaults to the strong biolink:treats (labeled "Indication") predicate and offers a single "Include investigational (studied/applied) treatments" checkbox to expand to CTD's weaker biolink:treats_or_applied_or_studied_to_treat (labeled "Investigational"). Replaces the predicate multi-select. The first, unfiltered fetch reveals whether the weaker predicate is present; the toggle then appears only when both are, and the table scopes to indications until the user opts in. Gracefully handles nodes with only one of the two predicates (no toggle, no empty table). Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff (base is What it does
Code quality
Potential issues
Test coverage
Backend
Nothing blocking — the flagged items are mostly polish/consistency suggestions. Since this is a draft stacked on #1355, worth a final pass once retargeted to |
- Extract the two-phase toggle/scoping logic into a pure, unit-tested
predicateFilterState() helper (empty-before-facet, only-default, only-weaker,
both checked/unchecked, non-filterable) instead of inline logic in the section.
- Drop the dead PREDICATE_LABELS/formatPredicate ("Indication"/"Investigational"
never reached the table rows, which render the raw predicate badge); emit the
raw predicate as the facet option label.
- parseRetrievalSources now falls back to a bare resource_id for plain-CURIE
source entries instead of silently dropping non-JSON provenance.
Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff (this branch only — the multivalued Correctness
Minor observations (non-blocking)
Test coverageGood — new pure logic ( Security / performanceNothing of concern — this is UI display logic and a Solr query mapping change; no new user input reaches string interpolation into a query in an unsafe way beyond the existing patterns (values are still quoted the same way Nice work, especially the provenance-chain parsing and the thoughtful predicate-toggle UX to avoid an empty table for nodes that only carry the weaker CTD predicate. |
…tions table On a disease page the drug-indications/treatments table (Direct tab) fell into the generic branch that drops subject + predicate, leaving only the object — which for this section is the disease itself, so every row just restated the page node. Treat drug_indications like the other disease-is-object sections: drop the object (disease) and keep the chemical/treatment (subject) + predicate. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
…nferred sets The filter watchers refetched only the active dataset, so the inferred/all dataset kept its mount-time unfiltered result. Switching to the inferred treatments tab then showed all predicates rather than matching the indications checkbox (and likewise for the taxon filter). Refetch both datasets on filter change so either tab stays consistent with the current filter. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
…d inferred sets The predicate options that gate the "include investigational" checkbox were emitted from only the active dataset's facet. On fresh load the default tab is Direct, whose facet has only biolink:treats — the weaker CTD predicate appears only in the inferred/all set — so the toggle stayed hidden until the user visited the inferred tab. Emit predicate options from the union of both datasets' predicate facets so the toggle reflects the whole section regardless of the active tab or load order. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
…ilter Including investigational (CTD) edges changes the direct count, which flipped the default direct/inferred tab and jerked the user's view over to Direct. Pin the currently-active tab into selectedTabs before applying the filter change (only when the user hasn't already chosen a tab), so toggling the checkbox filters the rows in place without restructuring which tab is active. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
Brings this branch onto the current base, including the KG refresh to monarch-kg-dev 2026-08-20 and the explicit `match_criteria` opt-in. `drug_indications` deliberately does *not* set `match_criteria: full`. It exists to merge two categories into one section, which category-only matching already does via the OR. Measured against the live index, the two are identical — 56 edges either way, with every subject a biolink:ChemicalEntity and every object a Disease or PhenotypicFeature — so the extra criteria buy nothing and would only create the risk of undercounting if the ingest ever emits an edge whose node categories differ from the declared ones. That is the failure mode that cost GeneToExpressionSite -83%, so the default is the safer side to be on. Worth noting for review: this section is now doing more work than when it was written. `ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociation` — the "Medical Action" section's only category — has **0 edges** in the new KG; its 56 moved to `ChemicalEntityToDiseaseOrPhenotypicFeatureAssociation` under `biolink:applied_to_treat`. Because `drug_indications` spans both, it picks them up where the standalone Medical Action section no longer can. Also fixes a type error the merge surfaced: `SectionAssociationDetails` reads `association.sources`, which the KG dropped between the 2026-07-08 and 2026-07-14 builds — it is absent from both the regenerated model and the Solr schema, so the retrieval-sources panel renders empty. Read defensively rather than deleting the panel: the model allows extra fields, so it revives itself if the ingest restores `sources`. 596 passed / 16 skipped backend; 321 frontend unit, types and lint clean. Claude-Session: https://claude.ai/code/session_01N6fjfGqaFpyjepw23qCyLv
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1357 +/- ##
=======================================
Coverage 83.53% 83.53%
=======================================
Files 126 126
Lines 6822 6822
=======================================
Hits 5699 5699
Misses 1123 1123 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…edic-ctd-drug-indications
Picks up the loader validation, table gating, path-param validation and the key/category split in use-association-categories. One test needed adapting rather than merging cleanly. #1355 added a test using ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociation as its example of a hidden section — which is correct on main, where HIDDEN_CATEGORIES suppresses it. This branch exists to surface that category as the merged `drug_indications` section, so HIDDEN_CATEGORIES is empty here and the section must come through. The test now asserts that, while still exercising the thing #1355 fixed: the hidden-set lookup reads `category` rather than `id`, which matters for every section this branch adds, since all of them have a key that differs from their category. 606 passed / 16 skipped backend; 323 frontend unit, types and lint clean. Claude-Session: https://claude.ai/code/session_01N6fjfGqaFpyjepw23qCyLv
✅ Deploy Preview for monarch-app ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Draft — stacked on #1355 (flexible section-matching enabler); base is that branch so the diff is just the MEDIC/CTD work. Retarget to
mainonce #1355 merges. Supersedes #1352 (the earlier single-category approach).What
One "Drug Indications / Treatments" section merging two sources that carry different association categories, via the enabler's multivalued
categorycriterion — no ingest change needed:biolink:treats(FDA-approved, text-mined) —biolink:ChemicalOrDrugOrTreatmentToDiseaseOrPhenotypicFeatureAssociationbiolink:treats_or_applied_or_studied_to_treat(curated) —biolink:ChemicalEntityToDiseaseOrPhenotypicFeatureAssociationMapping
key: drug_indications,category: [medic, ctd],subject_category: [ChemicalEntity],object_category: [Disease, PhenotypicFeature]. Shown as "Indications" on a drug/chemical page and "Treatments" on a disease/phenotype page.Also includes the association-details modal enrichment: knowledge level, the nested retrieval-source provenance chain (MEDIC's
infores:medic ← infores:dailymed/FDA), aggregator source, original predicate, qualifiers, frequency data, FDA adverse-event level, negated (parseRetrievalSourcesutil + test).Verification
get_mappingon the bare MEDIC category still resolves todrug_indicationsso the table endpoint works either way; counts fixtures regenerated; backend suite green (134).parseRetrievalSourcesunit-tested; frontend typecheck/lint clean.https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL