F6.1 · cliente Android para abrir inspecciones
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
|||||||
|
package com.korexlabs.dhinspeccion.data
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.korexlabs.dhinspeccion.BuildConfig
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.Path
|
||||||
|
|
||||||
|
data class MobilePlanningAsset(
|
||||||
|
val id: String,
|
||||||
|
val code: String,
|
||||||
|
val name: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MobilePlanningAssetResponse(
|
||||||
|
val data: List<MobilePlanningAsset> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class OpenMobileInspectionRequest(
|
||||||
|
val operationalAreaId: String,
|
||||||
|
val operatorCompanyId: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
private interface MobileInspectionOpenApi {
|
||||||
|
@GET("inspection-visits/mobile/planning-context/areas")
|
||||||
|
suspend fun areas(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
): MobilePlanningAssetResponse
|
||||||
|
|
||||||
|
@GET("inspection-visits/mobile/planning-context/areas/{areaId}/operators")
|
||||||
|
suspend fun operators(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Path("areaId") areaId: String,
|
||||||
|
): MobilePlanningAssetResponse
|
||||||
|
|
||||||
|
@POST("inspection-visits/mobile/open")
|
||||||
|
suspend fun open(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Body request: OpenMobileInspectionRequest,
|
||||||
|
): VisitDetail
|
||||||
|
|
||||||
|
@POST("auth/mobile/refresh")
|
||||||
|
suspend fun refresh(@Body request: RefreshRequest): MobileSessionResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
class MobileInspectionOpenRepository(context: Context) {
|
||||||
|
private val store = SecureSessionStore(context.applicationContext)
|
||||||
|
private val refreshMutex = Mutex()
|
||||||
|
private val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
|
||||||
|
private val api: MobileInspectionOpenApi = Retrofit.Builder()
|
||||||
|
.baseUrl(BuildConfig.API_BASE_URL)
|
||||||
|
.client(OkHttpClient.Builder().build())
|
||||||
|
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||||
|
.build()
|
||||||
|
.create(MobileInspectionOpenApi::class.java)
|
||||||
|
|
||||||
|
suspend fun areas(): MobilePlanningAssetResponse = authorized { session ->
|
||||||
|
api.areas("Bearer ${session.accessToken}")
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun operators(areaId: String): MobilePlanningAssetResponse = authorized { session ->
|
||||||
|
api.operators("Bearer ${session.accessToken}", areaId)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun open(areaId: String, companyId: String): VisitDetail = authorized { session ->
|
||||||
|
api.open(
|
||||||
|
"Bearer ${session.accessToken}",
|
||||||
|
OpenMobileInspectionRequest(areaId, companyId),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun <T> authorized(block: suspend (StoredSession) -> T): T {
|
||||||
|
var session = store.load() ?: throw IllegalStateException("Sesión no iniciada")
|
||||||
|
try {
|
||||||
|
return block(session)
|
||||||
|
} catch (error: HttpException) {
|
||||||
|
if (error.code() != 401) throw error
|
||||||
|
}
|
||||||
|
session = refresh(session.refreshToken)
|
||||||
|
return block(session)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun refresh(previousRefreshToken: String): StoredSession = refreshMutex.withLock {
|
||||||
|
val latest = store.load() ?: throw IllegalStateException("Sesión no iniciada")
|
||||||
|
if (latest.refreshToken != previousRefreshToken) return@withLock latest
|
||||||
|
try {
|
||||||
|
store.save(api.refresh(RefreshRequest(previousRefreshToken)))
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
store.clear()
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user