Files
sam-manage/docs/06_PHASE6_COMM_STATS.md
hskwon 76c8a94e4f docs: MNG 프로젝트 문서 정비
- 개발 단계별 문서 추가 (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 업데이트
2025-11-30 21:04:19 +09:00

18 KiB
Raw Blame History

ㅑ# Phase 6: 커뮤니케이션 & 통계

기간: 1-2주 우선순위: 중간 (완성도 및 부가 기능) 의존성: Phase 1-5 (모든 데이터 활용)

📋 Phase 개요

고객 커뮤니케이션 및 데이터 분석 기능을 완성합니다.

포함 기능:

  1. 설정 - 이메일 관리
  2. 설정 - 문자 관리
  3. 통계 (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 애플리케이션의 핵심 기능이 모두 구현됩니다.

다음 단계:

  1. 전체 통합 테스트
  2. 성능 최적화
  3. 사용자 매뉴얼 작성
  4. 배포 준비

참고 문서:

  • 00_OVERVIEW.md - 전체 개발 계획
  • 99_TECHNICAL_STANDARDS.md - 기술 표준

최종 업데이트: 2025-11-21 작성자: Claude Code 버전: 1.0.0