Commit Graph

73 Commits

Author SHA1 Message Date
SEAN
347c9aa4bf improvement: 이력 목록/상세 API 추가 (#233)
- POST /v1/in/stats/history/list: 메시지별 발송 이력 목록 조회
  (keyword/status/date 필터, 페이지네이션)
- POST /v1/in/stats/history/detail: 특정 메시지 상세 이력 조회
  (기본정보+집계+실패사유 Top 5+본문)
- SendStatus.Determine() 규칙 재사용

Closes #233
2026-02-25 16:23:11 +09:00
SEAN
ffde006e94 improvement: 대시보드 통합 API 추가 (#231)
Closes #231
2026-02-25 16:04:00 +09:00
SEAN
a3b2da5ffb improvement: 통계 서비스 범위 정책 고정 (#229)
- Stats 도메인 에러코드 추가 (171: DateRangeInvalid, 172: ServiceScopeInvalid)
- StatsService ParseDateRange에서 generic BadRequest → StatsDateRangeInvalid로 교체
- StatsController 전 엔드포인트 Swagger Description에 스코프 정책 안내 추가
- SpmsHeaderOperationFilter에서 message/list를 Optional로 반영 (미들웨어 정합)

Closes #229
2026-02-25 15:47:02 +09:00
SEAN
46a2105c13 improvement: 메시지 발송 상태 집계 규칙 고정 (#178)
Closes #178
2026-02-25 15:09:01 +09:00
SEAN
0eacf25eb3 improvement: 메시지 상세/프리뷰 응답 강화 (#226)
- MessageInfoResponseDto에 service_name, service_code, created_by_name, latest_send_status 추가
- MessagePreviewRequestDto/ResponseDto에 JsonPropertyName snake_case 적용
- MessagePreviewResponseDto에 link_type 필드 추가
- Repository에 GetByMessageCodeWithDetailsAsync (Navigation Include), GetSendStatsAsync 추가
- MessageService.GetInfoAsync에서 서비스/작성자/발송상태 매핑
- MessageService.PreviewAsync에서 link_type 반환

Closes #226
2026-02-25 14:43:29 +09:00
SEAN
011cb9b380 improvement: 메시지 목록 확장 (#224)
- ServiceCodeMiddleware: message/list를 OPTIONAL_FOR_ADMIN에 추가
- MessageListRequestDto: service_code, send_status 필터 필드 추가
- MessageSummaryDto: service_name, service_code, latest_send_status 추가
- IMessageRepository + MessageRepository: GetPagedForListAsync 구현
  (Service 조인 + PushSendLog 집계 한 번의 쿼리)
- IMessageService + MessageService: serviceId nullable 변경, DetermineSendStatus 헬퍼
- MessageController: GetServiceIdOrNull() 헬퍼 + Swagger 업데이트

Closes #224
2026-02-25 14:28:09 +09:00
SEAN
b373d59710 improvement: 메시지 저장/검증 계약 통일 (#222)
- MessageValidateRequestDto에 JsonPropertyName 추가 (snake_case 통일)
- MessageValidateRequestDto.Data 타입 string? → object? 변경
- MessageValidationService.ValidateData 파라미터 타입 변경
- Swagger Description 업데이트 (save/validate 엔드포인트)

Closes #222
2026-02-25 14:06:54 +09:00
SEAN
351135549e improvement: API Key 마스킹 및 전체 조회 엔드포인트 추가 (#220)
- 상세 조회 시 API Key 마스킹 (앞 8자 + ********)
- API Key 전체 조회 엔드포인트 신규 (apikey/view)
- 기존 재발급 엔드포인트 (apikey/refresh) 유지
- Swagger Description 업데이트

Closes #220
2026-02-25 13:56:59 +09:00
SEAN
17caeb08e2 improvement: 수정/삭제/진단 계약 확장 (#218)
- 플랫폼 자격증명 삭제 API 추가 (APNs/FCM 각각)
- 자격증명 진단 응답에 credentialStatus/statusReason 추가
- 수정 API에 Status 필드 추가 (원자적 상태 변경)
- Swagger Description 업데이트

Closes #218
2026-02-25 13:36:47 +09:00
SEAN
e3ed3d4267 improvement: 서비스 목록/상세 응답에 플랫폼 상태 판정 추가 (#216)
- PlatformSummaryDto / PlatformCredentialSummaryDto 신규 생성
- ServiceSummaryDto에 Platforms 필드 추가 (목록 응답)
- ServiceResponseDto에 ApnsAuthType + Platforms 필드 추가 (상세 응답)
- BuildPlatformSummary 메서드로 Android/iOS 상태 판정
  - Android: FcmCredentials 유무 → ok/none
  - iOS p8: → ok
  - iOS p12: 만료됨→error, 30일 이내→warn, 그 외→ok
- Swagger Description 업데이트

Closes #216
2026-02-25 13:21:30 +09:00
SEAN
d051ff3b97 improvement: APNs p12 인증서 지원 추가 (#214)
- Service 엔티티에 ApnsAuthType/ApnsCertificate/ApnsCertPassword/ApnsCertExpiresAt 추가
- EF Core Configuration + Migration (AddApnsP12Support)
- DTO: AuthType 분기 (p8/p12) 지원, p12 필드 추가
- 서비스 로직: AuthType별 검증/저장/조회 분기, X509CertificateLoader로 만료일 추출
- AuthType 전환 시 이전 타입 필드 null 초기화
- 컨트롤러 Swagger Description 업데이트

Closes #214
2026-02-25 13:01:55 +09:00
SEAN
4916488175 improvement: 서비스 통합 등록 플로우 구현 (#212)
- POST /v1/in/service/register 통합 등록 엔드포인트 추가
- RegisterServiceRequestDto/ResponseDto 신규 생성
- 서비스 생성 + FCM/APNs 자격증명을 트랜잭션으로 원자성 보장
- 검증 로직 private 메서드 추출 (기존 코드 재사용)
- 자격증명은 선택사항, 검증 실패 시 전체 롤백

Closes #212
2026-02-25 12:26:45 +09:00
SEAN
4577d8c10d improvement: 서비스명 중복 확인 API 및 전용 에러코드 추가 (#210)
- POST /v1/in/service/name/check 엔드포인트 추가
- ServiceNameDuplicate(134) 에러코드 추가
- CreateAsync/UpdateAsync 서비스명 중복 에러코드 변경
- CreateServiceRequestDto MinimumLength=2 검증 추가

Closes #210
2026-02-25 12:15:28 +09:00
SEAN
42aa04f58e improvement: 인증 보안 정책 — Rate Limit + 시도제한 + 보안 로깅 (#190)
- auth_sensitive 명명 Rate Limit 정책 추가 (20회/15분/IP)
- AuthController 3개 + PasswordController 2개 메서드에 EnableRateLimiting 적용
- 로그인 시도 제한 구현 (5회/15분, Redis 카운터, LoginAttemptExceeded 에러코드 활성화)
- 비밀번호 찾기/임시 비밀번호 요청 제한 (3회/1시간, silent 반환)
- AuthService 보안 이벤트 구조적 로깅 (ILogger 주입)
- Swagger 429 응답 문서화

Closes #190
2026-02-25 11:13:49 +09:00
SEAN
3acae06ed1 improvement: 임시 비밀번호 발급 및 강제변경 플로우 구현 (#207)
- Admin 엔티티에 MustChangePassword, TempPasswordIssuedAt 필드 추가
- POST /v1/in/account/password/temp 엔드포인트 추가
- 임시비밀번호 생성(12자, 영대소+숫자+특수) 및 메일 발송
- 로그인 시 CHANGE_PASSWORD 분기 추가 (VERIFY_EMAIL > CHANGE_PASSWORD > GO_DASHBOARD)
- 비밀번호 변경 시 MustChangePassword 플래그 자동 해제
- LoginResponseDto에 must_change_password 필드 추가
- EF Core 마이그레이션 생성 및 적용

Closes #207
2026-02-25 10:51:37 +09:00
SEAN
3cc99c0284 improvement: 이메일 인증/재전송 강화 (#205)
- verify API: verifySessionId 기반 입력 지원 (email 하위호환)
- verify API: 시도 횟수 5회 제한 (30분 TTL)
- verify API: 응답에 verified, nextAction 필드 추가
- resend API 신규: POST /v1/in/auth/email/verify/resend
- resend API: 60초 쿨다운, 기존 코드 자동 무효화
- email_verify TTL 1시간→5분 변경 (signup/login 포함)
- ErrorCodes 추가: VerifyResendCooldown(116), VerifyAttemptExceeded(117)

Closes #205
2026-02-25 10:38:41 +09:00
SEAN
859eabd83c improvement: 로그인 분기 계약 확장 (#177)
- LoginResponseDto에 nextAction, emailVerified, verifySessionId, emailSent 추가
- 미인증 유저 로그인 시 verify session/인증코드 생성 + 메일 발송
- Swagger Description에 분기 설명 추가

Closes #177
2026-02-25 10:08:45 +09:00
SEAN
8224c7a17b improvement: 가입 계약 확장 — 동의 필드/세션/메일 발송 안정화 (#202)
- Admin 엔티티에 AgreeTerms, AgreePrivacy, AgreedAt 필드 추가
- SignupRequestDto에 동의 필드 추가 (필수 검증)
- SignupResponseDto에 verifySessionId, emailSent 응답 추가
- AuthService.SignupAsync: 동의 검증, verify session 생성, 메일 발송 try-catch
- ErrorCodes에 TermsNotAgreed(114), PrivacyNotAgreed(115) 추가
- EF Core 마이그레이션 AddConsentFieldsToAdmin 생성/적용

Closes #202
2026-02-25 09:29:17 +09:00
SEAN
bf8f82e66c improvement: 로그아웃 시 Access Token 즉시 무효화 (#169)
- IJwtService/JwtService에 GetTokenInfo(JTI, 만료시간 추출) 추가
- LogoutAsync에 Redis 블랙리스트 로직 추가 (key: blacklist:{jti}, TTL: 남은 만료시간)
- AuthenticationExtensions OnTokenValidated에서 블랙리스트 체크
- 로그아웃 후 동일 Access Token 재사용 시 401 반환

Closes #169
2026-02-24 17:33:37 +09:00
SEAN
f04eb44fff improvement: 서비스 스코프 정책 고정 (#199)
- ErrorCodes.ServiceScopeRequired("133") 추가
- SpmsException.Forbidden 팩토리 추가
- ServiceCodeMiddleware 3-카테고리 라우팅 (SKIP/REQUIRED/OPTIONAL_FOR_ADMIN)
- Swagger 필터 stats/device-list X-Service-Code optional 표시
- StatsController/DeviceController GetOptionalServiceId() 적용
- IStatsService/IDeviceService/레포지토리 시그니처 long? serviceId 변경
- StatsService/DeviceService null serviceId 전체 서비스 모드 처리

Closes #199
2026-02-24 17:11:30 +09:00
SEAN
4bc08715fa improvement: 공통 응답/에러 포맷 고정 (#164)
- FieldError DTO 공통화 (SPMS.Domain/Common)
- ValidationErrorData + ApiResponse.ValidationFail() 추가
- InvalidModelStateResponseFactory로 ModelState 에러 ApiResponse 변환
- Controller Unauthorized 응답 throw SpmsException으로 통일 (에러코드 102)
- MessageValidationService ValidationErrorDto → FieldError 교체

Closes #164
2026-02-24 16:24:56 +09:00
SEAN
c63a61bf6a fix: Health check Redis 상태를 실제 PING 체크로 변경 (#156)
- not_configured 하드코딩 제거
- RedisConnection 주입 후 PingAsync()로 실제 연결 상태 확인
- 응답에 latency 포함

Closes #156
2026-02-11 10:49:47 +09:00
SEAN
2aa676d60f feat: 웹훅 설정 API 구현 (#144)
Closes #144
2026-02-11 10:03:03 +09:00
SEAN
a5b8bda162 feat: 실패원인 순위 API 구현 (#142)
Closes #142
2026-02-11 09:51:44 +09:00
SEAN
3a973f56ce feat: 상세 로그 다운로드 API 구현 (#140)
- POST /v1/in/push/log/export (EXP-02, API_SPMS_07_PUSH_09)
- 발송 로그 CSV 파일 다운로드 (페이징 없이 전체 반환)
- 최대 조회 기간 30일, 최대 100,000건 제한
- message_code, device_id, status 필터 지원

Closes #140
2026-02-11 09:43:47 +09:00
SEAN
d3bd4356a8 feat: 통계 리포트 다운로드 API 구현 (#138)
- POST /v1/in/stats/export (EXP-01)
- 일별/시간대별/플랫폼별 통계를 엑셀(.xlsx) 3시트로 생성
- ClosedXML 패키지 추가

Closes #138
2026-02-11 09:38:46 +09:00
SEAN
bcc40b4c01 feat: 발송 상세 로그 조회 API 구현 (#136)
- POST /v1/in/stats/send-log (DDL-02)
- 특정 메시지의 개별 디바이스별 발송 로그 조회
- 플랫폼(iOS/Android/Web), 성공/실패 필터 지원
- Device Include로 디바이스 토큰, 플랫폼 정보 포함

Closes #136
2026-02-11 09:29:03 +09:00
SEAN
3e5aeacd5e feat: 운영자 관리 API 구현 (#134)
- POST /v1/in/account/operator/create (계정 생성 + 비밀번호 설정 이메일)
- POST /v1/in/account/operator/delete (Soft Delete, 자기 자신 삭제 방지)
- POST /v1/in/account/operator/list (페이징 + role/is_active 필터)
- POST /v1/in/account/operator/password/reset (비밀번호 초기화 + 세션 무효화)

Closes #134
2026-02-11 09:16:04 +09:00
0911fc763a feat: 통계 API 구현 (8.1~8.5) (#132)
- POST /v1/in/stats/daily: 기간별 일별 통계
- POST /v1/in/stats/summary: 대시보드 요약 통계
- POST /v1/in/stats/message: 메시지별 발송 통계
- POST /v1/in/stats/hourly: 시간대별 발송 추이
- POST /v1/in/stats/device: 디바이스 분포 통계
- IDailyStatRepository, DailyStatRepository 신규
- IPushSendLogRepository 통계 메서드 확장

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:08:04 +09:00
830cbf2edc feat: 대용량 발송/상태조회/취소 API 구현 (#130)
- POST /v1/in/push/send/bulk: CSV 대량 발송 (비동기)
- POST /v1/in/push/job/status: Job 상태 조회
- POST /v1/in/push/job/cancel: Job 취소
- BulkJobStore: Redis Hash 기반 Job 상태 관리
- PushWorker: Job 진행률 추적 및 취소 체크

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 22:55:39 +09:00
fc7ab51fa3 feat: 메시지 CRUD API 구현 (#128)
- 메시지 저장 API (POST /v1/in/message/save)
- 메시지 목록 조회 API (POST /v1/in/message/list)
- 메시지 상세 조회 API (POST /v1/in/message/info)
- 메시지 삭제 API (POST /v1/in/message/delete)
- message_code 자동 생성 (접두3+순번4+접미3)
- 변수 추출 ({{변수명}} 패턴)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 22:38:24 +09:00
f70d8a8558 fix: Health check 503 응답에 상세 데이터 포함 (#126)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:27:44 +09:00
3fc3bb8144 fix: RabbitMQ 상태 모니터링 및 백그라운드 재시도 추가 (#124)
- RabbitMQInitializer를 BackgroundService로 변경 (30초 간격 재시도)
- RabbitMQConnection에 IsConnected 속성 추가
- Health check에 RabbitMQ 연결/초기화 상태 반영
- DI 등록 변경 (Singleton + HostedService 패턴)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:15:42 +09:00
SEAN
b56170f10c feat: 발송 로그 조회 API 구현 (#122)
- POST /v1/in/push/log 엔드포인트 추가
- PushSendLogRepository (페이징, 필터링: message_code, device_id, status, 날짜범위)
- PushService.GetLogAsync 구현
- 누락된 Push DTO 파일 포함 (PushSendRequestDto, PushSendResponseDto, PushSendTagRequestDto)
2026-02-10 17:41:38 +09:00
SEAN
ef6d71a921 feat: 메시지 미리보기 API 구현 (#120)
- POST /v1/in/message/preview 엔드포인트 추가
- MessageService: 메시지 조회 → 변수 치환 → 미리보기 데이터 반환
- IMessageService 인터페이스 정의 (향후 CRUD 확장용)

Closes #120
2026-02-10 17:27:56 +09:00
SEAN
ce7b8b3d35 feat: 메시지 유효성 검사 서비스 구현 (#118)
- MessageValidationService: title/body/image_url/link_url/link_type/data 검증
- POST /v1/in/message/validate 엔드포인트 추가
- MessageController 기반 구성

Closes #118
2026-02-10 17:15:57 +09:00
SEAN
fe1dcd0176 feat: 예약 발송 등록/취소 API 구현 (#116)
- POST /v1/in/push/schedule (예약 발송 등록)
- POST /v1/in/push/schedule/cancel (예약 취소)
- ScheduleCancelStore: Redis 기반 예약 취소 추적
- ScheduleWorker: 취소된 예약 메시지 ACK 후 스킵 로직 추가

Closes #116
2026-02-10 17:06:04 +09:00
SEAN
73de5efd84 feat: 즉시 발송 요청 API 구현 (#114)
- POST /v1/in/push/send (단건 발송)
- POST /v1/in/push/send/tag (태그 발송)
- PushService: 메시지 조회 → 변수 치환 → RabbitMQ 큐 발행
- MessageNotFound(151) 에러 코드 추가

Closes #114
2026-02-10 16:38:51 +09:00
SEAN
0db4a8824d feat: CSV 검증/템플릿 다운로드 API 구현 (#100) 2026-02-10 15:22:12 +09:00
SEAN
658fa1d63d feat: 파일 업로드/조회/삭제 API 구현 (#98) 2026-02-10 15:03:24 +09:00
SEAN
e355c8be62 feat: 디바이스 태그/동의 설정 API 구현 (#96) 2026-02-10 14:49:07 +09:00
SEAN
e9bcd5358f feat: 디바이스 CRUD + 목록 API 구현 (#94) 2026-02-10 14:44:16 +09:00
SEAN
2037a409ef feat: 점검 안내 API 구현 (#92) 2026-02-10 14:33:32 +09:00
SEAN
57fdfdea0e fix: Public API에서 X-Service-Code 의존성 제거 (#90) 2026-02-10 14:26:41 +09:00
SEAN
7485e139cd feat: 앱 기본 설정 API 구현 (#88) 2026-02-10 14:17:22 +09:00
SEAN
0d80b8c25f feat: 앱 버전 체크 API 구현 (#86) 2026-02-10 14:11:28 +09:00
SEAN
6475c0c753 feat: 이용약관/개인정보처리방침 API 구현 (#84) 2026-02-10 14:07:13 +09:00
SEAN
e24e0c2398 feat: FAQ 목록 API 구현 (#82) 2026-02-10 13:57:17 +09:00
SEAN
ad1bf2e4e6 feat: 배너 목록 API 구현 (#80) 2026-02-10 13:41:19 +09:00
SEAN
f0d325fda9 feat: 공지사항 목록/상세 API 구현 (#78) 2026-02-10 13:34:36 +09:00