postrust_server/
custom.rs1use axum::{
7 extract::State,
8 http::StatusCode,
9 response::{IntoResponse, Json},
10 routing::get,
11 Router,
12};
13use serde::{Deserialize, Serialize};
14use std::sync::Arc;
15
16use crate::state::AppState;
17
18pub fn custom_router() -> Router<Arc<AppState>> {
20 Router::new()
21 .route("/health", get(health_check))
22 .route("/ready", get(readiness_check))
23 }
27
28pub fn admin_router() -> Router<Arc<AppState>> {
37 Router::new()
38 .route("/live", get(health_check))
39 .route("/health", get(health_check))
40 .route("/ready", get(readiness_check))
41}
42
43async fn health_check() -> Json<HealthResponse> {
48 Json(HealthResponse {
49 status: "ok".to_string(),
50 version: env!("CARGO_PKG_VERSION").to_string(),
51 })
52}
53
54async fn readiness_check(State(state): State<Arc<AppState>>) -> impl IntoResponse {
55 match sqlx::query("SELECT 1").execute(&state.pool).await {
57 Ok(_) => (
58 StatusCode::OK,
59 Json(ReadinessResponse {
60 ready: true,
61 database: true,
62 message: None,
63 }),
64 ),
65 Err(e) => (
66 StatusCode::SERVICE_UNAVAILABLE,
67 Json(ReadinessResponse {
68 ready: false,
69 database: false,
70 message: Some(e.to_string()),
71 }),
72 ),
73 }
74}
75
76#[derive(Serialize)]
81struct HealthResponse {
82 status: String,
83 version: String,
84}
85
86#[derive(Serialize)]
87struct ReadinessResponse {
88 ready: bool,
89 database: bool,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 message: Option<String>,
92}
93
94#[derive(Deserialize)]
99#[allow(dead_code)]
100struct WebhookPayload {
101 event_type: String,
102 data: serde_json::Value,
103}
104
105#[allow(dead_code)]
106async fn handle_webhook(
107 State(state): State<Arc<AppState>>,
108 Json(payload): Json<WebhookPayload>,
109) -> impl IntoResponse {
110 tracing::info!("Received webhook: {}", payload.event_type);
111
112 let _pool = &state.pool;
114
115 (
118 StatusCode::OK,
119 Json(serde_json::json!({ "received": true })),
120 )
121}
122
123#[derive(Deserialize)]
128#[allow(dead_code)]
129struct CustomRpcRequest {
130 action: String,
131 params: serde_json::Value,
132}
133
134#[allow(dead_code)]
135async fn custom_rpc(
136 State(state): State<Arc<AppState>>,
137 Json(req): Json<CustomRpcRequest>,
138) -> impl IntoResponse {
139 let result = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM users")
141 .fetch_one(&state.pool)
142 .await;
143
144 match result {
145 Ok(count) => (
146 StatusCode::OK,
147 Json(serde_json::json!({
148 "action": req.action,
149 "result": count
150 })),
151 ),
152 Err(e) => (
153 StatusCode::INTERNAL_SERVER_ERROR,
154 Json(serde_json::json!({
155 "error": e.to_string()
156 })),
157 ),
158 }
159}