---
title: Filter associations and select the default
summary: Applies ownership-based association filtering and selects the default association type for header rendering.
status: draft
owner: SAIF Documentation Generation
last_reviewed: 2026-07-31
library: SAIF.Application.Policy
reference_type: package
operation_id: OP-06
trigger: Header associations are loaded or the selected association type is unset
---

# Filter associations and select the default

This operation narrows the policy-header association set to the rows the current principal may see and chooses the default association type used by the header.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-06 |
| **Trigger** | Header associations are loaded or the selected association type is unset |
| **Inputs** | Policy-header associations, security principal, validated association types |
| **Outputs** | Filtered association rows and default association-type selection |
| **Primary components** | `clsPolicyHeaderSecurityManager.FilterAssociationsByUserType`, `PolicyAppManager.GetDefaultAssociationType` |
| **Entry point** | `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb` |

## Steps

1. Classify the principal as policyholder, agent, or neither.
2. If the principal is neither a policyholder nor an agent, return the incoming associations unchanged ([BR-113](../business-rules.md#br-113-association-filtering-applies-only-to-policyholders-and-agents)).
3. Resolve the caller's user number and convert it to `Decimal`.
   - If conversion fails, raise `ApplicationException("Unable to determine user number.")` ([BR-114](../business-rules.md#br-114-non-numeric-user-number-fails-closed)).
4. For policyholders, collect the association types where the user's own policy is the parent and keep only rows of those types ([BR-115](../business-rules.md#br-115-policyholders-see-only-their-parented-association-types)).
5. For agents, keep only rows whose `AgentNumber` or `AgencySeqNum` matches the user's number ([BR-116](../business-rules.md#br-116-agents-see-only-their-own-agent-or-agency-associations)).
6. When the header needs a default association type, keep only rows whose types survive both `AssociationTypeTargets` and `ValidatedAssociationTypes`, then select the lowest `SortOrder` type.
   - If no association survives both filters, return `clsUnknownAssociationTypeCode` instead of throwing ([BR-117](../business-rules.md#br-117-default-association-type-is-lowest-sort-order)).

## Process flow

The following diagram visualizes ownership filtering and default selection.

```mermaid
flowchart TD
    Start([Associations loaded]) --> Role{Policyholder or agent?}
    Role -->|Neither| All[Return all rows]
    Role -->|Yes| UserNo[Resolve numeric user number]
    UserNo --> Convert{Numeric?}
    Convert -->|No| Fail([Raise exception])
    Convert -->|Yes| Branch{Policyholder or agent?}
    Branch -->|Policyholder| PH[Keep parented association types]
    Branch -->|Agent| AG[Keep matching agent or agency rows]
    PH --> Default[Choose lowest-sort-order type]
    AG --> Default
    All --> Default
    Default --> Done([Return filtered rows and default type])
```

## Failure and edge-case behavior
- User-number conversion fails closed through [BR-114](../business-rules.md#br-114-non-numeric-user-number-fails-closed).
- Empty post-filter results fall back to `clsUnknownAssociationTypeCode` rather than surfacing an invalid-operation exception ([BR-117](../business-rules.md#br-117-default-association-type-is-lowest-sort-order)).

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Security and authorization](../security-authorization.md)

## Sources
- `Application\SAIF.Application.Policy\PolicyAppManager.vb`
- `Application\SAIF.Application.Policy\PolicyHeader\clsPolicyHeaderSecurityManager.vb`
