1
0
mirror of https://github.com/pcvolkmer/mv64e-onkostar-data.git synced 2025-07-02 02:22:54 +00:00

feat: add display and system to diagnosis data

This commit is contained in:
2025-06-22 12:52:42 +02:00
parent 21739a055d
commit 6a3ee860b7
6 changed files with 192 additions and 15 deletions

View File

@ -43,8 +43,16 @@ public class PropertyCatalogue {
public Entry getByCodeAndVersion(String code, int version) {
try {
return this.jdbcTemplate.queryForObject(
"SELECT code, shortdesc, description FROM property_catalogue_version_entry WHERE code = ? AND property_version_id = ?",
(rs, rowNum) -> new Entry(rs.getString("code"), rs.getString("shortdesc"), rs.getString("description")),
"SELECT code, shortdesc, e.description, v.oid AS version_oid, v.description AS version_description FROM property_catalogue_version_entry e" +
" JOIN property_catalogue_version v ON (e.property_version_id = v.id)" +
" WHERE code = ? AND property_version_id = ?",
(rs, rowNum) -> new Entry(
rs.getString("code"),
rs.getString("shortdesc"),
rs.getString("description"),
rs.getString("version_oid"),
rs.getString("version_description")
),
code,
version);
} catch (RuntimeException e) {
@ -59,11 +67,19 @@ public class PropertyCatalogue {
private final String code;
private final String shortdesc;
private final String description;
private final String versionOid;
private final String versionDescription;
public Entry(String code, String shortdesc, String description) {
this(code, shortdesc, description, null, null);
}
public Entry(String code, String shortdesc, String description, String versionOid, String versionDescription) {
this.code = code;
this.shortdesc = shortdesc;
this.description = description;
this.versionOid = versionOid;
this.versionDescription = versionDescription;
}
public String getCode() {
@ -77,6 +93,14 @@ public class PropertyCatalogue {
public String getShortdesc() {
return shortdesc;
}
public String getVersionOid() {
return versionOid;
}
public String getVersionDescription() {
return versionDescription;
}
}
}

View File

@ -1,8 +1,16 @@
package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.Coding;
import dev.pcvolkmer.mv64e.mtb.MtbDiagnosis;
import dev.pcvolkmer.mv64e.mtb.*;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.KpaCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TumorausbreitungCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TumorgradingCatalogue;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Mapper class to load and map diagnosis data from database table 'dk_dnpm_kpa'
@ -13,9 +21,20 @@ import dev.pcvolkmer.onco.datamapper.datacatalogues.KpaCatalogue;
public class KpaDiagnosisDataMapper implements DataMapper<MtbDiagnosis> {
private final KpaCatalogue kpaCatalogue;
private final TumorausbreitungCatalogue tumorausbreitungCatalogue;
private final TumorgradingCatalogue tumorgradingCatalogue;
private final PropertyCatalogue propertyCatalogue;
public KpaDiagnosisDataMapper(final KpaCatalogue kpaCatalogue) {
public KpaDiagnosisDataMapper(
final KpaCatalogue kpaCatalogue,
final TumorausbreitungCatalogue tumorausbreitungCatalogue,
final TumorgradingCatalogue tumorgradingCatalogue,
final PropertyCatalogue propertyCatalogue
) {
this.kpaCatalogue = kpaCatalogue;
this.tumorausbreitungCatalogue = tumorausbreitungCatalogue;
this.tumorgradingCatalogue = tumorgradingCatalogue;
this.propertyCatalogue = propertyCatalogue;
}
/**
@ -31,12 +50,102 @@ public class KpaDiagnosisDataMapper implements DataMapper<MtbDiagnosis> {
var builder = MtbDiagnosis.builder();
builder
.id(data.getString("id"))
.patient(Reference.builder().id(data.getString("patient_id")).build())
.code(
Coding.builder()
.code(data.getString("icd10"))
.system("http://fhir.de/CodeSystem/bfarm/icd-10-gm")
.display(propertyCatalogue.getByCodeAndVersion(data.getString("icd10"), data.getInteger("icd10_propcat_version")).getShortdesc())
.version(propertyCatalogue.getByCodeAndVersion(data.getString("icd10"), data.getInteger("icd10_propcat_version")).getVersionDescription())
.build()
);
)
.topography(Coding.builder().code(data.getString("icdo3localisation")).build())
// Nicht in Onkostar erfasst
//.germlineCodes()
.guidelineTreatmentStatus(
getMtbDiagnosisGuidelineTreatmentStatusCoding(data.getString("leitlinienstatus"), data.getInteger("leitlinienstatus_propcat_version"))
)
.grading(getGrading(id))
.staging(getStaging(id))
;
return builder.build();
}
private MtbDiagnosisGuidelineTreatmentStatusCoding getMtbDiagnosisGuidelineTreatmentStatusCoding(final String code, final int version) {
if (code == null || !Arrays.stream(MtbDiagnosisGuidelineTreatmentStatusCodingCode.values()).map(MtbDiagnosisGuidelineTreatmentStatusCodingCode::toValue).collect(Collectors.toSet()).contains(code)) {
return null;
}
var resultBuilder = MtbDiagnosisGuidelineTreatmentStatusCoding.builder()
.display(propertyCatalogue.getByCodeAndVersion(code, version).getShortdesc())
.system("dnpm-dip/mtb/diagnosis/guideline-treatment-status");
try {
resultBuilder.code(MtbDiagnosisGuidelineTreatmentStatusCodingCode.forValue(code));
} catch (IOException e) {
throw new IllegalStateException("No valid code found");
}
return resultBuilder.build();
}
private Grading getGrading(final int id) {
var all = tumorgradingCatalogue.getAllByParentId(id).stream()
.map(resultSet -> {
var builder = TumorGrading.builder()
.date(resultSet.getDate("zeitpunkt"));
if (null != resultSet.getString("tumorgrading") && !resultSet.getString("tumorgrading").isBlank()) {
var propertyEntry = propertyCatalogue
.getByCodeAndVersion(resultSet.getString("tumorgrading"), resultSet.getInteger("tumorgrading_propcat_version"));
builder.codes(
List.of(
Coding.builder()
.code(resultSet.getString("tumorgrading"))
.system("https://www.basisdatensatz.de/feld/161/grading")
// TODO Annahme: "v1" ist Version 2025
.version(propertyEntry.getVersionDescription().equals("v1") ? "2025" : null)
.display(propertyEntry.getShortdesc())
.build()
)
);
return builder.build();
} else if (null != resultSet.getString("whograd") && !resultSet.getString("whograd").isBlank()) {
var propertyEntry = propertyCatalogue
.getByCodeAndVersion(resultSet.getString("whograd"), resultSet.getInteger("whograd_propcat_version"));
builder.codes(
List.of(
Coding.builder()
.code(resultSet.getString("whograd"))
.system("dnpm-dip/mtb/who-grading-cns-tumors")
.version(propertyEntry.getVersionDescription())
.display(propertyEntry.getShortdesc())
.build()
)
);
return builder.build();
}
return null;
}
).filter(Objects::nonNull).collect(Collectors.toList());
if (all.isEmpty()) {
return null;
}
return Grading.builder().history(all).build();
}
private Staging getStaging(final int id) {
var subMapper = new KpaTumorausbreitungDataMapper(tumorausbreitungCatalogue);
var all = tumorausbreitungCatalogue.getAllByParentId(id).stream()
.map(it -> subMapper.getById(it.getInteger("id")))
.collect(Collectors.toList());
if (all.isEmpty()) {
return null;
}
return Staging.builder().history(all).build();
}
}

View File

@ -39,7 +39,14 @@ public class KpaTumorausbreitungDataMapper extends AbstractSubformDataMapper<Tum
builder
.date(resultSet.getDate("zeitpunkt"))
.method(getTumorStagingMethodCoding(resultSet.getString("typ")))
.otherClassifications(List.of(Coding.builder().code(resultSet.getString("wert")).build()))
.otherClassifications(
List.of(
Coding.builder()
.code(resultSet.getString("wert"))
.system("dnpm-dip/mtb/diagnosis/kds-tumor-spread")
.build()
)
)
.tnmClassification(getTnmClassification(resultSet))
;
@ -51,7 +58,8 @@ public class KpaTumorausbreitungDataMapper extends AbstractSubformDataMapper<Tum
return null;
}
var resultBuilder = TumorStagingMethodCoding.builder();
var resultBuilder = TumorStagingMethodCoding.builder()
.system("dnpm-dip/mtb/tumor-staging/method");
try {
resultBuilder.code(TumorStagingMethodCodingCode.forValue(value));
} catch (IOException e) {
@ -69,7 +77,11 @@ public class KpaTumorausbreitungDataMapper extends AbstractSubformDataMapper<Tum
var tnmt = resultSet.getString("tnmt");
if (tnmt != null && !tnmt.isBlank()) {
tnpmClassificationBuilder.tumor(
Coding.builder().code(String.format("%s%s", resultSet.getString("tnmtprefix"), tnmt)).build()
Coding.builder()
// TODO With or withour prefix?
.code(String.format("%s%s", resultSet.getString("tnmtprefix"), tnmt))
.system("UICC")
.build()
);
hasContent = true;
}
@ -77,7 +89,11 @@ public class KpaTumorausbreitungDataMapper extends AbstractSubformDataMapper<Tum
var tnmn = resultSet.getString("tnmn");
if (tnmn != null && !tnmn.isBlank()) {
tnpmClassificationBuilder.nodes(
Coding.builder().code(String.format("%s%s", resultSet.getString("tnmnprefix"), tnmn)).build()
Coding.builder()
// TODO With or withour prefix?
.code(String.format("%s%s", resultSet.getString("tnmnprefix"), tnmn))
.system("UICC")
.build()
);
hasContent = true;
}
@ -85,7 +101,11 @@ public class KpaTumorausbreitungDataMapper extends AbstractSubformDataMapper<Tum
var tnmm = resultSet.getString("tnmm");
if (tnmm != null && !tnmm.isBlank()) {
tnpmClassificationBuilder.metastasis(
Coding.builder().code(String.format("%s%s", resultSet.getString("tnmmprefix"), tnmm)).build()
Coding.builder()
// TODO With or withour prefix?
.code(String.format("%s%s", resultSet.getString("tnmmprefix"), tnmm))
.system("UICC")
.build()
);
hasContent = true;
}

View File

@ -63,7 +63,8 @@ public class MtbDataMapper implements DataMapper<Mtb> {
var diagnosisDataMapper = new KpaDiagnosisDataMapper(
kpaCatalogue,
catalogueFactory.catalogue(TumorausbreitungCatalogue.class),
catalogueFactory.catalogue(TumorgradingCatalogue.class)
catalogueFactory.catalogue(TumorgradingCatalogue.class),
propertyCatalogue
);
var prozedurMapper = new KpaProzedurDataMapper(catalogueFactory.catalogue(ProzedurCatalogue.class));

View File

@ -1,8 +1,11 @@
package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.MtbDiagnosis;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.KpaCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TumorausbreitungCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TumorgradingCatalogue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -21,13 +24,24 @@ import static org.mockito.Mockito.doAnswer;
class KpaDiagnosisDataMapperTest {
KpaCatalogue kpaCatalogue;
TumorausbreitungCatalogue tumorausbreitungCatalogue;
TumorgradingCatalogue tumorgradingCatalogue;
PropertyCatalogue propertyCatalogue;
KpaDiagnosisDataMapper dataMapper;
@BeforeEach
void setUp(@Mock KpaCatalogue kpaCatalogue) {
void setUp(
@Mock KpaCatalogue kpaCatalogue,
@Mock TumorausbreitungCatalogue tumorausbreitungCatalogue,
@Mock TumorgradingCatalogue tumorgradingCatalogue,
@Mock PropertyCatalogue propertyCatalogue
) {
this.kpaCatalogue = kpaCatalogue;
this.dataMapper = new KpaDiagnosisDataMapper(kpaCatalogue);
this.tumorausbreitungCatalogue = tumorausbreitungCatalogue;
this.tumorgradingCatalogue = tumorgradingCatalogue;
this.propertyCatalogue = propertyCatalogue;
this.dataMapper = new KpaDiagnosisDataMapper(kpaCatalogue, tumorausbreitungCatalogue, tumorgradingCatalogue, propertyCatalogue);
}
@Test
@ -46,6 +60,10 @@ class KpaDiagnosisDataMapperTest {
.when(kpaCatalogue)
.getById(anyInt());
doAnswer(invocationOnMock ->
new PropertyCatalogue.Entry("C00.0", "Bösartige Neubildung: Äußere Oberlippe", "Bösartige Neubildung: Äußere Oberlippe")
).when(propertyCatalogue).getByCodeAndVersion(anyString(), anyInt());
var actual = this.dataMapper.getById(1);
assertThat(actual).isInstanceOf(MtbDiagnosis.class);
assertThat(actual.getId()).isEqualTo("1");

View File

@ -69,7 +69,12 @@ class KpaTumorausbreitungDataMapperTest {
var actual = actualList.get(0);
assertThat(actual).isInstanceOf(TumorStaging.class);
assertThat(actual.getDate()).isEqualTo(new java.sql.Date(Date.from(Instant.parse("2000-01-01T12:00:00Z")).getTime()));
assertThat(actual.getMethod()).isEqualTo(TumorStagingMethodCoding.builder().code(TumorStagingMethodCodingCode.PATHOLOGIC).build());
assertThat(actual.getMethod()).isEqualTo(
TumorStagingMethodCoding.builder()
.code(TumorStagingMethodCodingCode.PATHOLOGIC)
.system("dnpm-dip/mtb/tumor-staging/method")
.build()
);
assertThat(actual.getOtherClassifications()).hasSize(1);
assertThat(actual.getOtherClassifications().get(0).getCode()).isEqualTo("tumor-free");
assertThat(actual.getTnmClassification().getTumor().getCode()).isEqualTo("p0");