use axum::{
Json,
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
};
use fraiseql_core::db::traits::DatabaseAdapter;
use serde::{Deserialize, Serialize};
use crate::routes::graphql::app_state::AppState;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdminUser {
pub sub: String,
pub email: String,
pub provider: String,
pub created_at: String,
pub last_sign_in: Option<String>,
pub mfa_enrolled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserListResponse {
pub users: Vec<AdminUser>,
pub total: u64,
pub page: u32,
pub page_size: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInviteRequest {
pub email: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInviteResponse {
pub success: bool,
pub message: String,
}
pub async fn list_users_handler<A>(State(_state): State<AppState<A>>) -> impl IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
Json(UserListResponse {
users: vec![],
total: 0,
page: 1,
page_size: 50,
})
}
pub async fn invite_user_handler<A>(
State(_state): State<AppState<A>>,
Json(req): Json<UserInviteRequest>,
) -> impl IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
Json(UserInviteResponse {
success: true,
message: format!("Invitation queued for {}", req.email),
})
}
pub async fn revoke_user_handler<A>(
Path(_user_id): Path<String>,
State(_state): State<AppState<A>>,
) -> impl IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
Json(serde_json::json!({"success": true, "message": "All sessions revoked"}))
}
pub async fn mfa_status_handler<A>(
Path(_user_id): Path<String>,
State(_state): State<AppState<A>>,
) -> impl IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
(
StatusCode::NOT_IMPLEMENTED,
Json(serde_json::json!({
"error": "Not Implemented",
"message": "MFA status endpoint available in a future release"
})),
)
}