mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-19 17:26:51 +00:00
Add statistics for state per patient
This commit is contained in:
parent
26312c8620
commit
5c6384e878
@ -20,6 +20,7 @@
|
|||||||
package dev.dnpm.etl.processor.monitoring
|
package dev.dnpm.etl.processor.monitoring
|
||||||
|
|
||||||
import org.springframework.data.annotation.Id
|
import org.springframework.data.annotation.Id
|
||||||
|
import org.springframework.data.jdbc.repository.query.Query
|
||||||
import org.springframework.data.relational.core.mapping.Embedded
|
import org.springframework.data.relational.core.mapping.Embedded
|
||||||
import org.springframework.data.relational.core.mapping.Table
|
import org.springframework.data.relational.core.mapping.Table
|
||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
@ -45,10 +46,20 @@ data class Report(
|
|||||||
val dataQualityReport: String = ""
|
val dataQualityReport: String = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class CountedState(
|
||||||
|
val count: Int,
|
||||||
|
val status: RequestStatus,
|
||||||
|
)
|
||||||
|
|
||||||
interface RequestRepository : CrudRepository<Request, Long> {
|
interface RequestRepository : CrudRepository<Request, Long> {
|
||||||
|
|
||||||
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: String): List<Request>
|
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: String): List<Request>
|
||||||
|
|
||||||
fun findByUuidEquals(uuid: String): Optional<Request>
|
fun findByUuidEquals(uuid: String): Optional<Request>
|
||||||
|
|
||||||
|
@Query("SELECT count(*) AS count, status FROM (" +
|
||||||
|
"SELECT status, rank() OVER (PARTITION BY patient_id ORDER BY processed_at DESC) AS rank FROM request WHERE status NOT IN ('DUPLICATION')" +
|
||||||
|
") rank WHERE rank = 1 GROUP BY status ORDER BY count DESC;")
|
||||||
|
fun findPatientUniqueStates(): List<CountedState>
|
||||||
|
|
||||||
}
|
}
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.web
|
package dev.dnpm.etl.processor.web
|
||||||
|
|
||||||
|
import dev.dnpm.etl.processor.monitoring.PatientUniqueState
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
import org.reactivestreams.Publisher
|
import org.reactivestreams.Publisher
|
||||||
@ -95,6 +96,19 @@ class StatisticsRestController(
|
|||||||
.sortedBy { it.date }
|
.sortedBy { it.date }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(path = ["requestpatientstates"])
|
||||||
|
fun requestPatientStates(): List<NameValue> {
|
||||||
|
return requestRepository.findPatientUniqueStates().map {
|
||||||
|
val color = when (it.status) {
|
||||||
|
RequestStatus.ERROR -> "red"
|
||||||
|
RequestStatus.WARNING -> "darkorange"
|
||||||
|
RequestStatus.SUCCESS -> "green"
|
||||||
|
else -> "slategray"
|
||||||
|
}
|
||||||
|
NameValue(it.status.toString(), it.count, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(path = ["events"], produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
|
@GetMapping(path = ["events"], produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
|
||||||
fun updater(): Flux<ServerSentEvent<Any>> {
|
fun updater(): Flux<ServerSentEvent<Any>> {
|
||||||
return statisticsUpdateProducer.asFlux().flatMap {
|
return statisticsUpdateProducer.asFlux().flatMap {
|
||||||
@ -105,6 +119,9 @@ class StatisticsRestController(
|
|||||||
.build(),
|
.build(),
|
||||||
ServerSentEvent.builder<Any>()
|
ServerSentEvent.builder<Any>()
|
||||||
.event("requestslastmonth").id("none").data(this.requestsLastMonth())
|
.event("requestslastmonth").id("none").data(this.requestsLastMonth())
|
||||||
|
.build(),
|
||||||
|
ServerSentEvent.builder<Any>()
|
||||||
|
.event("requestpatientstates").id("none").data(this.requestPatientStates())
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -281,4 +281,13 @@ input.inline:focus-visible {
|
|||||||
|
|
||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
|
width: calc(100% - 2.4rem - 4px);
|
||||||
|
height: 320px;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-50pc {
|
||||||
|
width: calc(50% - 2.4rem - 4px);
|
||||||
}
|
}
|
@ -10,20 +10,27 @@
|
|||||||
<main>
|
<main>
|
||||||
<h1>Statistiken</h1>
|
<h1>Statistiken</h1>
|
||||||
|
|
||||||
<div id="piechart" class="chart" style="width: 320px; height: 320px; display: inline-block"></div>
|
<div>
|
||||||
<div id="barchart" class="chart" style="width: 720px; height: 320px; display: inline-block"></div>
|
<div id="piechart1" class="chart chart-50pc"></div>
|
||||||
|
<div id="piechart2" class="chart chart-50pc"></div>
|
||||||
|
</div>
|
||||||
|
<div id="barchart" class="chart"></div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
<script th:src="@{/echarts.min.js}"></script>
|
<script th:src="@{/echarts.min.js}"></script>
|
||||||
<script th:src="@{/scripts.js}"></script>
|
<script th:src="@{/scripts.js}"></script>
|
||||||
<script>
|
<script>
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
drawPieChart('statistics/requeststates', 'piechart', 'Statusverteilung aller Anfragen');
|
drawPieChart('statistics/requeststates', 'piechart1', 'Statusverteilung aller Anfragen');
|
||||||
|
drawPieChart('statistics/requestpatientstates', 'piechart2', 'Statusverteilung nach Patient');
|
||||||
drawBarChart('statistics/requestslastmonth', 'barchart', 'Anfragen der letzten 30 Tage');
|
drawBarChart('statistics/requestslastmonth', 'barchart', 'Anfragen der letzten 30 Tage');
|
||||||
|
|
||||||
const eventSource = new EventSource('statistics/events');
|
const eventSource = new EventSource('statistics/events');
|
||||||
eventSource.addEventListener('requeststates', event => {
|
eventSource.addEventListener('requeststates', event => {
|
||||||
drawPieChart('statistics/requeststates', 'piechart', 'Statusverteilung aller Anfragen', JSON.parse(event.data));
|
drawPieChart('statistics/requeststates', 'piechart1', 'Statusverteilung aller Anfragen', JSON.parse(event.data));
|
||||||
|
});
|
||||||
|
eventSource.addEventListener('requestpatientstates', event => {
|
||||||
|
drawPieChart('statistics/requestpatientstates', 'piechart2', 'Statusverteilung nach Patient', JSON.parse(event.data));
|
||||||
});
|
});
|
||||||
eventSource.addEventListener('requestslastmonth', event => {
|
eventSource.addEventListener('requestslastmonth', event => {
|
||||||
drawBarChart('statistics/requestslastmonth', 'barchart', 'Anfragen des letzten Monats', JSON.parse(event.data));
|
drawBarChart('statistics/requestslastmonth', 'barchart', 'Anfragen des letzten Monats', JSON.parse(event.data));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user