Add repository overview endpoint
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package de.ruvnox.tactical
|
package de.ruvnox.tactical
|
||||||
|
|
||||||
import de.ruvnox.tactical.api.statusRoutes
|
import de.ruvnox.tactical.api.statusRoutes
|
||||||
|
import de.ruvnox.tactical.api.systemRoutes
|
||||||
import io.ktor.server.application.Application
|
import io.ktor.server.application.Application
|
||||||
import io.ktor.server.application.install
|
import io.ktor.server.application.install
|
||||||
import io.ktor.server.engine.embeddedServer
|
import io.ktor.server.engine.embeddedServer
|
||||||
@@ -35,5 +36,6 @@ fun Application.module() {
|
|||||||
|
|
||||||
routing {
|
routing {
|
||||||
statusRoutes()
|
statusRoutes()
|
||||||
|
systemRoutes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package de.ruvnox.tactical.api
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CountSummaryResponse(
|
||||||
|
val total: Long,
|
||||||
|
val active: Long
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SystemOverviewResponse(
|
||||||
|
val service: String,
|
||||||
|
val status: String,
|
||||||
|
val users: CountSummaryResponse,
|
||||||
|
val devices: CountSummaryResponse,
|
||||||
|
val operationRooms: CountSummaryResponse,
|
||||||
|
val messages: Long,
|
||||||
|
val auditEvents: Long
|
||||||
|
)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package de.ruvnox.tactical.api
|
||||||
|
|
||||||
|
import de.ruvnox.tactical.repository.AuditEventRepository
|
||||||
|
import de.ruvnox.tactical.repository.DeviceRepository
|
||||||
|
import de.ruvnox.tactical.repository.MessageRepository
|
||||||
|
import de.ruvnox.tactical.repository.OperationRoomRepository
|
||||||
|
import de.ruvnox.tactical.repository.UserRepository
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
|
||||||
|
fun Route.systemRoutes() {
|
||||||
|
get("/api/v1/system/overview") {
|
||||||
|
call.respond(
|
||||||
|
SystemOverviewResponse(
|
||||||
|
service = "ruvnox-tactical-server",
|
||||||
|
status = "online",
|
||||||
|
users = CountSummaryResponse(
|
||||||
|
total = UserRepository.countTotal(),
|
||||||
|
active = UserRepository.countActive()
|
||||||
|
),
|
||||||
|
devices = CountSummaryResponse(
|
||||||
|
total = DeviceRepository.countTotal(),
|
||||||
|
active = DeviceRepository.countActive()
|
||||||
|
),
|
||||||
|
operationRooms = CountSummaryResponse(
|
||||||
|
total = OperationRoomRepository.countTotal(),
|
||||||
|
active = OperationRoomRepository.countActive()
|
||||||
|
),
|
||||||
|
messages = MessageRepository.countTotal(),
|
||||||
|
auditEvents = AuditEventRepository.countTotal()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
object AuditEventRepository {
|
||||||
|
fun countTotal(): Long {
|
||||||
|
return queryLong("select count(*) from audit_events")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
object DeviceRepository {
|
||||||
|
fun countTotal(): Long {
|
||||||
|
return queryLong("select count(*) from devices")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun countActive(): Long {
|
||||||
|
return queryLong("select count(*) from devices where is_active = true")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
object MessageRepository {
|
||||||
|
fun countTotal(): Long {
|
||||||
|
return queryLong("select count(*) from messages")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
object OperationRoomRepository {
|
||||||
|
fun countTotal(): Long {
|
||||||
|
return queryLong("select count(*) from operation_rooms")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun countActive(): Long {
|
||||||
|
return queryLong("select count(*) from operation_rooms where is_active = true")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
import de.ruvnox.tactical.Database
|
||||||
|
|
||||||
|
internal fun queryLong(sql: String): Long {
|
||||||
|
return Database.connection().use { connection ->
|
||||||
|
connection.createStatement().use { statement ->
|
||||||
|
statement.executeQuery(sql).use { result ->
|
||||||
|
if (result.next()) result.getLong(1) else 0L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.ruvnox.tactical.repository
|
||||||
|
|
||||||
|
object UserRepository {
|
||||||
|
fun countTotal(): Long {
|
||||||
|
return queryLong("select count(*) from app_users")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun countActive(): Long {
|
||||||
|
return queryLong("select count(*) from app_users where is_active = true")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user