mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-10 06:49:21 +02:00
152 lines
5.2 KiB
SQL
152 lines
5.2 KiB
SQL
-- name: CreateSquad :one
|
||
INSERT INTO squad (workspace_id, name, description, leader_id, creator_id, avatar_url)
|
||
VALUES ($1, $2, $3, $4, $5, $6)
|
||
RETURNING *;
|
||
|
||
-- name: GetSquad :one
|
||
SELECT * FROM squad WHERE id = $1;
|
||
|
||
-- name: GetSquadInWorkspace :one
|
||
SELECT * FROM squad WHERE id = $1 AND workspace_id = $2;
|
||
|
||
-- name: ListSquads :many
|
||
SELECT * FROM squad WHERE workspace_id = $1 AND archived_at IS NULL ORDER BY created_at ASC;
|
||
|
||
-- name: ListSquadMemberPreviewRows :many
|
||
-- Static squad membership summary for list/hover previews. This deliberately
|
||
-- excludes derived runtime/task status; the squad detail members-status
|
||
-- endpoint owns live state.
|
||
SELECT
|
||
sm.squad_id,
|
||
sm.member_type,
|
||
sm.member_id,
|
||
sm.role
|
||
FROM squad_member sm
|
||
JOIN squad s ON s.id = sm.squad_id
|
||
WHERE s.workspace_id = $1 AND s.archived_at IS NULL
|
||
ORDER BY
|
||
sm.squad_id ASC,
|
||
(sm.member_type = 'agent' AND sm.member_id = s.leader_id) DESC,
|
||
sm.created_at ASC;
|
||
|
||
-- name: ListSquadMemberPreviewRowsBySquad :many
|
||
SELECT
|
||
sm.squad_id,
|
||
sm.member_type,
|
||
sm.member_id,
|
||
sm.role
|
||
FROM squad_member sm
|
||
JOIN squad s ON s.id = sm.squad_id
|
||
WHERE sm.squad_id = $1
|
||
ORDER BY
|
||
(sm.member_type = 'agent' AND sm.member_id = s.leader_id) DESC,
|
||
sm.created_at ASC;
|
||
|
||
-- name: ListAllSquads :many
|
||
SELECT * FROM squad WHERE workspace_id = $1 ORDER BY created_at ASC;
|
||
|
||
-- name: UpdateSquad :one
|
||
UPDATE squad SET
|
||
name = COALESCE(sqlc.narg('name'), name),
|
||
description = COALESCE(sqlc.narg('description'), description),
|
||
leader_id = COALESCE(sqlc.narg('leader_id'), leader_id),
|
||
avatar_url = COALESCE(sqlc.narg('avatar_url'), avatar_url),
|
||
instructions = COALESCE(sqlc.narg('instructions'), instructions),
|
||
updated_at = now()
|
||
WHERE id = $1
|
||
RETURNING *;
|
||
|
||
-- name: ArchiveSquad :one
|
||
UPDATE squad SET archived_at = now(), archived_by = $2, updated_at = now()
|
||
WHERE id = $1
|
||
RETURNING *;
|
||
|
||
-- name: AddSquadMember :one
|
||
INSERT INTO squad_member (squad_id, member_type, member_id, role)
|
||
VALUES ($1, $2, $3, $4)
|
||
RETURNING *;
|
||
|
||
-- name: RemoveSquadMember :execrows
|
||
DELETE FROM squad_member
|
||
WHERE squad_id = $1 AND member_type = $2 AND member_id = $3;
|
||
|
||
-- name: ListSquadMembers :many
|
||
SELECT * FROM squad_member WHERE squad_id = $1 ORDER BY created_at ASC;
|
||
|
||
-- name: UpdateSquadMemberRole :one
|
||
UPDATE squad_member SET role = $4
|
||
WHERE squad_id = $1 AND member_type = $2 AND member_id = $3
|
||
RETURNING *;
|
||
|
||
-- name: IsSquadMember :one
|
||
SELECT EXISTS(
|
||
SELECT 1 FROM squad_member
|
||
WHERE squad_id = $1 AND member_type = $2 AND member_id = $3
|
||
) AS is_member;
|
||
|
||
-- name: CountSquadMembers :one
|
||
SELECT count(*) FROM squad_member WHERE squad_id = $1;
|
||
|
||
-- name: GetSquadByAssignee :one
|
||
-- Look up the squad when an issue is assigned to a squad.
|
||
SELECT s.* FROM squad s WHERE s.id = $1 AND s.workspace_id = $2;
|
||
|
||
-- name: ListSquadsByMember :many
|
||
-- Find all squads a given entity belongs to in a workspace.
|
||
SELECT s.* FROM squad s
|
||
JOIN squad_member sm ON sm.squad_id = s.id
|
||
WHERE s.workspace_id = $1 AND sm.member_type = $2 AND sm.member_id = $3
|
||
ORDER BY s.created_at ASC;
|
||
|
||
-- name: TransferSquadAssignees :exec
|
||
-- Transfer all issues assigned to a squad to the squad's leader agent.
|
||
UPDATE issue SET assignee_type = 'agent', assignee_id = $2, updated_at = now()
|
||
WHERE assignee_type = 'squad' AND assignee_id = $1;
|
||
|
||
-- name: TransferSquadAutopilotsToLeader :exec
|
||
-- Mirrors TransferSquadAssignees for autopilot rows: when a squad is archived,
|
||
-- any autopilot still pointing at the squad would otherwise dangle and the
|
||
-- admission gate would skip every subsequent dispatch with "assignee squad
|
||
-- cannot be resolved". Rewrite the assignee in place to the leader agent so
|
||
-- the autopilot keeps firing under the same leader-only execution semantics
|
||
-- it had a moment before the archive (Path A from MUL-2429).
|
||
UPDATE autopilot
|
||
SET assignee_type = 'agent',
|
||
assignee_id = $2,
|
||
updated_at = now()
|
||
WHERE assignee_type = 'squad' AND assignee_id = $1;
|
||
|
||
-- name: ListSquadMemberStatusRows :many
|
||
-- Per-row join used to build the squad-members status view. One row per
|
||
-- (squad_member × active_task); members with no active task return a
|
||
-- single row with NULL task_* columns. Human members and agent members
|
||
-- with no agent row also return one row with NULL agent_/runtime_ columns.
|
||
-- The handler aggregates rows by member_id.
|
||
SELECT
|
||
sm.id AS squad_member_id,
|
||
sm.member_type AS member_type,
|
||
sm.member_id AS member_id,
|
||
a.archived_at AS agent_archived_at,
|
||
ar.status AS runtime_status,
|
||
ar.last_seen_at AS runtime_last_seen_at,
|
||
atq.id AS task_id,
|
||
atq.status AS task_status,
|
||
atq.issue_id AS task_issue_id,
|
||
atq.dispatched_at AS task_dispatched_at,
|
||
i.number AS issue_number,
|
||
i.title AS issue_title,
|
||
i.status AS issue_status
|
||
FROM squad_member sm
|
||
LEFT JOIN agent a
|
||
ON sm.member_type = 'agent' AND a.id = sm.member_id
|
||
LEFT JOIN agent_runtime ar
|
||
ON ar.id = a.runtime_id
|
||
LEFT JOIN agent_task_queue atq
|
||
ON sm.member_type = 'agent'
|
||
AND atq.agent_id = sm.member_id
|
||
AND atq.status IN ('dispatched', 'running')
|
||
LEFT JOIN issue i
|
||
ON i.id = atq.issue_id
|
||
WHERE sm.squad_id = $1
|
||
ORDER BY sm.created_at ASC, atq.dispatched_at DESC NULLS LAST;
|