mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 21:39:54 +02:00
fix(server): allow deleting runtimes when all bound agents are archived
Previously, runtimes could never be deleted once an agent was created because agents can only be archived (not deleted) and the count check included archived agents. Now the check only counts active agents, and archived agents are cleaned up before runtime deletion.
This commit is contained in:
@@ -343,14 +343,20 @@ func (h *Handler) DeleteAgentRuntime(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if any agents are bound to this runtime (ON DELETE RESTRICT).
|
||||
agentCount, err := h.Queries.CountAgentsByRuntime(r.Context(), rt.ID)
|
||||
// Check if any active (non-archived) agents are bound to this runtime.
|
||||
activeCount, err := h.Queries.CountActiveAgentsByRuntime(r.Context(), rt.ID)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to check runtime dependencies")
|
||||
return
|
||||
}
|
||||
if agentCount > 0 {
|
||||
writeError(w, http.StatusConflict, "cannot delete runtime: it has agents bound to it. Reassign or remove the agents first.")
|
||||
if activeCount > 0 {
|
||||
writeError(w, http.StatusConflict, "cannot delete runtime: it has active agents bound to it. Archive or reassign the agents first.")
|
||||
return
|
||||
}
|
||||
|
||||
// Remove archived agents so the FK constraint (ON DELETE RESTRICT) won't block deletion.
|
||||
if err := h.Queries.DeleteArchivedAgentsByRuntime(r.Context(), rt.ID); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to clean up archived agents")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const countAgentsByRuntime = `-- name: CountAgentsByRuntime :one
|
||||
SELECT count(*) FROM agent WHERE runtime_id = $1
|
||||
const countActiveAgentsByRuntime = `-- name: CountActiveAgentsByRuntime :one
|
||||
SELECT count(*) FROM agent WHERE runtime_id = $1 AND archived_at IS NULL
|
||||
`
|
||||
|
||||
func (q *Queries) CountAgentsByRuntime(ctx context.Context, runtimeID pgtype.UUID) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, countAgentsByRuntime, runtimeID)
|
||||
func (q *Queries) CountActiveAgentsByRuntime(ctx context.Context, runtimeID pgtype.UUID) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, countActiveAgentsByRuntime, runtimeID)
|
||||
var count int64
|
||||
err := row.Scan(&count)
|
||||
return count, err
|
||||
@@ -31,6 +31,15 @@ func (q *Queries) DeleteAgentRuntime(ctx context.Context, id pgtype.UUID) error
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteArchivedAgentsByRuntime = `-- name: DeleteArchivedAgentsByRuntime :exec
|
||||
DELETE FROM agent WHERE runtime_id = $1 AND archived_at IS NOT NULL
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteArchivedAgentsByRuntime(ctx context.Context, runtimeID pgtype.UUID) error {
|
||||
_, err := q.db.Exec(ctx, deleteArchivedAgentsByRuntime, runtimeID)
|
||||
return err
|
||||
}
|
||||
|
||||
const failTasksForOfflineRuntimes = `-- name: FailTasksForOfflineRuntimes :many
|
||||
UPDATE agent_task_queue
|
||||
SET status = 'failed', completed_at = now(), error = 'runtime went offline'
|
||||
|
||||
@@ -73,5 +73,8 @@ ORDER BY created_at ASC;
|
||||
-- name: DeleteAgentRuntime :exec
|
||||
DELETE FROM agent_runtime WHERE id = $1;
|
||||
|
||||
-- name: CountAgentsByRuntime :one
|
||||
SELECT count(*) FROM agent WHERE runtime_id = $1;
|
||||
-- name: CountActiveAgentsByRuntime :one
|
||||
SELECT count(*) FROM agent WHERE runtime_id = $1 AND archived_at IS NULL;
|
||||
|
||||
-- name: DeleteArchivedAgentsByRuntime :exec
|
||||
DELETE FROM agent WHERE runtime_id = $1 AND archived_at IS NOT NULL;
|
||||
|
||||
Reference in New Issue
Block a user