본문으로 건너뛰기

Mobile 도메인 모델

데이터 저장 규칙

  • mobile 스키마: 모바일 앱 초기화 및 시스템 설정 정보와 관련된 데이터를 저장합니다. 모바일 앱에서 조회하는 통합 정보, 버전 정보 등이 포함됩니다.

1. 엔티티 관계도 (ERD)

2. 엔티티

2.1 AppSettings

/**
* 모바일 앱 초기화 시 필요한 통합 시스템 설정 정보 엔티티.
* 서버에서 관리하는 통합 설정 엔티티입니다.
*/
interface AppSettings {
id: string; // 설정 ID (UUID)
version: number; // 버전 번호 (1부터 시작, 새 버전 생성 시 증가)
systemSettings: SystemSettings; // 시스템 설정 정보
agreementVersions: AgreementVersion[]; // 약관 버전 정보
questionnaireVersion: QuestionnaireVersion; // 설문지 번들 버전 정보
announcementSummaries: AnnouncementSummary[]; // 공지사항 요약 정보
featureFlags: FeatureFlag[]; // 기능 플래그 목록
mobile: MobileVersionInfo; // 모바일 앱 버전 정보 (Android/iOS latest/min 버전)
authenticationMethods: AuthenticationMethod[]; // 지원 인증 방식
createdAt: Date; // 생성 시간
updatedAt: Date; // 업데이트 시간
lastUsedAt: Date; // 마지막 사용 시간
}

2.2 AppSettingsHistory

/**
* AppSettings 변경 이력을 추적하는 엔티티.
* 모든 AppSettings 변경 사항을 버전별로 기록하여 감사 추적 및 롤백을 지원합니다.
*/
interface AppSettingsHistory {
id: string; // 이력 ID (UUID)
appSettingsId: string; // 원본 AppSettings ID
version: number; // 변경 버전 번호
operationType: AppSettingsOperationType; // 변경 유형 (INSERT, UPDATE, DELETE)
systemSettings: SystemSettings; // 변경 시점의 시스템 설정 정보
agreementVersions: AgreementVersion[]; // 변경 시점의 약관 버전 정보
announcementSummaries: AnnouncementSummary[]; // 변경 시점의 공지사항 요약 정보
featureFlags: FeatureFlag[]; // 변경 시점의 기능 플래그 목록
mobile: MobileVersionInfo; // 변경 시점의 모바일 앱 버전 정보
authenticationMethods: AuthenticationMethod[]; // 변경 시점의 지원 인증 방식
changedAt: Date; // 변경 시간
changedBy: string; // 변경자 (사용자 ID 또는 시스템)
changeReason: string; // 변경 사유
originalCreatedAt: Date; // 원본 생성 시간
originalUpdatedAt: Date; // 원본 업데이트 시간
originalLastUsedAt: Date; // 원본 마지막 사용 시간
}

/**
* AppSettings 변경 유형 열거형
*/
enum AppSettingsOperationType {
INSERT = 'INSERT', // 새로 생성
UPDATE = 'UPDATE', // 업데이트
DELETE = 'DELETE' // 삭제
}

2.3 UserMobileSettings

/**
* 사용자별 Mobile App 설정 정보 엔티티.
* 치료주기 시작 시 자동으로 초기화되는 사용자 맞춤 설정을 관리합니다.
*/
interface UserMobileSettings {
userId: string; // 사용자 ID (User 도메인과 연결)
screenshotAllowed: boolean; // 스크린샷 허용 여부
appNotificationEnabled: boolean; // 앱 알림 허용 여부
systemNotificationEnabled: boolean; // 시스템 알림 허용 여부
analyticsConfiguration: AnalyticsConfiguration; // Analytics 설정
healthKitPermissionGranted: boolean; // iOS HealthKit 권한 허용 여부 (iOS에서만 사용)
healthConnectPermissionGranted: boolean; // Android Health Connect 권한 허용 여부 (Android에서만 사용)
locationPermissionGranted: boolean; // 날씨정보를 위한 위치 접근 권한 허용 여부
videoRecordingAllowed: boolean; // 동영상 녹화 허용 여부
cameraPermissionGranted: boolean; // 카메라 접근 권한
photoLibraryPermissionGranted: boolean; // 앨범 접근 권한
fcmToken: string; // Firebase Cloud Messaging 토큰 (푸시 알림용)
// AppSettings 사용 추적 (문제 발생 시 디버깅용)
currentAppSettingsId?: string; // 현재 사용 중인 AppSettings ID
currentAppSettingsVersion?: number; // 현재 사용 중인 AppSettings 버전
appSettingsLastCheckedAt?: Date; // 마지막 AppSettings 확인 시간
createdAt: Date; // 생성 시간
updatedAt: Date; // 업데이트 시간
lastResetAt: Date; // 마지막 초기화 시간
}

3. 값 객체

3.1 SystemSettings

/**
* 시스템 설정 값 객체.
*/
interface SystemSettings {
globalConfig: Record<string, any>; // 글로벌 설정
}

3.2 FeatureFlag

/**
* 기능 플래그 값 객체.
*/
interface FeatureFlag {
name: string; // 플래그 이름
isEnabled: boolean; // 활성화 여부
description?: string; // 설명
targetGroups?: string[]; // 대상 그룹 (선택적)
}

3.3 AgreementVersion

/**
* 약관 버전 값 객체.
*/
interface AgreementVersion {
id: string; // 약관 ID
type: string; // 약관 유형 (e.g., 'terms', 'privacy')
version: string; // 버전 번호
validFrom: Date; // 유효 시작일
validTo?: Date; // 유효 종료일 (선택적)
isRequired: boolean; // 필수 동의 여부
}

3.4 QuestionnaireVersion

/**
* 설문지 번들 버전 값 객체.
* Questionnaire 도메인에서 관리하는 설문지 번들의 최신 활성화 버전 정보를 포함합니다.
* 이 정보는 모바일 앱에서 캐싱 및 버전 비교에 사용됩니다.
*/
interface QuestionnaireVersion {
id: string; // 설문지 번들 ID (UUID)
validFrom: Date; // 유효 시작일
validTo?: Date; // 유효 종료일 (선택적)
includedQuestionnaires: Array<{
type: string; // 설문지 유형 (ISI, DBAS16, PHQ9 등)
version: string; // 설문지 버전
}>; // 번들에 포함된 설문지 목록
}

3.5 AnnouncementSummary

/**
* 공지사항 요약 값 객체.
*/
interface AnnouncementSummary {
id: string; // 공지사항 ID
title: string; // 제목
createdAt: Date; // 생성 시간
isNew: boolean; // 신규 여부
importance: 'high' | 'medium' | 'low'; // 중요도
}

3.6 AuthenticationMethod

/**
* 인증 방식 값 객체.
*/
interface AuthenticationMethod {
type: string; // 인증 유형 (e.g., 'email', 'google', 'apple')
isEnabled: boolean; // 활성화 여부
displayName: string; // 표시 이름
}

3.7 AnalyticsConfiguration

/**
* Analytics 설정 값 객체.
* 치료주기 시작 시 기본값으로 초기화됩니다.
*/
interface AnalyticsConfiguration {
isEnabled: boolean; // Analytics 추적 활성화 여부
viewStateTypes?: string[]; // 추적할 뷰 상태 유형
componentCategories?: string[]; // 추적할 컴포넌트 카테고리
componentTypes?: string[]; // 추적할 컴포넌트 유형
}

3.8 HealthPermissionConfiguration

/**
* Health 데이터 접근 권한 설정 값 객체.
* 플랫폼별로 치료주기 시작 시 기본값으로 초기화됩니다.
*/
interface HealthPermissionConfiguration {
healthKitPermissionGranted: boolean; // iOS HealthKit 권한 허용 여부
healthConnectPermissionGranted: boolean; // Android Health Connect 권한 허용 여부
}

3.9 LocationPermissionConfiguration

/**
* 위치 접근 권한 설정 값 객체.
* 치료주기 시작 시 기본값으로 초기화됩니다.
*/
interface LocationPermissionConfiguration {
locationPermissionGranted: boolean; // 날씨정보를 위한 위치 접근 권한 허용 여부
}

3.10 MobileVersionInfo

/**
* 모바일 앱 버전 정보 값 객체.
* Android와 iOS 플랫폼별 최신 버전 및 최소 지원 버전 정보를 포함합니다.
*/
interface MobileVersionInfo {
android: {
latest: {
code: string; // Android 최신 버전 코드
name: string; // Android 최신 버전 이름
};
min: {
code: string; // Android 최소 버전 코드
name: string; // Android 최소 버전 이름
};
};
iOS: {
latest: {
build: number; // iOS 최신 빌드 번호
name: string; // iOS 최신 버전 이름
};
min: {
build: number; // iOS 최소 빌드 번호
name: string; // iOS 최소 버전 이름
};
};
}

4. 집계 (Aggregates)

AppSettings 집계

  • 루트: AppSettings
  • 연관 엔티티: AppSettingsHistory
  • 값 객체: SystemSettings, FeatureFlag, AgreementVersion, QuestionnaireVersion, AnnouncementSummary, AuthenticationMethod, MobileVersionInfo
  • 불변식:
    • 버전 정보는 의미있는 비교가 가능해야 함 (예: 1.0.0 < 1.0.1)
    • mobile 필드의 android/iOS 버전 정보는 항상 유효한 형식의 버전 문자열이어야 함
    • questionnaireVersion은 Questionnaire 도메인의 활성화된 최신 번들을 참조함
    • 모바일 앱은 번들 ID를 사용하여 캐싱된 설문지 정보가 최신인지 판단하고 필요한 경우에만 갱신해야 함
    • AppSettings 변경 시 반드시 AppSettingsHistory에 변경 이력이 기록되어야 함
    • AppSettingsHistory의 version은 동일한 appSettingsId 내에서 순차적으로 증가해야 함
    • 삭제된 AppSettings도 이력에서 조회 가능해야 함 (감사 목적)

UserMobileSettings 집계

  • 루트: UserMobileSettings
  • 값 객체: AnalyticsConfiguration, HealthPermissionConfiguration, LocationPermissionConfiguration
  • 불변식:
    • 새로운 치료주기 시작 시 모든 설정이 기본값으로 초기화되어야 함
    • 스크린샷 허용 설정은 환경(개발/프로덕션)에 따른 기본값을 가져야 함
    • Analytics 설정은 AnalyticsConfigurationDto 구조를 따라야 함
    • Health 권한 설정은 플랫폼별로 관리되며, 치료주기 시작 시 비허용 상태로 초기화되어야 함
    • 위치 권한 설정은 치료주기 시작 시 비허용 상태로 초기화되어야 함
    • 사용자는 하나의 활성 설정만 가져야 함

5. 도메인 서비스

5.1 AppInitializationService

interface AppInitializationService {
/**
* 앱 초기화 시 필요한 통합 정보를 제공합니다.
*/
getIntegratedInfo(deviceId: string, appVersion: string, platform: 'android' | 'ios'): Promise<AppSettings>;
}

5.2 AppVersionService

interface AppVersionService {
/**
* 앱 버전 호환성을 확인합니다.
*/
checkAppVersionCompatibility(appVersion: string, platform: 'android' | 'ios'): Promise<{
isCompatible: boolean;
isForceUpdateRequired: boolean;
minimumRequiredVersion: string;
}>;
}

5.3 ContentAccessService

interface ContentAccessService {
/**
* 약관의 상세 내용을 제공합니다.
*/
getAgreementDetails(agreementId: string, version: string): Promise<any>;

/**
* 설문지 구조를 제공합니다.
*/
getQuestionnaireStructure(questionnaireId: string, version: string): Promise<any>;

/**
* 공지사항 상세 내용을 제공합니다.
*/
getAnnouncementDetails(announcementId: string): Promise<any>;
}

5.4 UserMobileSettingsService

interface UserMobileSettingsService {
/**
* 사용자 Mobile App 설정을 기본값으로 초기화합니다.
*/
resetUserMobileSettings(userId: string, environment: 'development' | 'production'): Promise<UserMobileSettings>;

/**
* 사용자의 현재 Mobile App 설정을 조회합니다.
*/
getUserMobileSettings(userId: string): Promise<UserMobileSettings>;

/**
* 치료주기 시작 이벤트를 처리하여 설정을 초기화합니다.
*/
handleTreatmentCycleStart(userId: string): Promise<void>;
}

5.5 AppSettingsService

interface AppSettingsService {
/**
* 새 버전의 AppSettings를 생성합니다. 기존 버전이 있다면 AppSettingsHistory로 이관합니다.
*/
createNewVersionAppSettings(
dto: CreateAppSettingsDto,
changedBy: string,
changeReason?: string
): Promise<AppSettings>;

/**
* 현재 활성 AppSettings를 조회합니다.
*/
getCurrentAppSettings(): Promise<AppSettings>;

/**
* AppSettings를 완전히 삭제합니다.
*/
deleteAppSettings(settingsId: string, changedBy: string): Promise<void>;

/**
* AppSettings를 특정 버전으로 롤백합니다.
*/
rollbackToVersion(
settingsId: string,
targetVersion: number,
changedBy: string,
reason?: string
): Promise<AppSettings>;
}

5.6 AppSettingsHistoryService

interface AppSettingsHistoryService {
/**
* AppSettings 변경 이력을 기록합니다.
*/
recordHistory(
appSettingsId: string,
operationType: AppSettingsOperationType,
currentData: AppSettings,
changedBy: string,
changeReason?: string
): Promise<AppSettingsHistory>;

/**
* 특정 AppSettings의 변경 이력을 조회합니다.
*/
getHistory(appSettingsId: string, limit?: number): Promise<AppSettingsHistory[]>;

/**
* 특정 버전의 AppSettings 이력을 조회합니다.
*/
getHistoryByVersion(appSettingsId: string, version: number): Promise<AppSettingsHistory>;

/**
* 변경 이력을 기반으로 감사 리포트를 생성합니다.
*/
generateAuditReport(startDate: Date, endDate: Date): Promise<AppSettingsAuditReport>;
}

6. 도메인 이벤트

6.1 앱 초기화 및 시스템 설정 이벤트

interface IntegratedInfoRequestedEvent { deviceId: string; appVersion: string; platform: 'android' | 'ios'; timestamp: Date; }
interface IntegratedInfoProvidedEvent { deviceId: string; timestamp: Date; }
interface SystemSettingsUpdatedEvent { settingsId: string; updatedFields: string[]; timestamp: Date; }
interface AgreementVersionsUpdatedEvent { settingsId: string; timestamp: Date; }
interface QuestionnaireVersionUpdatedEvent {
settingsId: string;
oldBundleVersion?: number;
newBundleVersion: number;
timestamp: Date;
}
interface AnnouncementUpdatedEvent { settingsId: string; timestamp: Date; }
interface AppSettingsHistoryRecordedEvent { appSettingsId: string; version: number; operationType: AppSettingsOperationType; changedBy: string; timestamp: Date; }
interface AppSettingsRolledBackEvent { appSettingsId: string; fromVersion: number; toVersion: number; changedBy: string; timestamp: Date; }

6.2 앱 버전 관련 이벤트

interface AppVersionCompatibilityCheckedEvent { deviceId: string; appVersion: string; platform: 'android' | 'ios'; isCompatible: boolean; timestamp: Date; }
interface ForceUpdateRequiredEvent { deviceId: string; appVersion: string; minRequiredVersion: string; timestamp: Date; }

6.3 사용자 설정 관리 이벤트

interface UserTreatmentCycleStartedEvent { userId: string; cycleId: string; timestamp: Date; }
interface UserMobileSettingsResetEvent { userId: string; settingsId: string; timestamp: Date; }
interface ScreenshotSettingResetEvent { userId: string; newValue: boolean; timestamp: Date; }
interface AppNotificationSettingResetEvent { userId: string; newValue: boolean; timestamp: Date; }
interface SystemNotificationSettingResetEvent { userId: string; newValue: boolean; timestamp: Date; }
interface AnalyticsSettingResetEvent { userId: string; newConfiguration: AnalyticsConfiguration; timestamp: Date; }
interface HealthKitPermissionResetEvent { userId: string; newValue: boolean; timestamp: Date; }
interface HealthConnectPermissionResetEvent { userId: string; newValue: boolean; timestamp: Date; }
interface LocationPermissionResetEvent { userId: string; newValue: boolean; timestamp: Date; }

7. 도메인 규칙

본 문서에서는 모델 구조에 대한 설명에 중점을 두고 있으며, 상세한 비즈니스 규칙은 Mobile 도메인 비즈니스 규칙 문서를 참조하세요.

주요 규칙 카테고리는 다음과 같습니다:

  1. 시스템 초기화 규칙: 앱 초기화 통합 정보 제공, 시스템 설정 정보, 약관 버전 정보, 설문지 버전 정보, 공지사항 정보 규칙
  2. 성능 규칙: 초기화 성능, 데이터 최적화 규칙
  3. 보안 규칙: 통신 보안, 데이터 보안 규칙
  4. 가용성 규칙: 에러 처리 규칙
  5. 비즈니스 운영 규칙: 버전 관리, 알림 관리 규칙
  6. 의존성 규칙: 내부 도메인 의존성, 외부 의존성

8. 데이터베이스 스키마 (Prisma)

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["mobile"]
}

model AppSettings {
id String @id @default(uuid())
systemSettings Json @map("system_settings")
agreementVersions Json @map("agreement_versions")
announcementSummaries Json @map("announcement_summaries")
featureFlags Json @map("feature_flags")
mobile Json @map("mobile")
authenticationMethods Json @map("authentication_methods")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
lastUsedAt DateTime @default(now()) @map("last_used_at")

@@map("app_settings")
@@schema("mobile")
}

model AppSettingsHistory {
id String @id @default(uuid())
appSettingsId String @map("app_settings_id")
version Int @map("version")
operationType AppSettingsOperationType @map("operation_type")
systemSettings Json @map("system_settings")
agreementVersions Json @map("agreement_versions")
announcementSummaries Json @map("announcement_summaries")
featureFlags Json @map("feature_flags")
mobile Json @map("mobile")
authenticationMethods Json @map("authentication_methods")
changedAt DateTime @default(now()) @map("changed_at")
changedBy String? @map("changed_by")
changeReason String? @map("change_reason")
originalCreatedAt DateTime @map("original_created_at")
originalUpdatedAt DateTime @map("original_updated_at")
originalLastUsedAt DateTime @map("original_last_used_at")

@@map("app_settings_history")
@@schema("mobile")
}

enum AppSettingsOperationType {
INSERT
UPDATE
DELETE

@@schema("mobile")
}

model UserMobileSettings {
userId String @id @map("user_id")
questionnaireBundleId String @map("questionnaire_bundle_id")
screenshotAllowed Boolean @map("screenshot_allowed")
appNotificationEnabled Boolean @map("app_notification_enabled")
systemNotificationEnabled Boolean @map("system_notification_enabled")
analyticsConfiguration Json @map("analytics_configuration")
healthKitPermissionGranted Boolean @map("health_kit_permission_granted")
healthConnectPermissionGranted Boolean @map("health_connect_permission_granted")
locationPermissionGranted Boolean @map("location_permission_granted")
videoRecordingAllowed Boolean @default(false) @map("video_recording_allowed")
cameraPermissionGranted Boolean @default(false) @map("camera_permission_granted")
photoLibraryPermissionGranted Boolean @default(false) @map("photo_library_permission_granted")
fcmToken String? @map("fcm_token") // Firebase Cloud Messaging 토큰 (선택적)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
lastResetAt DateTime @default(now()) @map("last_reset_at")

@@map("user_mobile_settings")
@@schema("private")
}

9. 변경 이력

버전날짜작성자변경 내용
0.1.02025-05-15bok@weltcorp.com최초 작성
0.2.02025-06-04bok@weltcorp.com새로운 치료주기 시작 시 사용자 설정 초기화 관련 엔티티, 값 객체, 도메인 서비스, 이벤트, 스키마 추가
0.3.02025-07-11bok@weltcorp.com모바일 권한 설정 확장 (동영상 녹화, 카메라, 앨범 접근) 및 FCM 토큰 필드 추가
0.4.02025-07-12bok@weltcorp.comUserMobileSettings에서 id 필드 제거, userId를 Primary Key로 변경
0.5.02025-01-09bok@weltcorp.comAppSettings에 모바일 버전 정보 구조 개선, AppSettingsHistory 엔티티 추가, MobileVersionInfo 값 객체 추가, AppSettingsHistoryService 도메인 서비스 추가
0.5.12025-08-03bok@weltcorp.comAppSettings 구조 개선 - Immutable 버전 관리로 변경, AppSettingsService 인터페이스 수정
0.5.22025-08-03bok@weltcorp.comUserMobileSettings에 AppSettings 추적 필드 추가 - currentAppSettingsId, currentAppSettingsVersion, appSettingsLastCheckedAt
0.5.32025-08-03bok@weltcorp.comAppSettings에 version 필드 추가 - 클라이언트가 정확한 버전 정보를 받을 수 있도록 개선