diff --git a/android-app/app/src/main/java/com/korexlabs/dhinspeccion/domain/MobileWorkflowRules.kt b/android-app/app/src/main/java/com/korexlabs/dhinspeccion/domain/MobileWorkflowRules.kt new file mode 100644 index 0000000..79cc9a5 --- /dev/null +++ b/android-app/app/src/main/java/com/korexlabs/dhinspeccion/domain/MobileWorkflowRules.kt @@ -0,0 +1,54 @@ +package com.korexlabs.dhinspeccion.domain + +/** + * UX-side mirrors of server invariants used to prevent invalid field actions before a request is sent. + * The API remains authoritative; these rules must never be used to weaken backend validation. + */ +object MobileWorkflowRules { + private val validUrgencies = setOf("URGENT", "NON_URGENT") + private val terminalCompanyOutcomes = setOf("SIGNED", "REFUSED") + + fun canStartInspection(status: String): Boolean = status == "PLANNED" + + fun hasDraftAct(statuses: Iterable): Boolean = statuses.any { it == "DRAFT" } + + fun canCreateAct( + visitStatus: String, + actStatuses: Iterable, + hasSelectedInventory: Boolean, + urgency: String, + ): Boolean = + visitStatus == "IN_PROGRESS" && + !hasDraftAct(actStatuses) && + hasSelectedInventory && + urgency in validUrgencies + + fun canCreateFieldInventory(visitStatus: String): Boolean = visitStatus == "IN_PROGRESS" + + fun canRegisterFinding( + visitStatus: String, + selectedActStatus: String?, + inventoryReadyForFinding: Boolean, + ): Boolean = + visitStatus == "IN_PROGRESS" && + selectedActStatus == "DRAFT" && + inventoryReadyForFinding + + fun canLockAct(actStatus: String?, responsibleDefined: Boolean): Boolean = + actStatus == "DRAFT" && responsibleDefined + + fun canSealAct( + actStatus: String?, + inspectorSigned: Boolean, + companyOutcomeStatus: String?, + ): Boolean = + actStatus == "LOCKED" && + inspectorSigned && + companyOutcomeStatus in terminalCompanyOutcomes + + fun canCloseInspection(visitStatus: String, actStatuses: Iterable): Boolean { + if (visitStatus != "IN_PROGRESS") return false + val active = actStatuses.filter { it != "CANCELLED" } + return active.isNotEmpty() && active.all { it == "SEALED" } + } +}