The verify pipeline carried two scripts whose targets no longer
exist after the vanilla deletion at commit 25a9c4c:
test/calc-math.test.js — required public/js/calc-math.js (gone);
every assertion is now covered by shared/clinical/
calculators.test.ts (vitest).
scripts/lint-references.js — scans public/js/*.js for DOM id
references and checks each target exists in public/components/
*.html. Those trees are gone; TypeScript + knip + vite build
cover the equivalent dead-reference class for the React tree.
package.json:
• `verify` drops `test:node` and `lint:refs`; now runs
typecheck + vitest + knip + client vite build.
• `test:node` script removed (test/ directory empty).
public/app/assets/ — fresh vite build so the bundle hashes match
the current source (new chunks for ByVisitAge, Cms, DxPicker,
EditableResult, LabsList, Milestones, OutputActions, Recorder,
Shadess, SlideEditor, VisitNote — all features landed in the
preceding commits).
Verified locally on node 20: tsc + 9 test files / 177 tests pass,
knip finds nothing, vite builds 35 chunks, client bundle is 343 kB
initial / 106 kB gzipped (Cms is the biggest lazy chunk at 402 kB
due to Tiptap/ProseMirror).
1 line
No EOL
6.6 KiB
JavaScript
1 line
No EOL
6.6 KiB
JavaScript
import{i as e,n as t,t as n}from"./jsx-runtime-ByY1xr43.js";import{i as r}from"./index-C9wKWOAN.js";import{t as i}from"./OutputActions-6XZlmtIw.js";var a=e(t(),1),o=e=>`_savedEncId_`+e,s=e=>`_idempKey_`+e;function c(e){try{let t=sessionStorage.getItem(o(e));return t?Number(t):null}catch{return null}}function l(e,t){try{t==null?sessionStorage.removeItem(o(e)):sessionStorage.setItem(o(e),String(t))}catch{}}function u(e){try{let t=sessionStorage.getItem(s(e));if(t)return t}catch{}let t=typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e===`x`?t:t&3|8).toString(16)});try{sessionStorage.setItem(s(e),t)}catch{}return t}function d(e){try{sessionStorage.removeItem(s(e))}catch{}}var f=new Map;async function p(e){if(!e.label.trim())throw Error(`Enter a patient label first`);let t=c(e.type),n={label:e.label.trim(),enc_type:e.type,transcript:e.transcript,generated_note:e.generatedNote,partial_data:e.partialData==null?void 0:JSON.stringify(e.partialData),idempotency_key:u(e.type)};if(t!=null){n.id=t;let e=f.get(t);e!=null&&(n.expected_version=e)}let r=await fetch(`/api/encounters/saved`,{method:`POST`,credentials:`include`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)}),i=await r.json();if(r.status===409)throw Error(`Someone else edited this encounter. Reload to see the latest version.`);if(!i.success)throw Error(i.error||`Save failed`);return i.id!=null&&(l(e.type,i.id),i.version!=null&&f.set(i.id,i.version)),{id:i.id,version:i.version}}async function m(e){let t=await(await fetch(`/api/encounters/saved/`+e,{credentials:`include`})).json();if(!t.success)throw Error(t.error||`Load failed`);return t.encounter&&t.encounter.version!=null&&f.set(e,t.encounter.version),t.encounter}async function h(){return(await(await fetch(`/api/encounters/saved`,{credentials:`include`})).json()).encounters||[]}function g(e){l(e,null),d(e)}var _=n(),v=`rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-ring`,y=`inline-flex items-center gap-1 rounded-md border border-border bg-background px-3 py-1.5 text-xs font-medium hover:bg-muted disabled:opacity-50`,b=`inline-flex items-center gap-1 rounded-md bg-primary text-primary-foreground px-3 py-1.5 text-xs font-medium disabled:opacity-50`;function x({type:e,label:t,setLabel:n,transcript:r,generatedNote:i,partialData:o,onLoad:s,onClear:l}){let[u,d]=(0,a.useState)(null),[f,x]=(0,a.useState)(!1),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)([]),[E,D]=(0,a.useState)(!1),[O,k]=(0,a.useState)(``),[A,j]=(0,a.useState)(c(e));(0,a.useEffect)(()=>{j(c(e))},[r,i]);async function M(){if(!t.trim()){d({kind:`err`,text:`Enter a patient label first`});return}d(null),x(!0);try{j((await p({type:e,label:t,transcript:r,generatedNote:i,partialData:o})).id),d({kind:`ok`,text:`Saved (`+t+`)`})}catch(e){d({kind:`err`,text:e.message})}finally{x(!1)}}function N(){g(e),j(null),n(``),l(),d({kind:`info`,text:`New patient — fields cleared.`})}async function P(){if(S){C(!1);return}C(!0),D(!0);try{T((await h()).filter(t=>t.enc_type===e))}finally{D(!1)}}async function F(e){try{let t=await m(e);j(e),s(t),C(!1),d({kind:`ok`,text:`Loaded `+(t.label||``)})}catch(e){d({kind:`err`,text:e.message})}}let I=O?w.filter(e=>(e.label||``).toLowerCase().includes(O.toLowerCase())):w;return(0,_.jsxs)(`div`,{className:`space-y-2`,"data-testid":`enc-toolbar-`+e,children:[(0,_.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,_.jsx)(`input`,{className:v+` flex-1 min-w-[180px] max-w-md`,placeholder:`Patient label (e.g. JD-2026-04-24)`,value:t,onChange:e=>n(e.target.value),"data-testid":`enc-label`}),(0,_.jsxs)(`button`,{type:`button`,onClick:M,disabled:f,className:b,"data-testid":`enc-save`,children:[`💾 `,f?`Saving…`:A==null?`Save`:`Save (update)`]}),(0,_.jsxs)(`div`,{className:`relative`,children:[(0,_.jsx)(`button`,{type:`button`,onClick:P,className:y,"data-testid":`enc-load-toggle`,children:`📂 Load`}),S&&(0,_.jsxs)(`div`,{className:`absolute z-30 mt-1 right-0 w-80 max-h-96 overflow-auto rounded-md border border-border bg-card shadow-lg`,children:[(0,_.jsx)(`div`,{className:`sticky top-0 bg-card p-2 border-b border-border`,children:(0,_.jsx)(`input`,{type:`search`,placeholder:`Filter saved encounters…`,className:v+` w-full text-xs`,value:O,onChange:e=>k(e.target.value),autoFocus:!0,"data-testid":`enc-load-search`})}),E&&(0,_.jsx)(`div`,{className:`p-3 text-xs text-muted-foreground`,children:`Loading…`}),!E&&I.length===0&&(0,_.jsxs)(`div`,{className:`p-3 text-xs text-muted-foreground italic`,children:[`No saved `,e,` encounters.`]}),I.map(e=>(0,_.jsxs)(`button`,{type:`button`,onClick:()=>F(e.id),className:`w-full text-left px-3 py-2 hover:bg-muted border-b border-border last:border-0`,"data-testid":`enc-load-pick-`+e.id,children:[(0,_.jsx)(`div`,{className:`text-sm font-medium truncate`,children:e.label}),(0,_.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Updated `,new Date(e.updated_at).toLocaleString(),` · expires `,new Date(e.expires_at).toLocaleDateString()]})]},e.id))]})]}),(0,_.jsx)(`button`,{type:`button`,onClick:N,className:y,"data-testid":`enc-new`,children:`🆕 New patient`}),A!=null&&(0,_.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`Draft #`,A]})]}),u&&(0,_.jsx)(`div`,{className:`text-sm `+(u.kind===`ok`?`text-green-600`:u.kind===`err`?`text-destructive`:`text-muted-foreground`),children:u.text})]})}function S(e,t){if(!e||!t||e.trim()===t.trim())return!1;let n=e.split(/\s+/).length,r=t.split(/\s+/).length;return!(Math.abs(n-r)<2&&e.length>100&&Math.abs(e.length-t.length)<20)}function C({text:e,onChange:t,section:n,exportLabel:o,exportType:s,sourceContext:c,title:l}){let u=(0,a.useRef)(e);(0,a.useEffect)(()=>{!u.current&&e&&(u.current=e)},[e]);async function d(){if(n&&S(u.current,e))try{await r.post(`/api/memories/correction`,{section:n,original_snippet:u.current,corrected_snippet:e}),u.current=e}catch{}}return(0,_.jsxs)(`section`,{className:`rounded-lg border border-border bg-card`,"data-testid":`editable-result-`+s,children:[(0,_.jsx)(`header`,{className:`px-4 py-2 border-b border-border bg-muted/40`,children:(0,_.jsx)(`h2`,{className:`text-sm font-semibold`,children:l})}),(0,_.jsx)(`textarea`,{className:`w-full p-4 text-sm bg-transparent resize-y min-h-[200px] focus:outline-none focus:ring-0 border-0 whitespace-pre-wrap`,value:e,onChange:e=>t(e.target.value),onBlur:d,"data-testid":`editable-result-body-`+s,spellCheck:!0}),(0,_.jsx)(`div`,{className:`px-4 pb-4`,children:(0,_.jsx)(i,{text:e,onUpdate:e=>{u.current=e,t(e)},sourceContext:c,exportLabel:o,exportType:s})})]})}export{x as n,C as t}; |