use sea_orm::Set;
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "api_keys")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub name: String,
#[sea_orm(unique)]
pub key_hash: String,
pub key_prefix: String,
pub user_id: Option<Uuid>,
pub team_id: Option<Uuid>,
pub permissions: String,
pub rate_limits: Option<String>,
pub expires_at: Option<DateTimeWithTimeZone>,
pub is_active: bool,
pub last_used_at: Option<DateTimeWithTimeZone>,
pub usage_stats: String,
pub extra: Option<String>,
pub created_at: DateTimeWithTimeZone,
pub updated_at: DateTimeWithTimeZone,
pub version: i32,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "SetNull"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl Model {
pub fn to_domain_api_key(&self) -> crate::core::models::ApiKey {
use crate::core::models::{Metadata, RateLimits, UsageStats};
let permissions =
serde_json::from_str::<Vec<String>>(&self.permissions).unwrap_or_else(|_| vec![]);
let rate_limits = self
.rate_limits
.as_ref()
.and_then(|raw| serde_json::from_str::<RateLimits>(raw).ok());
let usage_stats = serde_json::from_str::<UsageStats>(&self.usage_stats).unwrap_or_default();
let extra = self
.extra
.as_ref()
.and_then(|raw| serde_json::from_str::<HashMap<String, serde_json::Value>>(raw).ok())
.unwrap_or_default();
let metadata = Metadata {
id: self.id,
created_at: self.created_at.naive_utc().and_utc(),
updated_at: self.updated_at.naive_utc().and_utc(),
version: self.version as i64,
extra,
};
crate::core::models::ApiKey {
metadata,
name: self.name.clone(),
key_hash: self.key_hash.clone(),
key_prefix: self.key_prefix.clone(),
user_id: self.user_id,
team_id: self.team_id,
permissions,
rate_limits,
expires_at: self.expires_at.map(|dt| dt.naive_utc().and_utc()),
is_active: self.is_active,
last_used_at: self.last_used_at.map(|dt| dt.naive_utc().and_utc()),
usage_stats,
}
}
pub fn from_domain_api_key(api_key: &crate::core::models::ApiKey) -> ActiveModel {
let permissions =
serde_json::to_string(&api_key.permissions).unwrap_or_else(|_| "[]".into());
let rate_limits = api_key
.rate_limits
.as_ref()
.and_then(|limits| serde_json::to_string(limits).ok());
let usage_stats =
serde_json::to_string(&api_key.usage_stats).unwrap_or_else(|_| "{}".into());
let extra = if api_key.metadata.extra.is_empty() {
None
} else {
serde_json::to_string(&api_key.metadata.extra).ok()
};
ActiveModel {
id: Set(api_key.metadata.id),
name: Set(api_key.name.clone()),
key_hash: Set(api_key.key_hash.clone()),
key_prefix: Set(api_key.key_prefix.clone()),
user_id: Set(api_key.user_id),
team_id: Set(api_key.team_id),
permissions: Set(permissions),
rate_limits: Set(rate_limits),
expires_at: Set(api_key.expires_at.map(Into::into)),
is_active: Set(api_key.is_active),
last_used_at: Set(api_key.last_used_at.map(Into::into)),
usage_stats: Set(usage_stats),
extra: Set(extra),
created_at: Set(api_key.metadata.created_at.into()),
updated_at: Set(api_key.metadata.updated_at.into()),
version: Set(api_key.metadata.version as i32),
}
}
}