---
title: SAIF.Framework.Core business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.Core
reference_type: package
---

# SAIF.Framework.Core business rules

Business rules in `SAIF.Framework.Core` are framework *mechanisms*, not concrete domain rules — Core defines no business objects with actual business rules of its own; those are defined by consuming (domain) libraries that inherit from Core's base classes.

## BR-001: Rule registration and enforcement framework

| Field | Value |
| --- | --- |
| **Statement** | Every `clsBusinessBase`-derived business object owns a `clsRulesManager` instance that stores rule-handler delegates and invokes them on demand.* |
| **Trigger** | Calling code (typically a property setter in a consuming business object) invokes `Rules.CheckRules("RuleName")`.* |
| **Enforcement** | `clsRulesManager` (`V1\BusinessRules\clsRulesManager.vb`) looks up and invokes the rule-handler method(s) registered for the named rule; handler methods in consuming classes are attributed with a `RuleData` attribute (`clsRuleAttributes.vb`) supplying the broken-rule message and `RuleType` (e.g., `ApplicationError`).* |
| **Outcome** | Any rule handler that determines the current object state is invalid records a broken rule; the resulting broken-rule state is available via the object's `Rules`/broken-rule collection. |
| **Source** | `SAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vb`, `SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb` |

---

## BR-002: Broken-rule tracking and surfacing

| Field | Value |
| --- | --- |
| **Statement** | Failed rules are captured as `clsBrokenRule` entries in a `clsBrokenRuleCollection`; a richer variant, `clsBrokenRuleResult`/`clsBrokenRuleResultManager`/`clsBrokenRuleResultReason`, supports reason-coded rule results. |
| **Trigger** | A rule handler invoked via [BR-001](#br-001-rule-registration-and-enforcement-framework) determines that the current object state violates the rule. |
| **Enforcement** | `clsBusinessBase` and `clsBusinessCollectionBase` both implement `IDataErrorInfo` (`Error`/`Item`), surfacing broken-rule state to UI data-binding consumers. |
| **Outcome** | Bound UI controls (or any `IDataErrorInfo` consumer) can display validation errors without directly querying the rules engine. |
| **Source** | `SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb`, `SAIF.Framework.Core\V1\BaseItems\clsBusinessCollectionBase.vb`, `SAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vb` |

---

## BR-003: Retrieve-only criteria SQL suppression

| Field | Value |
| --- | --- |
| **Statement** | `clsRetrieveOnlyBusinessCriteria` enforces, at the framework level, that mutating operations (Create/Insert/Update/Delete) are unsupported for read-only business objects. |
| **Trigger** | Any code path attempts to access `CreateSQL`, `InsertSQL`, `UpdateSQL`, or `DeleteSQL` on a `clsRetrieveOnlyBusinessCriteria`-derived instance. |
| **Enforcement** | The overridden property getters throw `ApplicationException("SQL property not available.")` immediately; only `RetrieveSQL` (settable via the protected `SetRetrieveSQL`) remains viable. |
| **Outcome** | An exception surfaces immediately rather than silently executing invalid or unintended SQL against a read-only business object. |
| **Source** | `SAIF.Framework.Core\V1\BaseItems\clsRetrieveOnlyBusinessCriteria.vb` |

---

## BR-004: API criteria SQL properties are always empty by design

| Field | Value |
| --- | --- |
| **Statement** | `clsBusinessApiCriteriaBase`'s five SQL properties (`RetrieveSql`, `InsertSql`, `UpdateSql`, `DeleteSql`, `CreateSql`) are `Overridable` but return the CLR default value (`Nothing`/empty string) unless a derived class explicitly overrides them.* |
| **Trigger** | Any code path constructs or uses an API-backed business object's criteria (`IBusinessApiCriteria`) instead of a SQL-backed criteria object. |
| **Enforcement** | The base implementation supplies no SQL text; API-backed criteria instead expose `ApiRoutes` (`SAIFDictionary(Of IApiRoute)`) and a `GetApiClient`/`FormatRoute` mechanism for resolving REST calls. |
| **Outcome** | API-backed business objects route requests through `IDataPortalInfo.ApiClients`/`DataApiAccessLayer` instead of the SQL data-access path, keeping the two models cleanly separated. |
| **Source** | `SAIF.Framework.Core\V1\Api\clsBusinessApiCriteriaBase.vb` |

## Notes
- Core defines no concrete, domain-specific business rules of its own — all four rules above describe framework *mechanisms* that consuming (domain) business-object libraries rely on to implement their own concrete rules.
- Statements marked with `*` were inferred from code structure, naming conventions, or header-comment usage examples where direct confirmation was not available in source artifacts.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **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.Framework.Core\V1\BusinessRules\clsRulesManager.vb`
- `SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb`
- `SAIF.Framework.Core\V1\BaseItems\clsBusinessCollectionBase.vb`
- `SAIF.Framework.Core\V1\BaseItems\clsRetrieveOnlyBusinessCriteria.vb`
- `SAIF.Framework.Core\V1\Api\clsBusinessApiCriteriaBase.vb`
