use models::users::user_agreement_acceptances; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use uuid::Uuid; use super::AuthService; use crate::errors::AuthError; use crate::share::types::AgreementDoc; #[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)] pub struct AcceptAgreementResp { pub recorded: bool, } impl AuthService { pub fn list_agreements(&self) -> Vec { self.config() .auth .agreements .iter() .map(|doc| AgreementDoc { key: doc.key.clone(), version: doc.version.clone(), title: doc.title.clone(), content_md: doc.content_md.clone(), }) .collect() } pub async fn accept_agreement( &self, uid: i64, key: &str, version: &str, ) -> Result { let Some(doc) = self .config() .auth .agreements .iter() .find(|doc| doc.key == key) else { return Err(AuthError::NotFound); }; if doc.version != version { return Err(AuthError::BadRequest( "agreement version mismatch".to_string(), )); } let db = self.db(); let existing = user_agreement_acceptances::Entity::find() .filter(user_agreement_acceptances::Column::UserId.eq(uid)) .filter(user_agreement_acceptances::Column::AgreementKey.eq(key)) .filter(user_agreement_acceptances::Column::AgreementVersion.eq(version)) .one(db.write()) .await?; if existing.is_some() { return Ok(AcceptAgreementResp { recorded: true }); } let row = user_agreement_acceptances::ActiveModel { id: Set(Uuid::now_v7()), user_id: Set(uid), agreement_key: Set(key.to_string()), agreement_version: Set(version.to_string()), accepted_at: Set(OffsetDateTime::now_utc()), }; row.insert(db.write()).await?; Ok(AcceptAgreementResp { recorded: true }) } }