Jump to content

About:Pharmacopedia.ext: Difference between revisions

From Pharmacopedia
[unchecked revision][unchecked revision]
Created page with "{{TOC right}} = Pharmacopedia extension — specification = '''Version:''' 0.7.10 · '''Requires:''' MediaWiki ≥ 1.45.0 '''Author:''' MDElliottMD · '''License:''' GPL-2.0-or-later '''Source:''' <code>/var/www/mediawiki/extensions/Pharmacopedia/</code> The Pharmacopedia extension turns a MediaWiki install into a structured, community-edited medicine reference. It adds parser tags, special pages, API modules, and a database schema that together support: * Structu..."
 
No edit summary
Line 8: Line 8:
The Pharmacopedia extension turns a MediaWiki install into a structured, community-edited medicine reference. It adds parser tags, special pages, API modules, and a database schema that together support:
The Pharmacopedia extension turns a MediaWiki install into a structured, community-edited medicine reference. It adds parser tags, special pages, API modules, and a database schema that together support:


* Structured medicine pages via the <code>{{tlx|MedTemplate}}</code> template
* Structured medicine pages via the <code>{{MedTemplate}}</code> template
* Per-user rating, voting, and reporting on effects, indications, titration strategies, anecdotes, and interactions
* Per-user rating, voting, and reporting on effects, indications, titration strategies, anecdotes, and interactions
* Two-perspective data capture (personal vs. provider) wherever clinically meaningful
* Two-perspective data capture (personal vs. provider) wherever clinically meaningful

Revision as of 03:06, 14 May 2026

Template:TOC right

Pharmacopedia extension — specification

Version: 0.7.10 · Requires: MediaWiki ≥ 1.45.0 Author: MDElliottMD · License: GPL-2.0-or-later Source: /var/www/mediawiki/extensions/Pharmacopedia/

The Pharmacopedia extension turns a MediaWiki install into a structured, community-edited medicine reference. It adds parser tags, special pages, API modules, and a database schema that together support:

  • Structured medicine pages via the
    About:Pharmacopedia.ext

    Experience

👥 No personal reports yet
No clinical reports yet

Log in to add your own experience.

Problems

No problems yet. Be the first to suggest one.

+ Add a problem

Titration strategies

No titration strategies yet. Be the first to suggest one.

+ Add a titration strategy

Effects

No effects listed yet. Be the first to suggest one.

+ Add an effect

Relevant anecdote

No anecdotes yet. Share a relevant one.

+ Add an anecdote

Relevant Literature

No literature entries yet.

Log in to submit relevant literature.

Pharmacy
Common uses
Classification(s)
Pharmacology
Pharmacopedia is intended for reference. Nothing here is advice. In an emergency call 911; US Poison Control 1-800-222-1222. See the full disclaimer.

template

  • Per-user rating, voting, and reporting on effects, indications, titration strategies, anecdotes, and interactions
  • Two-perspective data capture (personal vs. provider) wherever clinically meaningful
  • Curated drug-class categories used as interaction endpoints
  • A verified-provider role with document-based verification

High-level architecture

  • Backend (PHP): includes/ — one class per parser tag, store, special page, or API module. Auto-loaded under MediaWiki\Extension\Pharmacopedia\.
  • Frontend (JS): resources/ext.pharmacopedia.js — single IIFE binding click handlers, modals, and inline AJAX submits.
  • Styles (CSS): resources/ext.pharmacopedia.css — shared row layout, per-tag chrome, dark-theme-friendly colors.
  • Schema: sql/ — ten core tables plus four migration patches. Picked up via the LoadExtensionSchemaUpdates hook.

Parser tags

All eight tags are registered via Hooks::onParserFirstCallInit:

Tag Purpose Class
<vote> Generic up/down binary vote on an arbitrary slug VoteTag
<effect> Therapeutic or adverse effect, dual patient/provider perspectives EffectTag
<discuss> Threaded comment widget CommentTag
<effectsummary> Roll-up aggregate header EffectSummaryTag
<titration> Titration strategy card with up/down vote TitrationTag
<anecdote> Personal or provider story with up/down vote AnecdoteTag
<indication> Condition the medicine is used for, 0–5 likert rating IndicationTag
<pharmaInteractions/> Self-closing; renders the Interactions section for the current page InteractionTag

All tags except <pharmaInteractions/> take a slug argument and (where relevant) a title, label, author, ref, or perspective.

Tag wikitext examples

<indication slug="ssri-depression" title="Major depressive disorder"
  author="MDElliottMD">Use cautiously in adolescents.</indication>

<effect slug="nausea" label="Nausea"/>

<effect ref="hyperkalemia"/>   <!-- ref to global effect library -->

<titration slug="slow-start-elderly" title="Slow start (elderly)"
  author="MDElliottMD">Begin at 10 mg q AM; titrate by 10 mg every 14 days.</titration>

<anecdote slug="qi8sg2" perspective="provider"
  author="MDElliottMD">One patient developed serotonin syndrome at week 3...</anecdote>

<pharmaInteractions/>

The unified compact row layout

Indication, Effect, Interaction, Titration, and Anecdote all render through a shared row pattern:

<div class="pcp-row pcp-row-{type} pcp-{type}" ...data-*>
  <div class="pcp-row-head">
    <span class="pcp-row-title">...</span>
    <span class="pcp-row-aggs">...</span>
    <span class="pcp-row-actions">
      <button class="pcp-row-action pcp-row-action-toggle" data-target="rate">Rate</button>
      [<button data-target="notes">Notes (N)</button>]    # only for Interaction
      [× delete button]                                   # only for sysop/admin
    </span>
  </div>
  [<div class="pcp-row-panel pcp-row-rate-panel"   hidden>...</div>]
  [<div class="pcp-row-panel pcp-row-notes-panel"  hidden>...</div>]
  [<div class="pcp-row-body">...wikitext body, always visible if present...</div>]
</div>
  • Rate / Notes panels are hidden by default; the shared .pcp-row-action-toggle JS handler reveals them inline on click.
  • Bodies (page-specific descriptions for Indication / Effect / Titration / Anecdote) are always visible.
  • The × admin delete button uses the established .pcp-del-btn pattern (or .pcp-ix-del-row for interactions).
  • Each row sits in its own block-formatting context (display: flow-root) so its border-box respects floated infoboxes.

Voting / rating semantics

Element Scale Perspectives Storage
Vote tag +1 / −1 binary single pcp_votes
Titration +1 / −1 binary single pcp_votes
Anecdote +1 / −1 binary single (perspective is a metadata label, not a separate aggregate) pcp_votes
Indication 0–5 likert + "don't know" single pcp_likert_reports
Effect (patient) experienced ∈ {yes, no, unsure} + valence −3..+3 patient pcp_effect_reports (perspective=1)
Effect (provider) frequency ∈ {0, 5, 20, 33, 50, 66, 80, 95, −1 don't know} + valence −3..+3 provider pcp_effect_reports (perspective=2)
Interaction experience 1–5 + outcome −3..+3 + optional free-text note user + provider, separate aggregates pcp_interaction_reports

Server-side aggregates: n, mean of the rating field, and (where applicable) severe = (vmean ≤ −2.5).

Aggregates are recomputed and returned by every report-submit API call so the row re-renders in place without a page reload.

Effect bucketing

When a wiki <ul> contains only <effect> cards, JavaScript groups them into buckets by the provider frequency mean (data-fmean):

Bucket fmean band Default state
Common > 20 expanded, always visible
Uncommon > 5 and ≤ 20 collapsed
Rare ≤ 5, provider vmean > −2.5 collapsed
Rare but Severe ≤ 5 and vmean ≤ −2.5 expanded by default, red highlight
Not yet rated no provider data (n=0) collapsed, only renders if non-empty

The vmean ≤ −2.5 threshold is also the trip-wire for the "severe" red treatment on interaction rows.

Interactions feature

The Interactions section is rendered by placing <pharmaInteractions/> anywhere in the wikitext of a medicine article (NS_MAIN) or a Category page (NS_CATEGORY).

Entity model

An interaction is an undirected edge between two endpoints. Each endpoint has a type (medicine or category) and a slug (DB-key form of the page title).

Pairs are stored in canonical order: smaller (type, slug) tuple on the left. This collapses A↔B and B↔A into a single row.

Tables

pcp_interactions: one row per interaction edge.

 pi_id              auto-increment
 pi_element_id      FK -> pcp_votable_elements (reuse votes/comments infra)
 pi_left_type       'medicine' | 'category'
 pi_left_slug       VARBINARY(255)
 pi_right_type      'medicine' | 'category'
 pi_right_slug      VARBINARY(255)
 pi_created_user_id INT
 pi_created         BINARY(14)
 UNIQUE (pi_left_type, pi_left_slug, pi_right_type, pi_right_slug)

pcp_interaction_reports: one row per (interaction, user, perspective).

 pir_element_id   FK -> pcp_votable_elements
 pir_user_id      INT
 pir_perspective  1 = user, 2 = provider
 pir_experience   TINYINT (1..5, nullable)
 pir_valence      TINYINT (-3..+3, nullable)
 pir_note         MEDIUMBLOB (nullable)
 pir_created      BINARY(14)
 pir_updated      BINARY(14)
 UNIQUE (pir_element_id, pir_user_id, pir_perspective)

Rendering rules

  • On a medicine page M, list:
    • Direct edges: rows where M is one side.
    • Transitive edges: rows where one side is a category C that M is itself a member of (via MW's categorylinks).
  • Direct wins: if the same counterparty is reachable both directly and transitively, drop the transitive duplicate.
  • On a Category page, list direct edges only (no transitive walk).
  • Sort: pooled valence_mean ascending (most negative on top). Nulls sink. Tiebreakers: n desc, then alphabetic.
  • Severe (any of pooled / user / provider vmean ≤ −2.5): red 4 px left border + red-tinted background + "severe" pill + counterparty title in red.

Add-interaction modal

Triggered by the + Add interaction button at the bottom of the section. Two-stage UX:

  1. Search input → results split into Medicines (teal chip) and Categories (amber chip).
  2. Click Use → confirm via Add interaction button → POST to pharmacopediainteractionadd.

Categories appear in the modal only if tagged with the marker category (default Category:MedCategory, configurable via $wgPharmacopediaInteractionCategoryMarker). The transitive walk during rendering, however, uses all of a page's categories regardless of marker — historic data isn't hidden by changing the marker policy.

Delete

Two a