diff --git a/server/openapi.json b/server/openapi.json index 80e014af0..22aa18d59 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -149,6 +149,18 @@ }, "type": "object" }, + "BackgroundTaskStatus": { + "enum": [ + "running" + ], + "type": "string" + }, + "BackgroundTaskType": { + "enum": [ + "endpoint.recover" + ], + "type": "string" + }, "DashboardAccessOut": { "properties": { "token": { @@ -1980,6 +1992,25 @@ ], "type": "object" }, + "RecoverOut": { + "properties": { + "id": { + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/BackgroundTaskStatus" + }, + "task": { + "$ref": "#/components/schemas/BackgroundTaskType" + } + }, + "required": [ + "id", + "status", + "task" + ], + "type": "object" + }, "StatusCodeClass": { "description": "The different classes of HTTP status codes:\n- CodeNone = 0\n- Code1xx = 100\n- Code2xx = 200\n- Code3xx = 300\n- Code4xx = 400\n- Code5xx = 500", "enum": [ @@ -4402,7 +4433,14 @@ }, "responses": { "202": { - "description": "no content" + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecoverOut" + } + } + }, + "description": "" }, "401": { "content": { diff --git a/server/svix-server/src/core/types/mod.rs b/server/svix-server/src/core/types/mod.rs index ddd8339b3..62acf2165 100644 --- a/server/svix-server/src/core/types/mod.rs +++ b/server/svix-server/src/core/types/mod.rs @@ -550,6 +550,7 @@ create_id_type!( ); create_id_type!(MessageEndpointId, "msgep_"); create_id_type!(EventTypeId, "evtype_"); +create_id_type!(QueueBackgroundTaskId, "qtask_"); create_all_id_types!(ApplicationId, ApplicationUid, ApplicationIdOrUid, "app_"); create_all_id_types!(EndpointId, EndpointUid, EndpointIdOrUid, "ep_"); diff --git a/server/svix-server/src/v1/endpoints/endpoint/recovery.rs b/server/svix-server/src/v1/endpoints/endpoint/recovery.rs index b8d053007..5ae08c46b 100644 --- a/server/svix-server/src/v1/endpoints/endpoint/recovery.rs +++ b/server/svix-server/src/v1/endpoints/endpoint/recovery.rs @@ -1,18 +1,23 @@ use axum::extract::{Path, State}; use chrono::{DateTime, Utc}; +use schemars::JsonSchema; use sea_orm::{entity::prelude::*, QueryOrder, QuerySelect}; +use serde::{Deserialize, Serialize}; use svix_server_derive::aide_annotate; use super::RecoverIn; use crate::{ core::{ permissions, - types::{BaseId, MessageAttemptTriggerType, MessageEndpointId, MessageStatus}, + types::{ + BaseId, MessageAttemptTriggerType, MessageEndpointId, MessageStatus, + QueueBackgroundTaskId, + }, }, db::models::{application, endpoint, messagedestination}, error::{HttpError, Result, ValidationErrorItem}, queue::{MessageTask, TaskQueueProducer}, - v1::utils::{ApplicationEndpointPath, NoContentWithCode, ValidatedJson}, + v1::utils::{ApplicationEndpointPath, JsonStatus, ValidatedJson}, AppState, }; @@ -66,6 +71,26 @@ async fn bulk_recover_failed_messages( Ok(()) } +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "camelCase")] +pub enum BackgroundTaskStatus { + Running, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] +pub enum BackgroundTaskType { + #[serde(rename = "endpoint.recover")] + Recover, +} + +#[derive(Debug, Serialize, JsonSchema)] +#[serde(rename_all = "camelCase")] +pub struct RecoverOut { + id: QueueBackgroundTaskId, + status: BackgroundTaskStatus, + task: BackgroundTaskType, +} + /// Resend all failed messages since a given time. #[aide_annotate(op_id = "v1.endpoint.recover")] pub(super) async fn recover_failed_webhooks( @@ -75,7 +100,7 @@ pub(super) async fn recover_failed_webhooks( Path(ApplicationEndpointPath { endpoint_id, .. }): Path, permissions::Application { app }: permissions::Application, ValidatedJson(data): ValidatedJson, -) -> Result> { +) -> Result> { // Add five minutes so that people can easily just do `now() - two_weeks` without having to worry about clock sync let timeframe = chrono::Duration::days(14); let timeframe = timeframe + chrono::Duration::minutes(5); @@ -100,5 +125,9 @@ pub(super) async fn recover_failed_webhooks( async move { bulk_recover_failed_messages(db, queue_tx, app, endp, data.since).await }, ); - Ok(NoContentWithCode) + Ok(JsonStatus(RecoverOut { + id: QueueBackgroundTaskId::new(None, None), + status: BackgroundTaskStatus::Running, + task: BackgroundTaskType::Recover, + })) }