2.7 KiB
2.7 KiB
MSN[맥락] 메신저 기능 개발
왜 하는가
벡스플로어 ERP 내에서 사용자 간 실시간 커뮤니케이션 수단이 없다. 업무 맥락을 ERP 밖(카카오톡, 슬랙 등)으로 내보내지 않고 시스템 안에서 처리할 수 있도록 내장 메신저를 도입한다.
핵심 결정 및 근거
| 결정 | 근거 |
|---|---|
| Socket.IO 신규 도입 | HTTP 폴링은 메신저에 부적합. 실시간 타이핑 표시, 온라인 상태, 즉각적인 메시지 수신이 필요 |
| Gmail 스타일 우측 하단 모달 | 업무 화면을 방해하지 않고 언제든 접근 가능. 별도 페이지 이동 없이 사용 |
| DM + 그룹 + 채널 1차 구현 | 채널은 room_type 값으로만 분리하여 나중에 제거 용이하게 설계 |
| company_code 격리 | 기존 멀티테넌시 패턴과 동일하게 적용. 회사 간 데이터 유출 방지 |
| 파일 업로드: multer 로컬 | 기존 메일 첨부파일과 동일한 방식. 인프라 추가 없이 일관성 유지 |
| 프로필: photo BLOB 활용 | user_info.photo 컬럼에 이미 이미지 저장됨. 없으면 이름 첫 글자 원형 아바타 |
| 토스트 알림 on/off | 집중 업무 시 알림 방해 방지. localStorage에 설정 저장 |
관련 파일
참고 패턴 (기존 코드)
| 파일 | 참고 목적 |
|---|---|
backend-node/src/config/multerConfig.ts |
파일 업로드 설정 패턴 |
backend-node/src/services/authService.ts |
user_info.photo BLOB → base64 변환 패턴 |
backend-node/src/middleware/authMiddleware.ts |
JWT 인증 미들웨어 (Socket.IO handshake에도 동일 로직 적용) |
frontend/components/mail/ |
UI 컴포넌트 구조 참고 |
frontend/hooks/use-toast.ts |
기존 토스트 훅 사용 |
backend-node/src/app.ts |
라우트 등록 및 미들웨어 설정 위치 |
기술 참고
Socket.IO JWT 인증
// 서버: handshake 시 토큰 검증
io.use((socket, next) => {
const token = socket.handshake.auth.token;
const user = verifyJWT(token);
socket.data.user = user;
next();
});
// 클라이언트: 연결 시 토큰 전달
const socket = io(BACKEND_URL, {
auth: { token: localStorage.getItem('token') }
});
채널 분리 설계
채널 기능은 room_type = 'channel' 조건으로만 분리되어 있음.
제거 시: RoomList의 채널 탭 UI 제거 + /api/messenger/rooms?type=channel 호출 제거만으로 완전 비활성화 가능. DB 스키마 변경 불필요.
멀티테넌시 적용
모든 쿼리에 WHERE company_code = $n 조건 필수 적용.
Socket.IO 룸 네이밍: {company_code}:{room_id} 형식으로 회사별 격리.