Files
multica/server/pkg/db/queries/member.sql
d3c1b44d75 MUL-8014: fix(realtime): revoke workspace WebSocket access (#9249)
* fix(realtime): revoke workspace access on membership removal

Close removed members' sockets, revalidate registration, and gate captured write batches with fresh coalesced membership queries. Cover relay failure, replay, queue races, and transactional removal/rollback (MUL-8014).

Co-authored-by: multica-agent <[email protected]>

* fix(realtime): keep registration free of database waits

Co-authored-by: multica-agent <[email protected]>

* perf(realtime): narrow removal event prefilter

Co-authored-by: multica-agent <[email protected]>

* test(wakeup): avoid global backfill in workspace default test

Co-authored-by: multica-agent <[email protected]>

* fix(realtime): bound concurrent authorization and defer relay revocation

Co-authored-by: multica-agent <[email protected]>

* test(realtime): check caller budget without waiting for expiry

Co-authored-by: multica-agent <[email protected]>

* fix(realtime): decouple member-list invalidation from revocation

Co-authored-by: multica-agent <[email protected]>

* perf(realtime): skip removal decoding for member actor metadata

Co-authored-by: multica-agent <[email protected]>

---------

Co-authored-by: Sol-Boy <[email protected]>
Co-authored-by: multica-agent <[email protected]>
2026-10-15 12:36:00 +08:00

48 lines
1.2 KiB
SQL

-- name: ListMembers :many
SELECT * FROM member
WHERE workspace_id = $1
ORDER BY created_at ASC;
-- name: ListWorkspaceManagerUserIDs :many
SELECT user_id FROM member
WHERE workspace_id = $1 AND role IN ('owner', 'admin')
ORDER BY created_at ASC;
-- name: GetMember :one
SELECT * FROM member
WHERE id = $1;
-- name: GetMemberByUserAndWorkspace :one
SELECT * FROM member
WHERE user_id = $1 AND workspace_id = $2;
-- name: GetRealtimeMemberships :many
SELECT m.user_id, m.workspace_id
FROM member m
JOIN (
SELECT unnest(sqlc.arg(user_ids)::uuid[]) AS user_id,
unnest(sqlc.arg(workspace_ids)::uuid[]) AS workspace_id
) AS requested
ON m.user_id = requested.user_id AND m.workspace_id = requested.workspace_id;
-- name: CreateMember :one
INSERT INTO member (workspace_id, user_id, role)
VALUES ($1, $2, $3)
RETURNING *;
-- name: UpdateMemberRole :one
UPDATE member SET role = $2
WHERE id = $1
RETURNING *;
-- name: DeleteMember :exec
DELETE FROM member WHERE id = $1;
-- name: ListMembersWithUser :many
SELECT m.id, m.workspace_id, m.user_id, m.role, m.created_at,
u.name as user_name, u.email as user_email, u.avatar_url as user_avatar_url
FROM member m
JOIN "user" u ON u.id = m.user_id
WHERE m.workspace_id = $1
ORDER BY m.created_at ASC;