flowchart LR
A["📷 Photo taken\nby field worker"]
B["🤖 OCR runs\non device"]
C{"✅ All checks\npass?"}
D["📤 Data submitted\nto server"]
E["⚠️ Alert shown\nto worker"]
F["📝 Worker corrects\npaper form"]
A --> B --> C
C -- Yes --> D
C -- No --> E --> F --> A
In-Phone Validation
How In-Phone Validation Works
Key Concepts
| In-Phone Validation — Concept Glossary | |
| Concept | Meaning |
|---|---|
| Record eligibility | A patient row is only validated if a minimum number of its key fields contain data. Fully blank rows (unregistered slots) are silently skipped to avoid false alerts. |
| boxals_threshold_for_eligibility | The minimum number of filled boxes in a field before that field counts as ‘active’ for eligibility purposes. Example: a date field with threshold 2 is only considered active if at least 2 of its 8 boxes are filled. |
| check__boxes__enough_filled | Required field check — fires if the field has zero filled boxes. Used for digit/letter box fields that must not be left blank. |
| check__checkboxes__enough_answers | Minimum-one bubble check — fires if no bubble is crossed in the group. Used for mandatory single-select questions. |
| check__checkboxes__not_too_many_answers | Maximum-one bubble check — fires if more than one bubble is crossed in the group. Used for all single-select questions to prevent accidental multi-selection. |
| Exactly-one pair | When both enough_answers and not_too_many_answers are applied to the same field, the combined effect is: exactly one bubble must be selected — no more, no less. |
| At-most-one (solo) | When only not_too_many_answers is applied, the field is optional but cannot have more than one bubble selected. |
| Discard criteria | If the discard bubble is marked on the form, all validation checks for that record are suppressed — the row is intentionally void. |
| PageNumberBlock(0) | Alert message references the left-hand page (Page 1) of the two-page photopack. |
| PageNumberBlock(1) | Alert message references the right-hand page (Page 2) of the two-page photopack. |
Record Eligibility
Before any field-level check is evaluated, the app determines whether a given record (patient row) contains enough data to warrant validation. This prevents alerts on genuinely empty form slots.
Validated Fields
Page 1 — Validated Fields
| Variable | Field Label | Check Type | Alert shown to worker |
|---|---|---|---|
| dateVisit | Date of Visit | 🔴 Required | "Date of Visit" is required |
| referredFrom | Referred From | ✅ Exactly one | "Referred From" requires exactly one option |
| testingSetting | Setting | ✅ Exactly one | "Setting" requires exactly one option |
| modality | Modality | 🔴 Required | "Modality" is required |
| sex | Sex | ⚠️ At most one | "Sex" requires no more than one option |
| firstTimeVisit | First Time Visit | ⚠️ At most one | "First Time Visit" requires no more than one option |
| maritalStatus | Marital Status | ⚠️ At most one | "Marital Status" requires no more than one option |
| employmentStatusId | Employment Status | ⚠️ At most one | "Employment Status" requires no more than one option |
| educationId | Education Level | ⚠️ At most one | "Education Level" requires no more than one option |
| typeConsueling | Type of Session | ⚠️ At most one | "Type of Session" requires no more than one option |
| previouslyTested | Previously tested within the last 3 months | ⚠️ At most one | "Previously tested within the last 3 months" requires no more than one option |
| indexClient | Index Testing: Is client identified from an index client? | ⚠️ At most one | "Index Testing: Is client identified from an index client?" requires no more than one option |
| relationWithIndexClient | If yes — relation with index client | ⚠️ At most one | "If yes — relation with index client" requires no more than one option |
| pregnant | Client is Pregnant | ⚠️ At most one | "Client is Pregnant" requires no more than one option |
| breastFeedingUnder6 | Client breastfeeding < 6 months | ⚠️ At most one | "Client breastfeeding < 6 months" requires no more than one option |
| breastFeedingOver6 | Client breastfeeding > 6 months | ⚠️ At most one | "Client breastfeeding > 6 months" requires no more than one option |
| previousTestedHIVNegative | Previously tested HIV negative | ✅ Exactly one | "Previously tested HIV negative" requires exactly one option |
| timeLastHIVNegativeTestResult | Time of last HIV Negative test Results | ⚠️ At most one | "Time of last HIV Negative test Results" requires no more than one option |
| clientInformHivTransRoutes | Client informed about HIV transmission routes | ⚠️ At most one | "Client informed about HIV transmission routes" requires no more than one option |
| clientInformRiskkHivTrans | Client informed about risk factors for HIV transmission | ⚠️ At most one | "Client informed about risk factors for HIV transmission" requires no more than one option |
| clientInformPreventingsHivTrans | Client informed on preventing HIV transmission methods | ⚠️ At most one | "Client informed on preventing HIV transmission methods" requires no more than one option |
| clientInformPossibleTestResult | Client informed about possible test results | ⚠️ At most one | "Client informed about possible test results" requires no more than one option |
| informConsentHivTest | Informed consent for HIV testing given | ⚠️ At most one | "Informed consent for HIV testing given" requires no more than one option |
| everHadSexualIntercourse | Ever had sexual intercourse | ✅ Exactly one | "Ever had sexual intercourse" requires exactly one option |
| moreThanOneSexPartnerLastThreeMonths | More than 1 sex partner | ✅ Exactly one | "More than 1 sex partner" requires exactly one option |
| unprotectedVaginalSex | Unprotected Vaginal Sex | ✅ Exactly one | "Unprotected Vaginal Sex" requires exactly one option |
| uprotectedAnalSex | Unprotected Anal Sex | ✅ Exactly one | "Unprotected Anal Sex" requires exactly one option |
| bloodtransInlastThreeMonths | Blood transfusion in last 3 months | ✅ Exactly one | "Blood transfusion in last 3 months" requires exactly one option |
| sexUnderInfluence | Sex under the influence of drugs and alcohol | ✅ Exactly one | "Sex under the influence of drugs and alcohol" requires exactly one option |
| stiLastThreeMonths | History of STI | ✅ Exactly one | "History of STI" requires exactly one option |
| uprotectedSexWithRegularPartnerLastThreeMonths | Unprotected sex with regular partner in last 3 months | ✅ Exactly one | "Unprotected sex with regular partner in last 3 months" requires exactly one option |
| uprotectedSexWithCasualLastThreeMonths | Unprotected sex with casual partner in last 3 months | ✅ Exactly one | "Unprotected sex with casual partner in last 3 months" requires exactly one option |
Page 2 — Validated Fields
| Variable | Field Label | Check Type | Alert shown to worker |
|---|---|---|---|
| currentCough | Current cough | ⚠️ At most one | "Current cough" requires no more than one option |
| weightLoss | Weight loss | ⚠️ At most one | "Weight loss" requires no more than one option |
| fever | Fever | ⚠️ At most one | "Fever" requires no more than one option |
| nightSweats | Night sweats | ⚠️ At most one | "Night sweats" requires no more than one option |
| lymphadenopathy | Lymphadenopathy | ⚠️ At most one | "Lymphadenopathy" requires no more than one option |
| urethralDischargeFemale | Female: Vaginal discharge or burning when urinating? | ⚠️ At most one | "Female: Vaginal discharge or burning when urinating?" requires no more than one option |
| lowerAbdominalPains | Female: Lower abdominal pains with/without vaginal discharge? | ⚠️ At most one | "Female: Lower abdominal pains with/without vaginal discharge?" requires no more than one option |
| urethralDischargeMale | Male: Urethral discharge or burning when urinating? | ⚠️ At most one | "Male: Urethral discharge or burning when urinating?" requires no more than one option |
| complaintsOfScrotal | Male: Scrotal swelling and pain | ⚠️ At most one | "Male: Scrotal swelling and pain" requires no more than one option |
| complaits_genital | Genital sore(s) or swollen inguinal lymph nodes? | ⚠️ At most one | "Genital sore(s) or swollen inguinal lymph nodes?" requires no more than one option |
| sexPartnerHivPositive | Had sex with a partner who is HIV positive? | ⚠️ At most one | "Had sex with a partner who is HIV positive?" requires no more than one option |
| newDiagnosedHivlastThreeMonths | Partner newly diagnosed HIV, started treatment <3-6 months ago? | ⚠️ At most one | "Partner newly diagnosed HIV, started treatment <3-6 months ago?" requires no more than one option |
| currentlyArvForPmtct | Partner pregnant and receiving ARV for PMTCT? | ⚠️ At most one | "Partner pregnant and receiving ARV for PMTCT?" requires no more than one option |
| partnerAdolescent | Partner adolescent 10-19 yrs, HIV infected, on ARV or NOT? | ⚠️ At most one | "Partner adolescent 10-19 yrs, HIV infected, on ARV or NOT?" requires no more than one option |
| knowHivPositiveOnArv | Partner on ARV with unsuppressed VL? | ⚠️ At most one | "Partner on ARV with unsuppressed VL?" requires no more than one option |
| knowHivPositiveAfterLostToFollowUp | Partner returned to treatment after Lost to Follow Up? | ⚠️ At most one | "Partner returned to treatment after Lost to Follow Up?" requires no more than one option |
| sexPartnerUnprotectedAnalSex | Unprotected anal sex (sex partner section) | ⚠️ At most one | "Unprotected anal sex (sex partner section)" requires no more than one option |
| hivTestResult | HIV Test Result | ✅ Exactly one | "HIV Test Result" requires exactly one option |
| hivTestBefore | Have you been tested for HIV before within this year? | ⚠️ At most one | "Have you been tested for HIV before within this year?" requires no more than one option |
| hivRequestResult | HIV Request and Result form signed by tester(s) | ⚠️ At most one | "HIV Request and Result form signed by tester(s)" requires no more than one option |
| hivRequestResultCt | HIV Request and Result form filled with CT Intake Form | ⚠️ At most one | "HIV Request and Result form filled with CT Intake Form" requires no more than one option |
| clientReceivedHivTestResult | Client received HIV test result | ⚠️ At most one | "Client received HIV test result" requires no more than one option |
| postTestCounseling | Post test counseling done | ⚠️ At most one | "Post test counseling done" requires no more than one option |
| riskReduction | Risk reduction plan developed | ⚠️ At most one | "Risk reduction plan developed" requires no more than one option |
| postTestDisclosure | Post test disclosure plan developed | ⚠️ At most one | "Post test disclosure plan developed" requires no more than one option |
| bringPartnerHivtesting | Will bring partner(s) for HIV testing | ⚠️ At most one | "Will bring partner(s) for HIV testing" requires no more than one option |
| childrenHivtesting | Will bring own children <5 years for HIV testing | ⚠️ At most one | "Will bring own children <5 years for HIV testing" requires no more than one option |
| informationFp | Provided with information on FP and dual contraception | ⚠️ At most one | "Provided with information on FP and dual contraception" requires no more than one option |
| partnerFpThanCondom | Client/Partner use FP methods (other than condom) | ⚠️ At most one | "Client/Partner use FP methods (other than condom)" requires no more than one option |
| partnerFpUseCondom | Client/Partner use condoms as (one) FP method | ⚠️ At most one | "Client/Partner use condoms as (one) FP method" requires no more than one option |
| correctCondomUse | Correct condom use demonstrated | ⚠️ At most one | "Correct condom use demonstrated" requires no more than one option |
| condomProvidedToClient | Condoms provided to client | ⚠️ At most one | "Condoms provided to client" requires no more than one option |
| lubricantProvidedToClient | Lubricants provided to client | ⚠️ At most one | "Lubricants provided to client" requires no more than one option |
| referredToServices | Client referred to other services | ⚠️ At most one | "Client referred to other services" requires no more than one option |
| discordantCouple | Discordant couple? | ⚠️ At most one | "Discordant couple?" requires no more than one option |
| recencyTest | Recency test with RTRI | ⚠️ At most one | "Recency test with RTRI" requires no more than one option |
| cd4SemiQuantitative | CD4 Test Result - Semi-Quantitative | ⚠️ At most one | "CD4 Test Result - Semi-Quantitative" requires no more than one option |
| syphilisTestResult | Syphilis Test Result | ⚠️ At most one | "Syphilis Test Result" requires no more than one option |
| hepatitisBTest | Hepatitis B Virus Test Result | ⚠️ At most one | "Hepatitis B Virus Test Result" requires no more than one option |
| hepatitisCTest | Hepatitis C Virus Test Result | ⚠️ At most one | "Hepatitis C Virus Test Result" requires no more than one option |
| providerId | Provider ID | 🔴 Required | "Provider ID" is required |
Fields Not Validated In-Phone
| Fields Present on Form but Not Validated In-Phone | ||
| Variable(s) | Field Label | Why not validated in-phone |
|---|---|---|
| photoTaken1 / photoTaken2 | Photo taken (both pages) | Administrative flag — not a data quality concern |
| referredFromOther | Referred From — specify | Optional free-text; validated conditionally downstream |
| testingSettingOther | Setting — specify | Optional free-text; validated conditionally downstream |
| firstName / otherName / surname | Client names | Free-text letter boxes; completeness not enforced in-phone |
| age | Age (years) | Digit box; range checks handled in pipeline |
| numWives / numChildren | No. of wives / No. of children <5 years | Optional numeric fields |
| clientCode | Client Code | Pre-printed; format check handled in pipeline |
| recency | Recency Number | Optional identifier field |
| phoneNumber | Client Telephone Number | Optional contact detail |
| nearestLandmark / state / line / lga | Address fields | Free-text; completeness not enforced in-phone |
| indexClientCodeNew / indexClientCodeOld | Index Client Code (ScanForm / Legacy) | Conditional; only one should be filled; handled downstream |
| knowledgeAssessment | Knowledge Assessment Score | Derived sum; consistency check handled in pipeline |
| riskAssessment | Personal HIV Risk Assessment Score | Derived sum; consistency check handled in pipeline |
| tbScreening / stiScreening | TB / STI screening scores | Derived sums; consistency check handled in pipeline |
| sexPartnerRiskAssessment | Sex Partner Risk Assessment Score | Derived sum; consistency check handled in pipeline |
| condomProvidedToClientCount | How many condoms provided | Optional count; range check handled in pipeline |
| lubricantProvidedToClientCount | How many lubricants provided | Optional count; range check handled in pipeline |
| cd4FlowCytometry | CD4 Flow Cytometry (cells/m3) | Conditional (HIV+ only); range check handled in pipeline |
| date (completion) | Date signed by provider | Completion date; validated downstream |
Summary
| In-Phone Validation Summary — HTS 001 Client Intake | |
| Metric | Value |
|---|---|
| Total fields on form (OCR-banded) | 92 |
| Fields with in-phone validation | 73 |
| Fields NOT validated in-phone | 19 |
| "Required" checks (must not be blank) | 3 |
| "Exactly one" checks (mandatory single-select) | 13 |
| "At most one" checks (optional single-select) | 57 |
| Page 1 validated fields | 32 |
| Page 2 validated fields | 41 |
| Discard criteria fields | 1 (discardPage2) |
| Minimum attempts before record can be skipped | 3 |