---
title: Build the permitted policy list
summary: Builds the permitted policy list for the signed-in principal, dispatching on user type.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-31
library: SAIF.Business.View.Policy
reference_type: package
operation_id: OP-07
trigger: `clsPolicySecurity.PolicyList` is read for the first time
---

# Build the permitted policy list

Where the authorization check answers "may this user see this policy?", this operation answers the broader question "which policies may this user see at all?". Consuming applications use the result to populate policy pickers and search scopes. Each user type has its own source query, and the operation deliberately produces an empty list rather than an unrestricted one when nothing matches.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-07 |
| **Trigger** | `clsPolicySecurity.PolicyList` is read for the first time |
| **Inputs** | The principal supplied to the constructor |
| **Outputs** | A cached list of permitted policy numbers and names |
| **Primary components** | `clsPolicySecurity.PolicyList` |
| **Entry point** | `Business/SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Steps

1. Return the cached list when it has already been built; otherwise initialise an empty list and dispatch on the principal's user type.
2. For an agent, run the agency policy-list procedure against the group-membership store, passing the agent number and an agency-scope flag ([BR-018](../business-rules.md#br-018-agent-policy-lists-are-produced-only-for-numeric-agent-identifiers)).
   - The query runs only when the agent's user number is numeric; a non-numeric identifier leaves the list empty.
   - The agency-scope flag is the yes/no form of "the user is not a producer", so a non-producer agent receives the whole agency's book.
3. For a policyholder, enumerate the affiliated policies of the user's own policy and project each into a number-and-name pair ([Retrieve affiliated policies](retrieve-affiliated-policies.md)).
4. For a loss-control consultant, run the safety-consultant book procedure with the consultant identifier.
5. For a group user, run the group policy-list procedure with the group key, specific chapter code, and report date.
6. For a fee auditor, run an Oracle statement over the audit tables scoped to the auditor's vendor number and restricted to audits that are neither cancelled nor completed more than sixty days ago ([PA_AUDIT](../database-tables.md#pa-audit)).
7. Return the list. When no branch matched, the empty list built in the first step is returned rather than nothing or an unrestricted list ([BR-019](../business-rules.md#br-019-policy-lists-fail-closed)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([PolicyList read]) --> C{Already built?}
    C -->|Yes| Ret([Return cached list])
    C -->|No| E[Initialise an empty list]
    E --> D{User type}
    D -->|Agent| A{Agent number numeric?}
    A -->|Yes| AQ[(Agency policy list procedure)]
    A -->|No| Empty[Leave the list empty]
    D -->|Policyholder| PQ[Enumerate affiliated policies]
    D -->|Loss control| LQ[(Safety consultant book procedure)]
    D -->|Group| GQ[(Group policy list procedure)]
    D -->|Auditor| UQ[(Auditor policy list query)]
    D -->|Unmatched| Empty
    AQ --> Ret
    PQ --> Ret
    LQ --> Ret
    GQ --> Ret
    UQ --> Ret
    Empty --> Ret
```

## Failure and edge-case behavior

- A non-numeric agent identifier produces an empty list rather than an error ([BR-018](../business-rules.md#br-018-agent-policy-lists-are-produced-only-for-numeric-agent-identifiers)).
- An unmatched user type produces an empty list, never an unrestricted one ([BR-019](../business-rules.md#br-019-policy-lists-fail-closed)).
- Four of the six branches depend on the separately configured SQL Server store, so a configuration error silently narrows what a user can see.**

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)
- [Procedures](../procedures/index.md)
- [Security and authorization](../security-authorization.md)
- [API reference](../api/index.md)

## Sources

- `Business/SAIF.Business.View.Policy/clsPolicySecurity.vb`
