---
title: Image indexing
summary: Creates a new IMAGE record and its optional EAIP, agency, or group sub-records after validating category, type, date, and visibility rules.
status: draft
owner: <owner>
last_reviewed: 2026-07-30
library: SAIF.Business.Imaging
reference_type: package
operation_id: OP-IMG-01
trigger: Caller populates a clsImageIdx instance with document metadata and calls Save() (Create/Insert)
---

# Image indexing

Image indexing creates the metadata record for a scanned or received document image. The caller populates a `clsImageIdx` instance with file/category/document-type codes, a document date, and optional EAIP/agency/group context, then saves it. Before the row is written, the business rule set validates required fields, the document date, the category/type pairing, and external-view visibility; after the primary `IMAGE` row is inserted, up to three conditional sub-records are created depending on the image's context.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-IMG-01 |
| **Trigger** | Caller sets image metadata on `clsImageIdx` (file code, category code, document type code, document date, and optional EAIP/agency/group fields) and calls `Save()` |
| **Inputs** | Image file/category/document-type codes, claim ID/number, document date, comment text, discovery flag, security level number, external view code, and EAIP period/agency/group context |
| **Outputs** | Persisted `IMAGE` row with a new `IMAGE_SEQ_NUM`; optionally a persisted `IMAGE_EAIP`, `IMAGE_AGENCY`, or `IMAGE_GROUP` row |
| **Primary components** | `clsImageIdx.BeforeCreate`, `clsImageIdx.BeforeInsert`, `clsImageIdx.AfterInsert`, `clsImageIdx.AddBusinessRules` |
| **Entry point** | `Business\SAIF.Business.Imaging\clsImageIdx.vb` |

## Steps

1. **Caller sets image metadata** on a new `clsImageIdx` instance, including file code, category code, document type code, document date, and (optionally) EAIP period, agency, or group context via the embedded `m_EAIP` member and other fields.
2. **Validate required fields.** While the record is locally dirty, the rule set requires non-empty `ImageFileCode`, `ImageDocumentTypeCode`, `ImageCategoryCode`, and a `DocumentDate` other than `Date.MinValue` ([BR-IMG-02](../business-rules.md#br-img-02-image-index-required-fields)).
   - On failure: a broken rule with the corresponding required-field message is added and blocks `IsValid`.
3. **Validate the document date is not too far in the future.** The document date must not exceed `Today` plus the record's `DocumentDateDays` tolerance ([BR-IMG-03](../business-rules.md#br-img-03-image-document-date-cannot-be-in-the-future)).
   - On failure: a broken rule is added naming the allowed number of days.
4. **Validate the category/type pairing.** The rule set executes [SQL-029](../sql/SQL-029-saif-business-imaging.md) against [IMAGE_DOCUMENT_TYPE_CODE](../database-tables.md#image_document_type_code) to confirm the selected document type belongs to the selected category and file code ([BR-IMG-04](../business-rules.md#br-img-04-document-type-must-belong-to-the-selected-category-and-file-group)).
   - On failure (count = 0): a broken rule ("The Doc Type must be in the Doc Category") is added.
5. **Validate external-view visibility.** `ExternalViewCode = "SHOW"` is rejected when `DiscoveryFlag = "N"` or when `SecurityLevelNum > 0` ([BR-IMG-05](../business-rules.md#br-img-05-external-view-visibility-conflicts-with-discovery-and-security-level)).
   - On failure: a broken rule is added identifying the conflicting condition (non-discoverable or secured).
6. **Generate the sequence number.** `BeforeCreate` executes [SQL-002](../sql/SQL-002-saif-business-imaging.md) to obtain the next `IMAGE_SEQ_NUM` from `image_seq.nextval` ([DUAL](../database-tables.md#dual)).
7. **Insert the IMAGE row.** `BeforeInsert` executes [SQL-010](../sql/SQL-010-saif-business-imaging.md), binding 24 parameters, to insert the row into [IMAGE](../database-tables.md#image).
8. **Verify the insert.** `AfterInsert` confirms exactly one `IMAGE` row was affected.
   - On failure: an error is raised rather than allowing a partial index record.
9. **Conditionally insert EAIP context.** If `m_EAIP.IsEAIP = True` (the embedded `clsEAIP.EAIPPeriodSeq` is populated), `BeforeInsert` executes [SQL-007](../sql/SQL-007-saif-business-imaging.md) to insert an [IMAGE_EAIP](../database-tables.md#image_eaip) row.
10. **Conditionally insert agency context.** If `ImageFileCode = "AGNCY"`, `BeforeInsert` executes [SQL-008](../sql/SQL-008-saif-business-imaging.md) to insert an [IMAGE_AGENCY](../database-tables.md#image_agency) row.
11. **Conditionally insert group context.** If `ImageFileCode = "GROUP"`, `BeforeInsert` executes [SQL-009](../sql/SQL-009-saif-business-imaging.md) to insert an [IMAGE_GROUP](../database-tables.md#image_group) row.
12. **Verify each secondary insert.** Every conditional insert request (EAIP, agency, group) is individually checked for exactly one row affected.
    - On failure: an error is raised for the failing secondary insert.
13. **Retrieve or update an existing index record.** `BeforeRetrieve` executes [SQL-028](../sql/SQL-028-saif-business-imaging.md) to load an `IMAGE` row joined with category/document-type code descriptions; `BeforeUpdate` executes [SQL-036](../sql/SQL-036-saif-business-imaging.md) to persist changes to an existing row.
    - Note: `clsImageIdx` exposes a `DeleteSQL` property ([SQL-043](../sql/SQL-043-saif-business-imaging.md)) but does not implement a live `BeforeDelete`/`AfterDelete` pair, so direct deletion of `IMAGE` rows through this class is not functional in current code.**

## Process flow

The following diagram visualizes the image indexing operation's control flow, including validation and the conditional sub-record inserts.

```mermaid
flowchart TD
	Start([Caller sets image metadata<br>and calls Save]) --> Validate[Validate required fields,<br>document date, cat/type match,<br>external-view visibility]
	Validate --> VOk{Rules pass?}
	VOk -->|No| Fail([Broken rules returned;<br>no insert attempted])
	VOk -->|Yes| GenSeq[BeforeCreate: generate IMAGE_SEQ_NUM]
	GenSeq --> InsertImage[BeforeInsert: INSERT IMAGE row]
	InsertImage --> RowCheck{AfterInsert:<br>exactly 1 row?}
	RowCheck -->|No| Error([Error: insert failed])
	RowCheck -->|Yes| EAIPCheck{IsEAIP<br>= True?}
	EAIPCheck -->|Yes| InsertEAIP[Insert IMAGE_EAIP]
	EAIPCheck -->|No| AgencyCheck{ImageFileCode<br>= AGNCY?}
	InsertEAIP --> AgencyCheck
	AgencyCheck -->|Yes| InsertAgency[Insert IMAGE_AGENCY]
	AgencyCheck -->|No| GroupCheck{ImageFileCode<br>= GROUP?}
	InsertAgency --> GroupCheck
	GroupCheck -->|Yes| InsertGroup[Insert IMAGE_GROUP]
	GroupCheck -->|No| Done([Done: image indexed])
	InsertGroup --> Done
```

## Failure and edge-case behavior

- `AfterInsert` requires exactly one `IMAGE` row affected; each secondary insert request (EAIP, agency, group) is also individually checked and raises an error on its own if it fails.
- `clsImageIdx.DeleteSQL` exists but `clsImageIdx` does not implement a live `BeforeDelete`/`AfterDelete` pair, so direct deletion of `IMAGE` rows through this class is not functional in current code.**
- Validation rules only run `If IsLocalDirty`; records loaded from the database and not subsequently modified skip re-validation of required fields, document date, category/type match, and external-view visibility.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.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

- `Business\SAIF.Business.Imaging\clsImageIdx.vb`
- `Business\SAIF.Business.Imaging\clsImageMsgConst.vb`
- `Business\SAIF.Business.Imaging\clsEAIP.vb`
