feat(associations): MEDIC + CTD drug-indications section + details modal (#1348) - #1357
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
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