Skip to content

Healthcare: clinical components — problem list, presenting problems, assessment & plan#299

Draft
horner wants to merge 29 commits into
mainfrom
clinical-components
Draft

Healthcare: clinical components — problem list, presenting problems, assessment & plan#299
horner wants to merge 29 commits into
mainfrom
clinical-components

Conversation

@horner

@horner horner commented Jul 4, 2026

Copy link
Copy Markdown
Member

Reopens the work from #297 (which was merged prematurely and then reverted from main). This clean PR excludes the non-existent mieweb/codify git submodule that broke CI checkout on every job.

Summary

Implements the concern/assertion condition model from the design doc (Clinical-Med-Allergies-Conditions.md) as a set of Healthcare components, plus the supporting drag-and-drop infrastructure.

Design doc

  • §3.4 Conditions — concern vs. assertion: stable concernId as the durable identity orders reference; time-stamped ConditionAssertions carry the evolving ICD-10-CM / ICD-11 / SNOMED codings (refinement / revision / progression / reattribution lineage; revisions refute, never rewrite)
  • §3.5 Encounter scope & the three problem surfaces: problem-focused vs comprehensive encounters, relevance lives on the encounter reference, close-processing merge semantics
  • Order linkage: IndicationLink = durable concernId + frozen coding snapshot (billing ICD-10 is a projection, never the join key)

Components (props-only, controlled; each with Storybook stories under Healthcare/)

  • ProblemList — patient-level concerns grouped Unconfirmed / Active / Inactive / Resolved; expandable assertion timelines; parenthetical ICD codes with full coding/history/observations in tooltips; uncertainty badges; observations (quick progress notes); refine / revise / resolve / relate / observe actions
  • PresentingProblems — encounter-scoped relevant problem list fed by the patient problem list; scope banner; relevance tagging (Addressed / Relevant Hx / Noted); negative assertion gated to comprehensive scope
  • Assessment — visit A&P with orders nested under problems via concernId; inline add-order; unlinked-orders bucket with link chips
  • ConditionEditor — add / observe / refine / revise / relate dialog; capture-first (name only required); coding rows; fuzzy onset; three-state field uncertainty (unknown ≠ blank, confidence levels)
  • MedicationList — presenting-medications reconciliation list
  • useDragReorder — shared HTML5 DnD hook (no new deps, no localStorage; consumer persists id order)

Accessibility (508)

Every drag interaction has a keyboard equivalent: Alt+↑/↓ reorder, Alt+←/→ move orders between problems, per-row "Move to…" menus, roving focus, toolbar arrow-key navigation, and aria-live announcements.

Not ready to merge — remaining work

  • Orders: real order model/workflow (current AssessmentOrder is a display stub)
  • Code lookup: terminology autocomplete (SNOMED-first with ICD-10/11 crosswalk) for the ConditionEditor coding rows
  • AI support: suggested links/codings/observations
  • Store + projections (toFhir, closeEncounter merge) per design doc phases

CI fix vs #297

  • Removed the packages/codify submodule (pointed at https://github.com/mieweb/codify.git, which does not exist), so actions/checkout with submodules: true no longer fails. The codify build pipeline is dev/build-time only and is not imported by src/, tests, or CI.

horner added 21 commits July 3, 2026 21:49
…, assessment & plan

Implements the concern/assertion condition model from the design doc
(Clinical-Med-Allergies-Conditions.md):

- ProblemList: patient-level concerns with assertion history timelines
  (refine/revise/progress lineage), ICD-10/ICD-11/SNOMED codings shown
  parenthetically with full background in tooltips, uncertainty badges,
  observations (quick progress notes), and an Unconfirmed group separate
  from Active/Resolved
- PresentingProblems: encounter-scoped relevant problem list fed by the
  patient problem list, with problem-focused vs comprehensive scope
  banner and relevance tagging on the encounter reference
- Assessment: visit A&P with orders nested under problems via the
  durable concernId link, inline add-order, unlinked-orders bucket
- ConditionEditor: add/observe/refine/revise/relate dialog with
  capture-first entry, coding rows, fuzzy onset, and three-state
  field uncertainty (unknown != blank, confidence levels)
- MedicationList: presenting-medications reconciliation list
- useDragReorder hook: shared HTML5 drag & drop reordering used by all
  lists (concerns, orders incl. cross-problem moves, medications), with
  full keyboard equivalents (Alt+arrows, Move menus, roving focus) and
  aria-live announcements for 508 compliance
…browser)

- scripts/codify/extract.mjs: dumps 770K MedicalCodify_search rows (12
  codetypes) from the dockerized rxdb MariaDB to TSV
- scripts/codify/build-index.mjs: builds binary .mcdx index shards per
  clinical domain (condition/med/lab/procedure/vaccine) with a sorted
  token dictionary, posting lists, and curated alias expansion
  (aliases.json: chf/lvhf, lasix<->furosemide, a1c/hba1c, brand<->generic)
- src/components/CodeLookup: shard parser + multi-word-prefix BM25-ish
  engine ('con hea fa' -> Congestive heart failure) with edit-distance-1
  typo fallback, Web Worker loader, and combobox component + stories
- Artifacts land in .storybook/public/codify/ (gitignored); pnpm
  codify:extract && pnpm codify:build to regenerate
- Verified: golden queries return in 0.6-30 ms locally over 770K entries

Not exported from src/index.ts yet (worker bundling in tsup pending).
…down

- Results now render in a floating dropdown (combobox pattern): opens on
  results, closes on select/Esc/blur, hover highlight without clobbering
  keyboard navigation (mousemove, not mouseenter)
- Compact rows: label first, then codesystem + code right-aligned in
  small per-domain-tinted text (replaces the oversized badge)
- Medication rows drill into all forms & strengths with ArrowRight (or
  the chevron): re-searches the med shard by name, filters to dosed
  FDB/RxNORM entries, alphabetized; ArrowLeft/Back returns. Aliases make
  Lasix drill list furosemide forms (114 entries) and vice versa
- Selecting fills the input and suppresses the follow-up auto-search so
  the dropdown doesn't reopen
README covering the end-to-end design: extract/build pipeline, domain
sharding, the .mcdx binary format, the prefix+BM25-ish scoring algorithm
with alias and Damerau-Levenshtein-1 typo handling, worker loading,
component keyboard model incl. med forms/strengths drill-down, and the
production roadmap (RXCUI concept grouping, OPFS persistence, ranking
priors, licensing). Linked from the Storybook docs.
- Add order now uses a code lookup instead of free text: new
  renderOrderSearch prop (dependency-injected so the library build
  doesn't bundle the lookup worker; story wires CodeLookup)
- Order type defaults to 'Auto': the type is inferred from the picked
  code's system (RxNORM/FDB/NDC/CVX -> medication, LOINC/Quest/LabCorp
  -> lab, HCPCS/ICD10PCS -> procedure); selecting an explicit type
  filters the lookup to matching domains at query time
- CodeLookup: new searchDomains prop restricts searches per-query
  without reloading shards
- Picked orders carry code {fullid, codetype, fullcode}; the story shows
  it as the order detail
- Free-text entry remains the fallback when no lookup is provided
Dragging to select text in the embedded order search was hijacked by the
draggable problem block. The block now sets draggable=false (and drops
the grab cursor) while its add-order form is open, restoring normal text
selection; drag & drop resumes when the form closes.
- New bare prop renders just the input + dropdown (no card, no status
  line) for embedding in forms; loading progress and error state show in
  the placeholder instead
- Assessment add-order form uses bare mode: type filter, search, and
  Done now align at the same 40px height on one row
…s open

The block body yields to text selection/editing (draggable=false), but
the problem header row (number, name, codes) becomes the drag source, so
the block can still be reordered mid-entry — the open form travels with
it. The form itself is never inside a draggable ancestor.
New clearOnSelect prop, defaulting to true in bare mode: picking a
result clears the query and keeps focus so the user can type the next
order immediately. Standalone mode keeps the picked label in the input.
- New onAddAssessment prop + always-visible 'Add problem' search row
  (condition-domain code lookup): picking a dx adds a new problem to the
  assessment; the story creates the concern/assertion with the coding
- Unlinked bucket now renders whenever adding is possible and gains an
  'Add order' button opening the same type-filter + lookup form;
  onAddOrder's item param is null for unlinked orders (concernId unset),
  so they land in the bucket ready to be linked or dragged later
renderOrderSearch now receives a placeholder matched to the context:
'Search diagnoses… (try "chf"…)' for the add-problem row, and per
order-type hints ('Search medications… (try "lasix")', labs/a1c,
imaging/chest x, procedures, referrals) instead of one generic line.
The bottom row is now a single 'Add' search across all domains: picking
a diagnosis (ICD10/ICD9/SNOMED US via new isConditionCodetype) adds a
problem to the assessment, anything else becomes an (unlinked) order
typed by its coding system. The unlinked bucket's add button is gone and
the bucket only takes space once it actually contains orders.
- The unified add row gains a mode dropdown: Add (auto) / Add problem /
  Add order. Problem/order modes scope the search domains and route the
  pick directly; auto keeps codetype-based detection
- CodeLookup: new onFreeText prop - Enter with no highlighted result (or
  the new 'Use "..." as free text' footer row) submits the raw text
- Free text in problem/order mode adds directly; in auto mode an inline
  prompt asks 'Add "..." as: Problem / Order / Cancel' before adding.
  Free-text problems arrive uncoded and unconfirmed in the story
- onAddAssessment now takes AssessmentAddPick { label, code? } so coded
  and free-text problems share one callback
The toolbar actions previously only logged. They now open the editor
seeded from the concern; saving appends the new assertion (revision
refutes the prior) and repoints the visit item's assertionId so the
block header, plan, and link chips update immediately.
Security / correctness:
- extract.mjs no longer hardcodes the MariaDB password: reads
  RXDB_MYSQL_PASSWORD / MYSQL_PWD / --password, fails fast when missing,
  and passes it via the child environment instead of argv
- engine.ts: viaAlias is now tracked per-document (aliasBuf scratch
  buffer, reset with the other buffers) instead of one shard-level flag
- reorderIds() ignores dragged ids that aren't in the list (stale/cross-
  list payloads can no longer inject unknown ids)
- useDragReorder keeps the dragged id in a ref set synchronously in
  dragstart (dragover no longer races React state) and clears the stale
  drop indicator when hovering invalid targets

Accessibility:
- CodeLookup ids are per-instance via React.useId (aria-controls /
  aria-activedescendant survive multiple instances); aria-expanded now
  mirrors actual dropdown visibility (incl. drill mode / free-text row)
- Keyboard reordering (Alt+arrows + roving focus) added to
  MedicationList rows and PresentingProblems selected rows; Assessment
  unlinked orders now render via OrderRow (focusable + Move menu),
  replacing the pointer-only chip row
- Pointer drag & drop now announces via the aria-live regions in
  ProblemList, MedicationList, and Assessment (reorder, move-to-problem)
- ProblemList: Alt+arrow reordering and its aria-label hint are disabled
  in readOnly mode (canReorder follows drag.enabled)

Styling / misc:
- ProblemList timeline dot uses -left-5 (valid on Tailwind 3 + 4)
- Drag indicator classes (opacity-40, inset shadows, cursor-grab) added
  to miewebUISafelist for Tailwind 3 consumers
- ConditionEditor: seed effect depends on open/mode/prior (no stale form
  when switching while open); coding values are trimmed on save
- PresentingProblems: unselected rows are only dimmed/badged out-of-
  scope in problem-focused encounters, not comprehensive ones
- Prettier pass over all touched component files
…-fields file

The MedicationListField import referenced a file that isn't part of this
PR (removed in 923a7c1), which broke pnpm typecheck in CI.
- New useLiveAnnouncement hook: clears the aria-live region before
  setting the message (after a tick), so repeated identical
  announcements (e.g. two 'moved down' reorders in a row) are announced
  every time instead of being swallowed by React state bailout. Adopted
  by ProblemList, MedicationList, PresentingProblems, and Assessment
- CodeLookup: domains/searchDomains now distinguish 'prop not provided'
  (undefined = all domains) from an explicit empty array (= none); the
  keys use null for absent and pass [] through to the worker
- ConditionEditor: fields marked explicitly unknown no longer persist
  contradictory values on save - coding/severity/onset are cleared when
  their unknown toggle is set (unknown wins over a seeded value)
…, git-lfs shard distribution; move pipeline to packages/codify submodule

- Build pipeline moved to the new packages/codify submodule (also hosts
  the SQLite FTS5 build + codify-mcp stdio server for agent loops)
- .mcdx v2: docPrior u8 section (log-quantized usage; simulated top-200
  meds/ICD-10 diagnoses/SNOMED procedures until a production export is
  wired in) + meta.locale; engine still reads v1 (prior=0)
- engine: final score x= (1 + 0.5*prior/255) - common codes outrank rare
  ones at equal text relevance (hypertension -> I10 first)
- Shards now per locale ({indexUrl}/{locale}/); es is a curated sample
  (common diagnoses + med ingredient INNs) with its own alias set (hta,
  dm2, ic...); CodeLookup gains a locale prop
- Worker: OPFS persistence - network-first manifest check, cached shards
  reused only when builtAt/version/bytes match, torn-cache-safe manifest
  write-after, full offline fallback when the network is down
- Storybook: Language toolbar global (en/es) wired to CodeLookup stories;
  shards committed via git-lfs and served from .storybook/public/codify/
  (no longer gitignored)
The packages/codify submodule pointed at https://github.com/mieweb/codify.git,
which does not exist on GitHub, so every CI job failed at the 'Checkout code'
step (submodules: true). The codify data pipeline is build-time only and is not
imported by src/, the tests, or CI. Remove the submodule and gitignore the
local pipeline folder so checkout succeeds.
Copilot AI review requested due to automatic review settings July 4, 2026 11:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a set of new Healthcare-focused, controlled (props-only) UI components implementing the concern/assertion condition model described in the included design doc, plus shared drag-and-drop reordering infrastructure and an offline CodeLookup proof-of-concept for Storybook.

Changes:

  • Added new Healthcare components: ProblemList, PresentingProblems, Assessment, ConditionEditor, MedicationList (+ Storybook stories).
  • Added shared hooks for accessibility announcements and HTML5 drag-reorder (useLiveAnnouncement, useDragReorder) and safelisted required Tailwind classes.
  • Added offline CodeLookup engine/worker/component + Storybook locale toolbar and committed CodeLookup shard manifests/LFS pointers.

Reviewed changes

Copilot reviewed 42 out of 43 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/tailwind-preset.ts Safelists new drag/drop-related Tailwind utility class strings.
src/index.ts Exports new Healthcare components from the package entrypoint.
src/hooks/useLiveAnnouncement.ts Adds a hook for repeatable aria-live announcements.
src/hooks/useDragReorder.ts Adds shared HTML5 drag-reorder hook + indicator class helper.
src/hooks/index.ts Re-exports new hooks from the hooks barrel.
src/components/ProblemList/ProblemList.tsx Implements patient-level concern/assertion problem list UI with grouping, history, reordering, and accessibility behaviors.
src/components/ProblemList/ProblemList.stories.tsx Adds Storybook stories for ProblemList (interactive/read-only/empty).
src/components/ProblemList/index.ts Barrel exports for ProblemList and its shared types/helpers.
src/components/PresentingProblems/PresentingProblems.tsx Implements encounter-scoped “relevant problems” selection/tagging UI with scope gating and reorder support.
src/components/PresentingProblems/PresentingProblems.stories.tsx Adds Storybook stories for PresentingProblems (problem-focused/comprehensive/read-only).
src/components/PresentingProblems/index.ts Barrel exports for PresentingProblems and its types/constants.
src/components/MedicationList/MedicationList.tsx Implements presenting-medications reconciliation UI with grouping, row actions, reorder support, and announcements.
src/components/MedicationList/MedicationList.stories.tsx Adds Storybook stories for MedicationList (interactive/default/fully reconciled/read-only/flags/limited actions).
src/components/MedicationList/index.ts Barrel exports for MedicationList and its types/constants.
src/components/Icons/index.ts Adds additional lucide icon re-exports needed by new Healthcare components.
src/components/ConditionEditor/index.ts Barrel exports for ConditionEditor and its types.
src/components/ConditionEditor/ConditionEditor.tsx Adds a modal condition assertion editor supporting add/observe/refine/revise/relate and per-field uncertainty.
src/components/ConditionEditor/ConditionEditor.stories.tsx Adds Storybook stories for ConditionEditor modes.
src/components/CodeLookup/README.md Documents the CodeLookup architecture, build pipeline, and runtime behavior.
src/components/CodeLookup/index.ts Barrel exports for CodeLookup component + engine utilities (but intentionally not from src/index.ts).
src/components/CodeLookup/engine.ts Adds the shard parsing + local scoring/search implementation for CodeLookup.
src/components/CodeLookup/codify.worker.ts Adds the worker that loads shards (with OPFS caching) and serves search results.
src/components/CodeLookup/CodeLookup.tsx Adds the CodeLookup combobox UI that talks to the worker and supports med drill-down.
src/components/CodeLookup/CodeLookup.stories.tsx Adds Storybook stories for CodeLookup across domains/locales.
src/components/Assessment/index.ts Barrel exports for Assessment and related types/constants.
src/components/Assessment/Assessment.tsx Implements visit-specific Assessment & Plan UI with nested orders and drag/link behaviors.
src/components/Assessment/Assessment.stories.tsx Adds Storybook stories for Assessment (interactive/assessment-only/read-only).
package.json Adds codify:* scripts to run external pipeline scripts under packages/codify.
eslint.config.js Adds globals used by worker/binary/encoding code to satisfy lint.
Clinical-Med-Allergies-Conditions.md Adds the design doc describing the canonical model and UI/projection plan.
.storybook/public/codify/es/med.mcdx Adds LFS pointer for Spanish sample med shard.
.storybook/public/codify/es/manifest.json Adds Spanish sample shard manifest metadata.
.storybook/public/codify/es/lab.mcdx Adds LFS pointer for Spanish sample lab shard.
.storybook/public/codify/es/condition.mcdx Adds LFS pointer for Spanish sample condition shard.
.storybook/public/codify/en/vaccine.mcdx Adds LFS pointer for English vaccine shard.
.storybook/public/codify/en/procedure.mcdx Adds LFS pointer for English procedure shard.
.storybook/public/codify/en/med.mcdx Adds LFS pointer for English med shard.
.storybook/public/codify/en/manifest.json Adds English shard manifest metadata.
.storybook/public/codify/en/lab.mcdx Adds LFS pointer for English lab shard.
.storybook/public/codify/en/condition.mcdx Adds LFS pointer for English condition shard.
.storybook/preview.tsx Adds a Storybook global toolbar locale selector and default locale.
.gitignore Ignores packages/codify/ and documents local/external pipeline expectations.
.gitattributes Tracks .mcdx shard files via Git LFS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/CodeLookup/README.md Outdated
Comment thread package.json Outdated
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 4, 2026

Copy link
Copy Markdown

Deploying ui with  Cloudflare Pages  Cloudflare Pages

Latest commit: ea3c75a
Status: ✅  Deploy successful!
Preview URL: https://9a314bc1.ui-6d0.pages.dev
Branch Preview URL: https://clinical-components.ui-6d0.pages.dev

View logs

@horner horner marked this pull request as draft July 4, 2026 11:29
… limit

The 34 MB en/med.mcdx exceeded Cloudflare Pages' hard 25 MiB per-file cap,
failing the deploy. Store it gzip-compressed (~11 MB) under the same filename;
the worker detects the gzip magic (1f 8b, never collides with MCDX) and
inflates transparently. Manifest bytes updated to the compressed size.
Copilot AI review requested due to automatic review settings July 4, 2026 13:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 42 changed files in this pull request and generated 6 comments.

Comment on lines +159 to +166
React.useEffect(() => {
const worker = new Worker(
new URL('./codify.worker.ts', import.meta.url),
{
type: 'module',
}
);
workerRef.current = worker;
Comment on lines +538 to +542
Index unavailable: {status.message}. Run{' '}
<code className="font-mono">
node scripts/codify/extract.mjs && node
scripts/codify/build-index.mjs
</code>
Comment on lines +33 to +34
Shards are committed via git-lfs and served from \`.storybook/public/codify/{locale}/\`;
rebuild with \`pnpm codify:build\` (pipeline lives in the \`packages/codify\` submodule).
Comment on lines +11 to +17
The build pipeline and server-side lookup live in the **external
[`mieweb/codify`](https://github.com/mieweb/codify) repo**, which is **not
tracked here** (`packages/codify/` is gitignored). Only the browser
engine/component live in this repo; the committed `.mcdx` shards under
`.storybook/public/codify/` are the build output. Clone `codify` locally into
`packages/codify/` (see [§1](#1-build-pipeline-external-codify-repo)) to
regenerate them — the links below only resolve once it is present.
Comment on lines +136 to +144
async function maybeGunzip(buf: ArrayBuffer): Promise<ArrayBuffer> {
if (buf.byteLength < 2) return buf;
const head = new Uint8Array(buf, 0, 2);
if (head[0] !== 0x1f || head[1] !== 0x8b) return buf;
const stream = new Response(buf).body!.pipeThrough(
new DecompressionStream('gzip')
);
return await new Response(stream).arrayBuffer();
}
Comment on lines +475 to +480
{renderSearch({
domains:
type === 'auto' ? undefined : ORDER_TYPE_SEARCH_DOMAINS[type],
placeholder: ORDER_TYPE_PLACEHOLDERS[type],
onPick: handlePick,
})}
horner added 2 commits July 4, 2026 09:14
Rebuild en+es shards with the always-gzip codify pipeline so every .mcdx is
stored compressed (condition 13.7→4.1 MB, med 33.4→14.0 MB, lab 20.6→8.2 MB,
procedure 13.0→3.9 MB). Shrinks the git-lfs footprint and download size; the
worker inflates transparently. Manifest bytes updated to compressed sizes.
Add per-token usage priors, a stronger usage weight for short/ambiguous
queries, and a leading-prefix bonus (new docFirstTok shard section) so
common meds surface first for one-letter queries.
Copilot AI review requested due to automatic review settings July 4, 2026 13:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 42 changed files in this pull request and generated 5 comments.

</span>
}
>
<span className="text-muted-foreground text-xs whitespace-nowrap">
Comment on lines +233 to +235
<Tooltip content={meta.label}>
<Icon size={14} />
</Tooltip>
Comment on lines +136 to +144
async function maybeGunzip(buf: ArrayBuffer): Promise<ArrayBuffer> {
if (buf.byteLength < 2) return buf;
const head = new Uint8Array(buf, 0, 2);
if (head[0] !== 0x1f || head[1] !== 0x8b) return buf;
const stream = new Response(buf).body!.pipeThrough(
new DecompressionStream('gzip')
);
return await new Response(stream).arrayBuffer();
}
Comment on lines +11 to +17
The build pipeline and server-side lookup live in the **external
[`mieweb/codify`](https://github.com/mieweb/codify) repo**, which is **not
tracked here** (`packages/codify/` is gitignored). Only the browser
engine/component live in this repo; the committed `.mcdx` shards under
`.storybook/public/codify/` are the build output. Clone `codify` locally into
`packages/codify/` (see [§1](#1-build-pipeline-external-codify-repo)) to
regenerate them — the links below only resolve once it is present.
Comment on lines +276 to +293
export function searchShards(
shards: CodifyShard[],
query: string,
limit = 20
): CodifyResult[] {
const qTokens = normalize(query)
.split(' ')
.filter(Boolean)
.slice(0, MAX_QUERY_TOKENS);
if (qTokens.length === 0) return [];
const results: CodifyResult[] = [];

for (const s of shards) {
searchShard(s, qTokens, results, limit);
}
results.sort((a, b) => b.score - a.score);
return results.slice(0, limit);
}
horner added 2 commits July 4, 2026 09:52
Search results now show one entry per med family (keyed by the leading
label word), represented by the shortest nearly-as-relevant label (the
base ingredient/brand name). Variants remain reachable via the forms &
strengths drill-down, which searches uncollapsed.
Collapsing after per-shard truncation let a few popular families crowd
everything else out ('la' returned only 6 rows). Group by docFirstTok
during doc collection instead, falling back to the label's first word
when the first token is too short to identify a family (L-Dopres).
Copilot AI review requested due to automatic review settings July 4, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 42 changed files in this pull request and generated 6 comments.

label,
items: concerns.filter((c) => concernGroupKey(c) === key),
})),
].filter((g) => g.items.length > 0 || g.key === 'active');
Comment on lines +216 to +232
const relevanceOf = (concernId: string): ProblemRelevance | null =>
presenting.find((p) => p.concernId === concernId)?.relevance ?? null;

const submitDraft = () => {
const text = draft.trim();
if (!text) return;
onAddProblem?.(text);
setDraft('');
};

// "Relevant this visit" renders in `presenting` order (drag-reorderable);
// the unselected pool keeps patient problem-list order.
const selected = presenting
.map((p) => patientConcerns.find((c) => c.concernId === p.concernId))
.filter((c): c is ConditionConcern => Boolean(c));
const unselected = patientConcerns.filter((c) => !relevanceOf(c.concernId));

Comment on lines +136 to +144
async function maybeGunzip(buf: ArrayBuffer): Promise<ArrayBuffer> {
if (buf.byteLength < 2) return buf;
const head = new Uint8Array(buf, 0, 2);
if (head[0] !== 0x1f || head[1] !== 0x8b) return buf;
const stream = new Response(buf).body!.pipeThrough(
new DecompressionStream('gzip')
);
return await new Response(stream).arrayBuffer();
}
Comment on lines +540 to +544
Index unavailable: {status.message}. Run{' '}
<code className="font-mono">
node scripts/codify/extract.mjs && node
scripts/codify/build-index.mjs
</code>
Comment on lines +33 to +34
Shards are committed via git-lfs and served from \`.storybook/public/codify/{locale}/\`;
rebuild with \`pnpm codify:build\` (pipeline lives in the \`packages/codify\` submodule).
Comment on lines +11 to +13
The build pipeline and server-side lookup live in the **external
[`mieweb/codify`](https://github.com/mieweb/codify) repo**, which is **not
tracked here** (`packages/codify/` is gitignored). Only the browser
horner added 2 commits July 4, 2026 10:27
- familyKey/familyTerm: conditions group by code (ICD-10 root, SNOMED
  concept id), labs per analyte (LOINC property bracket stripped), meds
  by ingredient/brand word, others by leading label words
- drill-down (→) generalized: forms & strengths on meds, specific
  billable codes on conditions, related tests on labs
- stories for every domain: Procedures, Immunizations (CVX), Allergies
  (med-as-allergen)
- noted plan: condition drill-down will also surface suggested orders
- occupational shard (OSHA/FMCSA/NFPA/FAA programs); each program is
  its own family (keyed by code)
- drill-down on a program resolves its curated order set from
  order-sets.json via new engine findByCodes() across loaded shards
  (blood lead + ZPP for 1910.1025, HepB vaccine + titer for 1910.1030)
- worker: loads order-sets.json sidecar (OPFS-cached), 'orders' message
- Assessment: surveillance programs are concerns (isConditionCodetype),
  problem search includes the occupational domain
- MedicalSurveillance story; shards rebuilt with the new domain

Next: multi-select picklist for adding several required orders at once
Copilot AI review requested due to automatic review settings July 4, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 44 out of 45 changed files in this pull request and generated 12 comments.

Comment on lines +457 to +461
<button
type="button"
id={optionId(i)}
role="option"
aria-selected={i === activeIndex}
Comment on lines +513 to +516
<button
type="button"
onClick={submitFreeText}
className={cn(
Comment on lines +583 to +586
<code className="font-mono">
node scripts/codify/extract.mjs && node
scripts/codify/build-index.mjs
</code>
Comment on lines +33 to +34
Shards are committed via git-lfs and served from \`.storybook/public/codify/{locale}/\`;
rebuild with \`pnpm codify:build\` (pipeline lives in the \`packages/codify\` submodule).
Comment on lines +11 to +17
The build pipeline and server-side lookup live in the **external
[`mieweb/codify`](https://github.com/mieweb/codify) repo**, which is **not
tracked here** (`packages/codify/` is gitignored). Only the browser
engine/component live in this repo; the committed `.mcdx` shards under
`.storybook/public/codify/` are the build output. Clone `codify` locally into
`packages/codify/` (see [§1](#1-build-pipeline-external-codify-repo)) to
regenerate them — the links below only resolve once it is present.
Comment on lines +508 to +512
onChange={(e) =>
updateCoding(i, { code: e.target.value })
}
placeholder="Code"
className="w-28 font-mono"
Comment on lines +517 to +521
onChange={(e) =>
updateCoding(i, { display: e.target.value })
}
placeholder="Display"
className="min-w-32 flex-1"
Comment on lines +101 to +103
// hovering an invalid target: clear any stale indicator
setOver((prev) => (prev ? null : prev));
return;
Comment on lines +318 to +320
'pointer-events-none opacity-0 transition-opacity',
'group-hover:pointer-events-auto group-hover:opacity-100',
'focus-within:pointer-events-auto focus-within:opacity-100'
Comment on lines +368 to +372
const range: number[] = new Array(hi - lo);
for (let t = lo; t < hi; t++) range[t - lo] = t;
range.sort((a, b) => {
const d = tp[b] - tp[a];
if (d) return d;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants