tdm_server_rust/dev/
routes.rs1use crate::{
4 app::AppState,
5 dev::{error_repo, health::run_health_checks, mcp},
6};
7use axum::{
8 extract::{Query, State},
9 http::StatusCode,
10 response::{IntoResponse, Redirect, Response},
11 routing::get,
12 Json, Router,
13};
14use serde::Deserialize;
15use serde_json::json;
16
17#[derive(Debug, Deserialize)]
19pub struct ErrorListQuery {
20 #[serde(default = "default_limit")]
22 pub limit: i64,
23}
24
25fn default_limit() -> i64 {
26 100
27}
28
29pub fn routes(state: AppState) -> Router {
31 Router::new()
32 .route("/dev/console.html", get(console_redirect))
33 .route("/dev/api/health", get(health))
34 .route("/dev/api/errors", get(list_errors))
35 .route("/dev/api/mcp/trace-query", get(mcp_trace_query))
36 .with_state(state)
37}
38
39#[tracing::instrument(skip_all, level = "info")]
41async fn console_redirect(State(state): State<AppState>) -> impl IntoResponse {
42 let url = state.config.telemetry.ui.skywalking.trim();
43 if url.is_empty() {
44 return Redirect::temporary("http://127.0.0.1:8080").into_response();
45 }
46 Redirect::temporary(url).into_response()
47}
48
49#[tracing::instrument(skip_all, level = "info")]
51async fn health(State(state): State<AppState>) -> Json<serde_json::Value> {
52 let report = run_health_checks(&state).await;
53 Json(serde_json::to_value(report).unwrap_or(json!({"ok": false})))
54}
55
56#[tracing::instrument(skip_all, level = "info")]
58async fn list_errors(
59 State(state): State<AppState>,
60 Query(q): Query<ErrorListQuery>,
61) -> Response {
62 let limit = q.limit.clamp(1, 500);
63 match error_repo::list_recent(&state.db, limit).await {
64 Ok(rows) => Json(json!({"entries": rows})).into_response(),
65 Err(e) => (
66 StatusCode::INTERNAL_SERVER_ERROR,
67 Json(json!({"msg": e.to_string()})),
68 )
69 .into_response(),
70 }
71}
72
73#[tracing::instrument(skip_all, level = "info")]
75async fn mcp_trace_query(
76 State(state): State<AppState>,
77 Query(q): Query<McpTraceQuery>,
78) -> Json<serde_json::Value> {
79 Json(mcp::trace_lookup_template(
80 &state.config.telemetry.ui.skywalking,
81 &q.trace_id,
82 ))
83}
84
85#[derive(Debug, Deserialize)]
87pub struct McpTraceQuery {
88 pub trace_id: String,
90}