Skip to main content

allsource_core/application/dto/
access_token_dto.rs

1use crate::domain::entities::{AccessMethod, AccessToken};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// DTO for granting free access
7#[derive(Debug, Deserialize)]
8pub struct GrantFreeAccessRequest {
9    pub tenant_id: String,
10    pub article_id: String,
11    pub reader_wallet: String,
12    pub duration_days: Option<i64>,
13    pub reason: Option<String>,
14}
15
16/// DTO for granting access response
17#[derive(Debug, Serialize)]
18pub struct GrantAccessResponse {
19    pub access_token: AccessTokenDto,
20    pub raw_token: String,
21}
22
23/// DTO for checking access
24#[derive(Debug, Deserialize)]
25pub struct CheckAccessRequest {
26    pub article_id: String,
27    pub wallet_address: String,
28}
29
30/// DTO for access check response
31#[derive(Debug, Serialize)]
32pub struct CheckAccessResponse {
33    pub has_access: bool,
34    pub access_token: Option<AccessTokenDto>,
35    pub remaining_days: Option<i64>,
36}
37
38/// DTO for revoking access
39#[derive(Debug, Deserialize)]
40pub struct RevokeAccessRequest {
41    pub token_id: String,
42    pub reason: String,
43}
44
45/// DTO for revoke access response
46#[derive(Debug, Serialize)]
47pub struct RevokeAccessResponse {
48    pub revoked: bool,
49    pub access_token: AccessTokenDto,
50}
51
52/// DTO for listing access tokens response
53#[derive(Debug, Serialize)]
54pub struct ListAccessTokensResponse {
55    pub tokens: Vec<AccessTokenDto>,
56    pub count: usize,
57}
58
59/// DTO for access method
60#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
61#[serde(rename_all = "snake_case")]
62pub enum AccessMethodDto {
63    Paid,
64    Bundle,
65    Free,
66    Subscription,
67}
68
69impl From<AccessMethod> for AccessMethodDto {
70    fn from(method: AccessMethod) -> Self {
71        match method {
72            AccessMethod::Paid => AccessMethodDto::Paid,
73            AccessMethod::Bundle => AccessMethodDto::Bundle,
74            AccessMethod::Free => AccessMethodDto::Free,
75            AccessMethod::Subscription => AccessMethodDto::Subscription,
76        }
77    }
78}
79
80impl From<AccessMethodDto> for AccessMethod {
81    fn from(dto: AccessMethodDto) -> Self {
82        match dto {
83            AccessMethodDto::Paid => AccessMethod::Paid,
84            AccessMethodDto::Bundle => AccessMethod::Bundle,
85            AccessMethodDto::Free => AccessMethod::Free,
86            AccessMethodDto::Subscription => AccessMethod::Subscription,
87        }
88    }
89}
90
91/// DTO for an access token in responses
92#[derive(Debug, Clone, Serialize)]
93pub struct AccessTokenDto {
94    pub id: Uuid,
95    pub tenant_id: String,
96    pub article_id: String,
97    pub creator_id: String,
98    pub reader_wallet: String,
99    pub transaction_id: Option<Uuid>,
100    pub access_method: AccessMethodDto,
101    pub issued_at: DateTime<Utc>,
102    pub expires_at: DateTime<Utc>,
103    pub is_valid: bool,
104    pub is_expired: bool,
105    pub is_revoked: bool,
106    pub revoked_at: Option<DateTime<Utc>>,
107    pub revocation_reason: Option<String>,
108    pub remaining_days: i64,
109    pub access_count: u32,
110    pub last_accessed_at: Option<DateTime<Utc>>,
111}
112
113impl From<&AccessToken> for AccessTokenDto {
114    fn from(token: &AccessToken) -> Self {
115        Self {
116            id: token.id().as_uuid(),
117            tenant_id: token.tenant_id().to_string(),
118            article_id: token.article_id().to_string(),
119            creator_id: token.creator_id().as_uuid().to_string(),
120            reader_wallet: token.reader_wallet().to_string(),
121            transaction_id: token.transaction_id().map(|t| t.as_uuid()),
122            access_method: token.access_method().into(),
123            issued_at: token.issued_at(),
124            expires_at: token.expires_at(),
125            is_valid: token.is_valid(),
126            is_expired: token.is_expired(),
127            is_revoked: token.is_revoked(),
128            revoked_at: token.revoked_at(),
129            revocation_reason: token.revocation_reason().map(|s| s.to_string()),
130            remaining_days: token.remaining_days(),
131            access_count: token.access_count(),
132            last_accessed_at: token.last_accessed_at(),
133        }
134    }
135}
136
137impl From<AccessToken> for AccessTokenDto {
138    fn from(token: AccessToken) -> Self {
139        AccessTokenDto::from(&token)
140    }
141}