1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
use axum::Json;
use serde_json::json;
use sqlx::SqlitePool;
use std::sync::Arc;
use tracing::warn;
use crate::migrations::MigrationManager;
#[utoipa::path(
get,
path = "/health",
responses(
(status = 200, description = "Health check response", body = serde_json::Value)
),
tag = "health"
)]
pub async fn health_handler(
axum::extract::State(pool): axum::extract::State<Arc<SqlitePool>>,
) -> Json<serde_json::Value> {
let mut status = "ok";
let details;
// Check database connectivity
match sqlx::query("SELECT 1").execute(&*pool).await {
Ok(_) => {
// Check migration status
match MigrationManager::check_migrations_status(&pool).await {
Ok(migrations_ok) => {
if migrations_ok {
details = json!({
"database": "connected",
"migrations": "up_to_date"
});
} else {
warn!("Health check: migrations are not up to date");
details = json!({
"database": "connected",
"migrations": "pending"
});
}
}
Err(e) => {
warn!("Health check: failed to check migration status: {}", e);
details = json!({
"database": "connected",
"migrations": "unknown",
"migration_error": e.to_string()
});
}
}
}
Err(e) => {
status = "error";
details = json!({
"database": "disconnected",
"error": e.to_string()
});
}
}
Json(json!({
"status": status,
"details": details
}))
}
#[derive(utoipa::ToSchema, serde::Serialize)]
pub struct HealthResponse {
pub status: String,
}
|