Eliminating Domain Confusion in a Notification System

도메인 정합성 확보: 알림 수신 주체를 유저/채널 -> 채널 기준으로 통일하여 알림 주체 혼란 제거

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

배경

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

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

  • ㅇ플 채널 정보: Channel

  • ㅇ플 유저 정보: PlaceUser

  • ㅇ타 유저 정보: TownUser

  • 차단/설정 정보: PlaceUser 기반

  • ㅇ타 플랫폼 푸시: TownUser 기반

  • ㅇ플 플랫폼 푸시: Channel 기반

  • 위치 정보: Channel 기반

  • 팔로우 정보: User 기반

  • 알림 설정 정보:

    • ㅇ플 로그인: User 기반

    • ㅇ타 로그인: TownUser 기반

등,

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

데이터를 조회할 때마다

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

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

원인 파악

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

  • 알림 실제 수신 주체는 채널

  • 하지만 판단에 필요한 데이터는 유저 기준으로 흩어져 있음

그 결과,

  • 푸시별 조회하는 데이터가 흩어져있었고

  • 동일한 기능이지만, 구현 경로가 매번 달라지는 형태로,

  • 관심사 분리가 어려운 상황

이었습니다.

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

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

해결 방법

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

방식

알림 로직에서 필요할 때마다

  • Channel -> PlaceUser

  • Channel -> TownUser

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

기술적 동작

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

문제점

  • 동일한 변환 로직이 여러 곳에 중복

  • 유저 구조 변경 시 유지보수 비용 상승

  • 도메인 혼란 지속

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

방식

  • 알림 테이블과 로직에서 유저Id, 채널Id를 모두 허용

  • 상황에 따라 기준을 선택

기술적 동작

  • 알림 생성 시 분기 처리

  • 조회/차단/설정 시 기준 판단 필요

문제점

  • 알림 주체에 대한 단일 규칙 부재

  • 신규 개발 시 항상 기준 선택 필요

  • 장기적으로 정합성X

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

방식

  • 알림 도메인에서는 채널ID만 사용

  • ㅇ타/ㅇ플 유저 정보는 채널의 내부 구현 세부사항으로 격리

기술적 동작

  • 채널 서비스가

    • ChannelId -> PlaceUser

    • ChannelId -> TownUser 변환 책임을 담당

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

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

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

핵심 설계

단일 알림 수신 주체: 채널

  • 알림 엔터티와 정책 판단 기준을 채널로 통일

  • 유저는 알림 도메인 외부로 격리

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

  • 채널을 기준으로 필요한 모든 연관 데이터를 여기서 제공

  • 채널 객체/ID로 ㅇ플유저 객체/ID 가져오기. 채널 객체/ID로 ㅇ타유저 객체/ID 가져오기 등,

  • 유저 구조 변경 시 영향 범위를 채널 서비스로 한정

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

Adapter 패턴 적용

  • (예시)차단 기능

    • isBlock(from채널A, to채널B)

    • 내부에서 채널 -> 유저 변환 후, 유저 차단 서비스에 판단 위임.

결과

  • 알림 생성 로직 전반에서 기준 확립

  • 동일한 기능은 동일한 경로로만 구현

  • 신규 알림/푸시 기능 추가 시, "기준은 무엇인가"에 대한 고민 제거

  • 도메인 언어와 코드 구조가 일치

Last updated