---
title: "Manage a user's menu favorites"
summary: "Creates, updates, removes, and retrieves favorite menu rows."
status: draft
owner: SAIF documentation team
last_reviewed: 2026-08-17
library: SAIF.Business.Menu
reference_type: package
operation_id: OP-MENU-002
trigger: "Caller maintains or loads favorites."
---

# Manage a user's menu favorites

Creates, updates, removes, and retrieves favorite menu rows.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-MENU-002 |
| **Trigger** | Caller maintains or loads favorites. |
| **Inputs** | `IDataPortalInfo`, user and favorite keys |
| **Outputs** | Persisted favorite rows and collections |
| **Primary components** | `clsMenuFavorite`, `clsMenuFavoriteCollection` |
| **Entry point** | `SAIF.Business.Menu\clsMenuFavorite.vb` |

## Steps

1. Create a new favorite key with [SQL-MENU-036](../sql/SQL-MENU-036-next-menu-favorite-sequence.md) against [MENU_FAVORITE](../database-tables.md#menufavorite).
2. Insert a new favorite with [SQL-MENU-038](../sql/SQL-MENU-038-insert-menu-favorite.md) or retrieve an existing favorite with [SQL-MENU-039](../sql/SQL-MENU-039-retrieve-menu-favorite.md).
3. Update order or inactive date with [SQL-MENU-040](../sql/SQL-MENU-040-update-menu-favorite.md), or delete the row with [SQL-MENU-037](../sql/SQL-MENU-037-delete-menu-favorite.md).
4. After every insert, update, or delete, validate that exactly one row changed so the object honors [BR-MENU-001](../business-rules.md#br-menu-001-optimistic-contention-on-write).
5. Load all favorites with [SQL-MENU-041](../sql/SQL-MENU-041-retrieve-all-menu-favorites.md) or one user's favorites with [SQL-MENU-042](../sql/SQL-MENU-042-retrieve-menu-favorites-for-user.md).
6. When menu composition later executes [SQL-MENU-043](../sql/SQL-MENU-043-retrieve-authorized-menu-items-for-user.md), active favorites re-enter the authorized set ([BR-MENU-004](../business-rules.md#br-menu-004-favorites-are-always-included-and-ordered)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Caller manages favorite]) --> CreateOrLoad{New, update,<br/>or delete?}

    CreateOrLoad -->|New favorite| NextVal["SQL-MENU-036: get next<br/>MENU_FAVORITE sequence value"]
    NextVal --> Insert["SQL-MENU-038: insert<br/>new favorite row"]
    Insert --> Verify{"Rows affected = 1?<br/>(BR-MENU-001)"}

    CreateOrLoad -->|Update order/<br/>inactive date| Update["SQL-MENU-040: update<br/>favorite order or<br/>ITEM_INACTIVE_DATE"]
    Update --> Verify

    CreateOrLoad -->|Delete| Delete["SQL-MENU-037: delete<br/>favorite row"]
    Delete --> Verify

    CreateOrLoad -->|Retrieve existing| Retrieve["SQL-MENU-039: retrieve<br/>one existing favorite"]
    Retrieve --> Ready(["Favorite persisted"])

    Verify -->|No| Error(["Report optimistic-contention<br/>error — do not commit"])
    Verify -->|Yes| Ready

    Ready --> LoadAll["Load all favorites<br/>(SQL-MENU-041) or one user's<br/>favorites (SQL-MENU-042)"]
    LoadAll --> Compose["Menu composition<br/>(SQL-MENU-043) re-includes<br/>active favorites<br/>(BR-MENU-004)"]
```

## Failure and edge-case behavior

- A soft-deleted favorite remains stored but drops out of active menu composition because [SQL-MENU-043](../sql/SQL-MENU-043-retrieve-authorized-menu-items-for-user.md) requires `ITEM_INACTIVE_DATE IS NULL`.
- Row-count mismatches surface through [BR-MENU-001](../business-rules.md#br-menu-001-optimistic-contention-on-write) instead of silently succeeding.

## Related documentation
- [Index](../index.md)
- [Overview](../overview.md)
- [Architecture](../architecture.md)
- [Dependencies](../dependencies.md)
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Security and authorization](../security-authorization.md)
- [Database tables](../database-tables.md)
- [SQL catalog](../sql/index.md)
- [API reference](../api/index.md)

## Sources
- `SAIF.Business.Menu\clsMenuFavorite.vb`
