research sidebar: delete-with-confirm per topic
Mirror the row-level delete affordance the loops sidebar already
has. Loops was wired earlier; research had a bare title-only card
with no way to remove a stale topic.
- cm-db: research_topics::delete cascades via existing FK rules
(research_topic_agents, research_publish_approvals, and the new
research_outcomes all CASCADE on topic_id; topology_runs's
research_topic_id back-ref is SET NULL so historical runs stay).
- cm-api: DELETE /api/research/{id} → 204. Idempotent.
- Frontend: deleteTopic helper. ResearchList row is now a card
with the existing title/status/outcome header plus a trash icon
that flips the card into an inline "Delete topic + all outcomes?"
confirm strip. Confirm → red Delete / gray Cancel. If the
deleted topic was selected, selection clears; local counter
bumps the list refetch without waiting on a parent.
This commit is contained in:
@@ -98,6 +98,21 @@ pub async fn get(
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
/// Hard-delete a topic and cascade every dependent row. FK cascades on
|
||||
/// research_topic_agents, research_publish_approvals, and research_outcomes
|
||||
/// clean themselves up; topology_runs.research_topic_id is SET NULL so
|
||||
/// historical runs survive with the back-ref cleared.
|
||||
pub async fn delete(pool: &PgPool, id: Uuid, workspace_id: Uuid) -> Result<(), DbError> {
|
||||
sqlx::query!(
|
||||
"DELETE FROM research_topics WHERE id = $1 AND workspace_id = $2",
|
||||
id,
|
||||
workspace_id,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Non-status fields; the state machine transitions are their own endpoints.
|
||||
pub async fn update_fields(
|
||||
pool: &PgPool,
|
||||
|
||||
Reference in New Issue
Block a user