Skip to main content

tdm_server_rust/web/
gray_release_controller.rs

1//! 灰度发布接口 (Gray Release Controller)
2//!
3//! 提供当前组员灰度命中查询和管理员灰度配置维护接口。
4
5use crate::{
6    app::AppState,
7    common::{AppJson, ResultBody},
8    entity::gray_release::{
9        GrayCurrentDecisionResponse, GrayFeatureAdminItem, GrayFeatureUpdateRequest,
10    },
11    error::ApiResult,
12    middleware::AuthMember,
13    service::gray_release_service::GrayReleaseService,
14};
15use axum::{
16    extract::{Extension, Path, State},
17    routing::{get, post, put},
18    Router,
19};
20
21/// 普通灰度查询路由(挂载于 `/api/gray`)。
22pub fn routes() -> Router<AppState> {
23    Router::new().route("/features/current", get(current_features))
24}
25
26/// 管理端灰度配置路由(挂载于 `/api/admin/gray`)。
27pub fn admin_routes() -> Router<AppState> {
28    Router::new()
29        .route("/features", get(list_features))
30        .route("/features/:featureKey", put(update_feature))
31        .route("/features/:featureKey/rollback", post(rollback_feature))
32        .route("/rollback-all", post(rollback_all))
33}
34
35/// 查询当前组员灰度命中结果。
36#[tracing::instrument(skip_all, level = "info")]
37pub async fn current_features(
38    State(state): State<AppState>,
39    Extension(AuthMember(member)): Extension<AuthMember>,
40) -> ApiResult<ResultBody<GrayCurrentDecisionResponse>> {
41    let data = GrayReleaseService::current_decisions(&state, member).await?;
42    Ok(ResultBody::success_data(data))
43}
44
45/// 查询灰度功能配置列表。
46#[tracing::instrument(skip_all, level = "info")]
47pub async fn list_features(
48    State(state): State<AppState>,
49    Extension(AuthMember(member)): Extension<AuthMember>,
50) -> ApiResult<ResultBody<Vec<GrayFeatureAdminItem>>> {
51    GrayReleaseService::ensure_admin(member)?;
52    let data = GrayReleaseService::list_admin(&state).await?;
53    Ok(ResultBody::success_data(data))
54}
55
56/// 新增或更新灰度功能配置。
57#[tracing::instrument(skip_all, level = "info")]
58pub async fn update_feature(
59    State(state): State<AppState>,
60    Extension(AuthMember(member)): Extension<AuthMember>,
61    Path(feature_key): Path<String>,
62    AppJson(body): AppJson<GrayFeatureUpdateRequest>,
63) -> ApiResult<ResultBody<()>> {
64    GrayReleaseService::ensure_admin(member)?;
65    GrayReleaseService::update_feature(&state, &feature_key, body).await?;
66    Ok(ResultBody::success())
67}
68
69/// 回退单个灰度功能到旧逻辑。
70#[tracing::instrument(skip_all, level = "info")]
71pub async fn rollback_feature(
72    State(state): State<AppState>,
73    Extension(AuthMember(member)): Extension<AuthMember>,
74    Path(feature_key): Path<String>,
75) -> ApiResult<ResultBody<()>> {
76    GrayReleaseService::ensure_admin(member)?;
77    GrayReleaseService::rollback_feature(&state, &feature_key).await?;
78    Ok(ResultBody::success())
79}
80
81/// 回退全部灰度功能到旧逻辑。
82#[tracing::instrument(skip_all, level = "info")]
83pub async fn rollback_all(
84    State(state): State<AppState>,
85    Extension(AuthMember(member)): Extension<AuthMember>,
86) -> ApiResult<ResultBody<()>> {
87    GrayReleaseService::ensure_admin(member)?;
88    GrayReleaseService::rollback_all(&state).await?;
89    Ok(ResultBody::success())
90}