Skip to content

SAIF.Presentation business rules

This page captures business rules enforced by SAIF.Presentation's sole public type, clsPreferences. All persistence is delegated to SAIF.Framework.Preferences.PreferenceData; no rule in this library involves SQL or database tables owned by this repository.

BR-PRES-001: Preference store scoped to one application

Field Value
Statement A preference store is always scoped to one application name supplied at construction.
Trigger clsPreferences construction
Enforcement clsPreferences.vb (Initialize)
Outcome All reads and writes filter on that application.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-002: Preference access uses the fixed Oracle user CLM

Field Value
Statement Preference data is always read as the fixed Oracle user CLM, against the database named by the framework OracleDatabase configuration key.
Trigger Load
Enforcement clsPreferences.vb (Load)
Outcome Preference access runs under a dedicated, environment-resolved account.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-003: Effective user identity comes from the data portal

Field Value
Statement The effective user identity for preference storage is the data portal's UserID, not the user ID passed to the constructor.
Trigger Load, Save
Enforcement clsPreferences.vb
Outcome Preferences follow the authenticated data-portal identity.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-004: All preferences loaded eagerly on construction

Field Value
Statement All of a user's preferences (every application, every page) are loaded eagerly on construction.
Trigger Load
Enforcement clsPreferences.vb (Load)
Outcome Subsequent reads incur no database round trips.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-005: User ID trimmed and lower-cased for lookup

Field Value
Statement The user ID used for the preference lookup is trimmed and lower-cased.
Trigger Load
Enforcement clsPreferences.vb (Load)
Outcome Case and whitespace differences do not split a user's preferences.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-006: A Nothing key is a no-op

Field Value
Statement A Nothing key is a no-op: reads return Nothing and writes/removals do nothing.
Trigger Any Item, Add, Remove call
Enforcement clsPreferences.vb
Outcome No null-reference failures from caller input.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-007: Preference keys are case-insensitive

Field Value
Statement Preference keys are case-insensitive — they are lower-cased on every read, add, and remove.
Trigger Any keyed operation
Enforcement clsPreferences.vb
Outcome ColNamesGrid1 and colnamesgrid1 address the same preference.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-008: Only PageLevel scope binds to a page

Field Value
Statement Only PrefScope.PageLevel binds a preference to a page; AppLevel and WebLevel both resolve to an empty page key.
Trigger PageKey
Enforcement clsPreferences.vb (PageKey)
Outcome AppLevel and WebLevel preferences currently share the same storage slot.*
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-009: Web page name derived from request path

Field Value
Statement In a web context the page name is the last path segment of Request.Path.
Trigger Page getter with a non-null HttpContext.Current
Enforcement clsPreferences.vb (Page)
Outcome Page-scoped preferences are keyed by the .aspx page name.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-010: Non-web page name derived from override or call stack

Field Value
Statement Outside a web context the page name is OverridePage when set, otherwise the declaring type name reflected from the call stack (skipping four frames).
Trigger Page getter with a null HttpContext.Current
Enforcement clsPreferences.vb (Page)
Outcome Desktop callers get a form-name-based page key; OverridePage must be set before Save.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-011: Preference record identified by application and page

Field Value
Statement A preference record is identified by the pair (application name, page name).
Trigger Any scoped read/write
Enforcement clsPreferences.vb
Outcome One JSON item bag exists per application + page per user.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-012: Explicit three-argument lookup matches lower-cased fields

Field Value
Statement The explicit three-argument lookup matches on lower-cased application and page names and treats Nothing arguments as empty strings.
Trigger Item(inApplication, inPage, inKey)
Enforcement clsPreferences.vb
Outcome Cross-application/page reads are possible without changing scope.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-013: Adding a preference creates a missing record

Field Value
Statement Adding a preference for an application/page combination that has no record creates the record on demand.
Trigger Add with no matching Preference
Enforcement clsPreferences.vb (Add)
Outcome New pages get a preference bag automatically.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-014: Adding an existing key replaces its value

Field Value
Statement Adding an existing key replaces the previous value (remove-then-add).
Trigger Add with a key already present
Enforcement clsPreferences.vb (Add)
Outcome Keys are unique within a preference record.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-015: Preference values stored as strings

Field Value
Statement Preference values are stored as strings (inValue.ToString()).
Trigger Add
Enforcement clsPreferences.vb (Add)
Outcome Callers must parse values back to their intended type.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-016: Removing an absent key is a no-op

Field Value
Statement Removing a key that is not present is a silent no-op.
Trigger Remove
Enforcement clsPreferences.vb (Remove)
Outcome No exception for an absent key.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-017: Clear empties all items in a scope's record

Field Value
Statement Clear(scope) empties every item in the current application's record for that scope.
Trigger Clear
Enforcement clsPreferences.vb (Clear)
Outcome A whole page's preferences are reset in one call.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-018: Delete empties every loaded record

Field Value
Statement Delete() empties every loaded preference record for the user, across all applications and pages.
Trigger Delete
Enforcement clsPreferences.vb (Delete)
Outcome Full user preference reset.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-019: Mutations are in-memory until Save

Field Value
Statement Mutations are in-memory only until Save() is called.
Trigger Add, Remove, Clear, Delete
Enforcement clsPreferences.vb
Outcome Callers must call Save() or changes are lost at the end of the request.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-020: Save persists only the current application's records

Field Value
Statement Save() persists only records belonging to the store's current application.
Trigger Save
Enforcement clsPreferences.vb (Save)
Outcome Records for other applications loaded into memory are left untouched.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-021: Preference items persisted as JSON

Field Value
Statement Preference items are persisted as a JSON-serialized dictionary.
Trigger Save with a non-empty item bag
Enforcement clsPreferences.vb (Save)
Outcome One JSON document per application + page per user.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-022: Empty preference record persisted as empty string

Field Value
Statement An emptied preference record is persisted as an empty string rather than an empty JSON object.
Trigger Save with PreferenceItems.Count = 0
Enforcement clsPreferences.vb (Save)
Outcome Cleared preference bags are stored as blank.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-023: Persistence always routed through PreferenceData

Field Value
Statement Persistence is always routed through PreferenceData.SavePreferences — this library issues no SQL.
Trigger Save
Enforcement clsPreferences.vb (Save)
Outcome Storage details remain the framework's concern.
Source SAIF.Presentation/clsPreferences.vb

BR-PRES-024: Persistence failures wrapped in ApplicationException

Field Value
Statement Any persistence failure is wrapped in an ApplicationException with the message "Unable to save preferences."
Trigger Exception inside Save
Enforcement clsPreferences.vb (Save)
Outcome Callers get a consistent, contextualized error.
Source SAIF.Presentation/clsPreferences.vb

Notes

  • Save() always returns False even on success — the result local is never assigned True before the (unreachable) trailing trace call. Callers checking the boolean return value of Save() cannot rely on it to detect failure; failures are instead signaled by the ApplicationException described in BR-PRES-024.*

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.

Sources

  • SAIF.Presentation/clsPreferences.vb