tdm_server_rust/web/
gray_release_controller.rs1use 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
21pub fn routes() -> Router<AppState> {
23 Router::new().route("/features/current", get(current_features))
24}
25
26pub 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#[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#[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#[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#[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#[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}