본문으로 건너뛰기
버전: 0.68.0

모바일 설문 개발 가이드

이 문서는 설문 시스템에서 QuestionOption 모델의 metadata 필드를 사용하여 특정 선택지에 대해 조건부로 텍스트 입력을 받는 UI를 구현하는 방법에 대해 설명합니다.

목차

1. 개요

설문 문항 중 특정 선택지를 골랐을 때, 사용자로부터 추가적인 텍스트 정보를 입력받아야 하는 경우가 있습니다. 예를 들어, "기타" 선택지를 고른 경우 구체적인 내용을 입력받거나, "예"라고 답변한 경우 관련 약물 이름을 입력받는 상황입니다.

이러한 동적 UI 요구사항을 지원하기 위해 QuestionOption 모델에는 metadata라는 Json 타입 필드가 존재합니다. 이 필드를 활용하여 모바일 앱에서 조건부로 텍스트 입력 필드를 표시하고 사용자 입력을 받을 수 있습니다.

입력된 텍스트 값은 QuestionResponse 모델의 textValue 필드에 저장됩니다.

2. metadata 필드 구조

조건부 텍스트 입력을 위해 metadata 필드 내에 다음과 같은 JSON 구조를 사용합니다.

2.1. 필수 속성

  • requiresTextInput (Boolean):
    • 필수 항목입니다.
    • true로 설정되면, 해당 선택지를 선택했을 때 모바일 앱에서 텍스트 입력 UI를 표시해야 함을 의미합니다.
    • false이거나 이 속성이 없으면 텍스트 입력을 요구하지 않습니다.
  • textInputLabel (String):
    • requiresTextInputtrue일 때 필수 항목입니다.
    • 모바일 앱에서 텍스트 입력 필드 위에 표시될 레이블 또는 placeholder 텍스트입니다. 사용자에게 어떤 정보를 입력해야 하는지 안내하는 역할을 합니다.

2.2. JSON 예시

{
"requiresTextInput": true,
"textInputLabel": "Bitte gib den Namen des Medikaments an."
}

이 예시는 텍스트 입력을 요구하며, 입력 필드에 "Bitte gib den Namen des Medikaments an." (복용 중인 약물 이름을 입력해주세요.)라는 안내 문구를 표시하도록 지시합니다.

3. 사용 사례: WIS 설문 1번 문항

실제 사용 사례로 WIS (WELT Insomnia Scale) 설문의 1번 문항을 살펴보겠습니다.

3.1. 문항 및 선택지 구성

  • 문항: "Nimmst du derzeit Schlafmittel ein?" (현재 수면제를 복용하고 있습니까?)
  • 선택지 및 metadata 설정:
    1. "Nein" (아니오)
      • metadata: null (또는 설정 안 함)
    2. "Ja, täglich" (예, 매일)
      • metadata:
        {
        "requiresTextInput": true,
        "textInputLabel": "Bitte gib den Namen des Medikaments an."
        }
    3. "Ja, aber nur bei Bedarf" (예, 필요시에만)
      • metadata:
        {
        "requiresTextInput": true,
        "textInputLabel": "Bitte gib den Namen des Medikaments an."
        }

4. 모바일 앱 구현 가이드라인

모바일 앱에서는 설문 데이터를 파싱하여 각 QuestionOption 객체를 UI에 렌더링할 때 다음 로직을 따릅니다:

  1. 선택지의 metadata 필드를 확인합니다.
  2. metadata 필드가 존재하고, metadata.requiresTextInput === true인 경우: a. 해당 선택지 UI 요소와 함께 텍스트 입력 필드를 동적으로 생성합니다. b. 텍스트 입력 필드의 레이블(또는 placeholder)로 metadata.textInputLabel 값을 사용합니다.
  3. 사용자가 특정 선택지를 고르고 (QuestionOption.metadata.requiresTextInput === true인 경우) 추가 텍스트를 입력하면, 모바일 앱은 이 텍스트 값을 해당 답변에 대한 SubmittedAnswerDto 객체 내의 textValue 필드에 담아 서버로 전송해야 합니다. 예를 들어, SubmittedAnswerDto는 다음과 같은 구조를 가질 수 있습니다:
    // 기본 구조
    interface BaseSubmittedAnswerDto {
    questionId: string;
    metadata?: Record<string, any>;
    }

    // SINGLE_CHOICE 예시
    interface SubmittedSingleChoiceAnswerDto extends BaseSubmittedAnswerDto {
    questionType: 'SINGLE_CHOICE';
    answer: string; // 선택된 QuestionOption의 value (QuestionOption.value)
    textValue?: string; // 조건부 텍스트 입력 값 (예: "Aspirin")
    }

    // LINEAR_SCALE 예시
    interface SubmittedLinearScaleAnswerDto extends BaseSubmittedAnswerDto {
    questionType: 'LINEAR_SCALE';
    answer: number;
    }

    // SubmittedAnswerDto 유니온 타입 (다른 타입들도 포함될 수 있음)
    type SubmittedAnswerDto =
    | SubmittedSingleChoiceAnswerDto
    | SubmittedLinearScaleAnswerDto
    // ... | SubmittedTimeAnswerDto 등등
    ;
    이렇게 전송된 textValue (또는 다른 유형의 answer)는 서버에서 최종적으로 QuestionResponse 객체의 해당 필드에 저장됩니다.
  4. 만약 metadata가 없거나 requiresTextInputfalse이면, 추가적인 텍스트 입력 UI를 표시하지 않습니다.

5. 향후 확장성

현재 이 metadata 구조는 조건부 텍스트 입력에 대해서만 정의되어 있습니다. 향후 다른 유형의 조건부 UI 요소(예: 날짜 선택기, 숫자 입력 범위 제한, 추가적인 정보 팝업 등)가 필요하게 되면, 이 metadata 필드의 구조를 확장하여 새로운 속성을 정의하고 사용할 수 있습니다. 이 경우, 본 가이드라인도 함께 업데이트될 예정입니다.

부록: 주요 Enum 타입 가이드

모바일 애플리케이션 개발 시, 설문 시스템의 다양한 Enum 타입들은 설문의 종류를 식별하고, 각 문항 유형에 맞는 적절한 UI를 동적으로 구성하며, 특정 비즈니스 로직을 이해하는 데 중요한 역할을 합니다. 다음은 모바일 개발자가 숙지해야 할 주요 Enum 타입에 대한 설명입니다.

A.1 QuestionnaireType

QuestionnaireType은 여러 종류의 설문을 구분하는 식별자입니다. 모바일 앱은 이 타입을 사용하여 특정 설문지에 맞는 맞춤형 UI를 제공하거나, 설문 완료 후 결과 해석 또는 다음 단계 안내 로직을 분기할 수 있습니다.

  • 정의:
    enum QuestionnaireType {
    ISI = \'ISI\', // 불면증 심각도 지수
    DBAS16 = \'DBAS16\', // 수면에 대한 비합리적 신념
    PHQ9 = \'PHQ9\', // 우울 척도
    GAD7 = \'GAD7\', // 불안 척도
    PSS = \'PSS\', // 지각된 스트레스 척도
    WIS = \'WIS\' // WELT Insomnia Scale
    }
  • 모바일 활용 방안:
    • 각 설문 타입에 따라 다른 소개 화면, 진행 방식 안내, 또는 결과 화면을 표시할 수 있습니다.
    • 예를 들어, WIS 설문은 다른 설문과 달리 점수 계산이 없는 정보 수집형 설문일 수 있으므로, 결과 화면에서 점수 대신 요약 정보를 보여줄 수 있습니다.
    • 특정 QuestionnaireType에 대해서만 특별한 사용자 안내나 교육 콘텐츠를 제공할 수 있습니다.

A.2 ScoreCalculationType

ScoreCalculationType은 해당 설문의 점수가 어떻게 계산되는지를 나타냅니다. 모바일 앱에서 직접 점수를 계산할 필요는 없지만 (서버에서 처리), 이 정보를 통해 결과 화면의 특성을 이해하거나, 디버깅 시 참고할 수 있습니다.

  • 정의:
    enum ScoreCalculationType {
    SUM = \'SUM\', // 문항 점수 합계
    AVERAGE = \'AVERAGE\', // 문항 점수 평균
    CUSTOM = \'CUSTOM\' // 맞춤 계산 로직 (점수 없음 또는 복잡한 로직)
    }
  • 모바일 활용 방안:
    • 대부분의 경우 서버에서 계산된 점수를 받아 표시하므로 모바일에서 직접적인 활용도는 낮을 수 있습니다.
    • CUSTOM 타입의 경우, 일반적인 점수 표시 외에 다른 형태의 결과 요약(예: WIS 설문)이 제공될 수 있음을 예상할 수 있습니다.

A.3 QuestionType

QuestionType은 각 문항이 어떤 형식의 사용자 입력을 요구하는지를 명시하며, 모바일 앱에서 가장 직접적으로 UI 렌더링에 사용되는 중요한 Enum입니다. 이 타입에 따라 각기 다른 입력 UI 컴포넌트(예: 슬라이더, 라디오 버튼 그룹, 텍스트 필드, 시간 선택기 등)를 표시해야 합니다.

  • 정의:
    enum QuestionType {
    LINEAR_SCALE = \'LINEAR_SCALE\', // 선형 척도 (예: 0-10점 슬라이더)
    SINGLE_CHOICE = \'SINGLE_CHOICE\', // 범주형/객관식 (예: 라디오 버튼 또는 드롭다운)
    TIME = \'TIME\', // 시간 정보 (예: HH:MM 형식 입력)
    SINGLE_LINE_TEXT = \'SINGLE_LINE_TEXT\', // 단일 라인 텍스트 입력
    MULTI_LINE_TEXT = \'MULTI_LINE_TEXT\' // 다중 라인 텍스트 입력
    }
  • 모바일 활용 방안:
    • LINEAR_SCALE: 사용자가 특정 범위 내에서 값을 선택할 수 있는 슬라이더나 스텝퍼 UI를 구현합니다. (관련 QuestionMetadata: minValue, maxValue, step)
    • SINGLE_CHOICE: QuestionOption 목록을 기반으로 라디오 버튼, 체크박스 그룹(다중 선택이 가능한 경우), 또는 드롭다운 메뉴 형태의 UI를 구현합니다. 본 가이드에서 설명한 QuestionOption.metadatarequiresTextInput은 주로 이 타입의 선택지와 함께 사용됩니다.
    • TIME: 시간(예: 취침 시간, 기상 시간)을 입력받기 위한 UI(Time Picker)를 제공합니다. 입력 형식(예: HH:mm)은 사전에 정의된 표준을 따릅니다.
    • SINGLE_LINE_TEXT: 한 줄의 텍스트 입력을 위한 입력 필드를 제공합니다. (관련 QuestionMetadata: maxLength)
    • MULTI_LINE_TEXT: 여러 줄의 텍스트 입력을 위한 텍스트 영역(Text Area)을 제공합니다.

이러한 Enum 타입 정보를 활용하여 보다 유연하고 정확한 설문 UI/UX를 사용자에게 제공할 수 있습니다.

6. 변경 이력

버전날짜작성자변경 내용
0.1.02024-07-11Gemini (AI Assistant)최초 작성