From 660ffd6acb1f2e84df15ce58e0261ec925ab45cf Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Sun, 26 Apr 2026 14:08:15 +0800 Subject: [PATCH] chore(api): remove entire admin module Admin Next.js app handles all admin tasks directly via database access. Only health check endpoint was remaining, not worth maintaining. --- libs/api/admin/alerts.rs | 45 -------------------------------------- libs/api/admin/mod.rs | 30 ------------------------- libs/api/admin/sync.rs | 47 ---------------------------------------- libs/api/lib.rs | 1 - libs/api/openapi.rs | 2 -- libs/api/route.rs | 1 - 6 files changed, 126 deletions(-) delete mode 100644 libs/api/admin/alerts.rs delete mode 100644 libs/api/admin/mod.rs delete mode 100644 libs/api/admin/sync.rs diff --git a/libs/api/admin/alerts.rs b/libs/api/admin/alerts.rs deleted file mode 100644 index 65d3ce7..0000000 --- a/libs/api/admin/alerts.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Alert trigger endpoint for admin. - -use actix_web::{HttpRequest, HttpResponse, Result, web}; -use service::AppService; - -use crate::error::ApiError; -use crate::ApiResponse; -use service::error::AppError; - -/// Validate the `x-admin-api-key` header against ADMIN_API_SHARED_KEY env var. -fn validate_admin_key(req: &HttpRequest) -> Result<(), ApiError> { - let expected = std::env::var("ADMIN_API_SHARED_KEY").ok(); - let Some(expected) = expected else { - return Err(ApiError(AppError::InternalServerError( - "ADMIN_API_SHARED_KEY not configured".into(), - ))); - }; - let provided = req - .headers() - .get("x-admin-api-key") - .and_then(|v| v.to_str().ok()) - .ok_or(ApiError(AppError::Unauthorized))?; - if provided != expected { - return Err(ApiError(AppError::Unauthorized)); - } - Ok(()) -} - -#[utoipa::path( - post, - path = "/api/admin/alerts/check", - responses( - (status = 200, description = "Alert check result", body = ApiResponse), - (status = 401, description = "Invalid or missing admin API key"), - ), - tag = "Admin" -)] -pub async fn admin_check_alerts( - req: HttpRequest, - service: web::Data, -) -> Result { - validate_admin_key(&req)?; - let resp = service.check_billing_alerts().await; - Ok(ApiResponse::ok(resp).to_response()) -} diff --git a/libs/api/admin/mod.rs b/libs/api/admin/mod.rs deleted file mode 100644 index d1a7b73..0000000 --- a/libs/api/admin/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Admin API endpoints — protected by `x-admin-api-key` header. -//! -//! Only platform-wide operations remain. AI model management and billing -//! are handled directly by the admin Next.js app via database access. - -use actix_web::web; - -pub mod alerts; -pub mod sync; - -pub fn init_admin_routes(cfg: &mut web::ServiceConfig) { - cfg.service( - web::scope("/api/admin") - .route("/health", web::get().to(health_check)) - .route("/ai/sync", web::post().to(sync::admin_sync_models)) - .route("/alerts/check", web::post().to(alerts::admin_check_alerts)), - ); -} - -#[utoipa::path( - get, - path = "/api/admin/health", - responses( - (status = 200, description = "Admin API is healthy"), - ), - tag = "Admin" -)] -async fn health_check() -> impl actix_web::Responder { - actix_web::HttpResponse::Ok().json(serde_json::json!({ "ok": true })) -} diff --git a/libs/api/admin/sync.rs b/libs/api/admin/sync.rs deleted file mode 100644 index dd68c9c..0000000 --- a/libs/api/admin/sync.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! AI model sync endpoint for admin. - -use actix_web::{HttpRequest, HttpResponse, Result, web}; -use service::AppService; - -use crate::error::ApiError; -use crate::ApiResponse; -use service::error::AppError; - -/// Validate the `x-admin-api-key` header against ADMIN_API_SHARED_KEY env var. -fn validate_admin_key(req: &HttpRequest) -> Result<(), ApiError> { - let expected = std::env::var("ADMIN_API_SHARED_KEY").ok(); - let Some(expected) = expected else { - return Err(ApiError(AppError::InternalServerError( - "ADMIN_API_SHARED_KEY not configured".into(), - ))); - }; - let provided = req - .headers() - .get("x-admin-api-key") - .and_then(|v| v.to_str().ok()) - .ok_or(ApiError(AppError::Unauthorized))?; - if provided != expected { - return Err(ApiError(AppError::Unauthorized)); - } - Ok(()) -} - -#[utoipa::path( - post, - path = "/api/admin/ai/sync", - responses( - (status = 200, description = "Sync result", body = ApiResponse), - (status = 401, description = "Invalid or missing admin API key"), - (status = 500, description = "Sync failed"), - ), - tag = "Admin" -)] -pub async fn admin_sync_models( - req: HttpRequest, - service: web::Data, -) -> Result { - validate_admin_key(&req)?; - let session = session::Session::no_op(); - let resp = service.sync_upstream_models(&session).await?; - Ok(ApiResponse::ok(resp).to_response()) -} diff --git a/libs/api/lib.rs b/libs/api/lib.rs index 9c21712..2e37498 100644 --- a/libs/api/lib.rs +++ b/libs/api/lib.rs @@ -1,4 +1,3 @@ -pub mod admin; pub mod agent; pub mod auth; pub mod error; diff --git a/libs/api/openapi.rs b/libs/api/openapi.rs index 0c51ebc..a291b24 100644 --- a/libs/api/openapi.rs +++ b/libs/api/openapi.rs @@ -31,8 +31,6 @@ use utoipa::OpenApi; crate::auth::email::api_email_change, crate::auth::email::api_email_verify, // Agent - crate::admin::sync::admin_sync_models, - crate::admin::alerts::admin_check_alerts, // Agent (CRUD) crate::agent::code_review::trigger_code_review, crate::agent::issue_triage::triage_issue, diff --git a/libs/api/route.rs b/libs/api/route.rs index a04813e..a1096f1 100644 --- a/libs/api/route.rs +++ b/libs/api/route.rs @@ -13,7 +13,6 @@ pub fn init_routes(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("/api") - // .configure(crate::admin::init_admin_routes) .configure(crate::auth::init_auth_routes) .configure(crate::git::init_git_routes) .configure(crate::git::init_git_toplevel_routes)