SPMS_API/TASKS.md
2026-02-11 09:51:44 +09:00

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 9 9 0 Phase 2-1 + 3-2
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 57 8 -

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.cs DbSet 등록 (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. #1 (Entity + DB 구축) → #2#3 (Domain Layer 완성)
  2. #4#5 (공통 응답/예외 체계)
  3. #6 (Repository) → #7, #8, #11 (병렬 가능)
  4. #10 (DI 통합)
  5. #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 — 로그인 요청 DTO
  • SPMS.Application/DTOs/Auth/LoginResponseDto.cs — 로그인 응답 DTO
  • SPMS.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 — 토큰 갱신 요청 DTO
  • SPMS.Application/DTOs/Auth/TokenRefreshResponseDto.cs — 토큰 갱신 응답 DTO
  • SPMS.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 — 비밀번호 변경 요청 DTO
  • SPMS.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.cs
  • SPMS.Application/DTOs/Account/UpdateAccountRequestDto.cs
  • SPMS.Application/DTOs/Account/AccountResponseDto.cs
  • SPMS.Application/DTOs/Account/AccountListRequestDto.cs
  • SPMS.Application/DTOs/Account/AccountListResponseDto.cs
  • SPMS.Application/Interfaces/IAccountService.cs
  • SPMS.Application/Services/AccountService.cs

체크리스트 — API Layer:

  • SPMS.API/Controllers/AccountController.cs
  • POST /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.cs
  • SPMS.Application/DTOs/Service/CreateServiceResponseDto.cs
  • SPMS.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.cs
  • SPMS.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.cs
  • SPMS.Application/DTOs/Auth/SignupResponseDto.cs
  • SPMS.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 — 요청 DTO
  • AuthService.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 — 요청 DTO
  • SPMS.Application/DTOs/Account/PasswordResetRequestDto.cs — 요청 DTO
  • SPMS.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 — 응답 DTO
  • SPMS.Application/DTOs/Account/UpdateProfileRequestDto.cs — 수정 요청 DTO
  • SPMS.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.csPOST /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 — 태그 조회 요청 DTO
  • SPMS.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.csPOST 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와 실제 코드 간 불일치를 해소한다.

불일치 내역:

  1. Admin 테이블: RefreshToken, RefreshTokenExpiresAt 2개 컬럼이 코드에만 있고 문서에 없음 (13→15 컬럼)
  2. AdminConfiguration.cs: 위 2개 컬럼의 명시적 EF 설정이 누락됨 (자동 매핑되지만 명시적 설정 필요)
  3. 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 설정 추가
  • 빌드 성공 확인

제목: [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.csLinkType 프로퍼티 추가
  • 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.cs
  • AppConfigConfiguration.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 [Feature] 딥링크 스키마 검증 UTL-02 API Spec 미정의 → 후순위 🔒 보류
22 [Feature] 실패건 재발송 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.json RabbitMQ 섹션 추가
    • 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 — 설정 POCO
  • SPMS.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: pushspms.push.queue, schedulespms.schedule.queue
  • 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

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 설정 POCO
  • SPMS.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) 사용
    • 이미 존재하면 → 중복으로 판단, 스킵
    • 없으면 → 키 생성 후 처리 진행

체크리스트 — 설정:

  • appsettings.json Redis 섹션
  • 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 — 단건 발송 요청 DTO
  • SPMS.Application/DTOs/Push/PushSendTagRequestDto.cs — 태그 발송 요청 DTO
  • SPMS.Application/DTOs/Push/PushSendResponseDto.cs — 발송 응답 DTO
  • SPMS.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 — 예약 발송 요청 DTO
  • SPMS.Application/DTOs/Push/PushScheduleCancelRequestDto.cs — 예약 취소 요청 DTO
  • SPMS.Application/DTOs/Push/PushScheduleResponseDto.cs — 예약 응답 DTO
  • SPMS.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.md HPR-03

체크리스트 — Application Layer:

  • SPMS.Application/DTOs/Message/MessageValidateRequestDto.cs — 검증 요청 DTO
  • SPMS.Application/DTOs/Message/MessageValidationResultDto.cs — 검증 결과 DTO
  • SPMS.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 — 미리보기 요청 DTO
  • SPMS.Application/DTOs/Message/MessagePreviewResponseDto.cs — 미리보기 응답 DTO
  • SPMS.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.md UTL-01

체크리스트 — Domain Layer:

  • SPMS.Domain/Interfaces/IPushSendLogRepository.cs — 발송 로그 Repository 인터페이스

체크리스트 — Application Layer:

  • SPMS.Application/DTOs/Push/PushLogRequestDto.cs — 조회 요청 DTO
  • SPMS.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

체크리스트 — 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.csbuilder.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.csbuilder.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) — 서비스 전체 무효화

체크리스트 — 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