> For the complete documentation index, see [llms.txt](https://wonjoon.gitbook.io/joons-til/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wonjoon.gitbook.io/joons-til/trustay/documentation/eliminating-domain-confusion-in-a-notification-system.md).

# Eliminating Domain Confusion in a Notification System

(사내 보안 규정에 따라 실제 서비스·테이블·코드 식별자는 모두 일반화되어 있습니다)

## 배경

알림 시스템은 "채널을 기준으로 알림을 생성하고, 푸시를 발송하는 구조"입니다.\
알림센터에 쌓이는 알림과 기기로 발송되는 푸시 모두, 개념적으로는 "채널에게 전달되는 이벤트"입니다.\
각 채널은 노크플 로그인 유저와, 노크타운 로그인 유저로 되어있었고, 구분하여 푸시를 발송해야했습니다.

그러나 알림 생성 과정에서 필요한 데이터들은 서로 다른 도메인에 분산되어 있었습니다.

* ㅇ플 채널 정보: Channel
* ㅇ플 유저 정보: PlaceUser
* ㅇ타 유저 정보: TownUser
* 차단/설정 정보: PlaceUser 기반
* ㅇ타 플랫폼 푸시: TownUser 기반
* ㅇ플 플랫폼 푸시: Channel 기반
* 위치 정보: Channel 기반
* 팔로우 정보: User 기반
* 알림 설정 정보:
  * ㅇ플 로그인: User 기반
  * ㅇ타 로그인: TownUser 기반

&#x20;등,

이로 인해 알림 대상 검증, 차단 여부 판단, 설정 조회, 위치 정보, 팔로우 정보 등 조회 과정에서\
**유저 정보를 경유해야하는 경우가 있는 구조**였습니다.

데이터를 조회할 때마다

"이 정보는 어느 도메인에 있지?"\
"이번 케이스는 ㅇ플 유저 기준인가, ㅇ타 유저 기준인가?"

를 매번 판단해야 했고, 이는 점점 개발 생산성과 안정성을 저하시켰습니다.

## 원인 파악

문제의 핵심은 기술적인 버그보다는, 도메인 기준의 불일치였습니다.

* 알림 실제 수신 주체는 채널
* 하지만 판단에 필요한 데이터는 유저 기준으로 흩어져 있음

그 결과,

* 푸시별 조회하는 데이터가 흩어져있었고
* 동일한 기능이지만, 구현 경로가 매번 달라지는 형태로,
* 관심사 분리가 어려운 상황

이었습니다.

즉, 알림 시스템은 ‘채널 기준으로 동작’하면서도,\
설계와 코드에서는 여전히 ‘유저 기준 사고’를 벗어나지 못한 상태였습니다.

이로 인해 동일한 목적의 로직임에도,\
매번 다른 도메인과 다른 조회 경로를 선택해야 하는 구조가 되었습니다.

## 해결 방법

### 1. 기존 구조 유지 + 매번 변환 처리(X)

#### 방식

알림 로직에서 필요할 때마다&#x20;

* Channel -> PlaceUser
* Channel -> TownUser

변환 수행. 각 서비스가 필요한 저장소를 직접 호출

#### 기술적 동작

알림 서비스, 푸시 서비스, 차단 서비스 등, 각각 유저 조회 로직을 보유

#### 문제점

* 동일한 변환 로직이 여러 곳에 중복
* 유저 구조 변경 시 유지보수 비용 상승
* 도메인 혼란 지속

### 2. ㅇ타유저/ㅇ플유저/채널 이중 기준 설계(X)

#### 방식

* 알림 테이블과 로직에서 유저Id, 채널Id를 모두 허용
* 상황에 따라 기준을 선택

#### 기술적 동작

* 알림 생성 시 분기 처리
* 조회/차단/설정 시 기준 판단 필요

#### 문제점

* 알림 주체에 대한 단일 규칙 부재
* 신규 개발 시 항상 기준 선택 필요
* 장기적으로 정합성X

### 3. 채널을 단일 진입점으로 통일(O)

#### 방식

* 알림 도메인에서는 채널ID만 사용
* ㅇ타/ㅇ플 유저 정보는 채널의 내부 구현 세부사항으로 격리

#### 기술적 동작

* 채널 서비스가
  * ChannelId -> PlaceUser
  * ChannelId -> TownUser 변환 책임을 담당

알림 로직은 채널 기준 메서드만 호출.

이 방식은 단순히 조회 경로를 정리한 것이 아니라,\
알림 도메인에서 ‘유저’라는 개념 자체를 제거함으로써\
도메인 언어와 실제 동작 기준을 일치시키는 선택이었습니다.

이 선택을 통해 알림 도메인은 더 이상\
유저 구조의 변화에 영향을 받지 않게 되었습니다.

## 핵심 설계

#### 단일 알림 수신 주체: 채널

* 알림 엔터티와 정책 판단 기준을 채널로 통일
* 유저는 알림 도메인 외부로 격리

#### 채널 서비스를 조회/변환 전용 퍼사드(Facade)로 정의

* 채널을 기준으로 필요한 모든 연관 데이터를 여기서 제공
* 채널 객체/ID로 ㅇ플유저 객체/ID 가져오기. 채널 객체/ID로 ㅇ타유저 객체/ID 가져오기 등,
* 유저 구조 변경 시 영향 범위를 채널 서비스로 한정

채널 서비스는 정책을 판단하지 않고,&#x20;\
채널을 기준으로 필요한 식별자와 연관 데이터만 제공하는&#x20;\
조회/변환 전용 계층으로 제한했습니다.

#### Adapter 패턴 적용

* (예시)차단 기능
  * isBlock(from채널A, to채널B)
  * 내부에서 채널 -> 유저 변환 후, 유저 차단 서비스에 판단 위임.

## 결과

* 알림 생성 로직 전반에서 기준 확립
* 동일한 기능은 동일한 경로로만 구현
* 신규 알림/푸시 기능 추가 시, "기준은 무엇인가"에 대한 고민 제거
* 도메인 언어와 코드 구조가 일치
