Commit Graph

48 Commits

Author SHA1 Message Date
SEAN
44f6defa84 improvement: Device External ID (UUID) 도입 (#275) 2026-03-03 12:55:53 +09:00
SEAN
71cd7a5e98 improvement: TagCode 도입 — 태그 식별자를 4자리 랜덤 코드로 변경 (#269)
Closes #269
2026-03-02 16:12:06 +09:00
SEAN
ecddbe1c26 fix: AdminCode 컬럼 길이 불일치 수정 (#257)
- HasMaxLength(8) → HasMaxLength(12) 변경
- 코드에서 12자 UUID를 생성하나 DB가 8자만 허용하는 버그
- 회원가입 시 'Data too long for column AdminCode' 500 에러 해결
2026-02-26 17:36:33 +09:00
SEAN
04dd5be046 improvement: 마이페이지 조회 확장 (#249)
- Admin 엔티티에 Organization 컬럼 추가 + Migration
- ProfileResponseDto에 last_login_at, organization 필드 추가
- UpdateProfileRequestDto에 organization 필드 추가
- AuthService 프로필 조회/수정 매핑 확장
- 활동 내역 DTO 및 GetActivityListAsync 메서드 추가
- ProfileController 활동 내역 조회 엔드포인트 추가

Closes #249
2026-02-26 10:01:48 +09:00
SEAN
c29a48163d improvement: Notification 도메인 구축 (#247)
- Domain: NotificationCategory enum, Notification entity, INotificationRepository
- Infrastructure: NotificationConfiguration, NotificationRepository, AppDbContext/DI 등록
- Migration: AddNotificationTable 생성 및 적용
- Application: DTO 7개, INotificationService, NotificationService, DI 등록
- API: NotificationController (summary, list, read, read-all)

Closes #247
2026-02-26 09:44:28 +09:00
SEAN
4db27aaf8a improvement: 태그 삭제 시 디바이스 orphan 참조 제거 (#186)
- IDeviceRepository에 GetDevicesByTagIdAsync 메서드 추가
- DeviceRepository에 LIKE 기반 태그 참조 디바이스 조회 구현
- TagService.DeleteAsync에서 트랜잭션으로 원자적 처리:
  디바이스 Tags JSON에서 삭제 대상 tagId 제거 후 태그 삭제
2026-02-26 09:12:41 +09:00
SEAN
7ffc152536 improvement: 태그 CRUD API 구현 (#186)
- 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
2026-02-25 18:07:11 +09:00
SEAN
c458cfe4e7 improvement: Tag 테이블 신설 및 도메인 모델 확정 (#243)
- 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
2026-02-25 17:36:14 +09:00
SEAN
a2d563aa9d improvement: 기기 엑셀 내보내기 API 추가 (#241)
- DeviceExportRequestDto: 목록 필터와 동일한 필터 파라미터 (page/size 제외)
- IDeviceRepository/DeviceRepository: GetAllFilteredAsync 추가 (전체 반환)
- DeviceService: ClosedXML 기반 엑셀 생성 (14개 컬럼)
- DeviceController: POST /v1/in/device/export [Authorize] 엔드포인트 추가

Closes #241
2026-02-25 17:16:13 +09:00
SEAN
afaeb6d116 improvement: 관리자 기기 목록 API 확장 (#237)
- DeviceListRequestDto: keyword, marketing_agreed 필터 추가
- DeviceSummaryDto: 8개 응답 필드 추가 (device_token, service_name, service_code, os_version, app_version, marketing_agreed, is_active, created_at)
- DeviceRepository: keyword/marketingAgreed 필터 + Include(Service) 추가
- DeviceService: 새 필터 전달 + 응답 매핑 확장

Closes #237
2026-02-25 16:56:59 +09:00
SEAN
3d8c57f690 improvement: 이력 엑셀 내보내기 API 추가 (#191)
- POST /v1/in/stats/history/export 엔드포인트 추가
- history/list와 동일 필터(keyword/status/date) 기준 엑셀 내보내기
- PushSendLogRepository에서 GroupBy 쿼리를 private helper로 리팩토링
- ClosedXML로 엑셀 생성 (메시지코드/제목/서비스명/발송일시/대상수/성공/실패/오픈율/상태)

Closes #191
2026-02-25 16:39:56 +09:00
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
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
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
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
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
87b48441cb feat: DailyStatWorker 구현 (#148)
Closes #148
2026-02-11 10:17:06 +09:00
SEAN
d717603365 feat: 웹훅 발송 서비스 구현 (#146)
Closes #146
2026-02-11 10:10:11 +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
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
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
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
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
e9bcd5358f feat: 디바이스 CRUD + 목록 API 구현 (#94) 2026-02-10 14:44:16 +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
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
SEAN
1aab5032db feat: Public API Entity 정의 및 DB 스키마 구축 (#76) 2026-02-10 13:21:15 +09:00
SEAN
aea0d358e8 improvement: Message Entity link_type 컬럼 추가 (#74) 2026-02-10 13:11:29 +09:00
SEAN
473fe525f3 chore: Admin EF Configuration에 RefreshToken 명시적 설정 추가 (#72) 2026-02-10 11:39:30 +09:00
SEAN
21dc6e608c feat: 서비스 등록 API 구현 (#52) 2026-02-10 09:38:56 +09:00
c8a3d616c3 feat: IP 화이트리스트 관리 API 구현 (#50)
- IP 목록 조회, 추가, 삭제 API 구현
- IPv4 형식 검증 추가
- 중복 IP 체크 로직 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 00:52:41 +09:00
336dcf8193 feat: 토큰 갱신 및 로그아웃 API 구현 (#38)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-09 23:08:29 +09:00
b11c8dc918 feat: 관리자 로그인 API 구현 (#36)
- LoginRequestDto, LoginResponseDto 추가
- IAuthService, AuthService 구현 (BCrypt 비밀번호 검증)
- AdminRepository 구현 (GetByEmailAsync)
- AuthController 추가 (POST /v1/in/auth/login)
- DI 등록 (IAuthService, IAdminRepository)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-09 22:16:25 +09:00
SEAN
df8a8e2e5b feat: X-Service-Code / X-API-KEY 서비스 식별 미들웨어 구현 (#32)
- ServiceRepository: IServiceRepository 구현 (GetByServiceCode, GetByApiKey)
- ServiceCodeMiddleware: X-Service-Code 헤더 검증, DB 조회, 서비스 상태 확인
- ApiKeyMiddleware: /v1/in/device/* 경로 X-API-KEY 검증
- ApplicationBuilderExtensions: 미들웨어 파이프라인 12~13번 등록
- DependencyInjection: IServiceRepository DI 등록

Closes #32
2026-02-09 17:25:19 +09:00
SEAN
787190f512 feat: Generic Repository 및 UnitOfWork 패턴 구현 (#18)
- IRepository<T> 구현체: CRUD, 페이징, 조건 검색 지원
- IUnitOfWork 구현체: 트랜잭션 관리 (Begin/Commit/Rollback)
- Program.cs에 DI 등록 (AddScoped)

Closes #18
2026-02-09 14:44:31 +09:00
SEAN
8b6fd84b98 feat: Domain Enum 및 에러 코드 상수 정의 (#10)
- 12개 Enum 추가 (Platform, ServiceStatus, SubTier, AdminRole, DeviceStatus, MessageStatus, PushResult, PaymentStatus, TargetType, LinkType, WebhookEvent, WebhookStatus)
- ErrorCodes 상수 클래스 추가 (Error_Codes.md 기반 3자리 코드)
- Entity byte 필드를 Enum 타입으로 변경 (Service, Admin, Device, PushSendLog, WebhookLog, Payment)
- WebhookLog.EventType 컬럼 타입 변경 (varchar→tinyint) 마이그레이션 적용
2026-02-09 13:31:50 +09:00
SEAN
cfce5ca8b8 feat: Domain Entity 정의 및 DB 스키마 구축 (#8)
- 12개 Domain Entity 클래스 정의 (DB_Schema.md 기반)
- 12개 EF Core Fluent API Configuration 구현
- AppDbContext에 DbSet 12개 등록 및 Configuration 자동 적용
- Soft Delete 글로벌 쿼리 필터 적용 (Service, Admin, Message)
- DesignTimeDbContextFactory 추가 (EF Core CLI 지원)
- InitialCreate 마이그레이션 생성 및 spms_dev DB 적용 완료
- .gitignore에 Documents/, CLAUDE.md, TASKS.md, .mcp.json 추가

Closes #8
2026-02-09 11:46:33 +09:00