use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::storage::StoredUser;
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct TokenRequest {
pub api_key: String,
pub api_secret: String,
}
#[derive(Debug, Serialize, utoipa::ToSchema)]
pub struct TokenResponse {
pub access_token: String,
pub token_type: String,
pub expires_in: u64,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct BootstrapRequest {
pub email: String,
pub password: String,
#[serde(default)]
pub display_name: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct UserView {
pub id: String,
pub email: String,
pub display_name: String,
pub role: String,
pub is_active: bool,
#[schema(value_type = Option<String>, example = "2026-04-15T12:00:00Z")]
pub last_login_at: Option<DateTime<Utc>>,
}
impl From<&StoredUser> for UserView {
fn from(u: &StoredUser) -> Self {
Self {
id: u.id.clone(),
email: u.email.clone(),
display_name: u.display_name.clone(),
role: u.role.to_string(),
is_active: u.is_active,
last_login_at: u.last_login_at,
}
}
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct LoginResponse {
pub user: UserView,
pub csrf_token: String,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct LoginRequest {
pub email: String,
pub password: String,
}
#[derive(Debug, Serialize, utoipa::ToSchema)]
pub struct CsrfResponse {
pub csrf_token: String,
}