창작마당

그누보드7 알림 허브 모듈- Glitter Notification Hub

Glitter Gim 2026.08.02 07:17 조회수:435
#모듈

알림의 시작부터 전달, 재시도, 실패 관리까지 하나의 허브로 연결하는 그누보드7 통합 알림 오케스트레이션 모듈.

개요

알림 허브는 새로운 알림 시스템을 별도로 만드는 모듈이 아닙니다. 그누보드7 코어의 Notification Definition, Template,
GenericNotification, 사용자 알림 정책과 채널 처리 구조를 그대로 활용하면서, 그 위에 전달 계획·재시도·중복 방지·실패 추적을 담당하는 오케스트레이션 계층을 추가하는 모듈입니다.

이메일, 관리자 알림, 사이트 알림 등의 전달 요청을 일관된 방식으로 계획하고 추적하는 메시지 전달 계층입니다.


왜 만들었나

각 모듈이 이메일이나 사이트 알림을 직접 구현하기 시작하면 시간이 지날수록 다음 문제가 발생합니다.

  • 발송 기록 형식이 모듈마다 달라집니다.
  • 실패 시 재시도 기준과 간격이 달라집니다.
  • 동일 이벤트가 중복 발송되는 것을 막기 어렵습니다.
  • 수신자와 채널 정책을 각 모듈에서 다시 구현하게 됩니다.
  • 예약 발송과 실패 이력을 한곳에서 확인하기 어렵습니다.
  • 운영자가 전체 전달 상태를 파악하기 어렵습니다.
  • 코어 알림 시스템과 별도의 알림 구현이 중복될 수 있습니다.

알림 허브는 각 업무 모듈이 직접 메일이나 알림을 보내는 대신, “누구에게 어떤 알림을 어느 채널로 전달할 것인지”를 Plan으로 등록하도록 설계했습니다.

실제 알림 생성과 채널 전달은 코어의 기존 알림 시스템에 위임합니다.


핵심 설계 원칙

1. 코어 알림 시스템을 대체하지 않습니다

알림 허브는 다음 기능을 새로 복제하지 않습니다.

  • Notification Definition
  • Notification Template
  • GenericNotification
  • 코어 채널 처리
  • 사용자 알림 설정
  • 코어 Notification Hook
  • 알림 로그

코어가 메시지의 내용과 실제 채널 전달을 담당한다면, 알림 허브는 그 앞뒤에서 다음을 담당합니다.

업무 이벤트
  → 전달 계획 생성
  → 정책 및 수신자 확인
  → 전달 시도 기록
  → 코어 Notification 호출
  → 성공·실패 결과 반영
  → 필요 시 재시도 또는 실패 보관

즉, 코어는 알림 엔진이고 알림 허브는 전달 오케스트레이터입니다.

2. 업무 모듈과 전달 구현을 분리합니다

폼, 예약, CRM, 커뮤니티, 포인트 같은 업무 확장은 메일러나 Notification 객체를 직접 다루지 않아도 됩니다.

업무 모듈은 전달에 필요한 정보만 알림 허브에 전달합니다.

예를 들면 다음과 같습니다.

  • 폼 접수 완료 안내
  • 예약 확정·취소 알림
  • CRM 담당자 알림
  • 커뮤니티 장애 또는 신고 경보
  • 주문·결제 상태 알림
  • 거래 또는 정산 알림

이를 통해 업무 모듈은 자신의 도메인 로직에 집중하고,
전달 정책은 알림 허브에서 일관되게 관리할 수 있습니다.


주요 기능

전달 계획

모든 전달 요청은 Notification Plan으로 저장됩니다.

Plan에는 다음 정보가 포함됩니다.

  • 알림 Definition
  • 요청한 확장 모듈
  • 업무 원본 식별자
  • 수신자 유형
  • 전달 채널
  • 예약 시각
  • 재시도 정책
  • 멱등성 정보
  • correlation ID
  • 현재 상태
  • 오류 및 감사 정보

주요 상태 흐름은 다음과 같습니다.

pending / scheduled / retry_scheduled
  → claimed
  → processing
  → accepted / skipped / failed

취소되거나 만료된 Plan도 별도 상태로 보존합니다.

중복 발송 방지

동일한 업무 이벤트가 여러 번 처리되더라도 같은 알림이 중복 생성되지 않도록
DB Unique Constraint를 최종 경계로 사용합니다.

다음 항목을 조합해 멱등성을 판단합니다.

  • 확장 유형과 식별자
  • Notification Definition
  • 업무에서 제공한 idempotency key
  • 수신자
  • 채널

사전 조회 후 INSERT하는 방식이 아니라,
INSERT 우선 후 중복 키 충돌을 기존 Plan으로 수렴시키는 방식을 사용했습니다.

전달 시도 이력

각 Plan의 실제 실행은 Delivery Attempt로 별도 기록합니다.

기록 항목은 다음과 같습니다.

  • 시도 번호
  • 처리 상태
  • Provider
  • 시작·완료 시각
  • 처리 시간
  • 재시도 가능 여부
  • 다음 재시도 시각
  • 오류 유형과 코드
  • Provider message ID
  • 코어 알림 로그 연결 정보
  • 정제된 요청·응답 metadata

Plan과 Attempt를 분리하여 하나의 알림이 여러 차례 재시도된 과정도 확인할 수 있습니다.

재시도 정책

현재 다음 정책을 지원합니다.

none
standard
aggressive

재시도 간격은 고정 backoff 방식이며,
일시적인 연결 오류나 timeout, rate limit 등의 경우에만 보수적으로 재시도하도록 설계했습니다.

다음 경우에는 재시도하지 않습니다.

  • 재시도 기능이 비활성화된 경우
  • 재시도 정책이 none인 경우
  • 최대 시도 횟수에 도달한 경우
  • Plan이 만료된 경우
  • 정책 거부 또는 수신자 복원 실패
  • 성공하거나 건너뛴 전달
  • 영구 실패로 분류된 오류

Provider가 구조화된 오류 분류를 제공하지 않는 경우
문자열 판정에는 한계가 있으므로, 향후 Provider별 오류 분류 계약을 확장할 예정입니다.

Dead Letter

재시도가 종료된 실패 건은 Dead Letter로 관리할 수 있습니다.

Dead Letter에는 다음 정보가 기록됩니다.

  • 원본 Plan
  • 마지막 Attempt
  • 실패 사유
  • 재시도 소진 여부
  • 해결 상태
  • 해결 관리자
  • 해결 메모
  • 수동 재시도 연결 정보

Laravel의 failed_jobs가 Queue 인프라 실패를 기록한다면,
알림 허브의 Dead Letter는 업무 전달 실패를 감사하기 위한 기록입니다.
두 기록은 서로 대체하지 않습니다.

예약 발송과 Queue

예약 또는 재시도 대상 Plan은 DB Claim을 거쳐 Job으로 전달됩니다.

중복 실행 방지를 위해 다음 방식을 사용합니다.

SELECT ... FOR UPDATE SKIP LOCKED
→ claim token 발급
→ Job에는 Plan UUID와 token만 전달
→ token을 원자적으로 소비한 작업만 실행

Scheduler 중복 방지의 최종 경계는 캐시 Lock이 아니라 DB Claim입니다.

현재 등록되는 명령은 다음과 같습니다.

notification-hub:dispatch-due
notification-hub:prune

Scheduler 선언은 다음과 같습니다.

dispatch-due: 매분
prune: 매일

관리자 화면

관리자 메뉴는 다음과 같이 구성했습니다.

알림 허브
 ├─ 전달 계획
 ├─ 전달 시도
 └─ 실패 보관함

각 화면에서는 다음 내용을 확인할 수 있습니다.

전달 계획

  • 상태
  • 채널
  • Notification Definition
  • 요청 모듈
  • 예약 및 처리 시각
  • 최근 오류
  • Attempt 이력
  • 취소 및 수동 재시도

전달 시도

  • 시도 번호
  • 상태
  • 채널과 Provider
  • 처리 시간
  • 재시도 여부
  • Provider 응답
  • 코어 Notification Log 연결

실패 보관함

  • 실패 사유
  • 재시도 소진 여부
  • 해결 상태
  • 원본 Plan
  • 수동 재시도
  • 운영자 해결 처리

민감정보 보호를 위해 관리자 API와 Resource에서는 다음 정보를 직접 노출하지 않습니다.

  • 수신자 해시
  • 수신자 Snapshot
  • claim token
  • idempotency hash
  • 원본 payload
  • 정책 Snapshot
  • Provider 요청·응답 전문

대신 payload key 목록과 상태 요약만 제공합니다.


관리자 권한

읽기와 쓰기 권한을 분리했습니다.

조회 권한

glitter-notification_hub.plans.read
glitter-notification_hub.attempts.read
glitter-notification_hub.dead-letters.read

쓰기 권한

glitter-notification_hub.plans.cancel
glitter-notification_hub.plans.retry
glitter-notification_hub.dead-letters.resolve
glitter-notification_hub.dead-letters.retry

조회 권한만 가진 관리자에게는 취소·재시도·해결 버튼과 모달이 렌더링되지 않습니다.
API Route도 각각의 쓰기 권한 Middleware로 다시 보호합니다.

별도의 조회 전용 역할 예시는 다음과 같습니다.

notification_hub_viewer

이 역할에는 조회 권한 3개와 알림 허브 메뉴만 연결하고,
쓰기 권한은 부여하지 않는 방식입니다.


기본값은 모두 차단

운영 설치만으로 알림이 발송되지 않도록 기본 설정을 보수적으로 구성했습니다.

enabled=false
allow_external_delivery=false
allowed_channels=[]

scheduler_enabled=false
queue_dispatch_enabled=false
retry_enabled=false
dead_letter_enabled=true

기본 DI도 실제 전달 구현이 아닌 다음 Null 구현을 사용합니다.

CoreNotificationAdapterInterface
  → NullCoreNotificationAdapter

PlanJobDispatcherInterface
  → NullPlanJobDispatcher

따라서 모듈을 설치하고 활성화해도 별도의 승인 없이 다음 동작이 발생하지 않습니다.

  • 이메일 발송
  • Database Notification 생성
  • Webhook 요청
  • Queue Job 등록
  • Scheduler 기반 전달
  • 기존 업무 Hook 자동 전달

채널 전달을 사용하려면 설정과 Adapter를 명시적으로 활성화해야 합니다.


현재 지원 범위

현재 코어 Adapter는 다음 채널을 대상으로 설계했습니다.

mail
database

Webhook은 코어 Notification 채널과 별개의 Provider 계층이 필요하므로
현재 실제 전달 범위에는 포함하지 않았습니다.

또한 회원 수신자는 코어 UserRepositoryInterface를 통해 복원하지만,
비회원 이메일은 암호화된 원문 보존 정책이 확정되지 않아 기본적으로 전달을 차단합니다.

다음 수신자 유형은 Plan 생성 전에 개별 수신자로 확장하도록 설계했습니다.

  • 역할
  • 그룹
  • Webhook endpoint

다국어와 보안

관리자 화면과 백엔드 메시지는 한국어·영어를 지원합니다.

Backend:
src/lang/ko
src/lang/en

Frontend:
resources/lang/ko.json
resources/lang/en.json

오류와 Provider metadata에는 재귀적인 민감정보 마스킹을 적용했습니다.

주요 마스킹 대상은 다음과 같습니다.

  • password
  • secret
  • token
  • API key
  • Authorization
  • Cookie
  • access token
  • refresh token
  • client secret
  • private key
  • Bearer·Basic 인증값
  • PEM Private Key

문자열 길이, 배열 크기, 재귀 깊이도 제한하며, 임의 객체를 자동 직렬화하지 않습니다.


설치 및 검증 상태

현재 개발 과정에서 다음 검증을 수행했습니다.

  • 전체 PHP 문법 검사
  • Pure/Mock Unit Test
  • Layout Vitest
  • JSON 및 번역 파일 검증
  • 한국어·영어 번역 Key parity
  • PSR-4 Namespace 검사
  • Interface와 구현체 Signature 검사
  • MariaDB DDL 정적 컴파일
  • 실제 Migration 적용
  • 실제 테이블·Index·FK Metadata 확인
  • 공식 모듈 설치·활성화·업데이트 Lifecycle 검증
  • 관리자 Route·Menu·Permission·Layout 등록 확인
  • 브라우저 목록 화면 확인
  • 외부 전달과 Job 발생 여부 확인

운영 정책에 따라 다음 파괴적 검증은 수행하지 않았습니다.

  • Duplicate Key 강제 충돌
  • FK 위반 INSERT
  • 사용자 삭제를 통한 SET NULL 실험
  • Migration Down·Rollback 반복
  • SKIP LOCKED 병렬 실행 실험
  • Attempt 번호 동시성 실험
  • 실제 이메일 및 Database Notification 발송
  • 관리자 쓰기 API 실행

이 부분은 실제 운영 사용 중 관측하거나 별도의 검증 환경에서 확인해야 합니다.


예상 연동 사례

알림 허브를 업무 모듈과 연결하면 다음과 같은 구성이 가능합니다.

Form

문의 접수
→ 접수자 완료 안내
→ 담당 관리자 알림
→ 전달 상태와 실패 이력 확인

예약

예약 생성
→ 고객 예약 확정 알림
→ 일정 전 예약 알림
→ 취소 시 예약 취소 안내

CRM

신규 Lead 생성
→ 담당자 지정
→ 담당자 사이트 알림
→ 장기 미처리 경보

Community

신고 또는 Incident 발생
→ 운영 담당자 알림
→ 반복 실패 시 Dead Letter 기록

Ecommerce

주문·결제 상태 변경
→ 회원 알림
→ 메일 전달
→ 중복 이벤트 방지

향후 계획

다음 작업을 순차적으로 검토하고 있습니다.

  • 업무 모듈용 연동 Contract 정리
  • Notification Definition별 Hub 사용 정책
  • 사용자 수신 동의 적용 경계 보완
  • Provider별 구조화된 오류 분류
  • Webhook Provider 계층
  • 운영 Metrics와 경보
  • Database 채널 제한적 활성화
  • 관리자 쓰기 권한의 단계적 승인
  • 실제 장기 실행 Worker 관측
  • 전달 성공률·재시도율·Dead Letter 통계

마무리

알림 허브는 기능마다 새로운 알림 구현을 추가하는 대신,
그누보드7 코어 알림 시스템을 중심으로 전달 흐름을 일관되게 관리하기 위해 만든 모듈입니다.

핵심 방향은 다음 한 문장으로 정리할 수 있습니다.

알림의 내용과 채널 처리는 코어에 맡기고,
알림 허브는 전달 계획·중복 방지·재시도·감사·운영 이력을 관리합니다.

아직 실제 채널 전달은 기본적으로 비활성화된 상태이며,
업무 모듈과의 연동 Contract부터 단계적으로 적용할 예정입니다.

그누보드7에서 여러 모듈이 공통으로 사용할 수 있는 알림 전달 구조를 고민하시는 분들께 설계 참고가 되었으면 합니다.


기술 스택

  • PHP 8.3+
  • Laravel 12.x
  • MySQL
  • Laravel Sanctum
  • TypeScript
  • Vite

관리자 페이지 설치

1. GitHub 저장소에서 설치 (권장)

관리자모듈 관리수동 설치GitHub

아래의 저장소 URL을 입력합니다.

https://github.com/glitter-node/glitter-notification_hub

설치 완료 후 모듈을 활성화하면 알림 허브 메뉴가 생성됩니다.

2. ZIP 패키지 설치

Release에서 ZIP 패키지를 다운로드한 후 관리자모듈 관리수동 설치파일 업로드를 통해 설치할 수도 있습니다.

다만 GitHub 저장소를 통한 설치 및 업데이트를 권장합니다.

3. 설치 후 생성된 페이지의 로드 에러 발생 시

관리자환경설정고급캐시 모두 삭제


저장소

GitHub

https://github.com/glitter-node/glitter-notification_hub

Release

https://github.com/glitter-node/glitter-notification_hub/releases/tag/v0.8.5


최적의 설치

파일 업로드 설치보다 GitHub 저장소 설치를 권합니다.
현재 GnuBoard7 관리자에서 GitHub 저장소 URL만으로 설치 및 업데이트가 가장 편리합니다.
이 방식이 가장 권장되는 설치 방법입니다.


라이선스

MIT License.

3개 댓글
0 / 2,000자
들레아빠
감사 합니다.
Glitter Gim
감사 합니다.

다른 창작물 살펴보기