Research 도메인 이벤트 스토밍
본 문서는 Research 도메인 요구사항(requirements.md)을 기반으로 Event Storming 방식으로 분석한 결과입니다.
목적
Research 도메인은 Dashboard의 연구 기능(연구 시트 접근/스코프, 연구 참여자 관리, 카드 파생 지표, 불성실 판정)을 다룹니다. 본 문서는 해당 기능을 도메인 이벤트/명령/정책 관점으로 구조화합니다.
1. 도메인 이벤트
1.1 접근/스코프 관련 이벤트
| Event | Description |
|---|---|
| ResearchAccessEvaluated | 연구 기능 접근 가능 여부가 평가됨 (clinicalResearch + IAM 평가) |
| ResearchAccessDenied | 연구 기능 접근이 거부됨 |
| ResearchScopeResolved | 조회 스코프가 결정됨 (all-sites 또는 site-scoped) |
| ResearchSiteFilterSelected | 플랫폼 전체 조회 권한 보유자가 특정 Site로 필터를 선택함 |
1.2 연구 참여자(Research Participant) 생명주기 이벤트
| Event | Description |
|---|---|
| ResearchParticipantImported | 진료용 환자 목록에서 연구 참여자로 등록됨 |
| ResearchParticipantCreated | 임상 연구용 신규 등록으로 연구 참여자가 생성됨 |
| ResearchAccessCodeDeliveryRequested | 코드 발송(이메일/SMS/카카오톡)이 요청됨 |
| ResearchAccessCodeDelivered | 코드 발송이 성공함 |
| ResearchAccessCodeDeliveryFailed | 코드 발송이 실패함 |
| ResearchParticipantRemovedFromList | 연구 참여자가 연구 리스트에서 제외됨(진료용 데이터는 유지) |
1.3 연구 참여자 수정 이벤트
| Event | Description |
|---|---|
| RandomizationNumberUpdateRequested | 무작위번호 변경이 요청됨 |
| RandomizationNumberValidated | 무작위번호 형식/가용성 검증이 성공함 |
| RandomizationNumberValidationFailed | 무작위번호 검증이 실패함 |
| RandomizationNumberUniquenessChecked | 병원(Site) 단위 중복 검증이 수행됨 |
| RandomizationNumberUpdated | 무작위번호가 저장/수정됨 |
| ParticipantMemoUpdated | 메모가 저장/수정됨(단일 최신본) |
1.4 불성실(NonCompliant) 관련 이벤트
| Event | Description |
|---|---|
| NonComplianceEvaluated | 불성실 여부가 평가됨 |
| NonCompliantFlagged | 불성실 상태로 전환됨 |
| NonCompliantUnflagged | 불성실 상태가 해제됨 |
| NonComplianceReasonChanged | 불성실 사유(수면기록/설문)가 변경됨(표시/강조 텍스트에 영향) |
1.5 카드 파생 지표 이벤트(조회/재계산)
| Event | Description |
|---|---|
| ParticipantCardMetricsRead | 연구 참여자 카드 지표가 조회됨 |
| ParticipantCardMetricsDerived | 파생 지표가 계산/갱신됨 |
2. 액터와 명령
2.1 액터 정의
| Actor | Description |
|---|---|
| PlatformViewer | 플랫폼 전체 조회 권한 보유자(예: medi.platform-admin) |
| SiteScopedResearchUser | 사이트 스코프 연구 사용자(예: medi.site-admin/member) |
| System | 스케줄러/이벤트 처리 등 자동 평가를 수행하는 주체 |
2.2 명령-이벤트 매핑
| Command | Actor | Event(s) |
|---|---|---|
| EvaluateResearchAccess | System | ResearchAccessEvaluated / ResearchAccessDenied |
| ResolveResearchScope | System | ResearchScopeResolved |
| SelectResearchSiteFilter | PlatformViewer | ResearchSiteFilterSelected |
| ListResearchParticipants | PlatformViewer, SiteScopedResearchUser | ParticipantCardMetricsRead |
| ImportResearchParticipant | SiteScopedResearchUser | ResearchParticipantImported |
| CreateResearchParticipant | SiteScopedResearchUser | ResearchParticipantCreated, ResearchAccessCodeDeliveryRequested |
| UpdateRandomizationNumber | SiteScopedResearchUser | RandomizationNumberUpdateRequested, RandomizationNumberUniquenessChecked, RandomizationNumberUpdated |
| UpdateParticipantMemo | SiteScopedResearchUser | ParticipantMemoUpdated |
| RemoveResearchParticipantFromList | SiteScopedResearchUser | ResearchParticipantRemovedFromList |
| EvaluateNonCompliance | System | NonComplianceEvaluated, NonCompliantFlagged/Unflagged |
3. Aggregate 매핑
3.1 ResearchParticipant
트랜잭션 경계:
- 연구 참여자의 연구 리스트 포함 여부, 무작위번호, 메모(최신본), 불성실 상태를 일관되게 관리
담당 Command:
- ImportResearchParticipant
- CreateResearchParticipant
- UpdateRandomizationNumber
- UpdateParticipantMemo
- RemoveResearchParticipantFromList
발행 Event:
- ResearchParticipantImported
- ResearchParticipantCreated
- RandomizationNumberUpdated
- ParticipantMemoUpdated
- ResearchParticipantRemovedFromList
3.2 ResearchScope(정책/도메인 서비스 성격)
책임:
- IAM 권한 평가 결과 +
siteId컨텍스트로 조회 스코프(all-sites vs site-scoped)를 결정
3.3 NonComplianceEvaluation(정책/도메인 서비스 성격)
책임:
- 수면기록/설문 데이터 변화에 따라 불성실 여부를 판정하고 상태를 갱신
4. 정책(Policy) 요약
4.1 연구 시트 접근 정책
| When | Then |
|---|---|
| Site.clinicalResearch=false | ResearchAccessDenied |
| clinicalResearch=true + IAM 허용 | ResearchAccessEvaluated, ResearchScopeResolved |
4.2 무작위번호 저장/수정 정책
| When | Then |
|---|---|
| RandomizationNumberUpdateRequested | 병원(Site) 단위 중복 검증 후 유효하면 RandomizationNumberUpdated 발행 |
| 중복/유효성 위반 | RandomizationNumberValidationFailed 발행 |
4.3 불성실 판정 정책
| When | Then |
|---|---|
| 수면기록률 ≤ 50% (8일차부터) | NonCompliantFlagged (수면기록 불성실) |
| 43일차 도달 + 마지막 설문 미실시 | NonCompliantFlagged (설문 불성실) |
| 조건을 더 이상 만족하지 않음 | NonCompliantUnflagged |
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-12-29 | jeff@weltcorp.com | 최초 작성 |