Server : Alteration error management
This commit is contained in:
parent
81c6450dbe
commit
acb445c480
10 changed files with 220 additions and 80 deletions
|
|
@ -46,11 +46,21 @@ class AlterationService(
|
||||||
return alterationHashFlow.value[alterationId]
|
return alterationHashFlow.value[alterationId]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(json: AlterationJson) {
|
@Throws
|
||||||
alterationStore.save(alteration = json)
|
fun save(
|
||||||
|
json: AlterationJson,
|
||||||
|
create: Boolean,
|
||||||
|
) {
|
||||||
|
alterationStore.save(
|
||||||
|
json = json,
|
||||||
|
create = create,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun delete(alterationId: String): Boolean {
|
@Throws
|
||||||
return alterationStore.delete(id = alterationId)
|
fun delete(alterationId: String) {
|
||||||
|
return alterationStore.delete(
|
||||||
|
id = alterationId,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,15 @@ class AlterationStore(
|
||||||
val scope = CoroutineScope(Dispatchers.IO + Job())
|
val scope = CoroutineScope(Dispatchers.IO + Job())
|
||||||
// load the initial data
|
// load the initial data
|
||||||
scope.launch {
|
scope.launch {
|
||||||
updateAlterations()
|
updateAlterationFlow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun alterationsFlow(): StateFlow<List<Alteration>> = alterationFlow
|
fun alterationsFlow(): StateFlow<List<Alteration>> = alterationFlow
|
||||||
|
|
||||||
private fun updateAlterations() {
|
private fun updateAlterationFlow() {
|
||||||
alterationFlow.value = try {
|
alterationFlow.value = try {
|
||||||
loadAlterations()
|
load()
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
println(exception) // TODO proper exception handling
|
println(exception) // TODO proper exception handling
|
||||||
emptyList()
|
emptyList()
|
||||||
|
|
@ -47,7 +47,9 @@ class AlterationStore(
|
||||||
FileReadException::class,
|
FileReadException::class,
|
||||||
JsonConversionException::class,
|
JsonConversionException::class,
|
||||||
)
|
)
|
||||||
private fun loadAlterations(): List<Alteration> {
|
private fun load(
|
||||||
|
directory: File = this.directory,
|
||||||
|
): List<Alteration> {
|
||||||
return directory
|
return directory
|
||||||
.listFiles()
|
.listFiles()
|
||||||
?.mapNotNull { file ->
|
?.mapNotNull { file ->
|
||||||
|
|
@ -60,8 +62,14 @@ class AlterationStore(
|
||||||
if (json.isBlank()) {
|
if (json.isBlank()) {
|
||||||
return@mapNotNull null
|
return@mapNotNull null
|
||||||
}
|
}
|
||||||
|
// decode the file
|
||||||
|
val data = try {
|
||||||
|
this.json.decodeFromString<AlterationJson>(json)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
throw JsonCodingException(root = exception)
|
||||||
|
}
|
||||||
|
// parse the json string.
|
||||||
try {
|
try {
|
||||||
val data = this.json.decodeFromString<AlterationJson>(json)
|
|
||||||
factory.convertFromJson(data)
|
factory.convertFromJson(data)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
throw JsonConversionException(root = exception)
|
throw JsonConversionException(root = exception)
|
||||||
|
|
@ -70,67 +78,76 @@ class AlterationStore(
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(JsonConversionException::class, FileWriteException::class)
|
@Throws(
|
||||||
|
BusinessException::class,
|
||||||
|
JsonConversionException::class,
|
||||||
|
JsonCodingException::class,
|
||||||
|
FileWriteException::class,
|
||||||
|
)
|
||||||
fun save(
|
fun save(
|
||||||
alteration: Alteration,
|
json: AlterationJson,
|
||||||
|
create: Boolean,
|
||||||
) {
|
) {
|
||||||
val json = try {
|
val file = alterationFile(id = json.id)
|
||||||
factory.convertToJson(data = alteration)
|
// Guard case on update alteration
|
||||||
|
if (create && file.exists()) {
|
||||||
|
val root = Exception("Alteration already exist, creation is impossible.")
|
||||||
|
throw BusinessException(root = root)
|
||||||
|
}
|
||||||
|
// Transform the json into the model.
|
||||||
|
val alteration = try {
|
||||||
|
factory.convertFromJson(json)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
throw JsonConversionException(root = exception)
|
throw JsonConversionException(root = exception)
|
||||||
}
|
}
|
||||||
|
// Encode the json into a string.
|
||||||
save(alteration = json)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(FileWriteException::class)
|
|
||||||
fun save(
|
|
||||||
alteration: AlterationJson,
|
|
||||||
) {
|
|
||||||
// encode the json into a string
|
|
||||||
val data = try {
|
val data = try {
|
||||||
json.encodeToString(alteration)
|
this.json.encodeToString(json)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
throw JsonConversionException(root = exception)
|
throw JsonCodingException(root = exception)
|
||||||
}
|
}
|
||||||
// write the alteration into a file.
|
// Write the alteration into a file.
|
||||||
try {
|
try {
|
||||||
val file = alterationFile(id = alteration.id)
|
|
||||||
file.writeText(
|
file.writeText(
|
||||||
text = data,
|
text = data,
|
||||||
charset = Charsets.UTF_8,
|
charset = Charsets.UTF_8,
|
||||||
)
|
)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
throw FileWriteException(
|
throw FileWriteException(root = exception)
|
||||||
root = exception
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// Update the dataflow.
|
// Update the dataflow.
|
||||||
alterationFlow.update { alterations ->
|
alterationFlow.update { alterations ->
|
||||||
val index = alterations.indexOfFirst { it.id == alteration.id }
|
val index = alterations.indexOfFirst {
|
||||||
val alt = factory.convertFromJson(alteration)
|
it.id == json.id
|
||||||
|
}
|
||||||
alterations.toMutableList().also {
|
alterations.toMutableList().also {
|
||||||
if (index >= 0) {
|
when {
|
||||||
it[index] = alt
|
index >= 0 -> it[index] = alteration
|
||||||
} else {
|
else -> it.add(alteration)
|
||||||
it.add(alt)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun delete(id: String): Boolean {
|
@Throws(BusinessException::class)
|
||||||
|
fun delete(id: String) {
|
||||||
val file = alterationFile(id = id)
|
val file = alterationFile(id = id)
|
||||||
val deleted = file.delete()
|
// Guard case on the file existence.
|
||||||
if (deleted) {
|
if (file.exists().not()) {
|
||||||
alterationFlow.update { alterations ->
|
val root = Exception("Alteration doesn't not exist, deletion is impossible.")
|
||||||
alterations.toMutableList().also { alteration ->
|
throw BusinessException(root = root)
|
||||||
alteration.removeIf { it.id == id }
|
}
|
||||||
}
|
// Guard case on the file deletion
|
||||||
|
if (file.delete().not()) {
|
||||||
|
val root = Exception("Alteration file have not been deleted for unknown reason.")
|
||||||
|
throw BusinessException(root = root)
|
||||||
|
}
|
||||||
|
// Update the data model with the deleted alteration.
|
||||||
|
alterationFlow.update { alterations ->
|
||||||
|
alterations.toMutableList().also { alteration ->
|
||||||
|
alteration.removeIf { it.id == id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return deleted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun alterationFile(id: String): File {
|
private fun alterationFile(id: String): File {
|
||||||
|
|
@ -139,6 +156,8 @@ class AlterationStore(
|
||||||
|
|
||||||
sealed class AlterationStoreException(root: Exception) : Exception(root)
|
sealed class AlterationStoreException(root: Exception) : Exception(root)
|
||||||
class JsonConversionException(root: Exception) : AlterationStoreException(root)
|
class JsonConversionException(root: Exception) : AlterationStoreException(root)
|
||||||
|
class JsonCodingException(root: Exception) : AlterationStoreException(root)
|
||||||
|
class BusinessException(root: Exception) : AlterationStoreException(root)
|
||||||
class FileWriteException(root: Exception) : AlterationStoreException(root)
|
class FileWriteException(root: Exception) : AlterationStoreException(root)
|
||||||
class FileReadException(root: Exception) : AlterationStoreException(root)
|
class FileReadException(root: Exception) : AlterationStoreException(root)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,23 @@
|
||||||
package com.pixelized.server.lwa.server.rest.alteration
|
package com.pixelized.server.lwa.server.rest.alteration
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.model.alteration.AlterationStore
|
||||||
import com.pixelized.server.lwa.server.Engine
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.MissingParameterException
|
||||||
import com.pixelized.server.lwa.utils.extentions.alterationId
|
import com.pixelized.server.lwa.utils.extentions.alterationId
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.response.respondText
|
|
||||||
|
|
||||||
fun Engine.deleteAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
fun Engine.deleteAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
try {
|
try {
|
||||||
val alterationId = call.parameters.alterationId
|
val alterationId = call.parameters.alterationId
|
||||||
|
|
||||||
val deleted = alterationService.delete(
|
alterationService.delete(
|
||||||
alterationId = alterationId
|
alterationId = alterationId
|
||||||
)
|
)
|
||||||
|
call.respond(
|
||||||
if (deleted.not()) error("Unexpected error occurred")
|
message = ResultJson.Success(),
|
||||||
|
|
||||||
call.respondText(
|
|
||||||
text = "${HttpStatusCode.OK}",
|
|
||||||
status = HttpStatusCode.OK,
|
|
||||||
)
|
)
|
||||||
webSocket.emit(
|
webSocket.emit(
|
||||||
value = ApiSynchronisation.AlterationDelete(
|
value = ApiSynchronisation.AlterationDelete(
|
||||||
|
|
@ -27,10 +25,26 @@ fun Engine.deleteAlteration(): suspend io.ktor.server.routing.RoutingContext.()
|
||||||
alterationId = alterationId,
|
alterationId = alterationId,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
} catch (exception: MissingParameterException) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = exception.errorCode,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (exception: AlterationStore.BusinessException) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = ResultJson.Error.FILE_DOES_NOT_EXIST,
|
||||||
|
message = "Alteration doesn't exist."
|
||||||
|
)
|
||||||
|
)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
call.respondText(
|
call.respond(
|
||||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
message = ResultJson.Error(
|
||||||
status = HttpStatusCode.UnprocessableEntity,
|
status = ResultJson.Error.GENERIC,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ package com.pixelized.server.lwa.server.rest.alteration
|
||||||
|
|
||||||
import com.pixelized.server.lwa.server.Engine
|
import com.pixelized.server.lwa.server.Engine
|
||||||
import com.pixelized.server.lwa.utils.extentions.alterationId
|
import com.pixelized.server.lwa.utils.extentions.alterationId
|
||||||
import io.ktor.http.HttpStatusCode
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
import io.ktor.server.response.respondText
|
|
||||||
|
|
||||||
fun Engine.getAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
fun Engine.getAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
|
|
@ -20,9 +19,11 @@ fun Engine.getAlteration(): suspend io.ktor.server.routing.RoutingContext.() ->
|
||||||
message = alteration,
|
message = alteration,
|
||||||
)
|
)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
call.respondText(
|
call.respond(
|
||||||
text = exception.localizedMessage,
|
message = ResultJson.Error(
|
||||||
status = HttpStatusCode.UnprocessableEntity,
|
status = ResultJson.Error.GENERIC,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,22 @@
|
||||||
package com.pixelized.server.lwa.server.rest.alteration
|
package com.pixelized.server.lwa.server.rest.alteration
|
||||||
|
|
||||||
import com.pixelized.server.lwa.server.Engine
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
|
|
||||||
fun Engine.getAlterationTags(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
fun Engine.getAlterationTags(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
call.respond(
|
try {
|
||||||
message = alterationService.tags(),
|
call.respond(
|
||||||
)
|
message = alterationService.tags(),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = ResultJson.Error.GENERIC,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,22 @@
|
||||||
package com.pixelized.server.lwa.server.rest.alteration
|
package com.pixelized.server.lwa.server.rest.alteration
|
||||||
|
|
||||||
import com.pixelized.server.lwa.server.Engine
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import io.ktor.server.response.respond
|
import io.ktor.server.response.respond
|
||||||
|
|
||||||
fun Engine.getAlterations(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
fun Engine.getAlterations(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
call.respond(
|
try {
|
||||||
message = alterationService.alterations(),
|
call.respond(
|
||||||
)
|
message = alterationService.alterations(),
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = ResultJson.Error.GENERIC,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,22 +1,27 @@
|
||||||
package com.pixelized.server.lwa.server.rest.alteration
|
package com.pixelized.server.lwa.server.rest.alteration
|
||||||
|
|
||||||
|
import com.pixelized.server.lwa.model.alteration.AlterationStore
|
||||||
import com.pixelized.server.lwa.server.Engine
|
import com.pixelized.server.lwa.server.Engine
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.MissingParameterException
|
||||||
|
import com.pixelized.server.lwa.utils.extentions.create
|
||||||
import com.pixelized.shared.lwa.model.alteration.AlterationJson
|
import com.pixelized.shared.lwa.model.alteration.AlterationJson
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
import com.pixelized.shared.lwa.protocol.websocket.ApiSynchronisation
|
||||||
import io.ktor.http.HttpStatusCode
|
|
||||||
import io.ktor.server.request.receive
|
import io.ktor.server.request.receive
|
||||||
import io.ktor.server.response.respondText
|
import io.ktor.server.response.respond
|
||||||
|
|
||||||
fun Engine.putAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
fun Engine.putAlteration(): suspend io.ktor.server.routing.RoutingContext.() -> Unit {
|
||||||
return {
|
return {
|
||||||
try {
|
try {
|
||||||
val form = call.receive<AlterationJson>()
|
val form = call.receive<AlterationJson>()
|
||||||
|
val create = call.queryParameters.create
|
||||||
|
|
||||||
alterationService.update(json = form)
|
alterationService.save(
|
||||||
|
json = form,
|
||||||
call.respondText(
|
create = create,
|
||||||
text = "${HttpStatusCode.OK}",
|
)
|
||||||
status = HttpStatusCode.OK,
|
call.respond(
|
||||||
|
message = ResultJson.Success(),
|
||||||
)
|
)
|
||||||
webSocket.emit(
|
webSocket.emit(
|
||||||
value = ApiSynchronisation.AlterationUpdate(
|
value = ApiSynchronisation.AlterationUpdate(
|
||||||
|
|
@ -24,10 +29,26 @@ fun Engine.putAlteration(): suspend io.ktor.server.routing.RoutingContext.() ->
|
||||||
alterationId = form.id,
|
alterationId = form.id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} catch (exception : Exception) {
|
} catch (exception: MissingParameterException) {
|
||||||
call.respondText(
|
call.respond(
|
||||||
text = "${HttpStatusCode.UnprocessableEntity}",
|
message = ResultJson.Error(
|
||||||
status = HttpStatusCode.UnprocessableEntity,
|
status = exception.errorCode,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (exception: AlterationStore.BusinessException) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = ResultJson.Error.FILE_ALREADY_EXIST,
|
||||||
|
message = "Alteration file already exist."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
call.respond(
|
||||||
|
message = ResultJson.Error(
|
||||||
|
status = ResultJson.Error.GENERIC,
|
||||||
|
message = exception.message ?: "?",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,30 @@
|
||||||
package com.pixelized.server.lwa.utils.extentions
|
package com.pixelized.server.lwa.utils.extentions
|
||||||
|
|
||||||
|
import com.pixelized.shared.lwa.protocol.rest.ResultJson
|
||||||
import io.ktor.http.Parameters
|
import io.ktor.http.Parameters
|
||||||
|
|
||||||
val Parameters.characterSheetId
|
val Parameters.characterSheetId
|
||||||
get() = this["characterSheetId"] ?: error("Missing characterSheetId parameter.")
|
get() = this["characterSheetId"]
|
||||||
|
?: throw MissingParameterException(
|
||||||
|
name = "characterSheetId",
|
||||||
|
errorCode = ResultJson.Error.MISSING_CHARACTER_SHEET_ID,
|
||||||
|
)
|
||||||
|
|
||||||
val Parameters.alterationId
|
val Parameters.alterationId
|
||||||
get() = this["alterationId"] ?: error("Missing alterationId parameter.")
|
get() = this["alterationId"]
|
||||||
|
?: throw MissingParameterException(
|
||||||
|
name = "alterationId",
|
||||||
|
errorCode = ResultJson.Error.MISSING_ALTERATION_ID,
|
||||||
|
)
|
||||||
|
|
||||||
|
val Parameters.create
|
||||||
|
get() = this["create"]?.toBooleanStrictOrNull()
|
||||||
|
?: throw MissingParameterException(
|
||||||
|
name = "create",
|
||||||
|
errorCode = ResultJson.Error.MISSING_CREATE
|
||||||
|
)
|
||||||
|
|
||||||
|
class MissingParameterException(
|
||||||
|
name: String,
|
||||||
|
val errorCode: Int,
|
||||||
|
) : Exception("Missing $name parameter.")
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ val toolsDependencies
|
||||||
get() = module {
|
get() = module {
|
||||||
factory {
|
factory {
|
||||||
Json {
|
Json {
|
||||||
|
encodeDefaults = true
|
||||||
explicitNulls = false
|
explicitNulls = false
|
||||||
prettyPrint = true
|
prettyPrint = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.pixelized.shared.lwa.protocol.rest
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed interface ResultJson {
|
||||||
|
val success: Boolean
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Error(
|
||||||
|
override val success: Boolean = false,
|
||||||
|
val status: Int,
|
||||||
|
val message: String,
|
||||||
|
) : ResultJson {
|
||||||
|
companion object {
|
||||||
|
const val GENERIC = 500
|
||||||
|
|
||||||
|
const val FILE_ALREADY_EXIST = GENERIC + 1
|
||||||
|
const val FILE_DOES_NOT_EXIST = GENERIC + 2
|
||||||
|
|
||||||
|
const val MISSING_PARAMETER = 1000
|
||||||
|
const val MISSING_CHARACTER_SHEET_ID = MISSING_PARAMETER + 1
|
||||||
|
const val MISSING_ALTERATION_ID = MISSING_PARAMETER + 2
|
||||||
|
const val MISSING_CREATE = MISSING_PARAMETER + 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Success(
|
||||||
|
override val success: Boolean = true,
|
||||||
|
val status: Int = 100,
|
||||||
|
) : ResultJson
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue