Email info CRUD and linking¶
clsEmailAddressInfo is a standalone EMAIL_ADDRESS row with a configurable validation model: callers choose both how strict the check is (syntax only vs. syntax-and-DNS) and how a failure is treated (warning vs. error). As with addresses, the owning collection tracks adds/removes and reconciles the COMPANY_EMAIL / PERSON_EMAIL link rows on save.
| Field | Value |
|---|---|
| Operation ID | OP-CC-06 |
| Trigger | Caller adds/removes a clsEmailAddressInfo in clsCustomer.Emails or clsContact.Emails, then the parent's Save() cascades into the collection; or mdlCustomerContact.CreateEmail is called directly |
| Inputs | Value (email address text), EmailCode (email type), IsPrimary, EmailAddressValidation (Warn/Error), EmailValidationType (None/Syntax/SyntaxAndDNS) |
| Outputs | Persisted EMAIL_ADDRESS row; persisted or removed COMPANY_EMAIL / PERSON_EMAIL link row; IsVerified flag reset on value change |
| Primary components | clsEmailAddressInfo.Create, clsEmailAddressInfo.OnValueChange, clsEmailAddressInfo.AddBusinessRules, mdlCustomerContact.CreateEmail, clsInfoCollection.Save |
| Entry point | Business\SAIF.Business.CustomerContact\InfoItems\clsEmailAddressInfo.vb |
Steps¶
- Create a new email row.
Create()assigns the row'sEmailAddressIDfromGetNextSeqNum. - Value-change side effect (BR-010).
OnValueChangecalls the base handler, then unconditionally setsIsVerified = False— any edit to the email text invalidates prior verification. - Configure the validation model (BR-006). Setting
EmailAddressValidation(WarnorError) rebuilds the rule set viaAddBusinessRules(), which clears existing rules and registers: - Required check:
ValidateEmailRequiredError(level one) ifEmailAddressValidation = Error, orValidateEmailRequiredWarningifWarn. - Syntax check (level two, only if
EmailValidationType = Syntax):ValidateEmailSyntaxError/ValidateEmailSyntaxWarning, backed byclsEmailAddress.IsValidEmailAddressSyntax(...). - Syntax-and-DNS check (level two, only if
EmailValidationType = SyntaxAndDNS):ValidateEmailSyntaxAndDNSError/ValidateEmailSyntaxAndDNSWarning, backed byclsEmailAddress.IsValidEmailAddress(...). - Persist the root
EMAIL_ADDRESSrow. Insert (SQL-014/SQL-015), update (SQL-071/SQL-072), and delete (SQL-088/SQL-089) against EMAIL_ADDRESS. - Reconcile link rows through
clsInfoCollection.Save(), in the same add/remove-tracking pattern used for addresses (see Address info CRUD and linking): save current email rows, delete removed link rows (customer: SQL-085 against COMPANY_EMAIL; contact: SQL-079 against PERSON_EMAIL), then insert added link rows (customer: SQL-011; contact: SQL-005). - Helper factory flow.
mdlCustomerContact.CreateEmail(dpi, contact, address, isPrimary, emailType): - Creates
clsEmailAddressInfo.NewEmailAddress(dpi). - Forces
EmailAddressValidation = ValidationLevel.Errorregardless of caller preference. - Sets
IsPrimaryandValue. - Resolves
EmailCodefrommdlCodeMaps.GetEmailTypes(dpi)(emailType).Code. - Adds the new email directly to
contact.Emailsunconditionally — unlike the phone helper (CreatePhone), it does not gate the add onIsValid. - Resolve the email-type description.
EmailTypeDescriptioncallsGetEmailCode(dpi)(EmailCode).Descriptionfrom the sharedSAIF.Businesscode-map module for display purposes only.
Process flow¶
The following diagram visualizes email validation configuration and the save/link cycle.
flowchart TD
Start([Caller sets Value on clsEmailAddressInfo]) --> Reset[OnValueChange:<br>IsVerified = False]
Reset --> Config[EmailAddressValidation set:<br>rebuild rules via AddBusinessRules]
Config --> Level{ValidationLevel?}
Level -->|Error| ReqError[Register required-error rule]
Level -->|Warn| ReqWarn[Register required-warning rule]
ReqError --> TypeCheck{EmailValidationType?}
ReqWarn --> TypeCheck
TypeCheck -->|Syntax| SyntaxRule[Register syntax rule]
TypeCheck -->|SyntaxAndDNS| DnsRule[Register syntax+DNS rule]
TypeCheck -->|None| NoRule[No format rule registered]
SyntaxRule --> ParentSave
DnsRule --> ParentSave
NoRule --> ParentSave
ParentSave([Parent Save cascades to collection]) --> SaveRows[Save each current EMAIL_ADDRESS row]
SaveRows --> DeleteLinks[Delete link rows for RemovedItems]
DeleteLinks --> InsertLinks[Insert link rows for AddedItems]
InsertLinks --> Done([Collection persisted])
Failure and edge-case behavior¶
- With
EmailAddressValidation = Errorand a required/syntax/DNS failure, the save is blocked by a broken rule; withWarn, the same conditions produce a warning only and do not block the save (BR-006). - Any edit to the email
ValueclearsIsVerified, even if the new value is identical in meaning to the old one (for example, only case differs) — verification is not re-derived automatically (BR-010). mdlCustomerContact.CreateEmailadds the new email to the contact's collection before any validation gate is checked, so an invalid address can be added and only surface as a broken rule later, at save time — unlikeCreatePhone, which checksIsValidbefore adding.*- Removing an email from a collection deletes only the
COMPANY_EMAIL/PERSON_EMAILlink row, not the standaloneEMAIL_ADDRESSrow.*
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Related documentation¶
Sources¶
Business\SAIF.Business.CustomerContact\InfoItems\clsEmailAddressInfo.vbBusiness\SAIF.Business.CustomerContact\InfoItems\clsInfoCollection.vbBusiness\SAIF.Business.CustomerContact\Customer\clsCustomerEmailCollection.vbBusiness\SAIF.Business.CustomerContact\Contact\clsContactEmailCollection.vbBusiness\SAIF.Business.CustomerContact\mdlCustomerContact.vb