// intake.jsx — 고객 인테이크(온보딩): 회사 → 여정(신규/갱신) → 실행 const { Icon, Pill, Button, Progress } = window.RAlly; // ── 판정 인터뷰: 앱이 질문을 하나씩 던져 정보를 받아 판정에 사용 ────────── const IV_QUESTIONS = [ { key: 'name', type: 'text', q: '제품(품목)의 이름은 무엇인가요?', ph: '예: 리스파이어 DTx', why: '문서 표제부·품목명에 사용됩니다.', required: true }, { key: 'indication', type: 'textarea', q: '제품의 용도와 핵심 기능을 설명해 주세요.', ph: '예: 만성호흡기질환 가정 호흡재활 디지털치료기기 소프트웨어, AI 분석 포함', why: '설명을 근거로 디지털·AI 여부를 1차 자동 판정합니다.' }, { key: 'digital', type: 'choice', q: '소프트웨어 의료기기(SaMD·디지털)인가요?', options: [['yes', '예'], ['no', '아니오'], ['unknown', '모르겠어요 — 설명으로 자동 판정']], why: '별표2·별표3 적용 여부를 결정합니다.' }, { key: 'ai', type: 'choice', q: '인공지능/머신러닝(AI/ML) 기능이 포함되나요?', options: [['yes', '예'], ['no', '아니오'], ['unknown', '모르겠어요 — 설명으로 자동 판정']], why: '별표4(AI 제어조치) 적용 여부를 결정합니다.' }, { key: '등급', type: 'choice', q: '의료기기 등급은 무엇인가요?', options: [['1', '1등급'], ['2', '2등급'], ['3', '3등급'], ['4', '4등급'], ['', '모르겠어요']], why: '심사 범위·문서 구성을 결정합니다. (공식 품목분류표 기준 — 자동 판정 불가)' }, { key: '품목분류', type: 'text', q: '품목분류번호를 알려주세요.', finder: true, ph: '예: E01020.01 (모르면 아래 “찾기 도우미”로 좁혀보세요)', why: '대상 품목을 확인합니다. 디지털 SW는 E코드(대분류 E·임상영역·기능)로 분류됩니다.' }, { key: '심사구분', type: 'choice', q: '신규 취득인가요, 갱신 심사인가요?', options: [['신규', '신규 취득'], ['갱신', '갱신 심사']], why: '신규/갱신 워크플로를 분기합니다.' }, ]; // 식약처 의료기기 소프트웨어(SaMD) 품목분류 — 대분류 E, 임상영역별 중분류 11개(웹 검증, 2025 고시). // 소분류(끝번호)·등급은 임상영역+기능+등급 조합으로 정해지므로 식약처 확정 필요. 확인된 예시만 subs에 수록. const SW_AREAS = [ { code: 'E01000', name: '심혈관 진료용', kw: '심혈관·심장·심전도·혈관·ASCVD·순환기', subs: [['E01010.01', '심혈관영상치료계획'], ['E01020.01', '심전도분석'], ['E01120.01', '심혈관영상검출·진단보조']] }, { code: 'E02000', name: '치의학 진료용', kw: '치과·구강·치아', subs: [['E02010.01', '치과영상전송(1등급)'], ['E02010.02', '치과영상전송(2등급)']] }, { code: 'E03000', name: '이비인후과학 진료용', kw: '귀·코·목·청력·이비인후', subs: [] }, { code: 'E04000', name: '위장병학·비뇨의학 진료용', kw: '소화기·위장·대장·비뇨·내시경', subs: [] }, { code: 'E05000', name: '병원 진료용(일반)', kw: '병원일반·통합·범용', subs: [] }, { code: 'E06000', name: '신경과학 진료용', kw: '뇌·신경·뇌파·EEG·뇌졸중', subs: [] }, { code: 'E07000', name: '산부인과학 진료용', kw: '산부인과·태아·자궁·임신', subs: [] }, { code: 'E08000', name: '안과학 진료용', kw: '눈·안과·망막·안저·시력', subs: [] }, { code: 'E09000', name: '정형외과학 진료용', kw: '뼈·관절·척추·정형외과·골', subs: [] }, { code: 'E10000', name: '재활의학 진료용', kw: '재활·물리치료·운동', subs: [] }, { code: 'E11000', name: '방사선종양학·영상의학 진료용', kw: '영상의학·CT·MRI·X선·방사선치료·판독', subs: [] }, ]; const SW_FUNCS = [ ['검출·진단보조', '영상/데이터에서 이상을 검출해 진단 보조 (…검출·진단보조소프트웨어)'], ['치료계획', '치료 계획 수립·보조 (…영상치료계획소프트웨어)'], ['신호분석', '생체신호(심전도·뇌파 등) 분석 (…분석소프트웨어)'], ['영상전송·저장', '영상 전송·저장·표시 (…영상전송장치소프트웨어)'], ['기타·모름', '위에 해당하지 않거나 확실치 않음'], ]; const _fbtn = (on) => ({ fontFamily: 'inherit', fontSize: 11.5, padding: '5px 9px', borderRadius: 6, cursor: 'pointer', border: `1px solid ${on ? 'var(--coral)' : 'var(--line)'}`, background: on ? 'var(--coral-soft)' : 'var(--surface)', color: on ? 'var(--coral-2)' : 'var(--ink)', }); // 품목 찾기 도우미: 임상영역+기능을 물어 중분류(E코드) 후보로 좁힘. 소분류·등급은 식약처 확정. const ClassFinder = ({ onPick }) => { const [area, setArea] = React.useState(null); const [func, setFunc] = React.useState(null); const a = SW_AREAS.find((x) => x.code === area); return (
품목 찾기 도우미
디지털 소프트웨어(SaMD)는 대분류 E(소프트웨어) · 임상영역별 중분류 · 기능별 소분류로 나뉩니다. 아래에서 좁혀보세요.
① 어느 임상영역인가요?
{SW_AREAS.map((x) => ( ))}
{area && (
② 핵심 기능은?
{SW_FUNCS.map(([k, desc]) => ( ))}
)} {area && (
대분류 E · 의료기기 소프트웨어(SaMD)
중분류 후보 {a.code} · {a.name} 소프트웨어
{a.subs.length > 0 ? (
이 영역의 실제 소분류 예: {a.subs.map(([c, n]) => c + ' ' + n).join(' · ')}
) : (
이 영역의 소분류(끝번호)는 식약처 품목분류에서 확인하세요.
)}
⚠ 정확한 소분류 끝번호·등급은 임상영역+기능+등급 조합으로 정해집니다. 지어내지 않습니다 — 식약처 의료기기 품목분류에서 최종 확인하세요.
식약처 품목분류 조회 ↗
)}
); }; // 임상 필요성 '안내'(참고용) — 확정 아님. Q1~Q4 → 동등/개량/신제품 경로 안내. const CG_TONE = { green: { bg: '#EAF7EF', bd: '#22C55E', fg: '#15924A' }, amber: { bg: '#FFF6E5', bd: '#F5A623', fg: '#9A6800' }, coral: { bg: 'var(--coral-soft)', bd: 'var(--coral)', fg: 'var(--coral-2)' }, }; const CG_DS = { req: { t: '필수', c: '#15924A', b: '#EAF7EF' }, cond: { t: '조건부', c: '#9A6800', b: '#FFF6E5' }, exempt: { t: '면제', c: 'var(--ink-3)', b: '#F1F2F4' }, }; const ClinicalGuide = ({ aiHint }) => { const [open, setOpen] = React.useState(false); const [ans, setAns] = React.useState(() => (aiHint ? { ai_decision: 'yes' } : {})); const [res, setRes] = React.useState(null); const [busy, setBusy] = React.useState(false); const set = (k, v) => { setAns((s) => ({ ...s, [k]: v })); setRes(null); }; const canAssess = ans.similar_exists === 'no' || (ans.similar_exists === 'yes' && ans.same_purpose === 'no') || (ans.similar_exists === 'yes' && ans.same_purpose === 'yes' && !!ans.diff_level); const run = () => { setBusy(true); fetch('/api/clinical-guide', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ answers: ans }), }).then((r) => r.json()).then((d) => { setRes(d); setBusy(false); }).catch(() => setBusy(false)); }; const Q = ({ label, k, opts }) => (
{label}
{opts.map(([v, t]) => )}
); return (
{!open &&
“우리도 임상해야 하나요?”를 몇 가지 질문으로 안내합니다. (확정 아님)
} {open && (
{/* 안내 원칙(면책) 배너 */}
RAlly는 임상 필요 여부를 확정하지 않고 안내만 합니다. 최종 판단은 식약처 심사에서 이루어지며, 아래는 참고용입니다. RAlly는 GMP 문서를 생성하되 임상시험·허가 제출 자료는 생성하지 않습니다.
{ans.similar_exists === 'yes' && ( )} {ans.similar_exists === 'yes' && ans.same_purpose === 'yes' && ( )}
{!canAssess && Q1~Q3에 답하면 경로를 안내합니다.}
{res && res.complete && (
{res.branch_label} {res.headline}
{res.clinical}
{res.ai_note && (
🧠 {res.ai_note}
)}
이 경로에서 필요할 수 있는 문서 (안내)
{res.docs.map((d, i) => (
{CG_DS[d.state].t}
{d.name}
{d.note}
))}
근거 · {(res.basis || []).join(' / ')}
{res.disclaimer}
)}
)}
); }; // ── 통합 프로필 입력 필드(회사·제품 전항목) ───────────────────────── const _inp = { width: '100%', fontFamily: 'inherit', fontSize: 13, padding: '7px 10px', border: '1px solid var(--line)', borderRadius: 7 }; const ProfileField = ({ f, value, onChange, note }) => (
{f.label}
{f.multiline ? (