> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gominerva.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Work Queues Guide

> How administrators set up work queues and how members use My Work and shared queues to process review work.

export const StorybookFrame = ({storyId, title, version = "20260419-1", height, zoom = 0.7, preferLocalPreview = false, manageStoryFocus = false, nonInteractivePreview = false}) => {
  const LOAD_TIMEOUT_MS = 15000;
  const POST_LOAD_STEAL_MS = 3000;
  const GESTURE_GRACE_MS = 1000;
  const STORYBOOK_HOST = "minerva-storybook.s3";
  const HOSTED_STORYBOOK_BASE_URL = "https://minerva-storybook.s3.ca-central-1.amazonaws.com/iframe.html";
  const isLocalDocsPreview = typeof window !== "undefined" && ["localhost", "127.0.0.1"].includes(window.location.hostname);
  const storybookBaseUrl = preferLocalPreview && isLocalDocsPreview ? "http://localhost:6006/iframe.html" : HOSTED_STORYBOOK_BASE_URL;
  const params = new URLSearchParams({
    id: storyId,
    viewMode: "story",
    singleStory: "true",
    shortcuts: "false",
    toolbar: "0",
    nav: "0",
    panel: "0"
  });
  params.set("v", version);
  const src = `${storybookBaseUrl}?${params.toString()}`;
  const unscaledHeight = `${Math.ceil(height / zoom)}px`;
  const unscaledWidth = `${100 / zoom}%`;
  const containerRef = useRef(null);
  const [failed, setFailed] = useState(false);
  useEffect(() => {
    if (failed) return undefined;
    const container = containerRef.current;
    if (!container || typeof document === "undefined") return undefined;
    let detach;
    const attach = iframe => {
      let loadCount = 0;
      let loadTimeoutId;
      const onLoad = () => {
        loadCount += 1;
        clearTimeout(loadTimeoutId);
        if (loadCount > 1) setFailed(true);
      };
      const startLoadTimeout = () => {
        if (loadTimeoutId || loadCount > 0) return;
        loadTimeoutId = setTimeout(() => {
          if (loadCount === 0) setFailed(true);
        }, LOAD_TIMEOUT_MS);
      };
      iframe.addEventListener("load", onLoad);
      let observer;
      if (typeof IntersectionObserver === "function") {
        observer = new IntersectionObserver(entries => {
          if (entries.some(entry => entry.isIntersecting)) startLoadTimeout();
        }, {
          rootMargin: "200px"
        });
        observer.observe(container);
      } else {
        startLoadTimeout();
      }
      return () => {
        iframe.removeEventListener("load", onLoad);
        clearTimeout(loadTimeoutId);
        if (observer) observer.disconnect();
      };
    };
    const tryAttach = () => {
      if (detach) return;
      const iframe = container.querySelector("iframe");
      if (iframe) detach = attach(iframe);
    };
    tryAttach();
    const mutations = new MutationObserver(tryAttach);
    mutations.observe(container, {
      childList: true,
      subtree: true
    });
    return () => {
      mutations.disconnect();
      if (detach) detach();
    };
  }, [failed]);
  useEffect(() => {
    if (!manageStoryFocus || typeof document === "undefined") return undefined;
    let animationFrameId;
    let guardUntil = 0;
    let lastGestureAt = 0;
    let previousActive = null;
    let stableScrollX = window.scrollX;
    let stableScrollY = window.scrollY;
    const frameLoadedAt = new WeakMap();
    const isStorybookFrame = element => element && element.tagName === "IFRAME" && (element.src || "").includes(STORYBOOK_HOST);
    const noteGesture = event => {
      if (event.key === "Tab") lastGestureAt = Date.now();
    };
    const checkFocus = () => {
      animationFrameId = undefined;
      if (document.visibilityState === "visible") {
        const active = document.activeElement;
        if (active === previousActive) {
          if (!active || active.tagName !== "IFRAME") {
            stableScrollX = window.scrollX;
            stableScrollY = window.scrollY;
          }
        } else {
          previousActive = active;
          if (!active || active.tagName !== "IFRAME") {
            stableScrollX = window.scrollX;
            stableScrollY = window.scrollY;
          } else if (isStorybookFrame(active)) {
            const loadedAt = frameLoadedAt.get(active);
            const deliberate = loadedAt && lastGestureAt > loadedAt && Date.now() - lastGestureAt < GESTURE_GRACE_MS;
            if (loadedAt && Date.now() - loadedAt <= POST_LOAD_STEAL_MS && !deliberate) {
              active.blur();
              window.scrollTo(stableScrollX, stableScrollY);
              previousActive = document.activeElement;
            }
          }
        }
      }
      if (Date.now() < guardUntil) animationFrameId = requestAnimationFrame(checkFocus);
    };
    const noteFrameLoad = event => {
      const target = event.target;
      if (!isStorybookFrame(target)) return;
      const loadedAt = Date.now();
      frameLoadedAt.set(target, loadedAt);
      guardUntil = Math.max(guardUntil, loadedAt + POST_LOAD_STEAL_MS);
      if (!animationFrameId) animationFrameId = requestAnimationFrame(checkFocus);
    };
    document.addEventListener("keydown", noteGesture, true);
    document.addEventListener("load", noteFrameLoad, true);
    return () => {
      document.removeEventListener("keydown", noteGesture, true);
      document.removeEventListener("load", noteFrameLoad, true);
      if (animationFrameId) cancelAnimationFrame(animationFrameId);
    };
  }, [manageStoryFocus]);
  const frameStyle = {
    height: `${height}px`,
    overflow: "hidden",
    border: "1px solid #e2e8f0",
    borderRadius: "12px",
    backgroundColor: "#ffffff",
    display: "flex",
    justifyContent: "center",
    alignItems: "flex-start"
  };
  if (failed) {
    return <div style={{
      width: "100%"
    }}>
        <div role="status" aria-live="polite" style={{
      ...frameStyle,
      alignItems: "flex-start",
      backgroundColor: "#f8fafc",
      color: "#475569",
      textAlign: "center",
      padding: "0 24px"
    }}>
          <div style={{
      width: "100%",
      height: "100%",
      maxHeight: "280px",
      display: "grid",
      placeItems: "center"
    }}>
            <div>
              <div role="heading" aria-level="4" style={{
      fontWeight: 600,
      margin: "0 0 4px"
    }}>
                {title}
              </div>
              <p style={{
      fontSize: "0.875rem",
      margin: 0
    }}>
                This figure is unavailable here. Continue with the instructions
                on this page.
              </p>
            </div>
          </div>
        </div>
      </div>;
  }
  return <div style={{
    width: "100%"
  }} ref={containerRef}>
      <div style={frameStyle}>
        <iframe src={src} tabIndex={nonInteractivePreview ? -1 : undefined} title={title} loading="lazy" style={{
    width: unscaledWidth,
    height: unscaledHeight,
    transform: `scale(${zoom})`,
    border: "0",
    display: "block",
    transformOrigin: "top center",
    pointerEvents: nonInteractivePreview ? "none" : "auto",
    flexShrink: 0
  }} allowFullScreen></iframe>
      </div>
      {nonInteractivePreview && <p style={{
    margin: "8px 0 0",
    textAlign: "right",
    fontSize: "0.875rem"
  }}>
          <a href={src} target="_blank" rel="noopener noreferrer">
            Open {title} in a new tab
          </a>
        </p>}
    </div>;
};

Work queues organize open review work across profiles, potential matches, risk assessments, and document verifications. Administrators define useful views and, when needed, an assignment pool. Members then work from **My Work** or open a shared queue to choose an item.

<Info>
  Your organization's standard operating procedures (SOPs) govern which work to
  prioritize, how often to review each queue, applicable service-level
  agreements (SLAs), escalation paths, and disposition policy. Minerva provides
  the work views and assignment tools; it does not replace those procedures.
</Info>

## Roles at a glance

| Role               | Responsibilities                                                                                                                                     |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Owner or Admin** | Create, edit, and delete queues; choose sections and filters; configure manual or round-robin assignment; maintain the assignment pool.              |
| **Member**         | Review assigned items in **My Work**; browse queues; take available work; complete review decisions on the item's own page; favourite useful queues. |

Members can open and use queues, but only Owners and Admins can change queue definitions or assignment settings. Demo organizations are read-only.

# Admin setup

## Create the first queue

Go to **Dashboards** > **Work Queues**. If the organization has no queues, the setup gallery appears on the page.

<StorybookFrame storyId="pages-dashboards-work-queues-manager--guide-admin-first-queue-setup" title="Admin First Queue Setup" height={760} preferLocalPreview version="20260827-work-queues-guide" />

1. Select **All open work** for the simplest starting point. It includes open profiles, potential matches, risk assessments, and document verifications in one queue.
2. Give the queue a name and description that match your team's operating language.
3. Review each section's item type and filters. A section is one tab in the finished queue.
4. Choose the sort order and default view.
5. Under **Assignment**, choose **Manual** or **Round robin**.
6. Save the queue, then open it from the queue list to confirm that its sections and counts match the intended workflow.

<Tip>
  Start with one broad queue and split it only when different work needs a
  different owner, cadence, SLA, or policy. Too many overlapping queues can make
  the same item appear in several places without changing who owns it.
</Tip>

## Choose queues for common situations

The setup gallery includes templates that can be adjusted before saving.

| Situation                                             | Recommended starting template                                                                                                      | Why it helps                                                                                                           |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| A team is adopting work queues for the first time     | **All open work**                                                                                                                  | Gives the team one place to see all supported open work before deciding whether to split it.                           |
| Teams are organized by how screening was initiated    | **Onboarding queue** or **Ongoing monitoring queue**                                                                               | Separates work by channel. The channel can be adjusted in the builder, including for Direct API calls where available. |
| A specialist team handles assessments                 | **Risk assessment queue**                                                                                                          | Shows assessments waiting for a human decision.                                                                        |
| One team handles all open matches                     | **All potential matches**                                                                                                          | Combines open matches from every channel.                                                                              |
| Different teams own onboarding and monitoring matches | **Onboarding potential matches** and **Ongoing monitoring potential matches**                                                      | Splits potential-match work by channel.                                                                                |
| Specialists own a finding category                    | **Sanctions review**, **PEP review**, **Adverse media review**, **Criminal review**, **Legal review**, or **Internal risk review** | Groups open profiles and matches by finding category. Available categories depend on the organization's entitlements.  |
| Senior reviewers handle escalated work                | **Escalations**                                                                                                                    | Collects escalated items across channels.                                                                              |
| Members should choose work from a shared pool         | **Unassigned work**                                                                                                                | Shows open work that nobody has picked up yet.                                                                         |

Queue templates are starting points. Confirm every section, filter, and assignment setting against the organization's SOP before saving.

## Choose an assignment method

### Manual

With **Manual** assignment, new items stay unassigned until a member takes one or an authorized user assigns it. Use this when members deliberately pull work based on expertise, jurisdiction, priority, or another rule in the team's SOP.

### Round robin

With **Round robin**, new unassigned items are shared across **available** members of the assignment pool. Use this when work can be distributed evenly and the team does not need to choose each item first.

Round robin applies to new assignments. Existing work keeps its current assignee when the pool or method changes; editing the pool does not rebalance it. Members control whether they are **Active** or **Away** under their account's work queue availability setting. Away excludes a member from new assignment decisions after the change is recorded, although an allocation already in flight can still complete.

<Note>
  The assignment pool selects who can receive new work. It does not grant access
  to a queue or its items. Some item types use assignment behavior owned by
  their source service. The queue builder shows which assignment controls apply.
  When assignment is not available in the queue table, open the item and use the
  assignment control on its own page.
</Note>

## Maintain the queue list

The Admin view includes queue-management controls in addition to the same queue list members use.

<StorybookFrame storyId="pages-dashboards-work-queues-list--guide-admin-work-queues" title="Admin Work Queues List" height={620} preferLocalPreview version="20260827-work-queues-guide" />

Administrators should periodically confirm that:

* queue sections still match the team's SOP and current product entitlements
* assignment pools contain active team members and exclude people who no longer receive that work
* overlapping queues remain intentional
* descriptions clearly tell members what belongs in each queue
* queues with no open items are genuinely caught up, rather than filtered incorrectly

# Member daily workflow

## Start in My Work

Go to **Dashboards** > **My Work** to see open items assigned to you across queues. My Work deduplicates items that appear in more than one saved queue, so its count is the most useful personal backlog count.

| Work item                  | When it appears in open work                                                                   | Common examples                                                                                                                     | Where it opens                                          |
| -------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| **Profiles**               | A customer profile still needs review because profile-level screening or verification is open. | Profile screening, profile verification                                                                                             | The customer profile                                    |
| **Potential matches**      | An alert is unresolved or reopened.                                                            | Sanctions, PEP, adverse media, criminal records, watchlists, legal, and internal risk                                               | The potential match on its parent customer profile      |
| **Risk assessments**       | A search assessment or agent workflow is assigned to you in a workable state.                  | Search assessments, agent risk-assessment workflows                                                                                 | The owning search assessment or agent assessment        |
| **Document verifications** | A returned verification session is in **Requires review** or **Escalation**.                   | Configured workflows for onboarding forms or questionnaires, KYB or document collection, identity verification, and liveness checks | The verification session on its parent customer profile |

<Info>
  Document verification availability and configuration vary by organization.
  Sessions in **Pending** or **Request sent** do not appear as open analyst work
  in My Work. **Held for review** is a finding-level label, not a universal
  work-queue state. Follow your organization's SOP for priority, escalation, and
  disposition decisions.
</Info>

<StorybookFrame storyId="components-work-queues-working-surface--guide-member-my-work" title="My Work with all supported work-item tabs" height={610} preferLocalPreview version="20260827-expanded-work-queues-guide" />

<StorybookFrame storyId="components-work-queues-working-surface--guide-assigned-risk-assessments" title="Assigned search and agent risk assessments" height={610} preferLocalPreview version="20260827-expanded-work-queues-guide" />

<StorybookFrame storyId="components-work-queues-working-surface--guide-document-verifications-requiring-review" title="Document verifications requiring review or escalation" height={650} preferLocalPreview version="20260827-expanded-work-queues-guide" />

Use the section tabs to move among **Profiles**, **Potential matches**, **Risk assessments**, and **Document verifications**. A section appears when that type is available to your organization and assignable to you.

Statuses are item-type specific rather than one universal queue workflow. Examples of open, workable states include:

* **Potential Match** or **In Review** on a profile
* **Unresolved** or **Reopened** on a potential match
* **Ready for review**, **In review**, **Waiting for user**, **Interrupted**, **Escalation**, or **Reopened** on a risk assessment
* **Requires review** or **Escalation** on a document verification

A document-verification finding can also be **Held for review** within its finding workflow. That label describes the finding, not a generic state shared by every queue item. Sessions that are still **Pending** or **Request sent** are not open analyst work.

Open an item and complete the review on its own page. An item leaves the default **Outstanding work** view when its status is no longer open and workable for that item type. As assigned items leave those states, the **My Work** count decreases. Use **All items** to see previous assigned work that is no longer in the outstanding view.

<StorybookFrame storyId="components-work-queues-working-surface--guide-member-my-work-caught-up" title="My Work Caught Up" height={520} preferLocalPreview version="20260827-work-queues-guide" />

Use **All items** when you need to see work that has left the outstanding view. A lower My Work count does not by itself determine whether an SLA or review obligation is complete; apply the organization's SOP and verify the item's final disposition.

## Pull work from a queue

If My Work is clear, or your SOP directs you to a shared queue:

1. Go to **Dashboards** > **Work Queues**.
2. Open the queue that matches the required priority, channel, finding type, or situation.
3. Use **Mine** to focus on items assigned to you, or use the queue's broader view to see available work.
4. Select **Take** on an available item, or open it and assign it on the item page when that is where assignment is supported.
5. Complete the review on the item's own page, following the required disposition and escalation policy.

<StorybookFrame storyId="components-work-queues-working-surface--guide-member-pull-from-queue" title="Member Pulling Unassigned Work" height={610} preferLocalPreview version="20260827-work-queues-guide" />

Return to the queue list to choose a different queue or favourite one you use often.

<StorybookFrame storyId="pages-dashboards-work-queues-list--guide-member-work-queues" title="Member Work Queues List" height={620} preferLocalPreview version="20260827-work-queues-guide" />

Favourite queues you use often. Favourites change how your queue list is organized; they do not change queue membership, item ownership, or priority.

## Wait for round-robin work

When your team uses round robin, keep your work queue availability accurate:

* choose **Active** when you are ready to receive new work
* choose **Away** when you should not receive new assignments
* work assigned items from **My Work** in the order required by your organization's SOP

Do not take work from another queue merely because My Work is temporarily clear if the team's SOP requires you to wait for a particular assignment or escalation path.

## When a view is loading, clear, or unavailable

* A loading view has not confirmed its counts yet. Wait for it to finish before deciding that no work exists.
* **This queue is clear** or **You're caught up** is a successful empty state for the current view. Check active filters and the selected section before relying on it.
* If a queue cannot load, use **Try again**. If the problem continues, check your connection and contact your Minerva administrator or [Minerva Support](mailto:support@gominerva.com).
* If no queues exist, a member sees that the organization has not created one yet. Ask an Owner or Admin to complete the first-queue setup.

<StorybookFrame storyId="pages-dashboards-work-queues-list--guide-member-work-queues-error" title="Work Queues Load Error" height={520} preferLocalPreview version="20260827-work-queues-guide" />

## Operational checklist

Before each review session:

* confirm the selected workspace and organization
* follow the queue order, cadence, and SLA defined by your SOP
* check **My Work** before pulling unassigned work, unless your SOP says otherwise
* keep round-robin availability current
* review active filters before concluding that a queue is clear
* complete the decision on the item's own page rather than treating assignment as completion
* escalate exceptions through the organization's approved process
