Skip to main content

allsource_core/application/dto/
creator_dto.rs

1use crate::domain::entities::{Creator, CreatorSettings, CreatorStatus, CreatorTier};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// DTO for registering a new creator
7#[derive(Debug, Deserialize)]
8pub struct RegisterCreatorRequest {
9    pub tenant_id: String,
10    pub email: String,
11    pub wallet_address: String,
12    pub blog_url: Option<String>,
13    pub name: Option<String>,
14}
15
16/// DTO for creator registration response
17#[derive(Debug, Serialize)]
18pub struct RegisterCreatorResponse {
19    pub creator: CreatorDto,
20}
21
22/// DTO for updating a creator
23#[derive(Debug, Deserialize)]
24pub struct UpdateCreatorRequest {
25    pub name: Option<String>,
26    pub wallet_address: Option<String>,
27    pub blog_url: Option<String>,
28    pub settings: Option<CreatorSettingsDto>,
29}
30
31/// DTO for updating creator response
32#[derive(Debug, Serialize)]
33pub struct UpdateCreatorResponse {
34    pub creator: CreatorDto,
35}
36
37/// DTO for upgrading creator tier
38#[derive(Debug, Deserialize)]
39pub struct UpgradeCreatorTierRequest {
40    pub tier: CreatorTierDto,
41}
42
43/// DTO for listing creators response
44#[derive(Debug, Serialize)]
45pub struct ListCreatorsResponse {
46    pub creators: Vec<CreatorDto>,
47    pub count: usize,
48}
49
50/// DTO for creator settings
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct CreatorSettingsDto {
53    pub default_price_cents: Option<u64>,
54    pub show_reading_time: Option<bool>,
55    pub brand_color: Option<String>,
56    pub unlock_button_text: Option<String>,
57}
58
59impl From<&CreatorSettings> for CreatorSettingsDto {
60    fn from(settings: &CreatorSettings) -> Self {
61        Self {
62            default_price_cents: Some(settings.default_price_cents),
63            show_reading_time: Some(settings.show_reading_time),
64            brand_color: settings.brand_color.clone(),
65            unlock_button_text: settings.unlock_button_text.clone(),
66        }
67    }
68}
69
70impl From<CreatorSettingsDto> for CreatorSettings {
71    fn from(dto: CreatorSettingsDto) -> Self {
72        Self {
73            default_price_cents: dto.default_price_cents.unwrap_or(50),
74            show_reading_time: dto.show_reading_time.unwrap_or(true),
75            brand_color: dto.brand_color,
76            unlock_button_text: dto.unlock_button_text,
77        }
78    }
79}
80
81/// DTO for creator status
82#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
83#[serde(rename_all = "snake_case")]
84pub enum CreatorStatusDto {
85    Pending,
86    Active,
87    Suspended,
88    Deactivated,
89}
90
91impl From<CreatorStatus> for CreatorStatusDto {
92    fn from(status: CreatorStatus) -> Self {
93        match status {
94            CreatorStatus::Pending => CreatorStatusDto::Pending,
95            CreatorStatus::Active => CreatorStatusDto::Active,
96            CreatorStatus::Suspended => CreatorStatusDto::Suspended,
97            CreatorStatus::Deactivated => CreatorStatusDto::Deactivated,
98        }
99    }
100}
101
102/// DTO for creator tier
103#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
104#[serde(rename_all = "snake_case")]
105pub enum CreatorTierDto {
106    Free,
107    Creator,
108    Pro,
109    Enterprise,
110}
111
112impl From<CreatorTier> for CreatorTierDto {
113    fn from(tier: CreatorTier) -> Self {
114        match tier {
115            CreatorTier::Free => CreatorTierDto::Free,
116            CreatorTier::Creator => CreatorTierDto::Creator,
117            CreatorTier::Pro => CreatorTierDto::Pro,
118            CreatorTier::Enterprise => CreatorTierDto::Enterprise,
119        }
120    }
121}
122
123impl From<CreatorTierDto> for CreatorTier {
124    fn from(dto: CreatorTierDto) -> Self {
125        match dto {
126            CreatorTierDto::Free => CreatorTier::Free,
127            CreatorTierDto::Creator => CreatorTier::Creator,
128            CreatorTierDto::Pro => CreatorTier::Pro,
129            CreatorTierDto::Enterprise => CreatorTier::Enterprise,
130        }
131    }
132}
133
134/// DTO for a creator in responses
135#[derive(Debug, Clone, Serialize)]
136pub struct CreatorDto {
137    pub id: Uuid,
138    pub tenant_id: String,
139    pub email: String,
140    pub name: Option<String>,
141    pub wallet_address: String,
142    pub blog_url: Option<String>,
143    pub status: CreatorStatusDto,
144    pub tier: CreatorTierDto,
145    pub settings: CreatorSettingsDto,
146    pub email_verified: bool,
147    pub total_revenue_cents: u64,
148    pub total_articles: u32,
149    pub fee_percentage: u64,
150    pub created_at: DateTime<Utc>,
151    pub updated_at: DateTime<Utc>,
152}
153
154impl From<&Creator> for CreatorDto {
155    fn from(creator: &Creator) -> Self {
156        Self {
157            id: creator.id().as_uuid(),
158            tenant_id: creator.tenant_id().to_string(),
159            email: creator.email().to_string(),
160            name: creator.name().map(std::string::ToString::to_string),
161            wallet_address: creator.wallet_address().to_string(),
162            blog_url: creator.blog_url().map(std::string::ToString::to_string),
163            status: creator.status().into(),
164            tier: creator.tier().into(),
165            settings: creator.settings().into(),
166            email_verified: creator.is_email_verified(),
167            total_revenue_cents: creator.total_revenue_cents(),
168            total_articles: creator.total_articles(),
169            fee_percentage: creator.fee_percentage(),
170            created_at: creator.created_at(),
171            updated_at: creator.updated_at(),
172        }
173    }
174}
175
176impl From<Creator> for CreatorDto {
177    fn from(creator: Creator) -> Self {
178        CreatorDto::from(&creator)
179    }
180}