1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::storage::StoredUser;
7
8#[derive(Debug, Deserialize, utoipa::ToSchema)]
10pub struct TokenRequest {
11 pub api_key: String,
13 pub api_secret: String,
15}
16
17#[derive(Debug, Serialize, utoipa::ToSchema)]
19pub struct TokenResponse {
20 pub access_token: String,
22 pub token_type: String,
24 pub expires_in: u64,
26}
27
28#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
30pub struct BootstrapRequest {
31 pub email: String,
32 pub password: String,
33 #[serde(default)]
34 pub display_name: Option<String>,
35}
36
37#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
39pub struct UserView {
40 pub id: String,
41 pub email: String,
42 pub display_name: String,
43 pub role: String,
44 pub is_active: bool,
45 #[schema(value_type = Option<String>, example = "2026-04-15T12:00:00Z")]
46 pub last_login_at: Option<DateTime<Utc>>,
47}
48
49impl From<&StoredUser> for UserView {
50 fn from(u: &StoredUser) -> Self {
51 Self {
52 id: u.id.clone(),
53 email: u.email.clone(),
54 display_name: u.display_name.clone(),
55 role: u.role.to_string(),
56 is_active: u.is_active,
57 last_login_at: u.last_login_at,
58 }
59 }
60}
61
62#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
64pub struct LoginResponse {
65 pub user: UserView,
66 pub csrf_token: String,
67}
68
69#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
70pub struct LoginRequest {
71 pub email: String,
72 pub password: String,
73}
74
75#[derive(Debug, Serialize, utoipa::ToSchema)]
76pub struct CsrfResponse {
77 pub csrf_token: String,
78}