summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2023-07-26 09:34:05 +0200
committerPaul-Christian Volkmer2023-07-26 09:39:31 +0200
commit5c6384e878318c0e86ed8bf59a973a063ab13f63 (patch)
tree2d985e086da43024e9ef411f3c112b81668826b6 /src/main
parent26312c86205681723dd8a9c249e886c8655aa078 (diff)
Add statistics for state per patient
Diffstat (limited to 'src/main')
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt11
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt17
-rw-r--r--src/main/resources/static/style.css9
-rw-r--r--src/main/resources/templates/statistics.html15
4 files changed, 48 insertions, 4 deletions
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
index 7955a9d..b3e2726 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
@@ -20,6 +20,7 @@
package dev.dnpm.etl.processor.monitoring
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.Table
import org.springframework.data.repository.CrudRepository
@@ -45,10 +46,20 @@ data class Report(
val dataQualityReport: String = ""
)
+data class CountedState(
+ val count: Int,
+ val status: RequestStatus,
+)
+
interface RequestRepository : CrudRepository<Request, Long> {
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: String): List<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>
+
} \ No newline at end of file
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
index 2741fd3..6da0bfb 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
@@ -19,6 +19,7 @@
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.RequestStatus
import org.reactivestreams.Publisher
@@ -95,6 +96,19 @@ class StatisticsRestController(
.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])
fun updater(): Flux<ServerSentEvent<Any>> {
return statisticsUpdateProducer.asFlux().flatMap {
@@ -105,6 +119,9 @@ class StatisticsRestController(
.build(),
ServerSentEvent.builder<Any>()
.event("requestslastmonth").id("none").data(this.requestsLastMonth())
+ .build(),
+ ServerSentEvent.builder<Any>()
+ .event("requestpatientstates").id("none").data(this.requestPatientStates())
.build()
)
)
diff --git a/src/main/resources/static/style.css b/src/main/resources/static/style.css
index bf37db2..185fead 100644
--- a/src/main/resources/static/style.css
+++ b/src/main/resources/static/style.css
@@ -281,4 +281,13 @@ input.inline:focus-visible {
border: 1px solid lightgray;
border-radius: 3px;
+
+ width: calc(100% - 2.4rem - 4px);
+ height: 320px;
+
+ display: inline-block;
+}
+
+.chart-50pc {
+ width: calc(50% - 2.4rem - 4px);
} \ No newline at end of file
diff --git a/src/main/resources/templates/statistics.html b/src/main/resources/templates/statistics.html
index 007303e..752b768 100644
--- a/src/main/resources/templates/statistics.html
+++ b/src/main/resources/templates/statistics.html
@@ -10,20 +10,27 @@
<main>
<h1>Statistiken</h1>
- <div id="piechart" class="chart" style="width: 320px; height: 320px; display: inline-block"></div>
- <div id="barchart" class="chart" style="width: 720px; height: 320px; display: inline-block"></div>
+ <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>
<script th:src="@{/echarts.min.js}"></script>
<script th:src="@{/scripts.js}"></script>
<script>
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');
const eventSource = new EventSource('statistics/events');
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 => {
drawBarChart('statistics/requestslastmonth', 'barchart', 'Anfragen des letzten Monats', JSON.parse(event.data));