User Management 도메인 모델
개요
User Management 도메인의 상세한 도메인 모델을 정의합니다. 도메인 이벤트, 엔티티, 열거형, 값 객체, Aggregate, 에러 코드를 포함합니다.
1. 도메인 이벤트
1.1 Internal Events
AppUsersQueryRequested
- Payload:
siteId,searchKey,status,operationUserId,limit,page,sortBy,sortOrder - 발행 시점: GetAppUsers 커맨드 실행 시
- 발행: AppUser Aggregate
- 구독: -
OperationUserRetrieved
- Payload:
operationUserId,siteId,roleIds - 발행 시점: 권한 검증을 위한 운영자 정보 조회 시
- 발행: AppUser Aggregate
- 구독: -
AccessVerified
- Payload:
operationUserId,siteId - 발행 시점: 운영자 사이트 권한 검증 성공 시
- 발행: AppUser Aggregate
- 구독: -
AccessDenied
- Payload:
operationUserId,requestedSiteId,actualSiteId - 발행 시점: 운영자 사이트 권한 검증 실패 시
- 발행: AppUser Aggregate
- 구독: -
AppUsersQueried
- Payload:
siteId,totalCount,count - 발행 시점: App-User 목록 DB 조회 완료 시
- 발행: AppUser Aggregate
- 구독: -
LastLoginTimeRetrieved
- Payload:
userId,lastLoginTime - 발행 시점: App-User별 마지막 로그인 시간 조회 시
- 발행: AppUser Aggregate
- 구독: -
AppUsersFiltered
- Payload:
filterCriteria,resultCount - 발행 시점: 필터 조건 적용 시
- 발행: AppUser Aggregate
- 구독: -
AppUsersSorted
- Payload:
sortBy,sortOrder - 발행 시점: 정렬 조건 적용 시
- 발행: AppUser Aggregate
- 구독: -
AppUsersRetrieved
- Payload:
appUsers,totalCount,showGroup - 발행 시점: App-User 목록 조회 완료 시
- 발행: AppUser Aggregate
- 구독: -
InvalidSiteIdProvided
- Payload:
siteId - 발행 시점: 유효하지 않은 사이트 ID 제공 시
- 발행: AppUser Aggregate
- 구독: -
AppUserReportRequested
- Payload:
userCycleId - 발행 시점: GetAppUserReport 커맨드 실행 시
- 발행: AppUserReport Aggregate
- 구독: -
UserCycleRetrieved
- Payload:
userCycleId,startAt,endAt - 발행 시점: 사용자 주기 정보 조회 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
CurrentDayCalculated
- Payload:
day,calculateFrom - 발행 시점: 치료 일차 계산 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
SleepDiariesRetrieved
- Payload:
userCycleId,count,startDate,endDate - 발행 시점: 수면 일기 목록 조회 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
RtibAlgorithmGoalRetrieved
- Payload:
userCycleId,goalId - 발행 시점: 첫 번째 rTIB 알고리즘 수면 목표 조회 시
- 발행: AppUserReport Aggregate
- 구독: -
SleepGoalsRetrieved
- Payload:
userCycleId,count,startDate,endDate - 발행 시점: 수면 목표 로그 목록 조회 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
QuestionnairesRetrieved
- Payload:
userCycleId,count - 발행 시점: 설문 응답 목록 조회 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
GoalSuccessRecordsRetrieved
- Payload:
userCycleId,lotSuccessCount,aetSuccessCount - 발행 시점: 목표 성공 기록 조회 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
SuccessCountCalculated
- Payload:
lotCount,aetCount - 발행 시점: 성공 횟수 계산 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
SleepDiaryCountCalculated
- Payload:
count - 발행 시점: 분모용 수면 일기 개수 계산 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
LotConsistencyCalculated
- Payload:
percentage - 발행 시점: LOT 일관성 퍼센티지 계산 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
AetConsistencyCalculated
- Payload:
percentage - 발행 시점: AET 일관성 퍼센티지 계산 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
ReportSummaryGenerated
- Payload:
userCycleId,treatmentProgress,sleepRecord,lotSuccess,aetSuccess - 발행 시점: 리포트 요약 정보 생성 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
AppUserReportGenerated
- Payload:
userCycleId,report - 발행 시점: App-User 리포트 생성 완료 시
- 발행: AppUserReport Aggregate
- 구독: -
1.2 External Events
Outbound: None
User Management는 외부로 이벤트를 발행하지 않습니다. 다른 도메인의 데이터를 조회만 합니다.
Inbound: None
User Management는 외부 이벤트를 구독하지 않습니다. 요청 기반으로만 동작합니다.
2. 엔티티 (Entities)
AppUser (Aggregate Root)
id: App-User 고유 식별자userId: 사용자 ID (Sleep 도메인 참조)userCycleId: 사용자 주기 IDstatus: App-User 상태 (Integer)siteId: 소속 사이트 IDoperationUserId: 담당 운영자 ID (선택적)lastLogin: 마지막 로그인 시간createdAt: 생성일시updatedAt: 수정일시
AppUserReport (Aggregate Root)
userCycleId: 사용자 주기 ID (식별자)userCycle: 사용자 주기 정보 (UserCycle)diaries: 수면 일기 목록 (Map<String, SleepDiary>)goals: 수면 목표 로그 목록 (Map<String, UserSleepGoalLog>)questionnaires: 설문 응답 목록 (Array)successCount: 성공 횟수 (WeeklyReportSuccessCount)summary: 리포트 요약 정보 (ReportSummary)
UserCycle
id: 사용자 주기 IDuserId: 사용자 IDstartAt: 시작일시endAt: 종료일시status: 상태
SleepDiary
id: 수면 일기 IDuserCycleId: 사용자 주기 IDdayIndex: 일차lotTime: 취침 시각aetTime: 기상 시각tst: 총 수면 시간 (분)se: 수면 효율 (%)
UserSleepGoalLog
id: 수면 목표 로그 IDuserCycleId: 사용자 주기 IDtypeId: 목표 타입 ID (1: 수동, 2: rTIB 알고리즘)targetDate: 목표 날짜lot: 목표 취침 시각aet: 목표 기상 시각rtib: 권장 침대 시간 (분)
WeeklyReportSuccessCount
lot: LOT 성공 횟수aet: AET 성공 횟수
ReportSummary
treatmentProgress: 치료 진행 상황 (TreatmentProgress)sleepRecord: 수면 기록 통계 (SleepRecord)lotSuccess: LOT 성공 통계 (LotSuccess)aetSuccess: AET 성공 통계 (AetSuccess)
TreatmentProgress
currentDay: 현재 일차totalUsageDays: 총 사용 일수 (app-user의 plan에 정의된 값으로 고정)
SleepRecord
count: 수면 기록 개수appUsageDays: 앱 사용 일수percentage: 수면 기록률 (%)
LotSuccess
count: LOT 성공 횟수appUsageDays: 앱 사용 일수sleepDiaryCountForDenominator: 분모용 수면 일기 개수percentage: 일관성 퍼센티지 (%)
AetSuccess
count: AET 성공 횟수appUsageDays: 앱 사용 일수sleepDiaryCountForDenominator: 분모용 수면 일기 개수percentage: 일관성 퍼센티지 (%)
3. Enums
AppUserStatus - App-User의 상태
ACTIVE(1): 활성INACTIVE(2): 비활성COMPLETED(3): 완료DROPPED_OUT(4): 중도 탈락
SortBy - 정렬 기준
CREATED_AT: 생성일 (기본값)LAST_LOGIN: 마지막 로그인 시간STATUS: 상태NAME: 이름
SortOrder - 정렬 순서
ASC: 오름차순DESC: 내림차순 (기본값)
4. 값 객체 (Value Objects)
SiteId
value: 사이트 ID (String)- 동등성: value가 동일하면 같은 객체
- 제약: 빈 문자열 불가
PaginationParams
limit: 페이지 크기 (기본값: 10)page: 페이지 번호 (기본값: 1)- 동등성: limit와 page가 모두 동일하면 같은 객체
- 제약: limit > 0, page > 0
SortParams
sortBy: 정렬 기준 (기본값: "createdAt")sortOrder: 정렬 순서 (기본값: "desc")- 동등성: sortBy와 sortOrder가 모두 동일하면 같은 객체
DateRange
startDate: 시작일endDate: 종료일- 동등성: startDate와 endDate가 모두 동일하면 같은 객체
- 제약: startDate ≤ endDate
ConsistencyPercentage
value: 퍼센티지 값 (Float32)- 동등성: value가 동일하면 같은 객체
- 제약: 0 ≤ value ≤ 100
5. Aggregates
AppUser
Methods:
getAppUsers(siteId, searchKey, status, operationUserId, limit, page, sortBy, sortOrder): App-User 목록 조회verifyOperationUserAccess(operationUserId, siteId): 운영자 접근 권한 검증applyFilters(searchKey, status, operationUserId): 필터 조건 적용applySorting(sortBy, sortOrder): 정렬 조건 적용getLastLoginTime(userId): 마지막 로그인 시간 조회isWeltSite(siteId): Welt 사이트 여부 확인
Repository:
findById(id): ID로 App-User 조회findBySiteId(siteId, limit, page): 사이트별 App-User 목록 조회searchAppUsers(query, searchKey, limit, page, sortBy, sortOrder): App-User 검색searchAppUsersByLastLogin(query, searchKey, limit, page, sortOrder): 마지막 로그인 기준 정렬 조회getLastLoginByUserId(userId): 사용자별 마지막 로그인 시간 조회countBySiteId(siteId): 사이트별 App-User 수 조회
Events Published:
AppUsersQueryRequestedOperationUserRetrievedAccessVerifiedAccessDeniedAppUsersQueriedLastLoginTimeRetrievedAppUsersFilteredAppUsersSortedAppUsersRetrievedInvalidSiteIdProvided
AppUserReport
Methods:
getAppUserReport(userCycleId): App-User 리포트 조회retrieveUserCycle(userCycleId): 사용자 주기 정보 조회calculateCurrentDay(userCycle): 현재 일차 계산retrieveSleepDiaries(userCycleId, startDate, endDate): 수면 일기 조회retrieveRtibAlgorithmGoal(userCycleId): 첫 번째 rTIB 알고리즘 목표 조회retrieveSleepGoals(userCycleId, startDate, endDate): 수면 목표 로그 조회retrieveQuestionnaires(userCycleId): 설문 응답 조회retrieveGoalSuccessRecords(userCycleId, startDate, endDate): 목표 성공 기록 조회calculateSuccessCount(goalSuccessRecords): 성공 횟수 계산calculateSleepDiaryCount(firstRtibGoal, goals, diaries): 분모용 수면 일기 개수 계산calculateLotConsistency(lotSuccessCount, denominator): LOT 일관성 계산calculateAetConsistency(aetSuccessCount, denominator): AET 일관성 계산generateReportSummary(day, totalCount, successCount, denominator, lotPercentage, aetPercentage): 리포트 요약 생성
Repository:
getUserCycleAndDates(userCycleId): 사용자 주기 및 날짜 범위 조회getUserSleepDiariesByUserCycleId(userCycleId, startDate, endDate): 수면 일기 목록 조회getFirstRtibAlgorithmUserSleepGoalLogByUserCycleId(userCycleId): 첫 번째 rTIB 목표 조회getUserSleepGoalLogsByUserCycleId(userCycleId, startDate, endDate): 수면 목표 로그 조회getUserQuestionnairesByUserCycleId(userCycleId): 설문 응답 조회getUserGoalSuccessByUserCycleId(userCycleId, startDate, endDate): 목표 성공 기록 조회
Events Published:
AppUserReportRequestedUserCycleRetrievedCurrentDayCalculatedSleepDiariesRetrievedRtibAlgorithmGoalRetrievedSleepGoalsRetrievedQuestionnairesRetrievedGoalSuccessRecordsRetrievedSuccessCountCalculatedSleepDiaryCountCalculatedLotConsistencyCalculatedAetConsistencyCalculatedReportSummaryGeneratedAppUserReportGenerated
6. Error Codes
4xx - Client Errors
4001INVALID_SITE_ID (400): 유효하지 않은 사이트 ID입니다4002SITE_ACCESS_DENIED (403): 사이트 접근 권한이 없습니다4003USER_CYCLE_NOT_FOUND (404): 사용자 주기를 찾을 수 없습니다4010OPERATION_USER_NOT_FOUND (404): 운영자를 찾을 수 없습니다4011INVALID_PAGINATION_PARAMS (400): 유효하지 않은 페이징 파라미터입니다4012INVALID_SORT_PARAMS (400): 유효하지 않은 정렬 파라미터입니다
5xx - Server Errors
5001INTERNAL_ERROR (500): 내부 서버 오류5002SLEEP_DATA_RETRIEVAL_FAILED (500): 수면 데이터 조회 실패5003QUESTIONNAIRE_DATA_RETRIEVAL_FAILED (500): 설문 데이터 조회 실패5004REPORT_GENERATION_FAILED (500): 리포트 생성 실패
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-12-31 | dalia@weltcorp.com | 문서 최초 작성 - GetAppUsers, GetAppUserReport 기반 |