일반사용자용 카테고리 전용 대화형 위저드 만들기
EasyPrompt에는 5060세대·어르신을 위한 "일반사용자용" 카테고리가 있다. 문제는 이 카테고리의 프롬프트 10개도 사무용 프롬프트와 똑같은 방식으로 노출되고 있었다는 것. 즉 label/placeholder가 붙은 입력 폼 여러 개를 한 화면에 쭉 늘어놓고, 타이핑하는 대로 실시간 미리보기가 갱신되는 구조였다.
이 방식은 사무직 사용자에게는 편하지만, 어르신 입장에서는 여러 개의 빈 칸이 한 번에 보이는 것 자체가 진입장벽이 될 수 있다. 그래서 한 번에 하나씩만 묻는 대화형 위저드로 바꾸기로 했다. 각 질문에는 "이걸 왜 물어보는지"에 대한 짧은 설명을 붙여서, 완성된 결과를 보여줄 때 그 이유까지 함께 보여주는 것이 핵심 아이디어였다.
단, 사무용 프롬프트(PromptDetail.jsx의 기존 폼 로직)는 절대 건드리지 않는 것을 전제 조건으로 잡았다.
prompt_forms 테이블에 point_reason TEXT 컬럼을 추가했다. 마이그레이션 파일(backend-hono/migrations/0001_add_prompt_forms_point_reason.sql)을 만들고 schema.sql도 동기화해뒀다.
일반사용자용(category_id=7) 프롬프트 10개, 폼 17개 전부에 대해 "이 항목을 왜 물어보는지" 한 줄 설명을 직접 작성해서 UPDATE했다. 예를 들어 "누구에게 보내는 문자인가요?" 같은 질문에는 "받는 사람에 따라 존댓말 수위나 표현이 달라지기 때문이에요" 같은 이유를 달아주는 식이다.
원격 D1을 마이그레이션한 뒤 로컬에서 검증하려고 보니, 로컬 D1에는 애초에 "일반사용자용" 카테고리 자체가 없었다. 로컬 시드가 예전 버전에 머물러 있어서 카테고리가 6개뿐이었고, 심지어 id=7 자리는 이미 "인사(HR)"가 차지하고 있는 상태였다.
임시로 카테고리를 id=9로 새로 넣고, 원격에 있는 프롬프트 10개 + 폼 17개를 그대로 복제해서 로컬에 심었다. 이건 검증용 임시 데이터라 테스트 후 삭제했고 저장소에는 커밋하지 않았다.
backend-hono/src/routes/prompts.ts의 GET /prompts/:id 핸들러가 반환하는 forms 배열에 point_reason이 포함되도록 컬럼 목록과 타입을 수정했다.
frontend/src/components/SimpleWizard.jsx를 신규로 만들었다. 동작 방식은 다음과 같다.
/generate를 호출해 서버에서 실제 치환된 문장을 받아옴톤은 기존에 만들어둔 Senior.jsx 스타일(큰 폰트 20~28px, 버튼 최소 56px, 진한 파스텔 대비)을 그대로 따랐다.
PromptDetail.jsx에는 카테고리 이름이 '일반사용자용'인 경우에만 기존 폼 UI 대신 <SimpleWizard>를 렌더링하도록 분기를 추가했다. 사무용 분기는 이제 항상 isSenior=false로 고정되므로, 글씨 크기 등을 결정하던 불필요한 삼항연산자들을 정리했다(렌더링 결과 자체는 기존과 동일하게 유지).
이 환경(WSL)에는 Playwright가 필요로 하는 libnspr4, libnss3 같은 시스템 라이브러리가 없었고, sudo 권한도 없어서 기본 설치 방법이 막혔다. 다행히 예전에 /home/sbs/.local/browser-libs/extracted에 미리 추출해둔 라이브러리 세트가 있어서, LD_LIBRARY_PATH로 그 경로를 지정해 headless Chromium을 띄우는 데 성공했다.
이후 wrangler dev(백엔드, :8787)와 vite(프론트, :5173)를 동시에 띄우고, .env.development.local로 API base만 잠깐 로컬로 오버라이드한 상태에서 Playwright 스크립트로 실제 흐름을 확인했다.
/prompts/65(일반사용자용)에서 위저드가 2단계까지 정상 진행/prompts/3(사무용) 페이지는 기존 폼 UI 그대로 렌더링되는 것도 재확인 — 회귀 없음테스트 후 임시 오버라이드 파일은 삭제했고, 사용자도 별도로 직접 동작을 확인했다.
백엔드(f92e634)와 프론트엔드(a0d0513) 각각 커밋 후 푸시까지 완료했다.
오늘 작업의 핵심은 "같은 데이터라도 대상 사용자에 따라 노출 방식은 완전히 달라야 한다"는 점이었다. 사무직에게는 여러 입력 필드를 한 화면에서 빠르게 채우는 게 효율적이지만, 어르신에게는 한 번에 하나씩, 그리고 "왜 이걸 물어보는지"를 설명해주는 대화형 흐름이 훨씬 덜 부담스럽다. 같은 백엔드 API(/generate)를 재사용하면서도 프론트 레이어만 완전히 다르게 가져간 것이 이번 작업의 포인트였다.