Skip to content

SAIF.Framework.Preferences business rules

This page captures business rules enforced by SAIF.Framework.Preferences when reading, writing, and normalizing preference data in USER_PREFERENCE.

BR-001: User IDs are normalized to lower case

Field Value
Statement User IDs are normalized to lower case before querying or storing preference data.
Trigger Any call to GetPreferences, GetPreferencesForUser, InsertPref, UpdatePref, DeletePref, or DoesPrefExist.
Enforcement userId.ToLower() is passed to SqlHelper.NewParm("userid", ...) in each method.
Outcome Preference lookups and writes are effectively case-insensitive on user ID.
Tables USER_PREFERENCE
SQL SQL-002, SQL-003, SQL-004, SQL-005, SQL-006, SQL-007
Source SAIF.Framework.Preferences\PreferenceData.cs

BR-002: Empty preference text triggers deletion

Field Value
Statement Saving an empty or whitespace-only preference value deletes the existing row rather than storing an empty value.
Trigger SavePreferences is called with preferenceText that is empty or whitespace-only after Trim().
Enforcement SavePreferences branches to the DeletePref path.
Outcome The preference row for that app/page/user is removed instead of persisting an empty value.
Tables USER_PREFERENCE
SQL SQL-006
Source SAIF.Framework.Preferences\PreferenceData.cs

BR-003: Preference identity is scoped by app, user, and optional page

Field Value
Statement A preference is uniquely identified by application name, user ID, and an optional page name; a preference with no page name is distinct from one scoped to a specific page.
Trigger Any read, write, or delete operation against USER_PREFERENCE.
Enforcement The whereNull (PAGE_NAME IS NULL) and wherePageName (PAGE_NAME = :pagename) constant clauses are applied consistently across GetPreferences, UpdatePref, DeletePref, and DoesPrefExist.
Outcome Application/user/page-scoped preferences do not collide with application/user-only preferences.
Tables USER_PREFERENCE
SQL SQL-002, SQL-004, SQL-005, SQL-006, SQL-007
Source SAIF.Framework.Preferences\PreferenceData.cs

BR-004: Update is skipped when stored value is unchanged

Field Value
Statement An update is a no-op when the new preference text is identical to the currently stored value.
Trigger UpdatePref executes as part of SavePreferences.
Enforcement The PREFERENCE_TEXT <> :prefs condition in the UPDATE ... WHERE clause.
Outcome Redundant writes and audit-timestamp churn are avoided when the new value equals the existing value.
Tables USER_PREFERENCE
SQL SQL-005
Source SAIF.Framework.Preferences\PreferenceData.cs

BR-005: Preference text is trimmed before storage

Field Value
Statement Preference text is trimmed of leading/trailing whitespace before it is persisted.
Trigger InsertPref or UpdatePref executes.
Enforcement preferenceText.Trim() is passed as the prefs parameter.
Outcome Leading/trailing whitespace is never persisted in PREFERENCE_TEXT.
Tables USER_PREFERENCE
SQL SQL-004, SQL-005
Source SAIF.Framework.Preferences\PreferenceData.cs

BR-006: Preference item payload is JSON-encoded key/value data

Field Value
Statement The PREFERENCE_TEXT column stores a JSON-encoded key/value dictionary, deserialized on read into Preference.PreferenceItems.
Trigger GetPreferencesForUser deserializes PREFERENCE_TEXT for each returned row.
Enforcement serializer.Deserialize<Dictionary<string, string>>(json) is invoked only when the trimmed JSON text has non-zero length.
Outcome Preference.PreferenceItems reflects the stored key/value pairs; empty stored text yields an empty dictionary.
Tables USER_PREFERENCE
SQL SQL-003
Source SAIF.Framework.Preferences\PreferenceData.cs

Notes

  • All six rules above are enforced entirely within PreferenceData; there is no separate IBusinessCriteria/business-object rule layer in this library.
  • No security, authorization, or segregation-of-duties rules were found in this library; userId is used purely as a data key, not as an authorization decision point.

Sources

  • SAIF.Framework.Preferences\PreferenceData.cs
  • SAIF.Framework.Preferences\Preference.cs