Security question management¶
This operation manages the per-user security-question answers stored in EXT_USER_SECURITY_QUESTION and the question catalog loaded from EXT_USER_SEC_QUESTION_CODE. It supports initial account setup, subsequent edits, and password-recovery style retrievals.
| Field | Value |
|---|---|
| Operation ID | OP-EU-03 |
| Trigger | User-account workflows load question choices or save question answers |
| Inputs | User ID, security-question code, answer text, culture code |
| Outputs | Persisted security-question row(s) or localized active question choices |
| Primary components | clsUserSecurityQuestionCollection.GetAllSecurityQuestions, clsUserSecurityQuestionCollection.GetUserSecurityQuestionsByUserID |
| Entry point | Business\SAIF.Business.External.Users\clsUserSecurityQuestion.vb |
Steps¶
- Allocate a question row when a new answer is created.
Createpulls the nextEXT_USER_SEC_QUESTION_SEQvalue so the answer row can be inserted later. - Load the current answers for a user.
GetUserSecurityQuestionsByUserIDselects all stored answers for a user, joins the code table for question text and expiration, and returns a collection keyed byUserID(SQL-028, EXT_USER_SECURITY_QUESTION, EXT_USER_SEC_QUESTION_CODE). - Load the active question catalog for selection UIs.
GetAllSecurityQuestionsreturns non-expired question codes and localized text by filtering the code table to rows whose expiration date is null or in the future (SQL-029, EXT_USER_SEC_QUESTION_CODE). - Validate each answer before persistence. The question object requires a non-empty answer, a non-empty question code, and a question code that still appears in the active catalog.
- If the selected question code is expired or absent from the active catalog, validation fails and reports the expired-question message.
- Validate the collection-level rules. The collection rejects duplicate question codes and, when editing existing rows, requires the collection count to remain at three questions.
- Insert a new answer row.
BeforeInsertstamps create/update metadata and writes the question code, answer text, and owning user ID intoEXT_USER_SECURITY_QUESTION(SQL-008, EXT_USER_SECURITY_QUESTION). - Update an existing answer row with optimistic concurrency.
BeforeUpdatebinds the same values plusUPDATE_NUM; a zero-row result becomes a DB-contention error (BR-EU-05, SQL-049, EXT_USER_SECURITY_QUESTION). - Delete an answer row by sequence number.
BeforeDeleteremoves the row usingEXT_USER_SEC_QUESTION_SEQ_NUM(SQL-055, EXT_USER_SECURITY_QUESTION).
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([Question load or save request]) --> Choice{Load choices or answers?}
Choice -->|Choices| Catalog[Load active question catalog]
Choice -->|Answers| Answers[Load stored user answers]
Answers --> Edit[User adds, edits, or removes answers]
Catalog --> Edit
Edit --> Validate[Validate answer text, code, duplicates, and count]
Validate --> Persist[Insert, update, or delete row]
Persist --> Done([Return saved questions])
Failure and edge-case behavior¶
- An expired question code can still exist on a stored row, but the next edit forces the user to replace it with an active code.
- Collection validation prevents the same question from being answered twice.
- Updates fail with DB-contention messaging when
UPDATE_NUMno longer matches the stored row (BR-EU-05).
Related documentation¶
Sources¶
Business\SAIF.Business.External.Users\clsUserSecurityQuestion.vbBusiness\SAIF.Business.External.Users\clsUser.vb