- ✅ Ticket 1.1: Estructura Clean Architecture en backend - ✅ Ticket 1.2: Schemas Zod compartidos - ✅ Ticket 1.3: Refactorización drugs.ts (1362 → 8 archivos modulares) - ✅ Ticket 1.4: Refactorización procedures.ts (3583 → 6 archivos modulares) - ✅ Ticket 1.5: Eliminación de duplicidades (~50 líneas) Cambios principales: - Creada estructura Clean Architecture en backend/src/ - Schemas Zod compartidos en backend/src/shared/schemas/ - Refactorización modular de drugs y procedures - Utilidades genéricas en src/utils/ (filter, validation) - Eliminados scripts obsoletos y documentación antigua - Corregidos errores: QueryClient, import test-error-handling - Build verificado y funcionando correctamente
2 lines
15 KiB
JavaScript
2 lines
15 KiB
JavaScript
import{u as E,r as p,j as e,R as C,q as I,I as T,E as k,s as w,S as B,A as D,U as z,G as O,t as V,v as q,i as L}from"./0-vendor-react-DWOJpYrt.js";import{A as R,a as A,C as M,B as u}from"./page-comunicacion-DmHQUHoW.js";import{B as m}from"./page-ajustes-DgawOEJM.js";import"./1-vendor-utils-Delnuc0l.js";import"./2-vendor-markdown-BQlHAcA7.js";const U={id:"pcr-recognition",title:"Reconocimiento de PCR",shortTitle:"PCR",description:"Identificar PCR en <10 segundos. Decisión binaria rápida.",category:"soporte_vital",rootNodeId:"responds",source:"BLOQUE_04_0_RECONOCIMIENTO_PCR.md",nodes:[{id:"responds",type:"question",text:"¿Responde? (Estímulo doloroso, voz fuerte)",yes:"not-pcr",no:"breathes"},{id:"breathes",type:"question",text:'¿Respira con normalidad? (Ver, oír, sentir <10"; buscar respiraciones agónicas/ineficaces)',yes:"not-pcr-breathing",no:"pcr-confirmed"},{id:"pcr-confirmed",type:"question",text:"¿Estoy solo o con equipo?",yes:"pcr-with-team",no:"pcr-alone"},{id:"pcr-with-team",type:"action",text:"CON EQUIPO: Asignar roles",action:'Asignar roles: "Tú, compresiones. Tú, prepara BVM y DESA. Yo lidero y cronometro". Iniciar RCP coordinada (Cap 4.5).',redirectTo:"/soporte-vital?id=rcp-dos-intervinientes",notes:"Iniciar RCP coordinada inmediatamente"},{id:"pcr-alone",type:"action",text:"SOLO: Activar y empezar RCP",action:'Activar altavoz del portátil/radio: "Solicito recurso para PCR en [ubicación], único interviniente, inicio RCP". Iniciar RCP (Cap 4.1) inmediatamente.',redirectTo:"/soporte-vital?id=rcp-adulto-svb",notes:"No demorar RCP por buscar material"},{id:"not-pcr",type:"action",text:"NO ES PCR",action:"Pasar a valoración ABCDE. Evaluar causa de inconsciencia.",redirectTo:"/escena?tab=abcde",notes:"Paciente responde: no es PCR"},{id:"not-pcr-breathing",type:"action",text:"NO ES PCR",action:"Colocar en PLS (ver Cap 4.9) y valorar. Monitorizar continuamente.",redirectTo:"/soporte-vital?id=posicion-lateral-seguridad",notes:"Respira normal pero inconsciente: PLS"}]},_={id:"svb-adult",title:"SVB Adulto - Árbol de Decisión",shortTitle:"SVB Adulto",description:"Árbol de decisión para iniciar RCP básica en adultos.",category:"soporte_vital",rootNodeId:"safe",source:"BLOQUE_04_1_RCP_ADULTOS.md",nodes:[{id:"safe",type:"question",text:"¿ES SEGURO?",yes:"responds-svb",no:"secure-scene"},{id:"secure-scene",type:"action",text:"Asegurar escena",action:"Asegura/retira riesgo si posible. No poner en riesgo tu seguridad.",notes:"Si no es seguro, no proceder hasta asegurar escena"},{id:"responds-svb",type:"question",text:"¿RESPONDE?",yes:"evaluate-abcde",no:"breathes-svb"},{id:"breathes-svb",type:"question",text:"¿RESPIRA NORMAL?",yes:"pls",no:"start-rcp"},{id:"start-rcp",type:"action",text:"INICIAR RCP",action:"ACTIVAR 112 + PEDIR DESA. INICIAR RCP (C-A-B). DESA EN CUANTO LLEGUE (Bloque 4.4). Compresiones 100–120/min y profundidad 5–6 cm.",redirectTo:"/soporte-vital?id=rcp-adulto-svb",notes:"PCR confirmada: iniciar RCP inmediatamente"},{id:"pls",type:"action",text:"Posición Lateral de Seguridad",action:"PLS (Bloque 4.9) + reevaluación continua. Monitorizar respiración y pulso.",redirectTo:"/soporte-vital?id=posicion-lateral-seguridad",notes:"Respira normal pero inconsciente: PLS"},{id:"evaluate-abcde",type:"action",text:"Valorar ABCDE",action:"Valorar, monitorizar, buscar causa, 112 si procede. No es PCR.",redirectTo:"/escena?tab=abcde",notes:"Paciente responde: evaluar ABCDE"}]},F=[U,_];function G(r){return r.nodes.find(o=>o.id===r.rootNodeId)}function P(r,o){return r.nodes.find(h=>h.id===o)}const Q=({tree:r,onReset:o})=>{const h=E(),[c,x]=p.useState(r.rootNodeId),[i,d]=p.useState([r.rootNodeId]),t=P(r,c),g=G(r);if(!t||!g)return e.jsx(R,{children:e.jsx(A,{children:"Error: Nodo no encontrado en el árbol de decisión."})});const f=n=>{const l=n==="yes"?t.yes:t.no;if(!l)return;const N=P(r,l);if(N){if(N.type==="action"||N.type==="redirect"){x(l),d([...i,l]);return}x(l),d([...i,l])}},s=()=>{x(r.rootNodeId),d([r.rootNodeId]),o&&o()},a=n=>{n&&h(n)},b=()=>{if(i.length>1){const n=[...i];n.pop();const l=n[n.length-1];x(l),d(n)}},j=i.length>1,v=t.type==="question",y=t.type==="action"||t.type==="redirect";return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-1",children:r.title}),e.jsx("p",{className:"text-muted-foreground text-sm",children:r.description})]}),e.jsx(m,{variant:"ghost",size:"sm",onClick:s,className:"shrink-0",title:"Reiniciar árbol",children:e.jsx(C,{className:"w-4 h-4"})})]}),i.length>1&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Paso ",i.length]}),j&&e.jsx(m,{variant:"ghost",size:"sm",onClick:b,className:"h-6 px-2 text-xs",children:"← Atrás"})]}),e.jsxs(M,{className:"p-4 space-y-4",children:[e.jsxs("div",{className:"space-y-3",children:[v&&e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center shrink-0 mt-0.5",children:e.jsx("span",{className:"text-primary font-bold text-sm",children:"?"})}),e.jsx("p",{className:"text-foreground font-medium text-base leading-relaxed pt-1",children:t.text})]}),y&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-success/10 flex items-center justify-center shrink-0 mt-0.5",children:e.jsx(I,{className:"w-4 h-4 text-success"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-foreground font-semibold text-base mb-2",children:t.text}),t.action&&e.jsx("p",{className:"text-foreground text-sm leading-relaxed bg-muted p-3 rounded-lg",children:t.action})]})]}),t.notes&&e.jsxs(R,{children:[e.jsx(T,{className:"w-4 h-4"}),e.jsx(A,{className:"text-sm",children:t.notes})]}),t.redirectTo&&e.jsxs(m,{onClick:()=>a(t.redirectTo),className:"w-full",variant:"default","aria-label":"Ir a procedimiento relacionado",children:[e.jsx(k,{className:"w-4 h-4 mr-2"}),"Ir a procedimiento relacionado"]})]})]}),v&&e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(m,{onClick:()=>f("yes"),className:"flex-1 bg-success hover:bg-success/90",size:"lg","aria-label":"Responder sí",children:"SÍ"}),e.jsx(m,{onClick:()=>f("no"),className:"flex-1 bg-destructive hover:bg-destructive/90",size:"lg","aria-label":"Responder no",children:"NO"})]}),y&&e.jsxs("div",{className:"flex gap-3 pt-2",children:[j&&e.jsx(m,{onClick:b,variant:"outline",className:"flex-1","aria-label":"Volver al paso anterior",children:"← Atrás"}),e.jsxs(m,{onClick:s,variant:"outline",className:"flex-1","aria-label":"Reiniciar árbol de decisión",children:[e.jsx(C,{className:"w-4 h-4 mr-2"}),"Reiniciar"]})]})]}),r.source&&e.jsxs("p",{className:"text-xs text-muted-foreground text-center",children:["Fuente: ",r.source]})]})},S=[{id:"seguridad",label:"Seguridad",icon:B},{id:"abcde",label:"ABCDE",icon:D},{id:"triage",label:"Triage",icon:z},{id:"decisiones",label:"Decisiones",icon:O},{id:"inmovilizacion",label:"Inmovil.",icon:V},{id:"extricacion",label:"Extric.",icon:q}],$=["Valorar mecanismo lesional","Identificar riesgos: tráfico, fuego, químicos, electricidad","Usar EPI adecuado","Señalizar/balizar la zona","Solicitar recursos si es necesario","Establecer zona de seguridad","Acceso seguro a la víctima"],H=[{letter:"A",title:"Airway - Vía Aérea",points:["Permeabilidad vía aérea","Control cervical si trauma","Aspirar secreciones","Cánula orofaríngea si inconsciente"]},{letter:"B",title:"Breathing - Respiración",points:["FR, profundidad, simetría","SpO2","Auscultación","Oxigenoterapia si precisa"]},{letter:"C",title:"Circulation - Circulación",points:["FC, TA, relleno capilar","Control de hemorragias","Acceso venoso","Fluidoterapia si shock"]},{letter:"D",title:"Disability - Neurológico",points:["Nivel consciencia (AVDN/Glasgow)","Pupilas","Glucemia","Movilidad extremidades"]},{letter:"E",title:"Exposure - Exposición",points:["Desvestir para explorar","Prevenir hipotermia","Inspección completa","Buscar lesiones ocultas"]}],J=[{color:"Negro",criteria:"No respira tras apertura vía aérea",action:"Fallecido / Expectante",colorClass:"bg-foreground text-background"},{color:"Rojo",criteria:"FR >30 o <10, TRC >2s, no obedece órdenes",action:"Prioridad 1 - Inmediato",colorClass:"bg-primary text-primary-foreground"},{color:"Amarillo",criteria:"No puede caminar, pero estable",action:"Prioridad 2 - Urgente",colorClass:"bg-warning text-background"},{color:"Verde",criteria:"Puede caminar",action:"Prioridad 3 - Demorado",colorClass:"bg-success text-background"}],ee=()=>{const[r]=w(),o=r.get("tab"),h=p.useMemo(()=>o&&S.some(s=>s.id===o)?o:"seguridad",[o]),[c,x]=p.useState(h),[i,d]=p.useState(new Set),[t,g]=p.useState(null),f=s=>{const a=new Set(i);a.has(s)?a.delete(s):a.add(s),d(a)};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-foreground mb-1",children:"Actuación en Escena"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Seguridad, valoración y triage"})]}),e.jsx("div",{className:"flex gap-2 overflow-x-auto scrollbar-hide -mx-4 px-4",children:S.map(s=>{const a=s.icon;return e.jsxs("button",{onClick:()=>x(s.id),className:`flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium whitespace-nowrap transition-colors ${c===s.id?"bg-secondary text-secondary-foreground":"bg-muted text-muted-foreground hover:bg-accent"}`,children:[e.jsx(a,{className:"w-4 h-4"}),s.label]},s.id)})}),c==="seguridad"&&e.jsxs("div",{className:"card-procedure",children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-4",children:"🛡️ Checklist Seguridad Escena"}),e.jsx("div",{className:"space-y-2",children:$.map((s,a)=>e.jsxs("button",{onClick:()=>f(a),className:"w-full flex items-center gap-3 p-3 rounded-lg bg-muted hover:bg-accent transition-colors text-left",children:[e.jsx("div",{className:`w-6 h-6 rounded border-2 flex items-center justify-center transition-colors ${i.has(a)?"bg-success border-success":"border-muted-foreground"}`,children:i.has(a)&&e.jsx(L,{className:"w-4 h-4 text-background"})}),e.jsx("span",{className:`text-foreground ${i.has(a)?"line-through opacity-60":""}`,children:s})]},a))}),e.jsx("button",{onClick:()=>d(new Set),className:"mt-4 text-sm text-muted-foreground hover:text-foreground",children:"Reiniciar checklist"})]}),c==="abcde"&&e.jsx("div",{className:"space-y-4",children:H.map(s=>e.jsxs("div",{className:"card-procedure",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx("span",{className:"step-number text-lg",children:s.letter}),e.jsx("h3",{className:"font-bold text-foreground",children:s.title})]}),e.jsx("ul",{className:"space-y-2 ml-11",children:s.points.map((a,b)=>e.jsxs("li",{className:"text-foreground flex items-start gap-2",children:[e.jsx("span",{className:"text-primary",children:"•"}),e.jsx("span",{children:a})]},b))})]},s.letter))}),c==="triage"&&e.jsxs("div",{className:"card-procedure",children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-4",children:"🏥 Triage START (Adultos)"}),e.jsx("div",{className:"space-y-3",children:J.map(s=>e.jsxs("div",{className:"flex items-stretch gap-3 rounded-lg overflow-hidden border border-border",children:[e.jsx("div",{className:`w-20 flex items-center justify-center font-bold text-sm ${s.colorClass}`,children:s.color}),e.jsxs("div",{className:"flex-1 p-3",children:[e.jsx("p",{className:"text-foreground text-sm font-medium",children:s.criteria}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:s.action})]})]},s.color))}),e.jsx("p",{className:"text-xs text-muted-foreground mt-4",children:"JumpSTART para pediátricos: ajustar FR (15-45 normal en lactantes)"})]}),c==="decisiones"&&e.jsx("div",{className:"space-y-4",children:t?e.jsxs("div",{children:[e.jsx("button",{onClick:()=>g(null),className:"mb-4 text-sm text-muted-foreground hover:text-foreground flex items-center gap-2",children:"← Volver a lista de árboles"}),e.jsx(Q,{tree:t,onReset:()=>g(null)})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-2",children:"🌳 Árboles de Decisión Binarios"}),e.jsx("p",{className:"text-muted-foreground text-sm mb-4",children:"Selecciona un árbol para tomar decisiones rápidas paso a paso"})]}),e.jsx("div",{className:"space-y-3",children:F.map(s=>e.jsx("button",{onClick:()=>g(s),className:"w-full text-left card-procedure hover:bg-accent transition-colors",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-semibold text-foreground mb-1",children:s.title}),e.jsx("p",{className:"text-muted-foreground text-sm",children:s.description})]}),e.jsx(u,{variant:"default",className:"shrink-0",children:s.category==="soporte_vital"?"SVB":s.category})]})},s.id))})]})}),c==="inmovilizacion"&&e.jsxs("div",{className:"card-procedure",children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-4",children:"🦴 Inmovilización"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"font-semibold text-foreground mb-2",children:"Indicaciones de inmovilización espinal"}),e.jsxs("ul",{className:"space-y-1 text-foreground text-sm",children:[e.jsx("li",{children:"• Mecanismo lesional de riesgo"}),e.jsx("li",{children:"• Dolor cervical o dorsolumbar"}),e.jsx("li",{children:"• Déficit neurológico"}),e.jsx("li",{children:"• Alteración nivel consciencia"}),e.jsx("li",{children:"• Intoxicación que impide valoración"})]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-semibold text-foreground mb-2",children:"Material"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(u,{variant:"default",children:"Collarín cervical"}),e.jsx(u,{variant:"default",children:"Tabla espinal"}),e.jsx(u,{variant:"default",children:"Dama de Elche"}),e.jsx(u,{variant:"default",children:"Férula de tracción"}),e.jsx(u,{variant:"default",children:"Férulas de vacío"})]})]})]})]}),c==="extricacion"&&e.jsxs("div",{className:"card-procedure",children:[e.jsx("h3",{className:"font-bold text-foreground text-lg mb-4",children:"🚗 Extricación Vehicular"}),e.jsx("div",{className:"space-y-4",children:e.jsxs("div",{children:[e.jsx("h4",{className:"font-semibold text-muted-foreground text-sm uppercase tracking-wide mb-2",children:"Maniobra de Rautek"}),e.jsx("ol",{className:"space-y-2",children:["Aproximarse por detrás de la víctima","Pasar brazos bajo axilas","Sujetar antebrazo de víctima contra su pecho","Extraer arrastrando hacia atrás","Mantener alineación espinal"].map((s,a)=>e.jsxs("li",{className:"flex items-start gap-3",children:[e.jsx("span",{className:"step-number",children:a+1}),e.jsx("span",{className:"text-foreground pt-1",children:s})]},a))})]})})]})]})};export{ee as default};
|