상담신청서(K-02) — feature/consult_intake/app

데스크 태블릿(834 세로) · QR 휴대폰(390)에서 산모가 직접 쓰는 상담신청서다. 패키지 이름은 consult_intake.

화면 주소 뷰 페이지
K-02 상담신청서 /consult_intake ConsultIntakeFormView(값 · 동작을 받는다) ConsultIntakeWizardPage(세계에 잇는다)

여섯 단계: 기본 정보 → 출산 정보 → 희망 조리 → 유입 경로 · 문의 → 보호자 → 확인 · 동의. 틀은 공용 KioskFrame(postpartum_ui — 머리 · 진행 · 바닥 단추)이고, 머리의 「앱 이름 · 지점 · 기기」는 셸의 KioskChromeScope 를 따른다. 셸이 아직 범위를 주지 않으면 페이지가 세계에서 읽어(지점 = DisplayProjector 의 branchName, 기기 = 코드의 deviceId 유무) 씌운다.

세계 계약(docs/demo-world.md §2)

  1. 세계 · 세션은 서비스 로케이터에서 받는다(PostpartumWorld · PostpartumSession — binding 의존 없음). 없으면 S-05.
  2. 세션의 코드(passId)가 없거나, 상담 코드가 아니거나, 제출됐거나, 만료(업무 시계 기준)면 /code(K-01)로 보낸다.
  3. 제출 = 한 트랜잭션(ConsultIntakeSubmission): intakes 행 intake_NNNN {passId, deviceId?, branchId, submittedAt, status: submitted, payload} + kioskPasses 의 status: submitted · submittedAt. 코드가 없으면 WorldRowMissing, 상담 코드가 아니거나 · 이미 제출됐거나 · 다른 기기가 작성 중이면 StateError — 아무것도 쓰지 않는다.
  4. 트랜잭션 뒤 session.endPass() → /done(K-05). 「처음으로」는 확인 뒤 입력을 지우고 endPass() → /code.
  5. 떠나는 동안(제출 · 처음으로)에는 코드가 놓여도 /code 로 되돌리지 않는다 — /done 이동과 겨루지 않게.

payload 키는 콘솔 접수함이 읽는 IntakeAnswers.keys 와 같은 19개다(ConsultIntakeForm.payloadKeys — 시험이 목록을 고정한다). 날짜는 YYYY-MM-DD, 코드 값은 세계 enum 이름(natural · nights13 · momCommunity · spouse …), 빈 칸은 넣지 않는다.

화면 · FR ↔ 구현 ↔ 시험

FR 내용 구현 시험
FR-121 자가 작성 단계를 오가도 입력 유지, 필수 검증 뒤 제출 ConsultIntakeForm(problemsAt · firstIncompleteStep) · 화면 맨 위 컨트롤러 묶음 consult_intake_form_test 11 · 뷰 「단계를 오가도 적은 값이 남고 …」 · 「필수 칸이 비면 넘어가지 않고 이유」 · 「제출을 누르면 막힌 첫 단계로」
FR-12(만드는 쪽) 제출이 접수함으로 ConsultIntakeSubmission consult_intake_submission_test 2 · 페이지 「제출 — intakes 행 · 코드 submitted … K-05」 · BDD 「여섯 단계를 적고 제출하면 상담실장 접수함으로」
FR-123 제출 뒤 정리 세션이 끝나고 뒤로 가도 입력이 다시 보이지 않음 endPass() + 쓸 수 없는 코드는 /code 로 페이지 「코드가 쓸 수 없으면 K-01 로」 4(없음 · 입실 코드 · 제출됨 · 만료) · 「처음으로는 코드를 놓고 K-01」 · BDD 「처음으로 …」
FR-120(쓰는 쪽) 10분 만료 PostpartumKioskPass.isExpiredAt(world.now) 페이지 「만료됐다 — 업무 시계가 만료 시각을 지났다」
DDR-06 동의 필수(개인정보)와 선택(알림톡 · 문자) 분리 확인 단계 _Consent 2줄 · 「자세히」 뷰 「필수 동의 없이는 제출하지 않는다 — 선택 동의는 없어도 된다」 · 「자세히」
NFR-08 최소 수집 연락처는 끝 4자리 숫자만 · 4자 제한 입력 뷰 「끝 4자리 칸은 숫자 네 개까지만」
FR-14 예정일 → 오늘 기준 임신 주수 GestationalAge(postpartum_rules) 뷰 「오늘 기준 임신 31주 1일」
S-05 세계가 없으면 서버 없음 화면 ServerMissingView 페이지 「S-05」
R-1 · R-2 · R-4 스케일 불변 · 가용 폭 · 터치 하한 _FieldGrid(640 이상 두 열) · KioskFrame testScaleInvariant — 6단계 × (390×844 · 834×1194) × 4조합(키오스크 테마) · 아랍어 RTL

골든: consult_intake_basic · consult_intake_birth · consult_intake_confirm(ko · en · ar pairwise — CI 러너가 만든다). BDD: test/src/bdd/consult_intake_wizard.feature 3 시나리오(공용 세계 · 메모리 저장소).

모의 경계

Figma 와 다르게 둔 점

Figma 구현 이유
「제출하기」 · 「제출 중…」 공용 틀의 「제출」(제출하는 동안 누를 수 없음) K-01 ~ K-05 가 같은 바닥 단추를 쓴다(공용 KioskFrame)
진행 줄 문구 공용 틀의 「n / 6 · 단계 · 다음 · 다음 단계」 같은 이유
QR 그림 없음(콘솔이 코드를 크게 보인다) 쓸 수 있는 QR 위젯이 없다
날짜 입력 coui DatePicker — 달력은 업무 시계의 달(2026-01)에서 연다 기기 시계(실제 오늘)로 열면 데모 세계와 달이 어긋난다
보호자 관계 「남편」 「배우자」 세계의 GuardianRelation.spouse 와 같게

번역