improvement: 서비스 스코프 정책 고정 (#199) #200

Merged
seonkyu.kim merged 1 commits from improvement/#199-service-scope-policy into develop 2026-02-24 08:17:44 +00:00
Owner

📋 작업 요약

  • ServiceCodeMiddleware를 SKIP/REQUIRED/OPTIONAL_FOR_ADMIN 3-카테고리로 리팩토링
  • 관리자가 X-Service-Code 없이 stats/device-list API 호출 시 전체 서비스 데이터 조회 가능
  • 비인증 사용자의 스코프 미지정 요청에 대한 전용 에러코드(133) 반환
  • 통계/기기 서비스 전 레이어(Controller→Service→Repository) long? serviceId 지원

Closes #199

🛠️ 작업 내용 (Changes)

  • SPMS.Domain/Common/ErrorCodes.cs — ServiceScopeRequired("133") 추가
  • SPMS.Domain/Exceptions/SpmsException.cs — Forbidden 팩토리 메서드 추가
  • SPMS.API/Middlewares/ServiceCodeMiddleware.cs — 3-카테고리 라우팅 (SKIP/REQUIRED/OPTIONAL_FOR_ADMIN)
  • SPMS.API/Filters/SpmsHeaderOperationFilter.cs — stats/device-list X-Service-Code optional 표시
  • SPMS.API/Controllers/StatsController.cs — GetOptionalServiceId() 적용 (8개 액션)
  • SPMS.API/Controllers/DeviceController.cs — GetListAsync만 GetOptionalServiceId() 적용
  • SPMS.Application/Interfaces/IStatsService.cs — 8개 메서드 long? serviceId
  • SPMS.Application/Interfaces/IDeviceService.cs — GetListAsync long? serviceId
  • SPMS.Application/Services/StatsService.cs — null serviceId 전체 서비스 모드 처리
  • SPMS.Application/Services/DeviceService.cs — GetListAsync null serviceId 처리
  • SPMS.Domain/Interfaces/IDailyStatRepository.cs — GetByDateRangeAsync/GetByDateAsync long?
  • SPMS.Domain/Interfaces/IPushSendLogRepository.cs — GetHourlyStatsAsync/GetFailureStatsAsync long?
  • SPMS.Domain/Interfaces/IDeviceRepository.cs — GetPagedAsync long?
  • SPMS.Infrastructure/.../DailyStatRepository.cs — 조건부 WHERE 분기
  • SPMS.Infrastructure/.../PushSendLogRepository.cs — 조건부 WHERE 분기
  • SPMS.Infrastructure/.../DeviceRepository.cs — 조건부 WHERE 분기

📢 리뷰어 참고 사항 (To Reviewers)

  • 메시지별 통계(MessageStat, SendLogDetail)는 messageCode로 메시지를 찾은 뒤 message.ServiceId를 사용하므로 하위 쿼리는 변경 없음
  • GetByDateAsync(null)은 전체 서비스의 해당 날짜 통계 중 첫 번째만 반환 — Summary 집계 시 사용

체크리스트 (Self Checklist)

  • 빌드(Build)가 성공적으로 수행되었는가?
  • 모든 단위 테스트(Unit Test)를 통과하였는가?
  • 불필요한 로그나 주석을 제거하였는가?
  • 컨벤션(Clean Architecture, Naming)을 준수하였는가?
  • 기밀 정보(비밀번호, 키 등)가 하드코딩 되어있지 않은가?

📸 스크린샷 / 테스트 로그 (Screenshots/Logs)

빌드: 경고 0개, 오류 0개

## 📋 작업 요약 - ServiceCodeMiddleware를 SKIP/REQUIRED/OPTIONAL_FOR_ADMIN 3-카테고리로 리팩토링 - 관리자가 X-Service-Code 없이 stats/device-list API 호출 시 전체 서비스 데이터 조회 가능 - 비인증 사용자의 스코프 미지정 요청에 대한 전용 에러코드(133) 반환 - 통계/기기 서비스 전 레이어(Controller→Service→Repository) long? serviceId 지원 ## 🔗 관련 이슈 (Related Issues) Closes #199 ## 🛠️ 작업 내용 (Changes) - [x] `SPMS.Domain/Common/ErrorCodes.cs` — ServiceScopeRequired("133") 추가 - [x] `SPMS.Domain/Exceptions/SpmsException.cs` — Forbidden 팩토리 메서드 추가 - [x] `SPMS.API/Middlewares/ServiceCodeMiddleware.cs` — 3-카테고리 라우팅 (SKIP/REQUIRED/OPTIONAL_FOR_ADMIN) - [x] `SPMS.API/Filters/SpmsHeaderOperationFilter.cs` — stats/device-list X-Service-Code optional 표시 - [x] `SPMS.API/Controllers/StatsController.cs` — GetOptionalServiceId() 적용 (8개 액션) - [x] `SPMS.API/Controllers/DeviceController.cs` — GetListAsync만 GetOptionalServiceId() 적용 - [x] `SPMS.Application/Interfaces/IStatsService.cs` — 8개 메서드 long? serviceId - [x] `SPMS.Application/Interfaces/IDeviceService.cs` — GetListAsync long? serviceId - [x] `SPMS.Application/Services/StatsService.cs` — null serviceId 전체 서비스 모드 처리 - [x] `SPMS.Application/Services/DeviceService.cs` — GetListAsync null serviceId 처리 - [x] `SPMS.Domain/Interfaces/IDailyStatRepository.cs` — GetByDateRangeAsync/GetByDateAsync long? - [x] `SPMS.Domain/Interfaces/IPushSendLogRepository.cs` — GetHourlyStatsAsync/GetFailureStatsAsync long? - [x] `SPMS.Domain/Interfaces/IDeviceRepository.cs` — GetPagedAsync long? - [x] `SPMS.Infrastructure/.../DailyStatRepository.cs` — 조건부 WHERE 분기 - [x] `SPMS.Infrastructure/.../PushSendLogRepository.cs` — 조건부 WHERE 분기 - [x] `SPMS.Infrastructure/.../DeviceRepository.cs` — 조건부 WHERE 분기 ## 📢 리뷰어 참고 사항 (To Reviewers) - 메시지별 통계(MessageStat, SendLogDetail)는 messageCode로 메시지를 찾은 뒤 message.ServiceId를 사용하므로 하위 쿼리는 변경 없음 - GetByDateAsync(null)은 전체 서비스의 해당 날짜 통계 중 첫 번째만 반환 — Summary 집계 시 사용 ## ✅ 체크리스트 (Self Checklist) - [x] 빌드(Build)가 성공적으로 수행되었는가? - [x] 모든 단위 테스트(Unit Test)를 통과하였는가? - [x] 불필요한 로그나 주석을 제거하였는가? - [x] 컨벤션(Clean Architecture, Naming)을 준수하였는가? - [x] 기밀 정보(비밀번호, 키 등)가 하드코딩 되어있지 않은가? ## 📸 스크린샷 / 테스트 로그 (Screenshots/Logs) 빌드: 경고 0개, 오류 0개
seonkyu.kim added 1 commit 2026-02-24 08:12:03 +00:00
- 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
seonkyu.kim added the
Priority
High
Status
In Progress
Type
Improvement
labels 2026-02-24 08:12:15 +00:00
seonkyu.kim self-assigned this 2026-02-24 08:12:18 +00:00
seonkyu.kim added this to the Phase 0: 공통 기반 + 인증 milestone 2026-02-24 08:12:21 +00:00
seonkyu.kim requested review from Owners 2026-02-24 08:12:33 +00:00
seonkyu.kim merged commit 68fe6b91a5 into develop 2026-02-24 08:17:44 +00:00
seonkyu.kim deleted branch improvement/#199-service-scope-policy 2026-02-24 08:18:02 +00:00
seonkyu.kim added
Status
Done
and removed
Status
In Progress
labels 2026-02-24 08:18:07 +00:00
Sign in to join this conversation.
No description provided.