- 개발 단계별 문서 추가 (00_OVERVIEW ~ 06_PHASE) - 기술 표준 문서 추가 (99_TECHNICAL_STANDARDS) - 개발 프로세스 및 패턴 문서 추가 - API_FLOW_TESTER_DESIGN, DEV_PROCESS - HTMX_API_PATTERN, LAYOUT_PATTERN - SETUP_GUIDE, MNG_PROJECT_PLAN - 프로젝트 관리 문서 추가 (project-management/) - INDEX.md, MNG_CRITICAL_RULES.md 업데이트
18 KiB
18 KiB
ㅑ# Phase 6: 커뮤니케이션 & 통계
기간: 1-2주 우선순위: 중간 (완성도 및 부가 기능) 의존성: Phase 1-5 (모든 데이터 활용)
📋 Phase 개요
고객 커뮤니케이션 및 데이터 분석 기능을 완성합니다.
포함 기능:
- 설정 - 이메일 관리
- 설정 - 문자 관리
- 통계 (Statistics & Analytics)
1️⃣ 설정 - 이메일 관리
기능 목록
1.1 SMTP 설정
- 경로:
/mng/settings/email/smtp - 기능:
- SMTP 서버 정보 (호스트, 포트, 암호화)
- 인증 정보 (사용자명, 비밀번호)
- 발신자 정보 (이름, 이메일)
- 테스트 메일 발송
- 권한:
settings.email.smtp
1.2 이메일 템플릿 관리
- 경로:
/mng/settings/email/templates - 기능:
- 템플릿 생성/수정/삭제
- 타입별 템플릿 (회원가입, 비밀번호 재설정, 결제 완료 등)
- HTML 에디터 (변수 치환 지원)
- 미리보기
- 권한:
settings.email.templates
1.3 이메일 발송 내역
- 경로:
/mng/settings/email/history - 기능:
- 발송 내역 목록
- 검색 (수신자, 제목)
- 필터 (상태, 날짜)
- 재발송
- 실패 로그 확인
- 권한:
settings.email.history
1.4 이메일 예약 발송
- 경로:
/mng/settings/email/scheduled - 기능:
- 예약 발송 목록
- 새 예약 생성
- 예약 취소
- 권한:
settings.email.scheduled
DB 스키마
CREATE TABLE email_settings (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL COMMENT 'NULL = 전역 설정',
smtp_host VARCHAR(255) NOT NULL,
smtp_port INT DEFAULT 587,
smtp_encryption ENUM('tls', 'ssl', 'none') DEFAULT 'tls',
smtp_username VARCHAR(255) NOT NULL,
smtp_password VARCHAR(255) NOT NULL COMMENT '암호화 저장',
from_name VARCHAR(255) NOT NULL,
from_email VARCHAR(255) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tenant_id (tenant_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE email_templates (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(100) NOT NULL COMMENT 'welcome, password_reset, payment_success 등',
subject VARCHAR(255) NOT NULL,
body TEXT NOT NULL COMMENT 'HTML 내용',
variables JSON NULL COMMENT '사용 가능한 변수',
is_default BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL,
INDEX idx_tenant_id (tenant_id),
INDEX idx_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE email_logs (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL,
template_id BIGINT UNSIGNED NULL,
recipient_email VARCHAR(255) NOT NULL,
recipient_name VARCHAR(255) NULL,
subject VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
status ENUM('pending', 'sent', 'failed') DEFAULT 'pending',
sent_at TIMESTAMP NULL,
failed_reason TEXT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tenant_id (tenant_id),
INDEX idx_status (status),
INDEX idx_recipient_email (recipient_email),
INDEX idx_sent_at (sent_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
API 엔드포인트
| Method | Endpoint | Description | FormRequest |
|---|---|---|---|
| GET | /mng/settings/email/smtp |
SMTP 설정 조회 | - |
| PUT | /mng/settings/email/smtp |
SMTP 설정 저장 | UpdateSmtpRequest |
| POST | /mng/settings/email/smtp/test |
테스트 메일 발송 | TestEmailRequest |
| GET | /mng/settings/email/templates |
템플릿 목록 | - |
| POST | /mng/settings/email/templates |
템플릿 생성 | StoreEmailTemplateRequest |
| PUT | /mng/settings/email/templates/{id} |
템플릿 수정 | UpdateEmailTemplateRequest |
| GET | /mng/settings/email/history |
발송 내역 | - |
| POST | /mng/settings/email/send |
이메일 발송 | SendEmailRequest |
Service 클래스
// app/Services/EmailService.php
class EmailService
{
public function getSettings(int $tenantId = null): ?EmailSetting;
public function updateSettings(array $data, int $tenantId = null): EmailSetting;
public function testConnection(EmailSetting $setting, string $testEmail): bool;
public function listTemplates(int $tenantId = null): Collection;
public function createTemplate(array $data): EmailTemplate;
public function updateTemplate(EmailTemplate $template, array $data): EmailTemplate;
public function render(EmailTemplate $template, array $variables): string;
public function send(string $to, string $subject, string $body, int $templateId = null): EmailLog;
public function sendBulk(array $recipients, string $subject, string $body): int;
public function getHistory(array $filters): LengthAwarePaginator;
public function retry(EmailLog $log): bool;
}
개발 체크리스트
EmailSetting,EmailTemplate,EmailLog모델 작성EmailService클래스 작성- Laravel Mail + Queue 설정
- SMTP 연결 테스트 기능
- 템플릿 변수 치환 로직
- 예약 발송 스케줄러 (Laravel Schedule)
- 실패 재시도 로직
- FormRequest 작성
- i18n 키 작성
- 테스트 작성
2️⃣ 설정 - 문자 관리
기능 목록
2.1 SMS API 설정
- 경로:
/mng/settings/sms/api - 기능:
- API 연동 설정 (알리고, 카카오 알림톡 등)
- API 키 관리
- 발신 번호 설정
- 테스트 문자 발송
- 권한:
settings.sms.api
2.2 문자 템플릿 관리
- 경로:
/mng/settings/sms/templates - 기능:
- 템플릿 생성/수정/삭제
- SMS (90자), LMS (2000자) 구분
- 변수 치환 지원
- 바이트 수 자동 계산
- 권한:
settings.sms.templates
2.3 문자 발송 내역
- 경로:
/mng/settings/sms/history - 기능:
- 발송 내역 목록
- 검색 (수신자, 내용)
- 필터 (상태, 날짜, 타입)
- 재발송
- 실패 로그 확인
- 권한:
settings.sms.history
2.4 대량 문자 발송
- 경로:
/mng/settings/sms/bulk - 기능:
- 엑셀 업로드 (수신자 목록)
- 템플릿 선택
- 예약 발송
- 발송 결과 확인
- 권한:
settings.sms.bulk
DB 스키마
CREATE TABLE sms_settings (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL,
provider VARCHAR(50) NOT NULL COMMENT 'aligo, kakao 등',
api_key VARCHAR(255) NOT NULL COMMENT '암호화 저장',
api_secret VARCHAR(255) NULL,
sender_number VARCHAR(20) NOT NULL COMMENT '발신 번호',
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tenant_id (tenant_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE sms_templates (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL,
name VARCHAR(255) NOT NULL,
type ENUM('sms', 'lms', 'mms') DEFAULT 'sms',
content TEXT NOT NULL,
variables JSON NULL,
byte_count INT NOT NULL COMMENT '바이트 수',
is_default BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL,
INDEX idx_tenant_id (tenant_id),
INDEX idx_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE sms_logs (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL,
template_id BIGINT UNSIGNED NULL,
recipient_number VARCHAR(20) NOT NULL,
content TEXT NOT NULL,
type ENUM('sms', 'lms', 'mms') DEFAULT 'sms',
status ENUM('pending', 'sent', 'failed') DEFAULT 'pending',
sent_at TIMESTAMP NULL,
failed_reason TEXT NULL,
api_message_id VARCHAR(255) NULL COMMENT 'API 메시지 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tenant_id (tenant_id),
INDEX idx_status (status),
INDEX idx_sent_at (sent_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
API 엔드포인트
| Method | Endpoint | Description | FormRequest |
|---|---|---|---|
| GET | /mng/settings/sms/api |
SMS API 설정 조회 | - |
| PUT | /mng/settings/sms/api |
SMS API 설정 저장 | UpdateSmsApiRequest |
| POST | /mng/settings/sms/api/test |
테스트 문자 발송 | TestSmsRequest |
| GET | /mng/settings/sms/templates |
템플릿 목록 | - |
| POST | /mng/settings/sms/templates |
템플릿 생성 | StoreSmsTemplateRequest |
| POST | /mng/settings/sms/send |
문자 발송 | SendSmsRequest |
| POST | /mng/settings/sms/bulk |
대량 발송 | SendBulkSmsRequest |
| GET | /mng/settings/sms/history |
발송 내역 | - |
Service 클래스
// app/Services/SmsService.php
class SmsService
{
public function getSettings(int $tenantId = null): ?SmsSetting;
public function updateSettings(array $data, int $tenantId = null): SmsSetting;
public function testConnection(SmsSetting $setting, string $testNumber): bool;
public function listTemplates(int $tenantId = null): Collection;
public function createTemplate(array $data): SmsTemplate;
public function updateTemplate(SmsTemplate $template, array $data): SmsTemplate;
public function calculateByteCount(string $content): int;
public function send(string $to, string $content, string $type = 'sms', int $templateId = null): SmsLog;
public function sendBulk(array $recipients, string $content, string $type = 'sms'): int;
public function getHistory(array $filters): LengthAwarePaginator;
public function retry(SmsLog $log): bool;
}
개발 체크리스트
SmsSetting,SmsTemplate,SmsLog모델 작성SmsService클래스 작성- SMS API 연동 (알리고 우선)
- 바이트 수 계산 로직 (한글 2바이트)
- 대량 발송 큐 처리
- 엑셀 업로드 파싱 (PhpSpreadsheet)
- 발송 결과 웹훅 처리
- FormRequest 작성
- i18n 키 작성
- 테스트 작성
3️⃣ 통계 (Statistics & Analytics)
기능 목록
3.1 대시보드
- 경로:
/mng/dashboard - 기능:
- 주요 KPI 카드 (회원 수, 매출, 구독 현황)
- 최근 활동 로그
- 영업 파이프라인 요약
- 결제 통계
- 권한:
dashboard.view
3.2 회원 통계
- 경로:
/mng/statistics/users - 기능:
- 가입자 추세 (일별, 월별)
- 활성/비활성 비율
- 부서별 분포
- 엑셀 내보내기
- 권한:
statistics.users
3.3 매출 통계
- 경로:
/mng/statistics/revenue - 기능:
- 매출 추세 (일별, 월별, 연별)
- 플랜별 매출
- MRR (Monthly Recurring Revenue)
- ARR (Annual Recurring Revenue)
- 차트 (Chart.js 또는 ApexCharts)
- 권한:
statistics.revenue
3.4 영업 통계
- 경로:
/mng/statistics/sales - 기능:
- 파이프라인 단계별 통계
- 전환율 (Conversion Rate)
- 담당자별 성과
- 기간별 비교
- 권한:
statistics.sales
3.5 구독 통계
- 경로:
/mng/statistics/subscriptions - 기능:
- 플랜별 구독 현황
- 이탈률 (Churn Rate)
- 업그레이드/다운그레이드 추세
- 리텐션 분석
- 권한:
statistics.subscriptions
DB 스키마
-- 통계 스냅샷 (일별 집계)
CREATE TABLE statistics_snapshots (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NULL COMMENT 'NULL = 전체',
snapshot_date DATE NOT NULL,
metric_type ENUM('users', 'revenue', 'sales', 'subscriptions') NOT NULL,
metric_data JSON NOT NULL COMMENT '통계 데이터',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_tenant_id (tenant_id),
INDEX idx_snapshot_date (snapshot_date),
INDEX idx_metric_type (metric_type),
UNIQUE KEY unique_snapshot (tenant_id, snapshot_date, metric_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
API 엔드포인트
| Method | Endpoint | Description | Query Params |
|---|---|---|---|
| GET | /mng/dashboard |
대시보드 데이터 | - |
| GET | /mng/statistics/users |
회원 통계 | start_date, end_date, group_by |
| GET | /mng/statistics/revenue |
매출 통계 | start_date, end_date, group_by |
| GET | /mng/statistics/sales |
영업 통계 | start_date, end_date |
| GET | /mng/statistics/subscriptions |
구독 통계 | start_date, end_date |
| GET | /mng/statistics/export |
엑셀 내보내기 | type, start_date, end_date |
Service 클래스
// app/Services/StatisticsService.php
class StatisticsService
{
public function getDashboardData(int $tenantId = null): array;
public function getUserStats(array $filters): array;
public function getRevenueStats(array $filters): array;
public function getSalesStats(array $filters): array;
public function getSubscriptionStats(array $filters): array;
public function calculateMRR(int $tenantId = null): float;
public function calculateARR(int $tenantId = null): float;
public function calculateChurnRate(array $filters): float;
public function calculateConversionRate(array $filters): float;
public function exportToExcel(string $type, array $filters): string; // 파일 경로
public function createSnapshot(string $metricType, int $tenantId = null): void; // 일별 스냅샷 생성
}
UI 컴포넌트
┌─────────────────────────────────────────────────────────┐
│ 대시보드 │
├─────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │회원 1,234│ │매출 5.2M │ │구독 567 │ │영업 89 │ │
│ │↑ 12% │ │↑ 8% │ │↓ 3% │ │↑ 15% │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐│
│ │ 매출 추세 (최근 6개월) [Chart.js 꺾은선] ││
│ └─────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────────────────────────────────────┐│
│ │ 영업 파이프라인 [Chart.js 퍼널 차트] ││
│ └─────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────┘
개발 체크리스트
StatisticsSnapshot모델 작성StatisticsService클래스 작성- 통계 계산 로직 (MRR, ARR, Churn Rate 등)
- Chart.js 또는 ApexCharts 통합
- 일별 스냅샷 스케줄러
- 엑셀 내보내기 (PhpSpreadsheet)
- 대시보드 UI 작성
- 날짜 필터 UI (Alpine.js)
- i18n 키 작성
- 테스트 작성
🎯 Phase 6 완료 조건
기능 완성도
- 이메일 발송 동작
- 문자 발송 동작
- 통계 차트 표시
- 엑셀 내보내기 동작
코드 품질
- Service-First, FormRequest 준수
- 큐 처리 안정성
- i18n 키 사용
- Pint, PHPStan 통과
외부 연동
- SMTP 연결 안정성
- SMS API 연동 동작
- 웹훅 처리 (발송 결과)
성능
- 대량 발송 큐 처리
- 통계 쿼리 최적화
- 스냅샷 생성 스케줄러
테스트
- 이메일 발송 테스트 (Mock)
- 문자 발송 테스트 (Mock)
- 통계 계산 로직 테스트
- 엑셀 생성 테스트
🎉 MNG 애플리케이션 전체 완료
Phase 6가 완료되면 MNG 애플리케이션의 핵심 기능이 모두 구현됩니다.
다음 단계:
- 전체 통합 테스트
- 성능 최적화
- 사용자 매뉴얼 작성
- 배포 준비
참고 문서:
00_OVERVIEW.md- 전체 개발 계획99_TECHNICAL_STANDARDS.md- 기술 표준
최종 업데이트: 2025-11-21 작성자: Claude Code 버전: 1.0.0