Repository: svix/svix-webhooks (language: rust)

Issue:
[server] delete event-type does not delete anything
## Bug Report

docker: svix/svix-server:v1.36.0

call: DELETE http://xxxxxxxxx:8071//api/v1/event-type/order.delivered/?expunge=true
response: 204

but a list event-types always shows:

```json
{
    "data": [
        {
            "name": "item.delivered",
            "description": "an item has been deliverd",
            "archived": false,
            "deprecated": false,
            "schemas": null,
            "createdAt": "2024-09-28T19:43:38.872620Z",
            "updatedAt": "2024-09-28T19:43:38.872620Z",
            "featureFlag": null
        },
        {
            "name": "order.delivered",
            "description": "an order has been deliverd",
            "archived": true,
            "deprecated": false,
            "schemas": null,
            "createdAt": "2024-09-28T18:01:01.953404Z",
            "updatedAt": "2024-09-28T20:08:19.369679Z",
            "featureFlag": null
        }
    ],
    "iterator": "order.delivered",
    "prevIterator": "-item.delivered",
    "done": true
}
``` 

so whatever I do, I cannot delete the "order.delivered" event-type 😢 
please let me know if I am doing something wrong.

thanks!


Discussion / hints:
It changes it to "archived". You need to pass `expunge` in order to fully remove it: https://api.svix.com/docs#tag/Event-Type/operation/v1.event-type.delete
@tasn 

![image](https://github.com/user-attachments/assets/77e4032e-fe7a-4452-a3fd-c3d18bea708d)

is that wrong ????


I missed that. It looks like another feature that was built in SaaS but hasn't been backported to OSS.
@tasn so... is it save to delete it directly in the database ? or are there any dependencies ??
You can delete it in the database, it shouldn't be a problem. Though we'll also fix it first thing next week!

Fix patch:
diff --git a/server/openapi.json b/server/openapi.json
index c6e235d0f..0159955eb 100644
--- a/server/openapi.json
+++ b/server/openapi.json
@@ -6991,6 +6991,17 @@
                             "type": "string"
                         },
                         "style": "simple"
+                    },
+                    {
+                        "description": "By default event types are archived when \"deleted\". Passing this to `true` deletes them entirely.",
+                        "in": "query",
+                        "name": "expunge",
+                        "schema": {
+                            "default": false,
+                            "description": "By default event types are archived when \"deleted\". Passing this to `true` deletes them entirely.",
+                            "type": "boolean"
+                        },
+                        "style": "form"
                     }
                 ],
                 "responses": {
diff --git a/server/svix-server/src/v1/endpoints/event_type.rs b/server/svix-server/src/v1/endpoints/event_type.rs
index 7d9fecebc..eb0974ba9 100644
--- a/server/svix-server/src/v1/endpoints/event_type.rs
+++ b/server/svix-server/src/v1/endpoints/event_type.rs
@@ -402,6 +402,14 @@ async fn patch_event_type(
     Ok(Json(ret.into()))
 }
 
+#[derive(Debug, Deserialize, Serialize, Validate, JsonSchema)]
+struct DeleteEventTypeQueryParams {
+    /// By default event types are archived when "deleted". Passing this to `true` deletes them
+    /// entirely.
+    #[serde(default)]
+    expunge: bool,
+}
+
 /// Archive an event type.
 ///
 /// Endpoints already configured to filter on an event type will continue to do so after archival.
@@ -412,6 +420,9 @@ async fn patch_event_type(
 async fn delete_event_type(
     State(AppState { ref db, .. }): State<AppState>,
     Path(EventTypeNamePath { event_type_name }): Path<EventTypeNamePath>,
+    ValidatedQuery(DeleteEventTypeQueryParams { expunge }): ValidatedQuery<
+        DeleteEventTypeQueryParams,
+    >,
     permissions::Organization { org_id }: permissions::Organization,
 ) -> Result<NoContent> {
     let evtype = eventtype::Entity::secure_find_by_name(org_id, event_type_name)
@@ -420,8 +431,13 @@ async fn delete_event_type(
         .ok_or_else(|| HttpError::not_found(None, None))?;
 
     let mut evtype: eventtype::ActiveModel = evtype.into();
-    evtype.deleted = Set(true);
-    evtype.update(db).await?;
+
+    if expunge {
+        evtype.delete(db).await?;
+    } else {
+        evtype.deleted = Set(true);
+        evtype.update(db).await?;
+    }
     Ok(NoContent)
 }
 


Test patch: