From 73f7d41619c18534fcd9f60538a88e8616326170 Mon Sep 17 00:00:00 2001 From: androidlover5842 Date: Sat, 31 Jan 2026 03:37:12 +0530 Subject: [PATCH] guest docs: improve extractor logic even more --- .../controller/GuestDocuments.kt | 295 ++++++++++-------- 1 file changed, 171 insertions(+), 124 deletions(-) diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt b/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt index c47bd30..e1804f0 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt @@ -215,83 +215,105 @@ class GuestDocuments( "${aiBaseUrl}/properties/$propertyId/guests/$guestId/documents/${document.id}/file?token=$token" val results = linkedMapOf() - results["isVehiclePhoto"] = llamaClient.ask( - imageUrl, - "IS THIS A VEHICLE NUMBER PLATE PHOTO? Answer YES or NO only." - ) - - if (isYes(results["isVehiclePhoto"])) { - results["vehicleNumber"] = llamaClient.ask( - imageUrl, - "VEHICLE NUMBER PLATE? Reply only number or NONE." - ) - } - results["hasAadhar"] = llamaClient.ask(imageUrl, "CONTAINS AADHAAR? Answer YES or NO only.") - results["hasUidai"] = llamaClient.ask(imageUrl, "CONTAINS UIDAI? Answer YES or NO only.") - val hasAadhar = isYes(results["hasAadhar"]) || isYes(results["hasUidai"]) - if (hasAadhar) { - val aadharQuestions = linkedMapOf( - "hasAddress" to "POSTAL ADDRESS PRESENT? Answer YES or NO only.", - "hasDob" to "DOB? Reply YES or NO.", - "hasGenderMentioned" to "GENDER MENTIONED? Reply YES or NO." - ) - for ((key, question) in aadharQuestions) { - results[key] = llamaClient.ask(imageUrl, question) - } - val hasAddress = isYes(results["hasAddress"]) - if (hasAddress) { - val addressQuestions = linkedMapOf( - DocumentPrompts.PIN_CODE, - DocumentPrompts.ADDRESS - ) - for ((key, question) in addressQuestions) { - results[key] = llamaClient.ask(imageUrl, question) + val detections = listOf( + Detection( + detect = { + results["isVehiclePhoto"] = llamaClient.ask( + imageUrl, + "IS THIS A VEHICLE NUMBER PLATE PHOTO? Answer YES or NO only." + ) + isYes(results["isVehiclePhoto"]) + }, + handle = { + results["vehicleNumber"] = llamaClient.ask( + imageUrl, + "VEHICLE NUMBER PLATE? Reply only number or NONE." + ) } - } - val hasDob = isYes(results["hasDob"]) - val hasGender = isYes(results["hasGenderMentioned"]) - if (hasDob && hasGender) { - val aadharFrontQuestions = linkedMapOf( - DocumentPrompts.NAME, - DocumentPrompts.DOB, - DocumentPrompts.ID_NUMBER, - DocumentPrompts.GENDER - ) - for ((key, question) in aadharFrontQuestions) { - results[key] = llamaClient.ask(imageUrl, question) + ), + Detection( + detect = { + results["hasAadhar"] = llamaClient.ask( + imageUrl, + "CONTAINS AADHAAR? Answer YES or NO only." + ) + results["hasUidai"] = llamaClient.ask( + imageUrl, + "CONTAINS UIDAI? Answer YES or NO only." + ) + isYes(results["hasAadhar"]) || isYes(results["hasUidai"]) + }, + handle = { + val aadharQuestions = linkedMapOf( + "hasAddress" to "POSTAL ADDRESS PRESENT? Answer YES or NO only.", + "hasDob" to "DOB? Reply YES or NO.", + "hasGenderMentioned" to "GENDER MENTIONED? Reply YES or NO." + ) + for ((key, question) in aadharQuestions) { + results[key] = llamaClient.ask(imageUrl, question) + } + val hasAddress = isYes(results["hasAddress"]) + if (hasAddress) { + val addressQuestions = linkedMapOf( + DocumentPrompts.PIN_CODE, + DocumentPrompts.ADDRESS + ) + for ((key, question) in addressQuestions) { + results[key] = llamaClient.ask(imageUrl, question) + } + } + val hasDob = isYes(results["hasDob"]) + val hasGender = isYes(results["hasGenderMentioned"]) + if (hasDob && hasGender) { + val aadharFrontQuestions = linkedMapOf( + DocumentPrompts.NAME, + DocumentPrompts.DOB, + DocumentPrompts.ID_NUMBER, + DocumentPrompts.GENDER + ) + for ((key, question) in aadharFrontQuestions) { + results[key] = llamaClient.ask(imageUrl, question) + } + } } - } - - } else { - results["hasDrivingLicence"] = llamaClient.ask( - imageUrl, - "CONTAINS DRIVING LICENCE? Answer YES or NO only." - ) - results["hasTransportDept"] = llamaClient.ask( - imageUrl, - "CONTAINS TRANSPORT DEPARTMENT? Answer YES or NO only." - ) - val isDriving = isYes(results["hasDrivingLicence"]) || isYes(results["hasTransportDept"]) - if (isDriving) { - val drivingQuestions = linkedMapOf( - DocumentPrompts.NAME, - DocumentPrompts.DOB, - "idNumber" to "DL NUMBER? Reply only number or NONE.", - DocumentPrompts.ADDRESS, - DocumentPrompts.PIN_CODE, - DocumentPrompts.CITY, - DocumentPrompts.GENDER, - DocumentPrompts.NATIONALITY - ) - for ((key, question) in drivingQuestions) { - results[key] = llamaClient.ask(imageUrl, question) + ), + Detection( + detect = { + results["hasDrivingLicence"] = llamaClient.ask( + imageUrl, + "CONTAINS DRIVING LICENCE? Answer YES or NO only." + ) + results["hasTransportDept"] = llamaClient.ask( + imageUrl, + "CONTAINS TRANSPORT DEPARTMENT? Answer YES or NO only." + ) + isYes(results["hasDrivingLicence"]) || isYes(results["hasTransportDept"]) + }, + handle = { + val drivingQuestions = linkedMapOf( + DocumentPrompts.NAME, + DocumentPrompts.DOB, + "idNumber" to "DL NUMBER? Reply only number or NONE.", + DocumentPrompts.ADDRESS, + DocumentPrompts.PIN_CODE, + DocumentPrompts.CITY, + DocumentPrompts.GENDER, + DocumentPrompts.NATIONALITY + ) + for ((key, question) in drivingQuestions) { + results[key] = llamaClient.ask(imageUrl, question) + } } - } else { - results["hasElectionCommission"] = llamaClient.ask( - imageUrl, - "CONTAINS ELECTION COMMISSION OF INDIA? Answer YES or NO only." - ) - if (isYes(results["hasElectionCommission"])) { + ), + Detection( + detect = { + results["hasElectionCommission"] = llamaClient.ask( + imageUrl, + "CONTAINS ELECTION COMMISSION OF INDIA? Answer YES or NO only." + ) + isYes(results["hasElectionCommission"]) + }, + handle = { val voterQuestions = linkedMapOf( DocumentPrompts.NAME, DocumentPrompts.DOB, @@ -305,66 +327,86 @@ class GuestDocuments( for ((key, question) in voterQuestions) { results[key] = llamaClient.ask(imageUrl, question) } - } else { + } + ), + Detection( + detect = { results["hasIncomeTaxDept"] = llamaClient.ask( imageUrl, "CONTAINS INCOME TAX DEPARTMENT? Answer YES or NO only." ) - if (isYes(results["hasIncomeTaxDept"])) { - val panQuestions = linkedMapOf( - DocumentPrompts.NAME, - DocumentPrompts.DOB, - "idNumber" to "PAN NUMBER? Reply only number or NONE.", - DocumentPrompts.ADDRESS, - DocumentPrompts.PIN_CODE, - DocumentPrompts.CITY, - DocumentPrompts.GENDER, - DocumentPrompts.NATIONALITY - ) - for ((key, question) in panQuestions) { - results[key] = llamaClient.ask(imageUrl, question) - } - } else { - results["hasPassport"] = llamaClient.ask( - imageUrl, - "CONTAINS PASSPORT? Answer YES or NO only." - ) - if (isYes(results["hasPassport"])) { - val passportQuestions = linkedMapOf( - DocumentPrompts.NAME, - DocumentPrompts.DOB, - "idNumber" to "PASSPORT NUMBER? Reply only number or NONE.", - DocumentPrompts.ADDRESS, - DocumentPrompts.PIN_CODE, - DocumentPrompts.CITY, - DocumentPrompts.GENDER, - DocumentPrompts.NATIONALITY - ) - for ((key, question) in passportQuestions) { - results[key] = llamaClient.ask(imageUrl, question) - } - } else { - val generalQuestions = linkedMapOf( - DocumentPrompts.NAME, - DocumentPrompts.DOB, - DocumentPrompts.ID_NUMBER, - DocumentPrompts.ADDRESS, - DocumentPrompts.VEHICLE_NUMBER, - DocumentPrompts.PIN_CODE, - DocumentPrompts.CITY, - DocumentPrompts.GENDER, - DocumentPrompts.NATIONALITY - ) - for ((key, question) in generalQuestions) { - results[key] = llamaClient.ask(imageUrl, question) - } - } + isYes(results["hasIncomeTaxDept"]) + }, + handle = { + val panQuestions = linkedMapOf( + DocumentPrompts.NAME, + DocumentPrompts.DOB, + "idNumber" to "PAN NUMBER? Reply only number or NONE.", + DocumentPrompts.ADDRESS, + DocumentPrompts.PIN_CODE, + DocumentPrompts.CITY, + DocumentPrompts.GENDER, + DocumentPrompts.NATIONALITY + ) + for ((key, question) in panQuestions) { + results[key] = llamaClient.ask(imageUrl, question) } } + ), + Detection( + detect = { + results["hasPassport"] = llamaClient.ask( + imageUrl, + "CONTAINS PASSPORT? Answer YES or NO only." + ) + isYes(results["hasPassport"]) + }, + handle = { + val passportQuestions = linkedMapOf( + DocumentPrompts.NAME, + DocumentPrompts.DOB, + "idNumber" to "PASSPORT NUMBER? Reply only number or NONE.", + DocumentPrompts.ADDRESS, + DocumentPrompts.PIN_CODE, + DocumentPrompts.CITY, + DocumentPrompts.GENDER, + DocumentPrompts.NATIONALITY + ) + for ((key, question) in passportQuestions) { + results[key] = llamaClient.ask(imageUrl, question) + } + } + ) + ) + + var handled = false + for (detection in detections) { + if (detection.detect()) { + detection.handle() + handled = true + break + } + } + + if (!handled) { + val generalQuestions = linkedMapOf( + DocumentPrompts.NAME, + DocumentPrompts.DOB, + DocumentPrompts.ID_NUMBER, + DocumentPrompts.ADDRESS, + DocumentPrompts.VEHICLE_NUMBER, + DocumentPrompts.PIN_CODE, + DocumentPrompts.CITY, + DocumentPrompts.GENDER, + DocumentPrompts.NATIONALITY + ) + for ((key, question) in generalQuestions) { + results[key] = llamaClient.ask(imageUrl, question) } } results["docType"] = when { + !handled -> "GENERAL" isYes(results["hasCourt"]) || isYes(results["hasHighCourt"]) || isYes(results["hasSupremeCourt"]) || @@ -505,6 +547,11 @@ private fun isYes(value: String?): Boolean { return value.orEmpty().contains("YES", ignoreCase = true) } +private data class Detection( + val detect: () -> Boolean, + val handle: () -> Unit +) + private fun cleanedValue(value: String?): String? { val trimmed = value?.trim().orEmpty() if (trimmed.isBlank()) return null