Restrict agent ticket visibility to strictly their own assigned tickets
Previous behavior also showed unassigned tickets to every agent (so new tickets stayed discoverable to pick up), but the actual want here is stricter: an agent sees only what's assigned to them, period. New tickets are now only visible to admins until explicitly assigned to an agent — an assign-then-work model rather than self-service pickup. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012o9j9RezxbZVKQMrB7oRLY
This commit is contained in:
1 parent
69467239ed
commit
ed636bdbd5
2 files changed
+6
-9
No files matched your search
@@ -417,10 +417,9 @@ export async function assignTicket(ticketId: string, assigneeId: string | null)
|
|||||||
* body in the thread — a plain LIKE search, not FTS5 (simpler and
|
* body in the thread — a plain LIKE search, not FTS5 (simpler and
|
||||||
* sufficient at this ticket volume; revisit if it gets slow).
|
* sufficient at this ticket volume; revisit if it gets slow).
|
||||||
*
|
*
|
||||||
* `visibility` restricts the result to what an agent should see: tickets
|
* `visibility` restricts the result to what an agent should see: only
|
||||||
* assigned to them, plus unassigned ones (so new/unclaimed tickets are
|
* tickets assigned to them, not the whole board. Admins see everything,
|
||||||
* still discoverable to pick up) — not the whole board. Admins see
|
* so pass `undefined`/role "admin" for that case.
|
||||||
* everything, so pass `undefined`/role "admin" for that case.
|
|
||||||
*/
|
*/
|
||||||
export async function listTickets(
|
export async function listTickets(
|
||||||
query?: string,
|
query?: string,
|
||||||
@@ -458,9 +457,7 @@ export async function listTickets(
|
|||||||
let filteredRows = idsToKeep ? rows.filter((r) => idsToKeep.has(r.ticket.id)) : rows;
|
let filteredRows = idsToKeep ? rows.filter((r) => idsToKeep.has(r.ticket.id)) : rows;
|
||||||
|
|
||||||
if (visibility?.role === "agent") {
|
if (visibility?.role === "agent") {
|
||||||
filteredRows = filteredRows.filter(
|
filteredRows = filteredRows.filter((r) => r.ticket.assigneeId === visibility.id);
|
||||||
(r) => r.ticket.assigneeId === null || r.ticket.assigneeId === visibility.id,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagsMap = await getTagsForTickets(filteredRows.map((r) => r.ticket.id));
|
const tagsMap = await getTagsForTickets(filteredRows.map((r) => r.ticket.id));
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { TicketDTO } from "./types";
|
import type { TicketDTO } from "./types";
|
||||||
|
|
||||||
/** Agents see tickets assigned to them plus unassigned ones (so new tickets are still discoverable to pick up); admins see everything. */
|
/** Agents see only tickets assigned to them, nothing else — admins see everything. */
|
||||||
export function isTicketVisibleTo(
|
export function isTicketVisibleTo(
|
||||||
ticket: Pick<TicketDTO, "assigneeId">,
|
ticket: Pick<TicketDTO, "assigneeId">,
|
||||||
user: { id: string; role: "admin" | "agent" },
|
user: { id: string; role: "admin" | "agent" },
|
||||||
): boolean {
|
): boolean {
|
||||||
if (user.role === "admin") return true;
|
if (user.role === "admin") return true;
|
||||||
return ticket.assigneeId === null || ticket.assigneeId === user.id;
|
return ticket.assigneeId === user.id;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user