61 lines
2.3 KiB
Rust
61 lines
2.3 KiB
Rust
//! Reminder endpoints for the dashboard.
|
|
//!
|
|
//! Lists pending reminders for the reminders tab, and lets the operator
|
|
//! cancel a pending reminder or reset its failure state so the scheduler
|
|
//! retries it on the next tick.
|
|
|
|
use axum::{
|
|
extract::{Path as AxumPath, State},
|
|
http::StatusCode,
|
|
response::{IntoResponse, Response},
|
|
};
|
|
|
|
use problem_details::ProblemDetails;
|
|
|
|
use super::{AppState, error_response};
|
|
|
|
pub(super) async fn api_reminders(State(state): State<AppState>) -> Response {
|
|
match state.coord.broker.list_pending_reminders() {
|
|
Ok(rows) => axum::Json(rows).into_response(),
|
|
Err(e) => error_response(&format!("reminders: {e:#}")),
|
|
}
|
|
}
|
|
|
|
pub(super) async fn post_cancel_reminder(
|
|
State(state): State<AppState>,
|
|
AxumPath(id): AxumPath<i64>,
|
|
) -> Response {
|
|
match state.coord.broker.cancel_reminder(id) {
|
|
Ok(0) => ProblemDetails::from_status_code(StatusCode::NOT_FOUND)
|
|
.with_detail(format!("reminder {id} not pending (already delivered?)"))
|
|
.into_response(),
|
|
Ok(_) => {
|
|
tracing::info!(%id, "operator cancelled reminder");
|
|
state.coord.emit_reminders_snapshot();
|
|
(StatusCode::OK, "ok").into_response()
|
|
}
|
|
Err(e) => error_response(&format!("cancel reminder {id} failed: {e:#}")),
|
|
}
|
|
}
|
|
|
|
/// Reset a pending reminder's failure state so the scheduler
|
|
/// retries it on the next tick. Useful when the failure was
|
|
/// transient (sqlite lock contention, disk full → freed up) and
|
|
/// the operator wants delivery to resume immediately instead of
|
|
/// the row sitting in attempt-count-capped purgatory.
|
|
pub(super) async fn post_retry_reminder(
|
|
State(state): State<AppState>,
|
|
AxumPath(id): AxumPath<i64>,
|
|
) -> Response {
|
|
match state.coord.broker.reset_reminder_failure(id) {
|
|
Ok(0) => ProblemDetails::from_status_code(StatusCode::NOT_FOUND)
|
|
.with_detail(format!("reminder {id} not pending (already delivered?)"))
|
|
.into_response(),
|
|
Ok(_) => {
|
|
tracing::info!(%id, "operator reset reminder failure for retry");
|
|
state.coord.emit_reminders_snapshot();
|
|
(StatusCode::OK, "ok").into_response()
|
|
}
|
|
Err(e) => error_response(&format!("retry reminder {id} failed: {e:#}")),
|
|
}
|
|
}
|