|
| 1 | +# Update Packet Handling for Unregistered Biometrics |
| 2 | + |
| 3 | +## Overview |
| 4 | +This document describes the design changes implemented in the MOSIP Registration Processor to correctly handle **update packets** where the biometric data is **not found in ABIS** (i.e., no biometric match exists for the UIN holder). |
| 5 | + |
| 6 | +This fix enhances the decision-making logic in the **Bio-Dedupe stage**, preventing unauthorized biometric updates and enabling correct fallback handling for **infant** and **biometric-exception** scenarios. |
| 7 | + |
| 8 | +--- |
| 9 | + |
| 10 | +## Approach Flow |
| 11 | + |
| 12 | +### 1. Identify Update Packet |
| 13 | +The system first determines whether the incoming packet is an **update** packet by checking the registration type. |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +### 2. Biometric Match Check |
| 18 | +In the Bio-Dedupe stage, biometrics extracted from the update packet are checked against ABIS. |
| 19 | +If **no match is found**, the system considers the update biometric as **unregistered** and applies fallback logic. |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +### 3. Check for Infant Scenario |
| 24 | +The system checks whether the applicant was an **infant** during the last interaction with MOSIP (registration or previous update). |
| 25 | + |
| 26 | +If the applicant qualifies as an infant, biometric match in ABIS is **not required**. |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +### 3.1 Infant Fallback Logic |
| 31 | +If the last interaction occurred while the applicant was still an infant, the system **allows biometric update**. |
| 32 | + |
| 33 | +To determine this: |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +### Step 1 — Fetch Date of Birth (DOB) |
| 38 | +Retrieve **date of birth** from the ID Repository for the UIN. |
| 39 | + |
| 40 | +--- |
| 41 | + |
| 42 | +### Step 2 — Determine Applicant's Last Interaction with MOSIP |
| 43 | +Age is calculated based on the last interaction date. |
| 44 | +The system determines this using the following fallback sequence: |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +#### **Fallback Order to Determine Last Interaction DateTime** |
| 49 | + |
| 50 | +##### a) Use `packetCreatedOn` field from `/idvid` API |
| 51 | +If **_packetCreatedOn_** field available in the `/idvid` response, use it directly. |
| 52 | +**_packetCreatedOn_** will be updated to ID Repository during the NEW and UPDATE operations. This field will be null only for legacy UINs created before the MOSIP version that introduced this field. |
| 53 | + |
| 54 | +--- |
| 55 | + |
| 56 | +##### b) If not available, use `/idvid-metadata/search` API |
| 57 | +This API returns metadata for the provided UIN such as: |
| 58 | +- `registrationId` : The registrationId associated with the latest interaction of the UIN. |
| 59 | +- `createdOn` : DateTime when the UIN was created. |
| 60 | +- `updatedOn` : DateTime when the UIN was last updated. |
| 61 | + |
| 62 | +Using these, the system performs: |
| 63 | + |
| 64 | +1. **Fetch packetId using registrationId from registration_list table** |
| 65 | + - Query `registration_list` using registrationId to obtain the packetId. |
| 66 | + - **_packetId_** is used for obtaining the **_packetCreatedOn_** as it contains the packet creation timestamp. Example: _10018301560378920240729070828-10219_10200-**20240729070828**_. Here last 14 digits represent the packetCreatedOn in **yyyyMMddHHmmss**. |
| 67 | + |
| 68 | +2. **If unable to find packetCreatedOn from packetId, derive the same from registrationId** |
| 69 | + - **_registrationId_** is used to determine the last interaction date. Example: _100183015603789**20240729070828**_ where last 14 digits represent the packetCreatedOn in **yyyyMMddHHmmss**. |
| 70 | + |
| 71 | +3. **If unable to obtain from registrationId, approximate using createdOn/updatedOn** |
| 72 | + **_createdOn_** or **_updatedOn_** are used to determine the last interaction. As the createdOn and updatedOn are the time when the UIN is created or updated respectively, includes the processing time taken for the packet i.e. equals to **packetCreatedOn** + **processing time**. In order to approximately determine the last interaction, following configuration is introduced:<br><br> |
| 73 | + **_registration.processor.expected-packet-processing-duration_** : This configuration holds the expected maximum duration taken for processing a packet in hours. This value is subtracted from createdOn or updatedOn to approximately determine the last interaction date. By default, this value is set to 0. The approximate packetCreatedOn is determined as follows:<br> |
| 74 | + ```packetCreatedOn = createdOn/updatedOn - expected-packet-processing-duration (in hours)```<br><br> |
| 75 | + **Note :** This property is kept for considering the time taken for processing the packet as createdOn and updatedOn includes that time. Country can configure this property based on their requirements. |
| 76 | +--- |
| 77 | + |
| 78 | +### Step 3 — Calculate Age at Last Interaction |
| 79 | +```age = packetCreatedOn - dateOfBirth``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +### Step 4 — Compare Against Effective Age Limit |
| 84 | +If the calculated age is less than the effective age limit, the applicant is considered an infant during last interaction. The effective age limit is obtained as given below:<br> |
| 85 | +```effective age limit = configured age limit (mosip.kernel.applicant.type.age.limit) + age limit buffer (registration.processor.applicant.type.age.limit.buffer)```<br><br> |
| 86 | +**Note :** **_registration.processor.applicant.type.age.limit.buffer_** is introduced to provide some buffer over the configured age limit to handle edge case scenarios in age calculation. Increasing this value provides a safety margin for age calculations near the eligibility boundary. By default, this value is set to 0. |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +### 4. Biometric Exception Fallback |
| 91 | +If the applicant was **not an infant**, the system checks if **all biometrics are marked as exception**, based on CBEFF biometric data stored in ID Repository. |
| 92 | + |
| 93 | +If **all biometrics are exception**, the packet is forwarded to **Manual Verification (MV)**. |
| 94 | +MV becomes the final decision-maker for the update. |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +### 5. Non-Infant and Not All Biometric Exception Scenario |
| 99 | +If: |
| 100 | +- The applicant was **not an infant** |
| 101 | +- The applicant does **not** have all biometrics as exception |
| 102 | +- ABIS returns **no match** |
| 103 | + |
| 104 | +Then the following configuration controls the behavior: |
| 105 | + |
| 106 | +**_mosip.regproc.bio.dedupe.non-infant-not-all-biometric-exception-decision_** |
| 107 | + |
| 108 | +Accepted values: |
| 109 | +- `REJECTED` |
| 110 | +- `MANUAL_VERIFICATION` |
| 111 | + |
| 112 | +Default: **REJECTED** |
| 113 | + |
| 114 | +- `REJECTED` → update packet is rejected. |
| 115 | +- `MANUAL_VERIFICATION` → packet sent to MV stage. |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +### 6. Biometric Match Found |
| 120 | +If ABIS returns a **successful match**, the system proceeds with the **normal update flow**. |
| 121 | + |
| 122 | +--- |
| 123 | + |
| 124 | +### Notes |
| 125 | + |
| 126 | +1. If `packetCreatedOn` cannot be determined, the system throws **_PacketDateComputationException_** and sends the packet to the MV stage for manual verification. |
| 127 | +2. If a `BiometricClassificationException` occurs during biometric exception evaluation, the packet is forwarded to MV. |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## Sequence Diagram |
| 132 | + |
| 133 | +```mermaid |
| 134 | +sequenceDiagram |
| 135 | + autonumber |
| 136 | + participant RC as Registration Client |
| 137 | + participant RP as Biodedupe Stage <Br> (Registration Processor) |
| 138 | + participant ABIS as ABIS |
| 139 | + participant IDR as ID Repository |
| 140 | + participant MV as Manual Verification |
| 141 | +
|
| 142 | + RC->>RP: Submit Update Packet |
| 143 | + Note over RP,RP: STEP 1 : Identify Update Packet |
| 144 | + RP->>RP: Identify registrationType == UPDATE |
| 145 | + |
| 146 | + Note over RP,RP: STEP 2 : Biometric Match Check |
| 147 | + RP->>ABIS: Perform biometric match |
| 148 | + ABIS-->>RP: No Match Found |
| 149 | +
|
| 150 | + Note over RP,RP: STEP 3 : Check Infant Scenario |
| 151 | + RP->>IDR: Fetch DOB |
| 152 | + IDR-->>RP: Date of Birth |
| 153 | +
|
| 154 | + RP->>IDR: /idvid (Fetch packetCreatedOn) |
| 155 | + alt packetCreatedOn available |
| 156 | + IDR-->>RP: packetCreatedOn |
| 157 | + else packetCreatedOn not available |
| 158 | + RP->>IDR: /idvid-metadata/search |
| 159 | + IDR-->>RP: registrationId, createdOn, updatedOn |
| 160 | +
|
| 161 | + RP->>RP: Query registration_list using registrationId |
| 162 | + alt packetId found |
| 163 | + RP->>RP: Derive packetCreatedOn from packetId |
| 164 | + else packetId not found |
| 165 | + RP->>RP: Derive packetCreatedOn from registrationId |
| 166 | + end |
| 167 | +
|
| 168 | + alt Still not determined |
| 169 | + RP->>RP: Approximate packetCreatedOn <Br> (createdOn/updatedOn - expected duration) |
| 170 | + end |
| 171 | + end |
| 172 | +
|
| 173 | + alt packetCreatedOn cannot be determined |
| 174 | + RP->>MV: Send to Manual Verification <BR> (PacketDateComputationException) |
| 175 | + end |
| 176 | +
|
| 177 | + RP->>RP: Calculate age at last interaction |
| 178 | + RP->>RP: Compare with effective age limit |
| 179 | +
|
| 180 | + alt Applicant was Infant |
| 181 | + RP->>RP: Allow biometric update |
| 182 | + RP->>RP: Continue normal update flow |
| 183 | + else Applicant not Infant |
| 184 | + Note over RP,RP: STEP 4 : Biometric Exception Fallback |
| 185 | + RP->>IDR: Fetch biometric exception status (CBEFF) |
| 186 | + alt All biometrics are exception |
| 187 | + RP->>MV: Send to Manual Verification |
| 188 | + else Not all biometrics exception |
| 189 | + Note over RP,RP: STEP 5 : Non-Infant and Not All Biometric Exception Scenario |
| 190 | + RP->>RP: Read config <Br> mosip.regproc.bio.dedupe.non-infant-not-all-biometric-exception-decision |
| 191 | + alt Decision = REJECTED |
| 192 | + RP->>RP: Reject update packet |
| 193 | + else Decision = MANUAL_VERIFICATION |
| 194 | + RP->>MV: Send to Manual Verification |
| 195 | + end |
| 196 | + end |
| 197 | + end |
| 198 | +
|
| 199 | + alt ABIS Match Found |
| 200 | + Note over RP,RP: STEP 6 : Biometric Match Found |
| 201 | + ABIS-->>RP: Match Success |
| 202 | + RP->>RP: Proceed with normal update flow |
| 203 | + end |
| 204 | +
|
0 commit comments