---
title: Worker health issue tracking
summary: Loads a worker's health-issue rows, validates exposure codes, and persists inserts and deletes for managed child rows.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Business.Claim.Person
reference_type: package
operation_id: OP-PER-08
trigger: Caller retrieves worker health issues for a worker, adds or removes a child row, and saves the managed collection.
---

# Worker health issue tracking

Worker health issue tracking retrieves all health-issue rows for one worker, lets the caller create additional child rows inside a managed collection, validates the exposure code on each row, and persists inserts or deletes against the worker health issue table. The implementation does not define an update SQL statement, so persistence is limited to create and delete behavior.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PER-08 |
| **Trigger** | Caller loads the worker's health-issue collection, creates or removes a child row, and calls `Save()` |
| **Inputs** | `WorkerID`; child `ExposureCode`; acting user from `DataPortalInfo.UserID` |
| **Outputs** | In-memory `clsWorkerHealthIssueCollection`; persisted inserts or deletes in `CL_WORKER_HEALTH_ISSUE`; broken rules and DB-contention messages |
| **Primary components** | `clsWorkerHealthIssueCollection.GetWorkerHealthIssueCollection`, `clsWorkerHealthIssueCollection.NewWorkerHealthIssue`, `clsWorkerHealthIssue.BeforeInsert`, `clsWorkerHealthIssue.BeforeDelete` |
| **Entry point** | `Business\SAIF.Business.Claim.Person\clsWorkerHealthIssueCollection.vb` |

## Steps

1. **Retrieve the worker's current health-issue rows.** `GetWorkerHealthIssueCollection` issues the worker-scoped read query, creates a `clsWorkerHealthIssue` for each returned row, and adds the child to the managed collection ([SQL-014](../sql/sql-014-select.md), [CL_WORKER_HEALTH_ISSUE](../database-tables.md#cl_worker_health_issue)).
2. **Create a new managed child row when requested.** `NewWorkerHealthIssue` creates a child through `clsWorkerHealthIssue.NewWorkerHealthIssue`, adds it to the collection, and returns the child for editing.
3. **Initialize default values for a new child.** `clsWorkerHealthIssue.Create` sets `ExposureCode` to empty, stamps the current time and acting user, zeros `UpdateNum`, and initializes `WorkerID` to `0` before the caller supplies row data.
4. **Validate the exposure code before save.** The row rule rejects blank exposure codes and rejects values less than `1` ([BR-PER-027](../business-rules.md#br-per-027-worker-health-issue-exposure-codes-are-required-and-must-be-at-least-1)).
5. **Persist inserts and deletes through BOF child processing.** The managed collection calls `ApplyEdit()` and delegates persistence to each child, which inserts new rows with the worker-health-issue create SQL and deletes removed rows with the delete SQL ([BR-PER-001](../business-rules.md#br-per-001-optimistic-concurrency-applies-to-crud-operations), [SQL-004](../sql/sql-004-insert.md), [SQL-023](../sql/sql-023-delete.md), [CL_WORKER_HEALTH_ISSUE](../database-tables.md#cl_worker_health_issue)).
6. **Translate row-count mismatches into contention errors.** After insert or delete, the child checks the returned row count and adds the standard DB-contention message when exactly one row was not affected ([BR-PER-001](../business-rules.md#br-per-001-optimistic-concurrency-applies-to-crud-operations)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Load worker health issues]) --> Read[Retrieve existing rows]
    Read --> Change{Add or remove a row?}
    Change -->|Add| NewRow[Create child and set defaults]
    Change -->|Remove| DeleteRow[Queue child delete]
    NewRow --> Validate[Validate exposure code]
    Validate --> Valid{Validation passes?}
    Valid -->|No| Fail([Broken rules returned])
    Valid -->|Yes| Save[Run managed child save]
    DeleteRow --> Save
    Save --> Rows{Rows affected = 1?}
    Rows -->|No| Contention([Add DB-contention message])
    Rows -->|Yes| Done([Save completes])
```

## Failure and edge-case behavior

- The collection is the supported retrieval path; the single-object `GetWorkerHealthIssue` path cannot execute because `clsWorkerHealthIssue.Criteria.RetrieveSQL` throws `InvalidSQLProperty`.
- Row persistence is create-or-delete only; `clsWorkerHealthIssue.Criteria.UpdateSQL` also throws `InvalidSQLProperty`.
- New child initialization sets `WorkerID` to `0`, so callers must populate the row before save if the worker ID is required downstream.
- `clsWorkerHealthIssue.Criteria` accepts an exposure code in one constructor but does not assign it to a field, which further limits the single-row retrieval path.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources
- `Business\SAIF.Business.Claim.Person\clsWorkerHealthIssue.vb`
- `Business\SAIF.Business.Claim.Person\clsWorkerHealthIssueCollection.vb`
