Add SNS Marketing Campaign feature
- Add cash_cc_balance to User model (withdrawable CC) - Create SnsShareSubmission model for SNS share verification - Add marketing campaign settings to SystemSettings - Add reward_type to ReferralReward model - Create /api/sns-share endpoints for submission and verification - Add referral signup reward logic (10CC on signup) - Create /sns-share user page for SNS sharing - Create /admin/sns-shares management page - Add marketing settings UI to admin settings page - Add SNS Shares menu to admin sidebar 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,10 @@ from .notification import (
|
||||
NotificationCreate, NotificationResponse,
|
||||
NotificationListResponse, NotificationMarkRead,
|
||||
)
|
||||
from .sns_share import (
|
||||
SnsShareSubmit, SnsShareResponse, SnsShareListResponse,
|
||||
SnsShareVerify, SnsShareStats,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"CarMakerCreate", "CarMakerResponse",
|
||||
@@ -78,4 +82,6 @@ __all__ = [
|
||||
"ReferralSettingsResponse", "ReferralSettingsUpdate",
|
||||
"NotificationCreate", "NotificationResponse",
|
||||
"NotificationListResponse", "NotificationMarkRead",
|
||||
"SnsShareSubmit", "SnsShareResponse", "SnsShareListResponse",
|
||||
"SnsShareVerify", "SnsShareStats",
|
||||
]
|
||||
|
||||
@@ -22,6 +22,16 @@ class SystemSettingsUpdate(BaseModel):
|
||||
referral_reward_percent: Optional[float] = None
|
||||
referral_reward_type: Optional[str] = None
|
||||
|
||||
# 마케팅 캠페인 설정
|
||||
marketing_enabled: Optional[bool] = None
|
||||
marketing_start_date: Optional[datetime] = None
|
||||
marketing_end_date: Optional[datetime] = None
|
||||
sns_share_reward_cc: Optional[float] = None
|
||||
referral_signup_reward_cc: Optional[float] = None
|
||||
event_cc_validity_months: Optional[int] = None
|
||||
withdrawal_enabled: Optional[bool] = None
|
||||
min_withdrawal_usd: Optional[float] = None
|
||||
|
||||
|
||||
class SystemSettingsResponse(BaseModel):
|
||||
"""시스템 설정 응답 스키마"""
|
||||
@@ -42,6 +52,17 @@ class SystemSettingsResponse(BaseModel):
|
||||
referral_reward_enabled: bool = True
|
||||
referral_reward_percent: float = 10.0
|
||||
referral_reward_type: str = "one_time"
|
||||
|
||||
# 마케팅 캠페인 설정
|
||||
marketing_enabled: bool = False
|
||||
marketing_start_date: Optional[datetime] = None
|
||||
marketing_end_date: Optional[datetime] = None
|
||||
sns_share_reward_cc: float = 3.0
|
||||
referral_signup_reward_cc: float = 10.0
|
||||
event_cc_validity_months: int = 6
|
||||
withdrawal_enabled: bool = True
|
||||
min_withdrawal_usd: float = 10.0
|
||||
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
57
backend/app/schemas/sns_share.py
Normal file
57
backend/app/schemas/sns_share.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class SnsShareSubmit(BaseModel):
|
||||
"""SNS 공유 제출 요청"""
|
||||
car_id: int
|
||||
platform: str # twitter, instagram, facebook
|
||||
sns_url: str # 공유 게시물 URL
|
||||
|
||||
|
||||
class SnsShareResponse(BaseModel):
|
||||
"""SNS 공유 제출 응답"""
|
||||
id: int
|
||||
user_id: int
|
||||
car_id: int
|
||||
platform: str
|
||||
sns_url: str
|
||||
status: str
|
||||
rejected_reason: Optional[str] = None
|
||||
reward_cc: float
|
||||
rewarded_at: Optional[datetime] = None
|
||||
submitted_at: datetime
|
||||
verified_at: Optional[datetime] = None
|
||||
verified_by: Optional[int] = None
|
||||
|
||||
# Car info for display
|
||||
car_name: Optional[str] = None
|
||||
car_image: Optional[str] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class SnsShareListResponse(BaseModel):
|
||||
"""SNS 공유 목록 응답"""
|
||||
submissions: List[SnsShareResponse]
|
||||
total: int
|
||||
pending_count: int
|
||||
approved_count: int
|
||||
rejected_count: int
|
||||
|
||||
|
||||
class SnsShareVerify(BaseModel):
|
||||
"""관리자 검증 요청"""
|
||||
approved: bool
|
||||
rejected_reason: Optional[str] = None
|
||||
|
||||
|
||||
class SnsShareStats(BaseModel):
|
||||
"""SNS 공유 통계"""
|
||||
total_submissions: int
|
||||
pending_submissions: int
|
||||
approved_submissions: int
|
||||
rejected_submissions: int
|
||||
total_rewarded_cc: float
|
||||
Reference in New Issue
Block a user