사용자 계정·이메일·정지·구독 관리를 담당하는 독서 게이미피케이션 플랫폼 Frolog의 사용자 도메인 서비스입니다.
사용자 CRUD, 계정 정지, 이메일 발송 (단건/대량/전체), 메일링 구 독/해지, 사용자 데이터 CSV 내보내기를 처리합니다.
- 사용자 생성·조회·수정·삭제 (관리자)
- 사용자 검색 (정지 상태, 생성일 범위 필터, 페이지네이션)
- 계정 정지 (suspended_until 설정)
- 이메일 발송 (AWS SES 연동, 템플릿 지원)
- 단건 이메일 발송 (SendEmail)
- 대량 이메일 발송 (SendEmailBulk, 초당 5건 제한)
- 전체 사용자 이메일 발송 (SendEmailToAll, 데이터 집계)
- 메일링 구독/해지 (hash 기반 토큰)
- 사용자 데이터 CSV 내보내기 (리뷰/메모, 태그 한글 번역)
- 이메일 템플릿 변수 (username, unsubscribeLink)
- 이메일/비밀번호 암호화 (EMAIL_SECRET, bcrypt)
- Node.js (ESM), Express 기반
@frolog/express-api-server - ORM: Sequelize (
@frolog/models) - 공통 유틸:
@frolog/common-utils(로거, HashId, 암호화 등) - API 계약:
@frolog/frolog-api - Email: AWS SES (
aws-sdkv2.1692.0) - 비밀번호:
bcryptv5.1.1 - CSV:
csv-writerv1.6.0 - Lint/Format: ESLint, Prettier
npm install
npm run dev # 개발 (nodemon)
npm start # 프로덕션
npm run lint # 코드 규칙 검사
npm run doc # JSDoc 생성src/
index.js # API 서버 부트스트랩 및 라우팅
common/
constants.js # 환경변수 (JWT, 이메일, bcrypt 등)
utils.js # 유틸리티 (이메일 해싱, 코드 생성)
services/
postUser.js # 사용자 생성 (이메일 암호화, 비밀번호 해싱)
getUser.js # 사용자 조회 (관리자)
editUser.js # 사용자 수정 (비밀번호, 관리자 상태)
deleteUser.js # 사용자 삭제 (소프트 삭제)
suspendUser.js # 계정 정지 (suspended_until 설정)
searchUser.js # 사용자 검색 (정지 상태, 날짜 범위, 페이지네이션)
sendEmail.js # 단건 이메일 발송 (템플릿 지원)
sendEmailBulk.js # 대량 이메일 발송 (초당 5건 제한, 비동기)
sendEmailToAll.js # 전체 사용자 이메일 발송 (데이터 집계)
subscribeMailing.js # 메일링 구독 (hash 토큰 생성)
unsubscribeMailing.js # 메일링 해지 (hash 기반, 인증 불필요)
exportUserDataToCsv.js # 사용자 데이터 CSV 내보내기 (리뷰/메모)
testCsvEmail.js # CSV 내보내기 테스트
mailing/
replacements.js # 이메일 템플릿 변수 레지 스트리
replacements/
username.js # username 변수 (profile-service 연동)
unsubscribeLink.js # unsubscribeLink 변수 생 성src/index.js에서 @frolog/frolog-api 스펙과 서비스 로직을 매핑합니다.
- GET: SearchUser (admin), GetUser (admin)
- POST: PostUser (admin), SendEmail (admin), SendEmailBulk (admin), SendEmailToAll (admin), SubscribeMailing (admin), UnsubscribeMailing (공개), SuspendUser (admin), ExportUserDataToCsv (admin), TestCsvEmail (공개)
- PATCH: EditUser (admin)
- DELETE: DeleteUser (admin)
없음. 대량 이메일 발송은 요청 기반으로 백그라운드에서 순차 처리됩니다 (초당 5건 제한)
- UnsubscribeMailing, TestCsvEmail: 공개 API (인증 불필요)
- UnsubscribeMailing: hash 기반 토큰으로 인증 대체
- 나머지 모든 엔드포인트: 관리자 전용 (is_admin=true)
- HashId 인코딩: 모든 사용자 ID는 해시 형식으로 처리
사용자 생성 (PostUser)
- login_type: 0 (로컬), 1 (Google OAuth)
- 이메일 암호화 (EMAIL_SECRET, 대칭키)
- 이메일 해시 (SHA-256, 중복 체크용)
- 비밀번호 해싱 (bcrypt, BCRYPT_ROUNDS)
- 반환: 인코딩된 사용자 해시 ID
사용자 조회 (GetUser)
- 사용자 ID, 관리자 상태, 생성일, 정지 상태 반환
- 관리자 전용
사용자 수정 (EditUser)
- 비밀번호 변경 (bcrypt 재해싱)
- 관리자 상태 변경 (is_admin)
- TODO: 이메일 변경 기능 미구현
사용자 삭제 (DeleteUser)
- 소프트 삭제 (deleted_at 타임스탬프)
- 물리적 삭제하지 않음
사용자 검색 (SearchUser)
- 필터: 정지 상태 (active/suspended), 생성일 범위 (start/end)
- 페이지네이션: limit (0-100, 기본값 10), page 오프셋
- 반환: 사용자 목록 + 메타데이터
계정 정지 (SuspendUser)
- suspended_until 설정 (ISO 날짜)
- 지정 날짜까지 접근 차단
단건 이메일 (SendEmail)
- AWS SES 연동
- 템플릿 지원 (template, subject, body)
- 변수 치환: {{username}}, {{unsubscribeLink}}
- 대상: 단일 사용자 ID
대량 이메일 (SendEmailBulk)
- 대상 유형: 특정 ID 배열, 전체 사용자, 마케팅 구독자
- 초당 5건 제한 (EMAIL_LIMIT_PER_SEC, AWS SES throttle 방 지)
- 비동기 순차 처리 (1초 간격 setTimeout)
- 성공/실패 카운트 로깅 (총 시간 포함)
- 템플릿 및 일반 텍스트 지원
전체 발송 (SendEmailToAll)
- 모든 비삭제 사용자에게 발송
- 사용자별 데이터 집계 (리뷰, 메모, 첫 메모)
- TODO: 이메일 본문 생성 미완성
- 개별 실패 로깅 (배치 중단하지 않음)
템플릿 변수
- {{username}}: profile-service의 GetProfile API 호출
- {{unsubscribeLink}}: https://www.frolog.kr/unsubscribe/{hash}
이메일 제한
- AWS SES 기본 제한: 초당 5건
- 환경변수 EMAIL_LIMIT_PER_SEC로 조정 가능
구독 (SubscribeMailing)
- EmailSubscription 레코드 생성
- 랜덤 32바이트 hash 토큰 생성
- 반환: base64url 인코딩된 hash (해지 링크용)
해지 (UnsubscribeMailing)
- hash 기반 인증 (JWT 불필요)
- EmailSubscription 삭제
- 공개 엔드포인트 (누구나 접근 가능, hash만 필요)
CSV 내보내기 (ExportUserDataToCsv)
- 전체 사용자의 리뷰/메모 데이터 추출
- CSV 헤더: type, book_title, author, publisher, isbn, date, rating, tags_pos, tags_neg, summary, content
- 태그 영한 번역 (예: easy → 완독하기 쉬운)
- 두 가지 모드: a. 통합 CSV 파일 b. 사용자별 개별 CSV + 이메일 발송
- 이메일 첨부: 사용자별 데이터 CSV
테스트 (TestCsvEmail)
- CSV 내보내기 기능 테스트
- 공개 엔드포인트 (인증 불필요)
User
- user_id (PK), email (암호화), email_hash (SHA-256)
- pw_hash (bcrypt), login_type (0=로컬, 1=구글)
- is_admin, suspended_until
- created_at, deleted_at
EmailSubscription
- user_id (PK), hash (해지 토큰)
Review
- review_id, writer_id, book_isbn, rating, tags_pos, tags_neg, content
Memo
- memo_id, writer_id, book_isbn, content
Book
- isbn, title, author, publisher
- Profile Service: 사용자 이름 조회 (GetProfile, 이메일 템플릿용)
- SSC_TOKEN: 서비스 간 인증 토큰