76 KiB
TASKS.md
SPMS API 전체 작업 목록 및 마일스톤 계획
📌 기준 문서:
Documents/API_Specification.md(65개 API)Feature_Spec.md, PRD.md는 참고 문서로만 사용. 문서 충돌 시 API_Specification.md 우선.
⚠️ 1이슈 1완료 원칙: 이슈 1개씩 순차 진행. 이슈 → 코드 → PR → 머지 완료 후, 다음 이슈는 사용자 승인 받고 시작. 여러 이슈 병렬 진행 금지.
0. API 커버리지 현황
API_Specification.md 기준 65개 API 구현 현황
| 도메인 | API 수 | 구현 완료 | 미구현 | Phase |
|---|---|---|---|---|
| Public | 10 | 10 | 0 | Phase 2-2 ✅ |
| Auth | 6 | 6 | 0 | Phase 2-1 ✅ |
| Account | 5 | 5 | 0 | Phase 2-1 ✅ |
| Service | 13 | 13 | 0 | Phase 2-1 ✅ |
| Device | 7 | 7 | 0 | Phase 2-2 ✅ |
| Message | 5 | 1 | 4 | Phase 3 ← 다음 |
| Push | 8 | 5 | 3 | Phase 3 |
| Stats | 5 | 0 | 5 | Phase 3-2 |
| File | 6 | 6 | 0 | Phase 2-2 ✅ |
| 총계 | 65 | 53 | 12 | - |
1. 마일스톤 로드맵
| 마일스톤 | 버전 | 상태 |
|---|---|---|
| Phase 1: 인프라 & 공통 모듈 | v0.1.0 | ✅ 완료 |
| Phase 2-1: 인증 & 계정 & 서비스 API | v0.2.0 | ✅ 완료 |
| Phase 2-2: Public & 디바이스 & 파일 API | v0.3.0 | ✅ 완료 |
| Phase 3: 메시지 & Push Core | v0.4.0 | 🔄 진행 중 |
| Phase 3-2: 통계 & Webhook & 배치 | v0.5.0 | ⬜ 대기 |
| MVP: 통합 테스트 & 안정화 & 배포 | v1.0.0 | ⬜ 대기 |
| Phase 4: Back Office (React) | v1.1.0 | ⬜ 대기 |
| Phase 5: SDK & 고급 기능 | v1.2.0 | ⬜ 대기 |
2. Phase 1: 인프라 & 공통 모듈
목표: 모든 도메인 API 구현의 기반이 되는 공통 모듈, 인증, 인프라를 구축한다.
선행 완료 항목:
- Docker Compose 인프라 (MariaDB, RabbitMQ, Redis)
- Clean Architecture 4-Layer 프로젝트 분리 (Issue #5)
- NuGet 패키지 설정 (EF Core, Serilog, BCrypt, FirebaseAdmin, RabbitMQ.Client)
Issue #1 — Domain Entity + EF Core Configuration + Migration
제목: [Feature] Domain Entity 정의 및 DB 스키마 구축
Labels: Type/Feature, Priority/Urgent, Status/Available
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#8-domain-entities-db
Gitea Issue: #8
상태: ✅ 완료 (PR #9 머지됨)
설명: DB_Schema.md 기반 12개 Entity 클래스를 정의하고, EF Core Fluent API 설정 후 초기 Migration으로 DB 테이블을 생성한다.
체크리스트 — Domain Entity (SPMS.Domain):
SPMS.Domain/Entities/디렉토리 생성BaseEntity.cs— 공통 필드 (Id)Service.cs— 서비스 정보 (21 컬럼)ServiceIp.cs— IP 화이트리스트 (3 컬럼)Admin.cs— 관리자 정보 (13 컬럼)Device.cs— 기기 정보 (15 컬럼)Message.cs— 메시지 내용 (12 컬럼)FileEntity.cs— 업로드 파일 (9 컬럼)PushSendLog.cs— 발송 로그 (7 컬럼)PushOpenLog.cs— 오픈 로그 (5 컬럼)DailyStat.cs— 일별 통계 (8 컬럼)WebhookLog.cs— 웹훅 로그 (9 컬럼)SystemLog.cs— 시스템 로그 (9 컬럼)Payment.cs— 결제 이력 (12 컬럼)
체크리스트 — EF Core Configuration (SPMS.Infrastructure):
SPMS.Infrastructure/Persistence/Configurations/디렉토리 생성- 12개 엔티티별
IEntityTypeConfiguration<T>구현 AppDbContext.csDbSet 등록 (12개)- Soft Delete 글로벌 쿼리 필터 적용 (Service, Admin, Message)
- 초기 마이그레이션 생성 (
dotnet ef migrations add InitialCreate) - DB 적용 (
dotnet ef database update) → spms_dev에 테이블 생성 확인
Issue #2 — Domain Enum 및 상수 정의
제목: [Feature] Domain Enum 및 상수 정의
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#10-domain-enums
Gitea Issue: #10
상태: ✅ 완료 (PR #11 머지됨)
설명: 도메인 전반에서 사용할 Enum과 상수를 정의한다.
체크리스트:
SPMS.Domain/Enums/디렉토리 생성Platform.cs— iOS(0), Android(1), Web(2)ServiceStatus.cs— Active(0), Suspended(1)SubTier.cs— Free(0), Basic(1), Pro(2)AdminRole.cs— Super(0), Manager(1), User(2)DeviceStatus.cs— Active(0), Inactive(1), Blocked(2)MessageStatus.cs— Draft(0), Pending(1), Sending(2), Sent(3), Failed(4), Cancelled(5)PushResult.cs— Success(0), Failed(1)PaymentStatus.cs— Completed(0), Cancelled(1), Refunded(2)TargetType.cs— All(0), Filter(1), CsvFile(2), UserList(3)LinkType.cs— App(0), Web(1), DeepLink(2)WebhookEvent.cs— PushSent(0), PushFailed(1), PushClicked(2)WebhookStatus.cs— Success(0), Failed(1)ErrorCodes.cs— Error_Codes.md 기반 3자리 에러 코드 상수- Entity
byte필드 → Enum 타입 변경 (Service, Admin, Device, PushSendLog, WebhookLog, Payment) - EF Core Migration 적용 (WebhookLog.EventType: varchar→tinyint)
- 빌드 성공 확인
Issue #3 — Domain Interface 정의
제목: [Feature] Domain Interface 정의 (Repository, Service)
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#12-domain-interfaces
Gitea Issue: #12
상태: ✅ 완료 (PR #13 머지됨)
설명: Clean Architecture 계층 참조 규칙에 따라 Domain 레이어에 Repository 및 Service 인터페이스를 정의한다.
체크리스트:
SPMS.Domain/Interfaces/디렉토리 생성IRepository<T>.cs— Generic CRUD 인터페이스 (GetById, GetAll, Find, GetPaged, Count, Exists, Add, Update, Delete)IUnitOfWork.cs— 트랜잭션 관리 (SaveChanges, BeginTransaction, Commit, Rollback)IServiceRepository.cs— 서비스 전용 쿼리 (ByServiceCode, ByApiKey, WithIps, ByStatus)IAdminRepository.cs— 관리자 전용 쿼리 (ByEmail, ByAdminCode, EmailExists)IDeviceRepository.cs— 디바이스 전용 쿼리 (ByServiceAndToken, ActiveCount, ByPlatform)IMessageRepository.cs— 메시지 전용 쿼리 (ByMessageCode)IPushLogRepository.cs— 발송 로그 전용 쿼리 (ByMessageId, Failed, BatchAdd, CountByStatus)IFileRepository.cs— 파일 전용 쿼리 (ByFileName, FileExists)IStatRepository.cs— 통계 전용 쿼리 (ByServiceAndDate, ByDateRange)- 빌드 성공 확인
Issue #4 — 공통 응답 포맷 및 에러 코드 구현
제목: [Feature] ApiResponse<T> 공통 응답 포맷 구현
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#14-api-response
Gitea Issue: #14
상태: ✅ 완료 (PR #15 머지됨)
설명: 모든 API에서 사용할 통일된 응답 포맷과 에러 코드 체계를 구현한다.
체크리스트:
SPMS.Domain/Common/ApiResponse.cs— 공통 응답 래퍼 (result, code, msg, data)ApiResponse<T>.Success(data)정적 팩토리 메서드ApiResponse<T>.Fail(code, msg)정적 팩토리 메서드SPMS.Domain/Common/ErrorCodes.cs— 에러 코드 상수 클래스 (Issue #10에서 구현 완료)- Error_Codes.md 기반 전체 에러 코드 매핑 (Issue #10에서 구현 완료)
- 빌드 성공 확인
Issue #5 — SpmsException 및 글로벌 예외 처리 미들웨어
제목: [Feature] SpmsException 및 글로벌 예외 처리 미들웨어
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#16-exception-handling
Gitea Issue: #16
상태: ✅ 완료 (PR #17 머지됨)
설명: 비즈니스 예외 클래스와 모든 예외를 ApiResponse 형태로 변환하는 글로벌 미들웨어를 구현한다.
📌 참조:
Documents/ProgramSetup.md§7 (미들웨어 파이프라인 순서) 및 §8.1 (ExceptionMiddleware 구현 가이드) 필독
체크리스트:
SPMS.Domain/Exceptions/SpmsException.cs— 커스텀 비즈니스 예외- ErrorCode, Message 프로퍼티
- HTTP 상태 코드 매핑
SPMS.API/Middlewares/ExceptionMiddleware.cs- SpmsException → ApiResponse.Fail() 변환
- 예상치 못한 예외 → 104 (서버 내부 오류) 변환
- Serilog 로깅 연동
- Program.cs에 미들웨어 등록 (파이프라인 순서 1번)
- 빌드 성공 확인
Issue #6 — Generic Repository 및 UnitOfWork 구현
제목: [Feature] Generic Repository 및 UnitOfWork 패턴 구현
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#18-repository-pattern
Gitea Issue: #18
상태: ✅ 완료 (PR #19 머지됨)
설명: Infrastructure 레이어에 Generic Repository와 UnitOfWork 패턴을 구현한다.
체크리스트:
SPMS.Infrastructure/Persistence/Repositories/Repository.cs— IRepository 구현- GetByIdAsync, GetAllAsync, FindAsync
- AddAsync, Update, Delete (Soft Delete)
- 페이징 지원 (Skip/Take)
SPMS.Infrastructure/Persistence/UnitOfWork.cs— IUnitOfWork 구현- SaveChangesAsync, BeginTransactionAsync
- DI 등록 (AddScoped)
- 빌드 성공 확인
Issue #7 — JWT 인증 모듈 구현
제목: [Feature] JWT 인증 모듈 구현 (Access + Refresh Token)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#20-jwt-auth
Gitea Issue: #20
상태: ✅ 완료 (PR #21 머지됨)
설명: JWT 기반 인증 체계를 구현한다. Access Token과 Refresh Token을 지원한다.
📌 참조:
Documents/ProgramSetup.md§6 (JWT 인증/인가 설정) 및 §7 (파이프라인 순서 10~11번) 필독
체크리스트:
SPMS.Application/Interfaces/IJwtService.cs— JWT 서비스 인터페이스SPMS.Application/Settings/JwtSettings.cs— JWT 설정 POCO (Options Pattern)SPMS.Infrastructure/Auth/JwtService.cs— JWT 생성/검증 구현- Access Token 생성 (Claim: AdminId, Role, ServiceCode)
- Access Token 검증
- Refresh Token 생성 (랜덤 문자열)
SPMS.API/Extensions/AuthenticationExtensions.cs— AddJwtAuthentication, AddAuthorizationPolicies 확장 메서드- appsettings JwtSettings 바인딩 (SecretKey, Issuer, Audience, ExpiryMinutes, RefreshTokenExpiryDays)
- Program.cs에 Authentication/Authorization 서비스 등록 (파이프라인 순서 10~11번)
- NuGet 패키지 추가 (System.IdentityModel.Tokens.Jwt, Microsoft.AspNetCore.Authentication.JwtBearer)
[Authorize],[AllowAnonymous]어트리뷰트 적용 준비- 빌드 성공 확인
Issue #8 — Serilog 구조적 로깅 설정
제목: [Feature] Serilog 구조적 로깅 설정
Labels: Type/Feature, Priority/Medium, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#22-serilog-logging
Gitea Issue: #22
상태: ✅ 완료 (PR #23 머지됨)
설명: Serilog를 활용한 구조적 로깅을 설정한다.
📌 참조:
Documents/ProgramSetup.md§7 (파이프라인 순서 3~4번) 및 §8.3 (RequestIdMiddleware) 필독
체크리스트:
- appsettings.json Serilog 섹션 설정
- Console Sink (Development)
- File Sink (Rolling, 일별)
SPMS.API/Middlewares/RequestIdMiddleware.cs— X-Request-ID 헤더 발급/반환UseSerilogRequestLogging()내장 미들웨어 등록 (파이프라인 순서 4번)- Program.cs에 Serilog 호스트 빌더 설정
- 환경별 로그 레벨 분리 (Development: Debug, Production: Warning)
Issue #9 — Health Check 엔드포인트 구현
제목: [Feature] Health Check 엔드포인트 구현
Labels: Type/Feature, Priority/Medium, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#24-health-check
Gitea Issue: #24
상태: ✅ 완료 (PR #25 머지됨)
설명: 시스템 주요 연동 구간의 상태를 확인하는 Health Check API를 구현한다. (HCK-01)
체크리스트:
SPMS.API/Controllers/PublicController.cs생성POST /v1/out/health엔드포인트- MariaDB 연결 확인 (SELECT 1)
- Redis PING 확인 (미설정 시 스킵)
- RabbitMQ 연결 확인 (미설정 시 스킵)
- 정상: HTTP 200 + ApiResponse.Success
- 이상: HTTP 503 + 상세 상태 JSON
Issue #10 — DI 컨테이너 및 서비스 등록 구조화
제목: [Feature] DI 컨테이너 및 서비스 등록 구조화
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#26-di-setup
Gitea Issue: #26
상태: ✅ 완료 (PR #27 머지됨)
설명: Program.cs의 DI 등록을 레이어별 확장 메서드로 분리하여 구조화한다.
📌 참조:
Documents/ProgramSetup.md§3 (전체 구조), §5 (DI 등록), §7 (UseMiddlewarePipeline) 필독
체크리스트:
SPMS.Infrastructure/DependencyInjection.cs— AddInfrastructure() 확장 메서드- DbContext, Repository, UnitOfWork, JwtService 등록
SPMS.Application/DependencyInjection.cs— AddApplication() 확장 메서드- Application Service 등록
SPMS.API/Extensions/ApplicationBuilderExtensions.cs— UseMiddlewarePipeline() 확장 메서드- Program.cs 정리
builder.Services.AddApplication()builder.Services.AddInfrastructure(builder.Configuration)app.UseMiddlewarePipeline()
- 환경별 설정 바인딩 (ConnectionStrings, JwtSettings, RabbitMQ)
Issue #11 — E2EE 암호화 유틸리티 구현
제목: [Feature] E2EE 암호화 유틸리티 구현 (RSA-2048 + AES-256)
Labels: Type/Feature, Priority/High, Status/Done
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#28-e2ee-crypto
Gitea Issue: #28
상태: ✅ 완료 (PR #29 머지됨)
설명: API 키, 인증서 등 민감 데이터 암호화를 위한 유틸리티와 E2EE 요청/응답 처리를 구현한다. (ENC-01, ENC-02, ENC-03)
📌 참조:
Documents/ProgramSetup.md§7.3 — E2EE는 글로벌 미들웨어가 아닌[SecureTransport]Action Filter로 구현 (보안등급 3 엔드포인트만 적용)
체크리스트:
SPMS.Infrastructure/Security/AesEncryption.cs— AES-256 암호화/복호화SPMS.Infrastructure/Security/RsaEncryption.cs— RSA-2048 키 쌍 관리SPMS.Infrastructure/Security/E2EEService.cs— 하이브리드 암복호화- EncryptedKey 복호화 → AES Key 획득
- RequestCipher 복호화 → 평문 데이터
- ResponseCipher 암호화 → 응답 암호문
SPMS.Infrastructure/Security/TimestampValidator.cs— 타임스탬프 검증 (±30초)SPMS.API/Filters/SecureTransportAttribute.cs— Action Filter 구현- Unit Test 작성 (Bad Padding 사전 방지) — 테스트 프로젝트 구축 후 진행
Issue #12 — API Rate Limiting + Swagger UI 구현
제목: [Feature] API Rate Limiting + Swagger UI 구현
Labels: Type/Feature, Priority/Medium, Status/In Progress
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#30-rate-limiting-swagger
Gitea Issue: #30
상태: ✅ 완료 (PR #31 머지됨)
설명: API 요청 속도 제한 미들웨어와 Swagger UI를 구현한다. (RAT-01)
📌 참조:
Documents/ProgramSetup.md§7 (파이프라인 순서 9번, 15번) 필독
체크리스트 — Rate Limiting:
- ASP.NET Core 내장 Rate Limiting (FixedWindow, IP 기반 분당 100회)
- 한도 초과 시 HTTP 429 + 에러코드 106 반환 (ApiResponse 형태)
- Program.cs에 서비스 등록 및 미들웨어 등록 (파이프라인 순서 9번)
체크리스트 — Swagger UI (Swashbuckle):
SPMS.API/Extensions/SwaggerExtensions.cs— AddSwaggerDocumentation() 확장 메서드- 도메인별 API 문서 그룹 (all, public, auth, account, service, device, message, push, stats, file)
- JWT Bearer 인증 UI (Authorize 버튼)
[SwaggerOperation]어노테이션 지원
SPMS.API/Filters/SpmsHeaderOperationFilter.cs— 커스텀 헤더 자동 표시/v1/in/*→ X-Service-Code 헤더/v1/in/device/*→ X-API-KEY 헤더
ApplicationBuilderExtensions.cs— UseSwagger + UseSwaggerUI (개발 환경만)PublicController.cs— GroupName, SwaggerOperation 어노테이션 적용- Swashbuckle.AspNetCore 6.9.0 + Annotations 6.9.0 설치
- Microsoft.AspNetCore.OpenApi 제거 (Swashbuckle과 충돌)
Issue #13 — 서비스 식별 미들웨어 (X-Service-Code / X-API-KEY)
제목: [Feature] X-Service-Code / X-API-KEY 서비스 식별 미들웨어 구현
Labels: Type/Feature, Priority/High, Status/Done
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#32-service-code-middleware
Gitea Issue: #32
상태: ✅ 완료 (PR #33 머지됨)
설명: 멀티테넌시 지원을 위해 X-Service-Code 헤더 기반 서비스 식별 미들웨어와 X-API-KEY 검증 미들웨어를 구현한다.
📌 참조:
Documents/ProgramSetup.md§7 (파이프라인 순서 12~13번) 및 §8.4~8.5 (구현 가이드) 필독
체크리스트:
SPMS.Infrastructure/Persistence/Repositories/ServiceRepository.cs— IServiceRepository 구현SPMS.Infrastructure/DependencyInjection.cs— ServiceRepository DI 등록SPMS.API/Middlewares/ServiceCodeMiddleware.cs— X-Service-Code 헤더 검증, DB 조회, 서비스 상태 확인SPMS.API/Middlewares/ApiKeyMiddleware.cs— X-API-KEY 검증 (SDK/디바이스 전용)ApplicationBuilderExtensions.cs— 미들웨어 파이프라인 12~13번 등록- 공개 API 경로 예외 처리 (
/v1/out/*,/swagger,/health)
Issue #14 — Sandbox 모드 구현
제목: [Feature] Sandbox 모드 구현 (X-SPMS-TEST)
Labels: Type/Feature, Priority/Low, Status/Done
Milestone: Phase 1: 인프라 & 공통 모듈
Branch: feature/#34-sandbox-mode
Gitea Issue: #34
상태: ✅ 완료 (PR #35 머지됨)
설명: 개발/테스트 환경에서 실제 FCM/APNs 발송 없이 동작하는 샌드박스 모드를 구현한다. (SND-01)
📌 참조:
Documents/ProgramSetup.md§7 (파이프라인 순서 14번) 및 §8.6 (SandboxMiddleware) 필독
체크리스트:
SPMS.API/Middlewares/SandboxMiddleware.cs— X-SPMS-TEST 헤더 감지, HttpContext.Items["IsSandbox"] 플래그 저장ApplicationBuilderExtensions.cs— 미들웨어 파이프라인 14번 위치 등록- 빌드 성공 확인
- 샌드박스 모드 시 실제 발송 스킵 로직 (Service 레이어에서 분기) — Push 구현 시 진행
[TEST]태그 로그 기록 — Push 구현 시 진행
Phase 1 이슈 우선순위 및 의존 관계
[Phase 1-1: Domain + DB]
#1 Entity + EF Core + Migration ──┐ (★ 최우선)
#2 Enum 정의 ─────────────────────┤
#3 Interface 정의 ────────────────┘
│
[Phase 1-2: 공통 모듈]
#4 ApiResponse ──────┐
#5 Exception 처리 ───┤
│ │
[Phase 1-3: 인프라] │
#6 Repository 구현 ──┤ (depends on #1, #3)
#7 JWT 인증 ─────────┤
#8 Serilog 로깅 ─────┤
│ │
[Phase 1-4: 미들웨어] │
#10 DI 구조화 ───────┤ (depends on #6, #7)
#9 Health Check ────┤ (depends on #10)
#11 E2EE 암호화 ─────┤
#12 Rate Limiting ───┤
#13 Service Code ────┤ (depends on #1)
#14 Sandbox 모드 ────┘
작업 순서 (권장):
#1(Entity + DB 구축) →#2→#3(Domain Layer 완성)#4→#5(공통 응답/예외 체계)#6(Repository) →#7,#8,#11(병렬 가능)#10(DI 통합)#9,#12,#13,#14(미들웨어/엔드포인트)
3. Phase 2-1: 인증 & 계정 & 서비스 API
목표: Auth, Account, Service 도메인 API를 구현한다.
| # | 이슈 제목 | Type | Priority | 기능 ID / API ID | 상태 |
|---|---|---|---|---|---|
| 1 | [Feature] 관리자 로그인 API | Feature | High | ADM-01 | ✅ |
| 2 | [Feature] 관리자 비밀번호 변경 API | Feature | Medium | ADM-02 | ✅ |
| 3 | [Feature] 세션 자동 만료 체크 | Feature | High | ADM-03 | ✅ |
| 4 | [Feature] 운영자 계정 CRUD API | Feature | Medium | ADM-04~07 | ✅ |
| 5 | [Feature] 감사 로그 조회 API | Feature | Low | LOG-01 | ⬜ |
| 6 | [Feature] 서비스 목록/상태변경 API | Feature | High | SVC-03, SVC-05 | ✅ |
| 7 | [Feature] API Key 발급/재발급 API | Feature | High | SEC-01~02 | ✅ |
| 8 | [Feature] IP 화이트리스트 관리 API | Feature | Medium | SEC-03 | ✅ |
| 9 | [Feature] APNs/FCM 키 등록 및 조회 API | Feature | High | CRT-01~03 | ✅ |
| 10 | [Feature] 서비스 등록 API | Feature | High | API_SPMS_04_SERVICE_01 | ✅ |
| 11 | [Feature] 서비스 수정 API | Feature | High | API_SPMS_04_SERVICE_04 | ✅ |
| 12 | [Feature] 회원가입 API | Feature | High | API_SPMS_02_AUTH_01 | ✅ |
| 13 | [Feature] 이메일 중복 체크 API | Feature | Medium | API_SPMS_02_AUTH_02 | ✅ |
| 14 | [Feature] 이메일 인증 API | Feature | Medium | API_SPMS_02_AUTH_03 | ✅ |
| 15 | [Feature] 비밀번호 찾기 요청 API | Feature | Medium | API_SPMS_03_ACCOUNT_01 | ✅ |
| 16 | [Feature] 비밀번호 재설정 API | Feature | Medium | API_SPMS_03_ACCOUNT_02 | ✅ |
| 17 | [Feature] 내 정보 조회 API | Feature | Medium | API_SPMS_03_ACCOUNT_04 | ✅ |
| 18 | [Feature] 내 정보 수정 API | Feature | Medium | API_SPMS_03_ACCOUNT_05 | ✅ |
| 19 | [Feature] 서비스 삭제 API | Feature | Medium | API_SPMS_04_SERVICE_05 | ✅ |
| 20 | [Feature] 서비스 태그 목록/수정 API | Feature | Medium | API_SPMS_04_SERVICE_10~11 | ✅ |
| 21 | [Improvement] X-Service-Code 미들웨어 경로 제외 수정 | Improvement | High | - | ✅ |
| 22 | [Chore] DB 스키마 문서 동기화 + Admin EF 설정 보완 | Chore | Medium | - | ✅ |
| 23 | [Improvement] Message Entity link_type 컬럼 추가 | Improvement | Medium | - | ✅ |
⚠️ 누락 항목 추가 (2026-02-10): API_Specification.md 기준으로 TASKS.md에 없던 항목들 보완
- 서비스 등록/수정/삭제 API: API_Specification.md §4 Service API 참조
- 서비스 태그 API: API_Specification.md §4 SERVICE_10~11
- Auth API: signup, email/check, email/verify (API_Specification.md §2 Auth API)
- Account API: password/forgot, password/reset, profile/info, profile/update (API_Specification.md §3 Account API)
Issue #1 — 관리자 로그인 API (ADM-01)
제목: [Feature] 관리자 로그인 API (ADM-01)
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#36-admin-login
Gitea Issue: #36
상태: ✅ 완료 (PR #37 머지됨)
설명: JWT 기반 관리자 로그인 API를 구현한다. Access Token과 Refresh Token을 발급한다.
체크리스트 — Application Layer:
SPMS.Application/DTOs/Auth/LoginRequestDto.cs— 로그인 요청 DTOSPMS.Application/DTOs/Auth/LoginResponseDto.cs— 로그인 응답 DTOSPMS.Application/Interfaces/IAuthService.cs— 인증 서비스 인터페이스SPMS.Application/Services/AuthService.cs— 로그인 비즈니스 로직
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Persistence/Repositories/AdminRepository.cs— IAdminRepository 구현
체크리스트 — API Layer:
SPMS.API/Controllers/AuthController.cs— 인증 컨트롤러POST /v1/in/auth/login엔드포인트 구현- Swagger 어노테이션 적용
체크리스트 — 검증:
- 빌드 성공 확인
- Swagger UI 테스트
- 에러 케이스 확인
Issue #2 — 세션 자동 만료 체크 및 토큰 관리 API (ADM-03)
제목: [Feature] 세션 자동 만료 체크 및 토큰 관리 API (ADM-03)
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#38-session-token-management
Gitea Issue: #38
상태: ✅ 완료 (PR #39 머지됨)
설명: Refresh Token을 사용한 토큰 갱신 및 로그아웃 API를 구현한다.
체크리스트 — Application Layer:
SPMS.Application/DTOs/Auth/TokenRefreshRequestDto.cs— 토큰 갱신 요청 DTOSPMS.Application/DTOs/Auth/TokenRefreshResponseDto.cs— 토큰 갱신 응답 DTOSPMS.Application/Interfaces/IAuthService.cs— RefreshTokenAsync, LogoutAsync 추가SPMS.Application/Services/AuthService.cs— 토큰 갱신/로그아웃 로직 구현
체크리스트 — Infrastructure Layer:
SPMS.Domain/Interfaces/IAdminRepository.cs— GetByRefreshTokenAsync 추가SPMS.Infrastructure/Persistence/Repositories/AdminRepository.cs— GetByRefreshTokenAsync 구현
체크리스트 — API Layer:
SPMS.API/Controllers/AuthController.cs— token/refresh, logout 엔드포인트POST /v1/in/auth/token/refresh— 토큰 갱신 (AllowAnonymous)POST /v1/in/auth/logout— 로그아웃 (Authorize)- Swagger 어노테이션 적용
체크리스트 — 검증:
- 빌드 성공 확인
- Swagger UI 테스트
- 에러 케이스 확인
Issue #3 — 관리자 비밀번호 변경 API (ADM-02)
제목: [Feature] 관리자 비밀번호 변경 API (ADM-02)
Labels: Type/Feature, Priority/Medium, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#40-change-password
Gitea Issue: #40
상태: ✅ 완료 (PR #41 머지됨)
설명: 인증된 관리자가 자신의 비밀번호를 변경할 수 있는 API를 구현한다.
체크리스트 — Application Layer:
SPMS.Application/DTOs/Auth/ChangePasswordRequestDto.cs— 비밀번호 변경 요청 DTOSPMS.Application/Interfaces/IAuthService.cs— ChangePasswordAsync 추가SPMS.Application/Services/AuthService.cs— 비밀번호 변경 로직 구현
체크리스트 — API Layer:
SPMS.API/Controllers/AuthController.cs— password/change 엔드포인트POST /v1/in/auth/password/change— 비밀번호 변경 (Authorize)- Swagger 어노테이션 적용
체크리스트 — 검증:
- 빌드 성공 확인
- 현재 비밀번호 검증 로직
- 새 비밀번호 BCrypt 해싱
Issue #4 — 운영자 계정 CRUD API (ADM-04~07)
제목: [Feature] 운영자 계정 CRUD API (ADM-04~07)
Labels: Type/Feature, Priority/Medium, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#42-account-crud
Gitea Issue: #42
상태: ✅ 완료 (PR #43 머지됨)
설명: Super Admin이 운영자(Manager/User) 계정을 생성, 조회, 수정, 삭제할 수 있는 API를 구현한다.
체크리스트 — Application Layer:
SPMS.Application/DTOs/Account/CreateAccountRequestDto.csSPMS.Application/DTOs/Account/UpdateAccountRequestDto.csSPMS.Application/DTOs/Account/AccountResponseDto.csSPMS.Application/DTOs/Account/AccountListRequestDto.csSPMS.Application/DTOs/Account/AccountListResponseDto.csSPMS.Application/Interfaces/IAccountService.csSPMS.Application/Services/AccountService.cs
체크리스트 — API Layer:
SPMS.API/Controllers/AccountController.csPOST /v1/in/account/create— 운영자 생성POST /v1/in/account/list— 운영자 목록 조회POST /v1/in/account/{adminCode}— 운영자 상세 조회POST /v1/in/account/{adminCode}/update— 운영자 수정POST /v1/in/account/{adminCode}/delete— 운영자 삭제
체크리스트 — 검증:
- Super Admin만 접근 가능 (Role 체크)
- 이메일 중복 검사
- BCrypt 비밀번호 해싱
- Soft Delete 처리
- 빌드 성공 확인
Issue #10 — 서비스 등록 API (API_SPMS_04_SERVICE_01)
제목: [Feature] 서비스 등록 API
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#52-service-create
Gitea Issue: #52
상태: ✅ 완료 (PR #53 머지됨)
설명: 새로운 서비스(프로젝트)를 등록하는 API를 구현한다. API_Specification.md §4 참조.
체크리스트:
SPMS.Application/DTOs/Service/CreateServiceRequestDto.csSPMS.Application/DTOs/Service/CreateServiceResponseDto.csSPMS.Application/Interfaces/IServiceManagementService.cs— CreateAsync 추가SPMS.Application/Services/ServiceManagementService.cs— 서비스 생성 로직 구현POST /v1/in/service/create엔드포인트- ServiceCode 자동 생성 (NanoID 8자리)
- API Key 자동 생성 (48자 Base64)
- ServiceName 중복 검사 (에러코드 107)
- 빌드 성공 확인
Issue #11 — 서비스 수정 API (API_SPMS_04_SERVICE_04)
제목: [Feature] 서비스 수정 API
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#54-service-update
Gitea Issue: #54
상태: ✅ 완료 (PR #55 머지됨)
설명: 기존 서비스 정보를 수정하는 API. API_Specification.md §4 참조.
체크리스트:
SPMS.Application/DTOs/Service/UpdateServiceRequestDto.csSPMS.Application/Interfaces/IServiceManagementService.cs— UpdateAsync 추가SPMS.Application/Services/ServiceManagementService.cs— 수정 로직 구현POST /v1/in/service/update엔드포인트- ServiceName 변경 시 중복 검사
- 변경 사항 없으면 NoChange 에러
- 빌드 성공 확인
Issue #12 — 회원가입 API (API_SPMS_02_AUTH_01) ⬜ 누락
제목: [Feature] 회원가입 API
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#XX-auth-signup
상태: ⬜ 대기
설명: 신규 관리자 회원가입 API. API_Specification.md §2.1 참조.
체크리스트:
SPMS.Application/DTOs/Auth/SignupRequestDto.csSPMS.Application/DTOs/Auth/SignupResponseDto.csSPMS.Application/Interfaces/IAuthService.cs— SignupAsync 추가POST /v1/in/auth/signup엔드포인트- BCrypt 비밀번호 해싱
- 이메일 중복 검사
- 빌드 성공 확인
Issue #13 — 이메일 중복 체크 API (API_SPMS_02_AUTH_02) ⬜ 누락
제목: [Feature] 이메일 중복 체크 API
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#XX-auth-email-check
상태: ⬜ 대기
체크리스트:
POST /v1/in/auth/email/check엔드포인트- 이메일 존재 여부 반환
Issue #14 — 이메일 인증 API (API_SPMS_02_AUTH_03)
제목: [Feature] 이메일 인증 인프라 및 API 구현
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#64-email-verify
Gitea Issue: #64
상태: ✅ 완료 (PR #65 머지됨)
체크리스트:
SPMS.Application/Interfaces/ITokenStore.cs— 토큰 저장소 인터페이스SPMS.Application/Interfaces/IEmailService.cs— 이메일 서비스 인터페이스SPMS.Infrastructure/Services/InMemoryTokenStore.cs— IMemoryCache 기반 구현SPMS.Infrastructure/Services/ConsoleEmailService.cs— 콘솔 로그 기반 구현SPMS.Application/DTOs/Auth/EmailVerifyRequestDto.cs— 요청 DTOAuthService.SignupAsync— 인증 코드 생성/저장/발송 추가AuthService.VerifyEmailAsync— 인증 코드 검증 구현POST /v1/in/auth/email/verify엔드포인트- DI 등록 (ITokenStore, IEmailService, MemoryCache)
Issue #15+#16 — 비밀번호 찾기/재설정 API (API_SPMS_03_ACCOUNT_01~02)
제목: [Feature] 비밀번호 찾기/재설정 API 구현
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#66-password-reset
Gitea Issue: #66
상태: ✅ 완료 (PR #67 머지됨)
체크리스트:
SPMS.Application/DTOs/Account/PasswordForgotRequestDto.cs— 요청 DTOSPMS.Application/DTOs/Account/PasswordResetRequestDto.cs— 요청 DTOSPMS.API/Controllers/PasswordController.cs— 비밀번호 컨트롤러AuthService.ForgotPasswordAsync— 재설정 토큰 생성/발송AuthService.ResetPasswordAsync— 토큰 검증/비밀번호 변경POST /v1/in/account/password/forgot엔드포인트POST /v1/in/account/password/reset엔드포인트
Issue #17+#18 — 내 정보 조회/수정 API (API_SPMS_03_ACCOUNT_04~05)
제목: [Feature] 내 정보 조회/수정 API 구현
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#62-profile-api
Gitea Issue: #62
상태: ✅ 완료 (PR #63 머지됨)
체크리스트:
SPMS.Application/DTOs/Account/ProfileResponseDto.cs— 응답 DTOSPMS.Application/DTOs/Account/UpdateProfileRequestDto.cs— 수정 요청 DTOSPMS.API/Controllers/ProfileController.cs— 프로필 컨트롤러 ([Authorize])AuthService.GetProfileAsync— 프로필 조회AuthService.UpdateProfileAsync— 프로필 수정 (name, phone)POST /v1/in/account/profile/info엔드포인트POST /v1/in/account/profile/update엔드포인트
Issue #19 — 서비스 삭제 API (API_SPMS_04_SERVICE_05)
제목: [Feature] 서비스 삭제 API (SERVICE_05)
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#68-service-delete
Gitea Issue: #68
PR: #69
상태: ✅ 완료 (PR #69 머지됨)
설명: 서비스를 삭제(Soft Delete)하는 API를 구현한다. API_Specification.md §4 SERVICE_05 참조.
체크리스트:
SPMS.Application/DTOs/Service/DeleteServiceRequestDto.cs— 요청 DTO 생성SPMS.Application/Interfaces/IServiceManagementService.cs— DeleteAsync 추가SPMS.Application/Services/ServiceManagementService.cs— 삭제 로직 구현 (Soft Delete)SPMS.API/Controllers/ServiceController.cs—POST /v1/in/service/delete엔드포인트- Soft Delete (IsDeleted, DeletedAt) + Status=Suspended
- 빌드 성공 확인
Issue #20 — 서비스 태그 목록/수정 API (API_SPMS_04_SERVICE_10~11)
제목: [Feature] 서비스 태그 목록/수정 API (SERVICE_10~11)
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: feature/#70-service-tags
Gitea Issue: #70
PR: #71
상태: ✅ 완료 (PR #71 머지됨)
설명: 서비스의 태그 목록 조회 및 수정 API를 구현한다. API_Specification.md §4 SERVICE_10~11 참조.
체크리스트:
SPMS.Application/DTOs/Service/ServiceTagsRequestDto.cs— 태그 조회 요청 DTOSPMS.Application/DTOs/Service/UpdateServiceTagsRequestDto.cs— 태그 수정 요청 DTO (최대 10개)SPMS.Application/DTOs/Service/ServiceTagsResponseDto.cs— 태그 응답 DTO (tag_index + tag_name)SPMS.Application/Interfaces/IServiceManagementService.cs— GetTagsAsync, UpdateTagsAsync 추가SPMS.Application/Services/ServiceManagementService.cs— 태그 JSON 파싱/직렬화 로직 구현SPMS.API/Controllers/ServiceController.cs—POST tags/list,POST tags/update엔드포인트- 빌드 성공 확인
Issue #21 — DB 스키마 문서 동기화 + Admin EF 설정 보완 ✅
제목: [Chore] DB 스키마 문서 동기화 + Admin EF 설정 보완
Labels: Type/Chore, Priority/Medium, Status/Available
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: chore/#72-db-schema-sync
Gitea Issue: #72
PR: #73
상태: ✅ 완료 (PR #73 머지됨)
설명: DB_Schema.md와 실제 코드 간 불일치를 해소한다.
불일치 내역:
- Admin 테이블:
RefreshToken,RefreshTokenExpiresAt2개 컬럼이 코드에만 있고 문서에 없음 (13→15 컬럼) - AdminConfiguration.cs: 위 2개 컬럼의 명시적 EF 설정이 누락됨 (자동 매핑되지만 명시적 설정 필요)
- DB_Schema.md 총 테이블 수: "16개"로 표기되어 있으나 실제 구현 12개 + 예정 4개 구분 필요
체크리스트:
Documents/DB_Schema.md— Admin 테이블에refresh_token VARCHAR(255),refresh_token_expires_at DATETIME추가 (13→15 컬럼)Documents/DB_Schema.md— 총 테이블 수 명확화 (구현 12 + 예정 4)AdminConfiguration.cs— RefreshToken, RefreshTokenExpiresAt 명시적 Fluent API 설정 추가- 빌드 성공 확인
Issue #22 — Message Entity link_type 컬럼 추가 ✅
제목: [Improvement] Message Entity link_type 컬럼 추가
Labels: Type/Improvement, Priority/Medium, Status/In Progress
Milestone: Phase 2-1: 인증 & 계정 & 서비스 API
Branch: improvement/#74-message-linktype
Gitea Issue: #74
PR: #75
상태: ✅ 완료 (PR #75 머지됨)
설명: DB_Schema.md에 정의된 Message.link_type 컬럼이 Entity/Configuration에 누락되어 있으므로 추가한다.
불일치 내역:
- DB_Schema.md:
link_type VARCHAR(20)— 링크 유형 (deeplink, web, none) - Message.cs: LinkType 프로퍼티 없음
- MessageConfiguration.cs: LinkType 설정 없음
체크리스트:
SPMS.Domain/Entities/Message.cs—LinkType프로퍼티 추가SPMS.Infrastructure/Persistence/Configurations/MessageConfiguration.cs— LinkType 설정 추가- EF Core Migration 생성 (
AddMessageLinkType) - DB 적용 (
dotnet ef database update) - 빌드 성공 확인
4. Phase 2-2: Public & 디바이스 & 파일 API
목표: Public, Device, File 도메인 API를 구현한다.
| # | 이슈 제목 | Type | Priority | 기능 ID / API ID | 상태 |
|---|---|---|---|---|---|
| 0 | [Feature] Public Entity + Migration (Notice, Banner, FAQ, AppConfig) | Feature | High | (선행) | ✅ |
| 1 | [Feature] 공지사항 목록/상세 API | Feature | Low | PUBLIC_01~02 | ✅ |
| 2 | [Feature] 배너 목록 API | Feature | Low | PUBLIC_03 | ✅ |
| 3 | [Feature] FAQ 목록 API | Feature | Low | PUBLIC_04 | ✅ |
| 4 | [Feature] 이용약관/개인정보처리방침 API | Feature | Low | PUBLIC_05~06 | ✅ |
| 5 | [Feature] 앱 버전 체크 API | Feature | Medium | PUBLIC_07 | ✅ |
| 6 | [Feature] 앱 기본 설정 API | Feature | Medium | PUBLIC_08 | ✅ |
| 6-1 | [Bug] Public API X-Service-Code 의존성 제거 | Bug | High | PUBLIC_01~08 | ✅ |
| 7 | [Feature] 점검 안내 API | Feature | Low | PUBLIC_10 | ✅ |
| 8 | [Feature] 디바이스 CRUD + 목록 API | Feature | High | DEVICE_01~04, 07 | ✅ |
| 9 | [Feature] 디바이스 태그/동의 설정 API | Feature | Medium | DEVICE_05~06 | ✅ |
| 10 | [Feature] 파일 업로드/조회/삭제 API | Feature | Medium | FILE_01~04 | ✅ |
| 11 | [Feature] CSV 검증/템플릿 다운로드 API | Feature | Medium | FILE_05~06 | ✅ |
⚠️ Phase 2-2 변경 이력 (2026-02-10):
- 추가: #0 Public Entity + Migration (선행 이슈) — Notice, Banner, FAQ, AppConfig 엔티티 및 DB 마이그레이션
- 삭제:
CAL-01~02 (필터 속성/모수 계산)→ Document_Consistency_Analysis.md: FLT 삭제에 따라 제거- 삭제:
FLT-01~03 (필터 그룹 CRUD)→ Document_Consistency_Analysis.md: 태그 기반 발송으로 대체- 삭제:
TST-01 (테스터 기기 관리)→ Document_Consistency_Analysis.md: Device.is_tester 플래그로 대체- 재구성: 디바이스 API를 API_Specification.md 기준 2개 이슈로 재분류 (CRUD+목록 / 태그+동의)
Phase 2-2 의존관계
[Phase 2-2 의존관계]
#0 Entity + Migration ──┬── #1 공지사항 API
├── #2 배너 API
├── #3 FAQ API
├── #4 약관/정책 API
├── #5 앱 버전 API
├── #6 앱 설정 API
└── #7 점검 API
#8 디바이스 CRUD ────────┬── #9 태그/동의 API
#10 파일 CRUD ───────────┬── #11 CSV API
Issue #0 — Public Entity + Migration (선행 이슈)
제목: [Feature] Public API Entity 정의 및 DB 스키마 구축 (Notice, Banner, FAQ, AppConfig)
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 2-2: Public & 디바이스 & 파일 API
Branch: feature/#76-public-entities
Gitea Issue: #76
PR: #77
상태: ✅ 완료 (PR #77 머지됨)
설명: DB_Schema.md에 정의된 Public API 관련 4개 테이블(Notice, Banner, FAQ, AppConfig)의 Entity를 생성하고 EF Core Configuration + Migration을 적용한다. Phase 2-2 Public API #1~#7 전체의 선행 작업.
체크리스트 — Domain Entity (SPMS.Domain/Entities/):
Notice.cs— 공지사항 (10 컬럼: Id, ServiceId, Title, Content, IsPinned, IsActive, CreatedAt, CreatedBy, UpdatedAt, IsDeleted)Banner.cs— 배너 (12 컬럼: Id, ServiceId, Title, ImageUrl, LinkUrl, LinkType, Position, SortOrder, IsActive, CreatedAt, UpdatedAt, IsDeleted)Faq.cs— FAQ (9 컬럼: Id, ServiceId, Category, Question, Answer, SortOrder, IsActive, CreatedAt, UpdatedAt)AppConfig.cs— 앱 설정 (6 컬럼: Id, ServiceId, ConfigKey, ConfigValue, CreatedAt, UpdatedAt)
체크리스트 — EF Core Configuration (SPMS.Infrastructure/Persistence/Configurations/):
NoticeConfiguration.cs— Soft Delete 글로벌 필터 적용BannerConfiguration.cs— Soft Delete 글로벌 필터 적용FaqConfiguration.csAppConfigConfiguration.cs— (ServiceId, ConfigKey) 복합 인덱스
체크리스트 — AppDbContext + Migration:
AppDbContext.cs에 DbSet 4개 추가 (Notices, Banners, Faqs, AppConfigs)- 마이그레이션 생성 (
AddPublicApiTables) - DB 적용 및 테이블 생성 확인
- 빌드 성공 확인
⚠️ 블로킹: 이 이슈가 완료되어야 Phase 2-2 Public API #1~#7을 구현할 수 있음
5. Phase 3: 메시지 & Push Core
목표: Message, Push 도메인 API와 RabbitMQ Worker를 구현한다.
📌 참조 문서:
Documents/RabbitMQ_Design.md,Documents/BatchScheduler_Design.md
Message API (API Spec §6)
| # | 이슈 제목 | API ID | URI | Priority | 상태 |
|---|---|---|---|---|---|
| 1 | [Feature] 메시지 저장 API | 06_01 | /v1/in/message/save |
High | ⬜ |
| 2 | [Feature] 메시지 목록 조회 API | 06_02 | /v1/in/message/list |
High | ⬜ |
| 3 | [Feature] 메시지 상세 조회 API | 06_03 | /v1/in/message/info |
High | ⬜ |
| 4 | [Feature] 메시지 삭제 API | 06_04 | /v1/in/message/delete |
Medium | ⬜ |
| 5 | [Feature] 메시지 미리보기 API | 06_05 | /v1/in/message/preview |
Medium | ✅ |
Push API (API Spec §7)
| # | 이슈 제목 | API ID | URI | Priority | 상태 |
|---|---|---|---|---|---|
| 6 | [Feature] 단건 발송 API | 07_01 | /v1/in/push/send |
Urgent | ✅ |
| 7 | [Feature] 태그 발송 API | 07_02 | /v1/in/push/send/tag |
Urgent | ✅ |
| 8 | [Feature] 대용량 발송 API (CSV) | 07_03 | /v1/in/push/send/bulk |
Medium | ✅ |
| 9 | [Feature] 발송 상태 조회 API | 07_04 | /v1/in/push/job/status |
Medium | ✅ |
| 10 | [Feature] 발송 취소 API | 07_05 | /v1/in/push/job/cancel |
Low | ✅ |
| 11 | [Feature] 발송 로그 조회 API | 07_06 | /v1/in/push/log |
Medium | ✅ |
| 12 | [Feature] 예약 발송 API | 07_07 | /v1/in/push/schedule |
High | ✅ |
| 13 | [Feature] 예약 취소 API | 07_08 | /v1/in/push/schedule/cancel |
High | ✅ |
인프라 (Worker / MQ / Redis)
| # | 이슈 제목 | Priority | 상태 |
|---|---|---|---|
| 14 | [Feature] RabbitMQ 인프라 설정 | Urgent | ✅ |
| 15 | [Feature] PushWorker 구현 | Urgent | ✅ |
| 16 | [Feature] ScheduleWorker 구현 | High | ✅ |
| 17 | [Feature] FCM 발송 모듈 구현 | Urgent | ✅ |
| 18 | [Feature] APNs 발송 모듈 구현 | Urgent | ✅ |
| 19 | [Feature] Redis 중복 발송 방지 | High | ✅ |
기타 (Feature_Spec 전용 — API Spec 미정의)
| # | 이슈 제목 | 기능 ID | 비고 | 상태 |
|---|---|---|---|---|
| 20 | [Feature] 메시지 유효성 검사 | HPR-03 | validate 엔드포인트 구현 완료 | ✅ |
| 21 | UTL-02 | API Spec 미정의 → 후순위 | 🔒 보류 | |
| 22 | ACT-05 | API Spec 미정의 → 후순위 | 🔒 보류 |
⚠️ Phase 3 변경 이력:
- (2026-02-10) 삭제:
TEM-01~04 (템플릿 생성/조회/목록/삭제)→ 템플릿 기능 삭제 결정- (2026-02-10) API Spec 기준 재정비: 딥링크(UTL-02), 재발송(ACT-05) 보류 / 메시지 CRUD(6.1~6.4), 대용량 발송(7.3~7.5) 추가
Issue #8 — RabbitMQ 인프라 설정
제목: [Feature] RabbitMQ 인프라 설정 (Exchange/Queue)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#102-rabbitmq-infrastructure
Gitea Issue: #102
상태: ✅ 완료 (PR #103 머지됨)
설명: RabbitMQ Exchange, Queue 선언 및 연결 설정을 구현한다.
📌 참조:
Documents/RabbitMQ_Design.md§2~3 (Exchange/Queue 정의), §8 (연결 설정)
체크리스트 — 설정:
appsettings.jsonRabbitMQ 섹션 추가- HostName, Port, UserName, Password
- Exchange:
spms.push.exchange - PushQueue:
spms.push.queue - ScheduleQueue:
spms.schedule.queue - PrefetchCount: 10
- MessageTtl: 86400000 (24시간)
체크리스트 — Infrastructure Layer:
SPMS.Application/Settings/RabbitMQSettings.cs— 설정 POCOSPMS.Infrastructure/Messaging/RabbitMQConnection.cs— 연결 관리- ConnectionFactory 설정 (AutomaticRecovery, NetworkRecoveryInterval, RequestedHeartbeat)
- IConnection, IChannel 관리
SPMS.Infrastructure/Messaging/RabbitMQInitializer.cs— Exchange/Queue 선언- Exchange:
spms.push.exchange(Direct, Durable) - Queue:
spms.push.queue(Durable, TTL 24시간) - Queue:
spms.schedule.queue(Durable, TTL 24시간) - Binding:
push→spms.push.queue,schedule→spms.schedule.queue
- Exchange:
SPMS.Infrastructure/DependencyInjection.cs— DI 등록
체크리스트 — 메시지 스키마:
SPMS.Application/DTOs/Push/PushMessageDto.cs— 발송 메시지 스키마- message_id, request_id, service_id, send_type
- title, body, image_url, link_url, custom_data
- target (type, value)
- created_by, created_at
SPMS.Application/DTOs/Push/ScheduleMessageDto.cs— 예약 발송 메시지 스키마- schedule_id, message_id, service_id, scheduled_at
- push_message (PushMessage 포함)
체크리스트 — Producer:
SPMS.Application/Interfaces/IPushQueueService.cs— 큐 발행 인터페이스SPMS.Infrastructure/Messaging/PushQueueService.cs— 큐 발행 구현- PublishPushMessage(PushMessage) →
spms.push.queue - PublishScheduleMessage(ScheduleMessage) →
spms.schedule.queue - DeliveryMode: Persistent
- ContentType: application/json
- PublishPushMessage(PushMessage) →
Issue #9 — PushWorker 구현
제목: [Feature] PushWorker 구현 (RabbitMQ Consumer)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#110-push-worker
Gitea Issue: #110
상태: ✅ 완료 (PR #111 → develop 머지됨)
설명: RabbitMQ spms.push.queue에서 메시지를 소비하여 FCM/APNs로 발송하는 BackgroundService Worker를 구현한다.
📌 참조:
Documents/BatchScheduler_Design.md§2 (PushWorker),Documents/RabbitMQ_Design.md§6.1 (Consumer 설정)
체크리스트 — Worker 구현:
SPMS.Infrastructure/Workers/PushWorker.cs— BackgroundService 상속- RabbitMQ Consumer 설정 (Prefetch 10, Auto Ack false)
- 메시지 수신 → JSON 역직렬화
- Redis 중복 체크 (request_id)
- send_type별 대상 Device 조회 (single, group, broadcast)
- 플랫폼별 분류 (iOS → APNs, Android → FCM)
- 배치 발송 (FcmSender/ApnsSender)
- 결과 처리 (PushSendLog INSERT)
- DailyStat 증분 업데이트
- ACK 전송
체크리스트 — 에러 처리:
- 재시도 정책 구현 (x-retry-count 헤더, 최대 3회)
- FCM/APNs 응답별 처리 (ShouldRemoveDevice → Device 비활성화)
체크리스트 — 등록:
SPMS.Infrastructure/DependencyInjection.cs— AddHostedService() 등록
Issue #10 — ScheduleWorker 구현
제목: [Feature] ScheduleWorker 구현 (예약 발송 스케줄러)
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#112-schedule-worker
Gitea Issue: #112
상태: ✅ 완료 (PR #113 → develop 머지됨)
설명: RabbitMQ spms.schedule.queue에서 예약 메시지를 폴링하여, 예약 시간 도래 시 spms.push.queue로 전달하는 BackgroundService Worker를 구현한다.
📌 참조:
Documents/BatchScheduler_Design.md§3 (ScheduleWorker),Documents/RabbitMQ_Design.md§6.2
체크리스트 — Worker 구현:
SPMS.Infrastructure/Workers/ScheduleWorker.cs— BackgroundService 상속- 30초 간격 폴링 (BasicGet 방식)
- ScheduleMessageDto 역직렬화 → scheduled_at 파싱
- 예약 시간 미도래 → NACK + requeue
- 예약 시간 도래 → push queue에 적재 → ACK
체크리스트 — 등록:
SPMS.Infrastructure/DependencyInjection.cs— AddHostedService() 등록
Issue #11 — FCM 발송 모듈 구현
제목: [Feature] FCM 발송 모듈 구현 (Firebase Cloud Messaging)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#104-fcm-sender
Gitea Issue: #104
상태: ✅ 완료 (PR #105 머지됨)
설명: Firebase Admin SDK를 사용하여 Android 디바이스에 푸시를 발송하는 모듈을 구현한다.
체크리스트 — Application Layer:
SPMS.Application/Interfaces/IFcmSender.cs— FCM 발송 인터페이스- SendAsync(deviceToken, title, body, data) → PushResult
- SendBatchAsync(List, title, body, data) → List
SPMS.Application/DTOs/Push/PushResultDto.cs— 발송 결과 DTO
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Push/FcmSender.cs— Firebase Admin SDK 연동- FirebaseApp 초기화 (Service Account JSON)
- HTTP v1 API 사용
- 배치 발송 (500건 단위)
- 응답 파싱 (success, failure, canonical_ids)
- Service별 Firebase 인스턴스 관리 (멀티테넌시, SHA256 해시 캐싱)
체크리스트 — 에러 처리:
- FCM 응답 코드별 처리 로직
- Unregistered → Device 삭제
- InvalidArgument/SenderIdMismatch → Device 삭제
- Unavailable/Internal/QuotaExceeded → 재시도
Issue #12 — APNs 발송 모듈 구현
제목: [Feature] APNs 발송 모듈 구현 (Apple Push Notification service)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#106-apns-sender
Gitea Issue: #106
상태: ✅ 완료 (PR #107 → develop 머지됨)
설명: Apple Push Notification service를 사용하여 iOS 디바이스에 푸시를 발송하는 모듈을 구현한다.
체크리스트 — Application Layer:
SPMS.Application/Interfaces/IApnsSender.cs— APNs 발송 인터페이스- SendAsync(deviceToken, title, body, data) → PushResult
- SendBatchAsync(List, title, body, data) → List
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Push/ApnsSender.cs— APNs HTTP/2 연동- JWT 토큰 생성 (.p8 Private Key, Key ID, Team ID)
- HTTP/2 클라이언트 (IHttpClientFactory, SocketsHttpHandler)
- 배치 발송 (500건 단위, 동시 50건)
- 응답 파싱 (APNs reason)
- Service별 APNs 설정 관리 (Bundle ID, Key ID, Team ID — 인터페이스 파라미터로 전달)
체크리스트 — 에러 처리:
- APNs 응답 코드별 처리 로직
- 410 Unregistered → Device 삭제
- 400 BadDeviceToken/DeviceTokenNotForTopic → Device 삭제
- 503/429 → 재시도
Issue #13 — Redis 중복 발송 방지
제목: [Feature] Redis 중복 발송 방지 구현
Labels: Type/Feature, Priority/High, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#108-redis-duplicate-check
Gitea Issue: #108
상태: ✅ 완료 (PR #109 → develop 머지됨)
설명: Redis를 사용하여 중복 발송을 방지하는 로직을 구현한다.
📌 참조:
Documents/BatchScheduler_Design.md§2 처리 흐름 [1] Redis 중복 체크
체크리스트 — Application Layer:
SPMS.Application/Settings/RedisSettings.cs— Redis 설정 POCOSPMS.Application/Interfaces/IDuplicateChecker.cs— 중복 체크 인터페이스
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Caching/RedisConnection.cs— Redis 연결 관리- StackExchange.Redis 사용
- ConnectionMultiplexer 싱글톤 관리
SPMS.Infrastructure/Caching/DuplicateChecker.cs— 중복 체크 로직- Key 형식:
{InstanceName}duplicate:{request_id} - TTL: 24시간
- SetNX (SET if Not eXists) 사용
- 이미 존재하면 → 중복으로 판단, 스킵
- 없으면 → 키 생성 후 처리 진행
- Key 형식:
체크리스트 — 설정:
appsettings.jsonRedis 섹션SPMS.Infrastructure/DependencyInjection.cs— DI 등록SPMS.Infrastructure/SPMS.Infrastructure.csproj— StackExchange.Redis 2.10.14 추가
Issue #5 — 즉시 발송 요청 API
제목: [Feature] 즉시 발송 요청 API (단건/태그)
Labels: Type/Feature, Priority/Urgent, Status/In Progress
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#114-push-send-api
Gitea Issue: #114
상태: ✅ 완료 (PR #115 → develop 머지됨)
설명: 단건 발송(device_id)과 태그 발송(tags) API를 구현한다.
📌 참조:
Documents/API_Specification.md§7.1~7.2
체크리스트 — Application Layer:
SPMS.Application/DTOs/Push/PushSendRequestDto.cs— 단건 발송 요청 DTOSPMS.Application/DTOs/Push/PushSendTagRequestDto.cs— 태그 발송 요청 DTOSPMS.Application/DTOs/Push/PushSendResponseDto.cs— 발송 응답 DTOSPMS.Application/Interfaces/IPushService.cs— 푸시 서비스 인터페이스SPMS.Application/Services/PushService.cs— 푸시 서비스 구현SPMS.Application/DependencyInjection.cs— DI 등록
체크리스트 — Domain Layer:
SPMS.Domain/Common/ErrorCodes.cs— MessageNotFound(151) 추가
체크리스트 — API Layer:
SPMS.API/Controllers/PushController.cs— send, send/tag 엔드포인트
Issue #6 — 예약 발송 등록/취소 API
제목: [Feature] 예약 발송 등록/취소 API
Labels: Type/Feature, Priority/High, Status/Done
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#116-push-schedule-api
Gitea Issue: #116
상태: ✅ 완료 (PR #117 → develop 머지됨)
설명: 예약 발송 등록 및 취소 API를 구현한다. 예약 취소는 Redis 기반 취소 플래그 방식.
📌 참조:
Documents/API_Specification.md§7.7~7.8
체크리스트 — Application Layer:
SPMS.Application/DTOs/Push/PushScheduleRequestDto.cs— 예약 발송 요청 DTOSPMS.Application/DTOs/Push/PushScheduleCancelRequestDto.cs— 예약 취소 요청 DTOSPMS.Application/DTOs/Push/PushScheduleResponseDto.cs— 예약 응답 DTOSPMS.Application/Interfaces/IScheduleCancelStore.cs— 취소 저장소 인터페이스SPMS.Application/Interfaces/IPushService.cs— ScheduleAsync, CancelScheduleAsync 추가SPMS.Application/Services/PushService.cs— 예약 발송/취소 로직 구현
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Caching/ScheduleCancelStore.cs— Redis 기반 취소 플래그 (7일 TTL)SPMS.Infrastructure/Workers/ScheduleWorker.cs— 취소 체크 로직 추가SPMS.Infrastructure/DependencyInjection.cs— IScheduleCancelStore DI 등록
체크리스트 — API Layer:
SPMS.API/Controllers/PushController.cs— schedule, schedule/cancel 엔드포인트
Issue #1 — 메시지 유효성 검사
제목: [Feature] 메시지 유효성 검사 서비스 구현
Labels: Type/Feature, Priority/High, Status/Done
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#118-message-validation
Gitea Issue: #118
상태: ✅ 완료 (PR #119 → develop 머지됨)
설명: 메시지 필드(title, body, image_url, link_url, link_type, data) 유효성 검사 서비스를 구현한다.
📌 참조:
Documents/Feature_Spec.mdHPR-03
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessageValidateRequestDto.cs— 검증 요청 DTOSPMS.Application/DTOs/Message/MessageValidationResultDto.cs— 검증 결과 DTOSPMS.Application/Interfaces/IMessageValidationService.cs— 검증 서비스 인터페이스SPMS.Application/Services/MessageValidationService.cs— 검증 로직 구현SPMS.Application/DependencyInjection.cs— DI 등록
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— validate 엔드포인트
Issue #2 — 메시지 미리보기 데이터 생성 API
제목: [Feature] 메시지 미리보기 API 구현
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#120-message-preview
Gitea Issue: #120
상태: ✅ 완료 (PR #121 → develop 머지됨)
설명: 메시지 코드와 변수를 조합하여 미리보기 데이터를 생성하는 API를 구현한다.
📌 참조:
Documents/API_Specification.md§6.5
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessagePreviewRequestDto.cs— 미리보기 요청 DTOSPMS.Application/DTOs/Message/MessagePreviewResponseDto.cs— 미리보기 응답 DTOSPMS.Application/Interfaces/IMessageService.cs— 메시지 서비스 인터페이스SPMS.Application/Services/MessageService.cs— 미리보기 로직 구현SPMS.Application/DependencyInjection.cs— DI 등록
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— preview 엔드포인트
Issue #4 — 메시지 이력 불러오기 API
제목: [Feature] 메시지 이력 불러오기 API (발송 로그 조회)
Labels: Type/Feature, Priority/Medium, Status/Done
Milestone: Phase 3: 메시지 & Push Core
Branch: feature/#122-push-log-api
Gitea Issue: #122
상태: ✅ 완료 (PR #123 머지됨)
설명: PushSendLog 테이블을 페이지네이션과 필터로 조회하는 발송 로그 조회 API를 구현한다.
📌 참조:
Documents/API_Specification.md§7.6,Documents/Feature_Spec.mdUTL-01
체크리스트 — Domain Layer:
SPMS.Domain/Interfaces/IPushSendLogRepository.cs— 발송 로그 Repository 인터페이스
체크리스트 — Application Layer:
SPMS.Application/DTOs/Push/PushLogRequestDto.cs— 조회 요청 DTOSPMS.Application/DTOs/Push/PushLogResponseDto.cs— 조회 응답 DTO (items + pagination)SPMS.Application/Interfaces/IPushService.cs— GetLogAsync 추가SPMS.Application/Services/PushService.cs— 발송 로그 조회 로직
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Persistence/Repositories/PushSendLogRepository.cs— Include(Message) 기반 페이징/필터링SPMS.Infrastructure/DependencyInjection.cs— IPushSendLogRepository DI 등록
체크리스트 — API Layer:
SPMS.API/Controllers/PushController.cs— log 엔드포인트
Issue — 메시지 저장 API (6.1)
제목: [Feature] 메시지 저장 API 구현
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: 메시지 템플릿을 저장하는 API를 구현한다. 메시지 코드를 자동 생성하고, 변수({{변수명}})를 포함할 수 있다.
📌 참조:
Documents/API_Specification.md§6.1
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessageSaveRequestDto.cs— 저장 요청 DTO (title, body, image_url, link_url, link_type, data)SPMS.Application/DTOs/Message/MessageSaveResponseDto.cs— 저장 응답 DTO (message_code, created_at)SPMS.Application/Interfaces/IMessageService.cs— SaveAsync 추가SPMS.Application/Services/MessageService.cs— 메시지 저장 로직, 메시지 코드 생성
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— save 엔드포인트
Issue — 메시지 목록 조회 API (6.2)
제목: [Feature] 메시지 목록 조회 API 구현
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: 서비스별 메시지 목록을 페이지네이션으로 조회한다. keyword 검색, is_active 필터 지원.
📌 참조:
Documents/API_Specification.md§6.2
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessageListRequestDto.cs— 목록 요청 DTO (page, size, keyword, is_active)SPMS.Application/DTOs/Message/MessageListResponseDto.cs— 목록 응답 DTO (items + pagination)SPMS.Application/Interfaces/IMessageService.cs— GetListAsync 추가SPMS.Application/Services/MessageService.cs— 목록 조회 로직
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— list 엔드포인트
Issue — 메시지 상세 조회 API (6.3)
제목: [Feature] 메시지 상세 조회 API 구현
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: 메시지 코드로 메시지 상세 정보를 조회한다. variables 필드에 템플릿 변수 목록을 반환한다.
📌 참조:
Documents/API_Specification.md§6.3
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessageInfoRequestDto.cs— 상세 요청 DTO (message_code)SPMS.Application/DTOs/Message/MessageInfoResponseDto.cs— 상세 응답 DTO (variables 포함)SPMS.Application/Interfaces/IMessageService.cs— GetInfoAsync 추가SPMS.Application/Services/MessageService.cs— 상세 조회 로직, 변수 추출
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— info 엔드포인트
Issue — 메시지 삭제 API (6.4)
제목: [Feature] 메시지 삭제 API 구현
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: 메시지를 Soft Delete 한다 (IsDeleted=true, DeletedAt 설정). Hard Delete는 스케줄러에서 30일 후 처리.
📌 참조:
Documents/API_Specification.md§6.4
체크리스트 — Application Layer:
SPMS.Application/DTOs/Message/MessageDeleteRequestDto.cs— 삭제 요청 DTO (message_code)SPMS.Application/Interfaces/IMessageService.cs— DeleteAsync 추가SPMS.Application/Services/MessageService.cs— Soft Delete 로직
체크리스트 — API Layer:
SPMS.API/Controllers/MessageController.cs— delete 엔드포인트
Issue — 대용량 발송 API (7.3)
제목: [Feature] 대용량 발송 API 구현 (CSV)
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: CSV 파일 기반 대용량 비동기 발송. job_id를 반환하고 백그라운드에서 처리한다.
📌 참조:
Documents/API_Specification.md§7.3
체크리스트:
- CSV 파싱 로직 (device_id 필수, 나머지 변수)
- 비동기 Job 처리 구조 설계
SPMS.API/Controllers/PushController.cs— send/bulk 엔드포인트
Issue — 발송 상태 조회 API (7.4)
제목: [Feature] 발송 상태 조회 API 구현
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: job_id로 대용량/태그 발송 작업의 진행 상태를 조회한다.
📌 참조:
Documents/API_Specification.md§7.4
체크리스트:
- Job 상태 관리 구조 (queued/processing/completed/failed/cancelled)
SPMS.API/Controllers/PushController.cs— job/status 엔드포인트
Issue — 발송 취소 API (7.5)
제목: [Feature] 발송 취소 API 구현
Labels: Type/Feature, Priority/Low, Status/Available
Milestone: Phase 3: 메시지 & Push Core
상태: ⬜ 대기
설명: 대기 중이거나 처리 중인 대용량 발송 작업을 취소한다. 이미 발송된 건은 취소 불가.
📌 참조:
Documents/API_Specification.md§7.5
체크리스트:
- Job 취소 로직 (이미 발송된 건 제외)
SPMS.API/Controllers/PushController.cs— job/cancel 엔드포인트
6. Phase 3-2: 통계 & Webhook & 배치
목표: Statistics, Webhook, Batch Scheduler를 구현한다.
📌 참조 문서:
Documents/BatchScheduler_Design.md§4~5 (DailyStatWorker, DeadTokenCleanupWorker)
| # | 이슈 제목 | Type | Priority | 기능 ID | 상태 |
|---|---|---|---|---|---|
| 1 | [Feature] 대시보드 요약 조회 API | Feature | High | DSH-01 | ✅ |
| 2 | [Feature] 시간대별 발송 추이 조회 API | Feature | Medium | DSH-02 | ✅ |
| 3 | [Feature] 플랫폼별 비중 조회 API | Feature | Medium | DSH-03 | ✅ |
| 4 | [Feature] 메시지별 전환율 조회 API | Feature | Medium | DSH-04 | ✅ |
| 5 | [Feature] 발송 이력 조회 API | Feature | High | DDN-01 | ✅ |
| 6 | [Feature] 발송 상세 로그 조회 API | Feature | High | DDL-02 | ⬜ |
| 7 | [Feature] 통계 리포트 다운로드 API | Feature | Medium | EXP-01 | ⬜ |
| 8 | [Feature] 상세 로그 다운로드 API | Feature | Medium | EXP-02 | ⬜ |
| 9 | [Feature] 실패원인 순위 API | Feature | Medium | ANA-01 | ⬜ |
| 10 | [Feature] 웹훅 설정 API | Feature | High | WHK-01 | ⬜ |
| 11 | [Feature] 웹훅 발송 서비스 | Feature | High | WHK-02 | ⬜ |
| 12 | [Feature] DailyStatWorker 구현 | Feature | Medium | AAG-01 | ⬜ |
| 13 | [Feature] DeadTokenCleanupWorker 구현 | Feature | Medium | DTK-01 | ⬜ |
| 14 | [Feature] 데이터 보관 주기 관리 배치 | Feature | Medium | RET-01 | ⬜ |
| 15 | [Feature] Redis 토큰 캐시 관리 | Feature | Medium | - | ⬜ |
Issue #11 — 웹훅 발송 서비스
제목: [Feature] 웹훅 발송 서비스 구현
Labels: Type/Feature, Priority/High, Status/Available
Milestone: Phase 3-2: 통계 & Webhook & 배치
Branch: feature/#XX-webhook-service
상태: ⬜ 대기
설명: 푸시 발송 결과, 예약 실행 등 이벤트 발생 시 등록된 Webhook URL로 알림을 전송하는 서비스를 구현한다.
📌 참조:
Documents/RabbitMQ_Design.md§7.2 (Webhook 재시도)
체크리스트 — Application Layer:
SPMS.Application/Interfaces/IWebhookService.cs— 웹훅 인터페이스- SendAsync(serviceId, eventType, payload) → WebhookResult
SPMS.Application/DTOs/Webhook/WebhookPayload.cs— 웹훅 페이로드- event_type:
push_result,schedule_executed,push_failed - timestamp, service_code, data
- event_type:
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Webhook/WebhookService.cs— HTTP 전송 구현- HttpClient로 POST 요청
- 타임아웃: 10초
- 재시도 정책: 3회 (30초 간격)
- 최종 실패 시 WebhookLog 기록
SPMS.Infrastructure/Persistence/Repositories/WebhookLogRepository.cs
체크리스트 — 이벤트 타입:
push_result— 발송 완료 (성공/실패 수)schedule_executed— 예약 발송 실행push_failed— 발송 전체 실패
Issue #12 — DailyStatWorker 구현
제목: [Feature] DailyStatWorker 구현 (일별 통계 집계)
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3-2: 통계 & Webhook & 배치
Branch: feature/#XX-daily-stat-worker
상태: ⬜ 대기
설명: 매일 00:05 KST에 전날의 발송 결과를 집계하여 DailyStat 테이블에 기록하는 BackgroundService Worker를 구현한다.
📌 참조:
Documents/BatchScheduler_Design.md§4 (DailyStatWorker)
체크리스트 — Worker 구현:
SPMS.Infrastructure/Workers/DailyStatWorker.cs— BackgroundService 상속- Cron 스케줄: 매일 00:05 KST
- 대상 날짜 계산 (어제)
- 서비스별 발송 통계 집계:
SELECT service_id, COUNT(*) as sent_cnt, SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as success_cnt, SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as fail_cnt FROM PushSendLog WHERE DATE(sent_at) = :yesterday GROUP BY service_id - 서비스별 열람 통계 집계:
SELECT service_id, COUNT(*) as open_cnt FROM PushOpenLog WHERE DATE(opened_at) = :yesterday GROUP BY service_id - DailyStat UPSERT (존재하면 UPDATE, 없으면 INSERT)
- SystemLog에 집계 완료 로그 기록
체크리스트 — 등록:
Program.cs—builder.Services.AddHostedService<DailyStatWorker>()- 환경별 활성화 설정 (Debug: 비활성, Staging/Release: 활성)
Issue #13 — DeadTokenCleanupWorker 구현
제목: [Feature] DeadTokenCleanupWorker 구현 (비활성 토큰 정리)
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3-2: 통계 & Webhook & 배치
Branch: feature/#XX-dead-token-cleanup
상태: ⬜ 대기
설명: 매주 일요일 03:00 KST에 비활성 상태로 7일 이상 경과한 Device 토큰을 물리 삭제하는 BackgroundService Worker를 구현한다.
📌 참조:
Documents/BatchScheduler_Design.md§5 (DeadTokenCleanupWorker)
체크리스트 — Worker 구현:
SPMS.Infrastructure/Workers/DeadTokenCleanupWorker.cs— BackgroundService 상속- Cron 스케줄: 매주 일요일 03:00 KST
- 삭제 대상 조회:
SELECT COUNT(*) FROM Device WHERE is_active = false AND updated_at < NOW() - INTERVAL 7 DAY - 배치 삭제 (1000건씩):
DELETE FROM Device WHERE is_active = false AND updated_at < NOW() - INTERVAL 7 DAY LIMIT 1000 - 삭제된 행 > 0 → 반복, = 0 → 완료
- Redis 토큰 캐시 무효화 (삭제된 Device 기반)
- SystemLog에 정리 완료 로그
체크리스트 — 안전장치:
- 배치 단위 삭제 (1000건씩) → DB 부하 분산
- 삭제 전 카운트 로깅
- 비정상 수치 감지 시 중단 (전체의 50% 이상이면 경고)
체크리스트 — 등록:
Program.cs—builder.Services.AddHostedService<DeadTokenCleanupWorker>()- 환경별 활성화 설정 (Debug/Staging: 비활성, Release: 활성)
Issue #14 — 데이터 보관 주기 관리 배치
제목: [Feature] 데이터 보관 주기 관리 배치
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3-2: 통계 & Webhook & 배치
Branch: feature/#XX-data-retention
상태: ⬜ 대기
설명: 보관 주기가 지난 로그 데이터를 정리하는 배치 작업을 구현한다.
체크리스트:
SPMS.Infrastructure/Workers/DataRetentionWorker.cs— BackgroundService 상속- Cron 스케줄: 매일 04:00 KST
- PushSendLog: 90일 이전 데이터 삭제
- PushOpenLog: 90일 이전 데이터 삭제
- WebhookLog: 30일 이전 데이터 삭제
- SystemLog: 180일 이전 데이터 삭제
- 배치 단위 삭제 (10000건씩)
- SystemLog에 정리 완료 로그
Issue #15 — Redis 토큰 캐시 관리
제목: [Feature] Redis 토큰 캐시 관리
Labels: Type/Feature, Priority/Medium, Status/Available
Milestone: Phase 3-2: 통계 & Webhook & 배치
Branch: feature/#XX-redis-token-cache
상태: ⬜ 대기
설명: 디바이스 토큰을 Redis에 캐싱하여 DB 조회를 최소화한다.
📌 참조: MEMORY.md Redis 설정
체크리스트 — Infrastructure Layer:
SPMS.Infrastructure/Caching/TokenCacheService.cs— 토큰 캐시 관리- Key 형식:
device:token:{serviceId}:{userId} - TTL: 1시간
- GetDeviceTokenAsync(serviceId, userId) → string?
- SetDeviceTokenAsync(serviceId, userId, token)
- InvalidateAsync(serviceId, userId)
- InvalidateByServiceAsync(serviceId) — 서비스 전체 무효화
- Key 형식:
체크리스트 — PushWorker 연동:
- 발송 시 Redis 캐시 우선 조회
- 캐시 미스 시 DB 조회 후 캐시 저장
- Device 삭제/비활성 시 캐시 무효화
7. MVP: 통합 테스트 & 안정화 & 배포
목표: 전체 API 통합 테스트, 성능 최적화, 배포 준비를 완료한다.
| # | 이슈 제목 | Type | Priority |
|---|---|---|---|
| 1 | [Task] 전체 API 통합 테스트 | Task | Urgent |
| 2 | [Improvement] 성능 최적화 및 부하 테스트 | Improvement | High |
| 3 | [Chore] Docker Compose Production 설정 | Chore | High |
| 4 | [Chore] Jenkins 배포 파이프라인 최종 설정 | Chore | High |
| 5 | [Documentation] API 문서 최종 정리 | Documentation | Medium |
| 6 | [Task] v1.0.0 릴리즈 | Task | Urgent |
8. Phase 4: Back Office (React)
목표: 관리자 웹 대시보드를 구현한다. (PRD Phase 4)
| # | 이슈 제목 | Type | Priority |
|---|---|---|---|
| 1 | [Feature] React 프로젝트 초기 설정 | Feature | High |
| 2 | [Feature] 로그인/인증 화면 | Feature | Urgent |
| 3 | [Feature] 대시보드 메인 화면 | Feature | High |
| 4 | [Feature] 메시지 작성 및 발송 UI | Feature | High |
| 5 | [Feature] 서비스/디바이스 관리 화면 | Feature | Medium |
| 6 | [Feature] 통계 및 이력 조회 화면 | Feature | Medium |
9. Phase 5: SDK & 고급 기능
목표: iOS/Android SDK 개발 및 고급 기능을 추가한다. (PRD Phase 5)
| # | 이슈 제목 | Type | Priority | 기능 ID |
|---|---|---|---|---|
| 1 | [Feature] iOS SDK 개발 | Feature | High | INI-01~02, REN-01~02, SDK-ACT-01~02, SET-01 |
| 2 | [Feature] Android SDK 개발 | Feature | High | INI-01~02, REN-01~02, SDK-ACT-01~02, SET-01 |
| 3 | [Documentation] SDK 연동 가이드 문서 | Documentation | Medium | - |
| 4 | [Improvement] 부하 테스트 및 성능 최적화 | Improvement | High | - |
부록: Gitea 이슈 생성 체크리스트
모든 이슈 생성 시 아래 항목을 준수한다. (Workflow.md 기준)
✅ 제목: [타입] 작업 제목
✅ 본문: 설명 + 체크리스트
✅ Labels: Type/*, Priority/*, Status/Available
✅ Milestone: Phase X: 설명
✅ Assignee: seonkyu.kim
PR 생성 시:
✅ 제목: 타입: 작업 요약 (#이슈번호)
✅ 본문: 요약 + Closes #n
✅ Labels: Type/*, Priority/*, Status/In Progress
✅ Milestone: Phase X: 설명
✅ Assignee: seonkyu.kim
✅ Reviewer: Team SPMS/Owners