This page captures business rules enforced by this library.
BR-MNU-01: Menu item visibility determined by security-group or user mapping¶
Field
Value
Statement
A menu item's visibility to a user is determined by whether the user's SecurityGroup (via clsMenuSecurityUser) or explicit user mapping matches a clsMenuSecurity record tied to that MenuItemSeqNum; items with no MENU_SECURITY record are treated as unsecured and visible to all users.**
Trigger
A presentation-layer or menu-rendering consumer requests the authorized menu-item list for a user.
Enforcement
Data is gathered by SQL-015 (all-user UNION query) or SQL-016 (per-user UNION query) in clsMenuAuthorizedItemCollection. The actual authorization gating decision is performed by the consuming presentation layer using this data, not within this library.**
Outcome
The authorized-item collection returned to the caller includes only items matching the user's security group, plus items with no security record (flagged UnsecuredFlag = 'Y'), plus the user's active favorites.
Every insert, update, or delete operation must affect exactly one row. If RowsAffected <> 1, an error is immediately raised and the operation is considered failed.
Trigger
AfterInsert, AfterUpdate, or AfterDelete lifecycle method is called following any DML SQL execution.
Enforcement
Each After* method checks RowsAffected <> 1 and calls AddErrorMessage("InsertError"/"UpdateError"/"DeleteError", ...). Applies to all 7 tables: BUSONLINE_APPS_CODE, MENU_CATEGORY_CODE, MENU_FAVORITE, MENU_ITEM, MENU_PAGE, MENU_SECURITY, MENU_SECURITY_USER.
Outcome
Failed operations add an error message to the business object; the save is rejected. Successful operations call MarkOld() (insert/update) or MarkNew() (delete).
When retrieving active application codes, only records where NVL(ACTIVE_CODE, 'Y') = 'Y' are returned. Records with a null ACTIVE_CODE are treated as active by default.
Trigger
clsApplicationCodeCollection.BeforeRetrieve is called with ActiveOnly = True.
Enforcement
SQL-013 applies the WHERE NVL(ACTIVE_CODE, 'Y') = 'Y' predicate.
Outcome
The collection contains only active application codes. Inactive codes are excluded.
Security group comparisons between MENU_SECURITY.SECURITY_GROUP_TXT and MENU_SECURITY_USER.SECURITY_GROUP_TXT are performed case-insensitively using UPPER().
Trigger
clsMenuAuthorizedItemCollection.BeforeRetrieve executes either SQL-015 or SQL-016.
Enforcement
Both UNION queries apply UPPER(USR.SECURITY_GROUP_TXT) = UPPER(SEC.SECURITY_GROUP_TXT) in the join predicate.
Outcome
Users are matched to security groups regardless of the case in which the SecurityGroup string was stored.
SAIF.Business.Menu includes two framework-derived classes (frameworkClassCount: 2 per dependency-resolution.json). The BOF framework base classes (clsBusinessBase, clsBusinessCollection(Of T)) define lifecycle and validation contracts that all BOF business objects inherit. Specific inherited rule details could not be enumerated: the Legends CLI has no indexed content for BOF framework base classes in this run.*
BR-MNU-01 describes a data model enforced in the database layer; the authorization gating decision itself resides in a consuming presentation-layer component outside this library's scope.
The clsMenuSecurityUserCollection.BeforeRetrieve method appears to invert its bind behavior: retrieveForUserSQL (SQL-029) is selected without AddParm("MenuUser", ...), while the unfiltered RetrieveSQL (SQL-030) branch adds :MenuUser even though the SQL text has no bind variable. This is a potential source defect noted in the DB analysis.*
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.