- Tag DTO 6종 생성 (List/Create/Update/Delete Request/Response)
- ITagRepository 확장 (GetTagListAsync, CountByServiceAsync)
- IDeviceRepository 확장 (GetDeviceCountsByTagIdsAsync)
- ITagService/TagService 구현 (CRUD 비즈니스 로직)
- TagController 신규 생성 (v1/in/tag/list, create, update, delete)
- DI 등록
Closes#186
- Tag 엔티티 생성 (ServiceId, Name, Description, CreatedAt, CreatedBy)
- ITagRepository 인터페이스 및 TagRepository 구현
- TagConfiguration: Unique Index (ServiceId, Name), FK Restrict
- Service.TagList Navigation 추가
- ErrorCodes에 Tag 에러코드 4종 추가 (191~194)
- AppDbContext DbSet<Tag>, DI 등록
- EF Core Migration AddTagTable 생성 및 적용
Closes#243
- DeviceExportRequestDto: 목록 필터와 동일한 필터 파라미터 (page/size 제외)
- IDeviceRepository/DeviceRepository: GetAllFilteredAsync 추가 (전체 반환)
- DeviceService: ClosedXML 기반 엑셀 생성 (14개 컬럼)
- DeviceController: POST /v1/in/device/export [Authorize] 엔드포인트 추가
Closes#241
- IDeviceService: AdminDeleteAsync(long deviceId) 추가
- DeviceService: Device 조회 → IsActive=false → 토큰 캐시 무효화
- DeviceController: POST /v1/in/device/admin/delete [Authorize] 엔드포인트 추가
- 기존 SDK 삭제 API와 분리, JWT 인증 기반 관리자 전용
Closes#239
- POST /v1/in/stats/history/export 엔드포인트 추가
- history/list와 동일 필터(keyword/status/date) 기준 엑셀 내보내기
- PushSendLogRepository에서 GroupBy 쿼리를 private helper로 리팩토링
- ClosedXML로 엑셀 생성 (메시지코드/제목/서비스명/발송일시/대상수/성공/실패/오픈율/상태)
Closes#191
- POST /v1/in/stats/history/list: 메시지별 발송 이력 목록 조회
(keyword/status/date 필터, 페이지네이션)
- POST /v1/in/stats/history/detail: 특정 메시지 상세 이력 조회
(기본정보+집계+실패사유 Top 5+본문)
- SendStatus.Determine() 규칙 재사용
Closes#233
- Stats 도메인 에러코드 추가 (171: DateRangeInvalid, 172: ServiceScopeInvalid)
- StatsService ParseDateRange에서 generic BadRequest → StatsDateRangeInvalid로 교체
- StatsController 전 엔드포인트 Swagger Description에 스코프 정책 안내 추가
- SpmsHeaderOperationFilter에서 message/list를 Optional로 반영 (미들웨어 정합)
Closes#229
- MessageValidateRequestDto에 JsonPropertyName 추가 (snake_case 통일)
- MessageValidateRequestDto.Data 타입 string? → object? 변경
- MessageValidationService.ValidateData 파라미터 타입 변경
- Swagger Description 업데이트 (save/validate 엔드포인트)
Closes#222
- 상세 조회 시 API Key 마스킹 (앞 8자 + ********)
- API Key 전체 조회 엔드포인트 신규 (apikey/view)
- 기존 재발급 엔드포인트 (apikey/refresh) 유지
- Swagger Description 업데이트
Closes#220
- 플랫폼 자격증명 삭제 API 추가 (APNs/FCM 각각)
- 자격증명 진단 응답에 credentialStatus/statusReason 추가
- 수정 API에 Status 필드 추가 (원자적 상태 변경)
- Swagger Description 업데이트
Closes#218
- Service 엔티티에 ApnsAuthType/ApnsCertificate/ApnsCertPassword/ApnsCertExpiresAt 추가
- EF Core Configuration + Migration (AddApnsP12Support)
- DTO: AuthType 분기 (p8/p12) 지원, p12 필드 추가
- 서비스 로직: AuthType별 검증/저장/조회 분기, X509CertificateLoader로 만료일 추출
- AuthType 전환 시 이전 타입 필드 null 초기화
- 컨트롤러 Swagger Description 업데이트
Closes#214
- POST /v1/in/service/register 통합 등록 엔드포인트 추가
- RegisterServiceRequestDto/ResponseDto 신규 생성
- 서비스 생성 + FCM/APNs 자격증명을 트랜잭션으로 원자성 보장
- 검증 로직 private 메서드 추출 (기존 코드 재사용)
- 자격증명은 선택사항, 검증 실패 시 전체 롤백
Closes#212
- POST /v1/in/service/name/check 엔드포인트 추가
- ServiceNameDuplicate(134) 에러코드 추가
- CreateAsync/UpdateAsync 서비스명 중복 에러코드 변경
- CreateServiceRequestDto MinimumLength=2 검증 추가
Closes#210
- 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
- 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
- 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