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

feat: additional mapping in TherapieplanDataMapper

This commit is contained in:
2025-06-30 00:46:07 +02:00
parent d53c2074e4
commit 5692dfbdc7
5 changed files with 165 additions and 37 deletions

View File

@ -36,25 +36,30 @@ var jsonResult = Converter.toJsonString(
## Status ## Status
| DNPM-Datenmodell 2.1 - Bereich | Status | Anmerkung | | DNPM-Datenmodell 2.1 - Bereich | Status | Anmerkung |
|----------------------------------|--------|----------------------------------------------------------------------------| |----------------------------------|--------|--------------------------------------------------------------------------------|
| Patient | ✅ | Verwendet Datenbank-ID, keine managing Site | | Patient | ✅ | Verwendet Datenbank-ID, keine managing Site |
| Episoden | ✅ | | | Episoden | ✅ | |
| Diagnosen | ✅ | Entsprechend Formularaufbau nur Diagnose der aktuellen Episode | | Diagnosen | ✅ | Entsprechend Formularaufbau nur Diagnose der aktuellen Episode |
| Verwandten-Diagnosen | ✅ | | | Verwandten-Diagnosen | ✅ | |
| Systemische Leitlinien-Therapien | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | | Systemische Leitlinien-Therapien | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 |
| Leitlinien-Prozeduren | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 | | Leitlinien-Prozeduren | ✅ | Siehe auch: https://github.com/dnpm-dip/mtb-model/issues/9 |
| ECOG-Verlauf | ✅ | | | ECOG-Verlauf | ✅ | |
| Tumor-Proben | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen | | Tumor-Proben | ⛅ | Best effort: Formular OS.Molekulargenetik erfüllt nicht alle Anforderungen (1) |
| vorherige Molekular-Diagnostik | ⌛ | Aktuell in Arbeit | | vorherige Molekular-Diagnostik | ⌛ | Aktuell in Arbeit |
| Histologie-Berichte | ⌛ | Aktuell in Arbeit | | Histologie-Berichte | ⌛ | Aktuell in Arbeit |
| IHC-Berichte | | | | IHC-Berichte | | |
| MSI-Befunde | | | | MSI-Befunde | | |
| NGS-Berichte | ⌛ | Aktuell in Arbeit | | NGS-Berichte | ⌛ | Aktuell in Arbeit |
| MTB-Beschlüsse | | Aktuell in Arbeit | | MTB-Beschlüsse | | Best effort: Stützende molekulare Alteration(en) aktuell nicht möglich (2) |
| Follow-Up Verlauf | | | | Follow-Up Verlauf | | |
| Antrag Kostenübernahme | | | | Antrag Kostenübernahme | | |
| Antwort Kostenübernahme | | | | Antwort Kostenübernahme | | |
| Therapien | | | | Therapien | | |
| Response Befunde | | | | Response Befunde | | |
### Hinweise
1. Nicht alle möglichen Ausprägungen in `OS.Molekulargenetik` vorhanden.
2. Nach Implementierung Mapping von HGNC-Symbol (Gen-Name) zu HGNC-ID ist die Angabe der optionalen stützenden
molekularen Alteration(en) möglich.

View File

@ -1,10 +1,12 @@
package dev.pcvolkmer.onco.datamapper.mapper; package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.MtbMedicationRecommendation; import dev.pcvolkmer.mv64e.mtb.*;
import dev.pcvolkmer.mv64e.mtb.Reference; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue;
import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -18,13 +20,19 @@ import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReferen
*/ */
public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlungDataMapper<MtbMedicationRecommendation> { public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlungDataMapper<MtbMedicationRecommendation> {
public EinzelempfehlungWirkstoffDataMapper(EinzelempfehlungCatalogue einzelempfehlungCatalogue) { private final PropertyCatalogue propertyCatalogue;
public EinzelempfehlungWirkstoffDataMapper(
EinzelempfehlungCatalogue einzelempfehlungCatalogue,
PropertyCatalogue propertyCatalogue
) {
super(einzelempfehlungCatalogue); super(einzelempfehlungCatalogue);
this.propertyCatalogue = propertyCatalogue;
} }
@Override @Override
protected MtbMedicationRecommendation map(ResultSet resultSet) { protected MtbMedicationRecommendation map(ResultSet resultSet) {
return MtbMedicationRecommendation.builder() var resultBuilder = MtbMedicationRecommendation.builder()
.id(resultSet.getString("id")) .id(resultSet.getString("id"))
.patient(getPatientReference(resultSet.getString("patient_id"))) .patient(getPatientReference(resultSet.getString("patient_id")))
// TODO Fix id? // TODO Fix id?
@ -37,8 +45,31 @@ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlun
) )
) )
.medication(JsonToMedicationMapper.map(resultSet.getString("wirkstoffe_json"))) .medication(JsonToMedicationMapper.map(resultSet.getString("wirkstoffe_json")))
.levelOfEvidence(getLevelOfEvidence(resultSet)) .levelOfEvidence(getLevelOfEvidence(resultSet));
.build();
if (null != resultSet.getString("art_der_therapie")) {
resultBuilder.category(
getMtbMedicationRecommendationCategoryCoding(
resultSet.getString("art_der_therapie"),
resultSet.getInteger("art_der_therapie_propcat_version")
)
);
}
if (null != resultSet.getString("empfehlungsart")) {
resultBuilder.useType(
getMtbMedicationRecommendationUseTypeCoding(
resultSet.getString("empfehlungsart"),
resultSet.getInteger("empfehlungsart_propcat_version")
)
);
}
if (null != resultSet.getString("st_mol_alt_variante")) {
// Empty for now
}
return resultBuilder.build();
} }
@Override @Override
@ -51,13 +82,47 @@ public class EinzelempfehlungWirkstoffDataMapper extends AbstractEinzelempfehlun
return catalogue.getAllByParentId(parentId) return catalogue.getAllByParentId(parentId)
.stream() .stream()
// Filter Wirkstoffempfehlung (Systemische Therapie) // Filter Wirkstoffempfehlung (Systemische Therapie)
.filter(it -> it.getString("art_der_therapie") == null .filter(it -> "systemisch".equals(it.getString("empfehlungskategorie")))
|| it.getString("art_der_therapie").isBlank())
.filter(it -> it.getString("empfehlungskategorie") == null
|| it.getString("empfehlungskategorie").isBlank()
|| "systemisch".equals(it.getString("empfehlungskategorie")))
.map(this::map) .map(this::map)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private MtbMedicationRecommendationCategoryCoding getMtbMedicationRecommendationCategoryCoding(String code, int version) {
if (code == null || !Arrays.stream(MtbMedicationRecommendationCategoryCodingCode.values()).map(MtbMedicationRecommendationCategoryCodingCode::toValue).collect(Collectors.toSet()).contains(code)) {
return null;
}
var resultBuilder = MtbMedicationRecommendationCategoryCoding.builder()
.system("dnpm-dip/mtb/recommendation/systemic-therapy/category");
try {
resultBuilder
.code(MtbMedicationRecommendationCategoryCodingCode.forValue(code))
.display(propertyCatalogue.getByCodeAndVersion(code, version).getShortdesc());
} catch (IOException e) {
return null;
}
return resultBuilder.build();
}
private MtbMedicationRecommendationUseTypeCoding getMtbMedicationRecommendationUseTypeCoding(String code, int version) {
if (code == null || !Arrays.stream(MtbMedicationRecommendationUseTypeCodingCode.values()).map(MtbMedicationRecommendationUseTypeCodingCode::toValue).collect(Collectors.toSet()).contains(code)) {
return null;
}
var resultBuilder = MtbMedicationRecommendationUseTypeCoding.builder()
.system("dnpm-dip/mtb/recommendation/systemic-therapy/use-type");
try {
resultBuilder
.code(MtbMedicationRecommendationUseTypeCodingCode.forValue(code))
.display(propertyCatalogue.getByCodeAndVersion(code, version).getShortdesc());
} catch (IOException e) {
return null;
}
return resultBuilder.build();
}
} }

View File

@ -86,6 +86,8 @@ public class MtbDataMapper implements DataMapper<Mtb> {
var therapieplanCatalogue = catalogueFactory.catalogue(TherapieplanCatalogue.class); var therapieplanCatalogue = catalogueFactory.catalogue(TherapieplanCatalogue.class);
var therapieplanDataMapper = new TherapieplanDataMapper( var therapieplanDataMapper = new TherapieplanDataMapper(
therapieplanCatalogue, therapieplanCatalogue,
catalogueFactory.catalogue(RebiopsieCatalogue.class),
catalogueFactory.catalogue(ReevaluationCatalogue.class),
einzelempfehlungCatalogue, einzelempfehlungCatalogue,
propertyCatalogue propertyCatalogue
); );

View File

@ -2,8 +2,7 @@ package dev.pcvolkmer.onco.datamapper.mapper;
import dev.pcvolkmer.mv64e.mtb.*; import dev.pcvolkmer.mv64e.mtb.*;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.*;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapieplanCatalogue;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@ -21,6 +20,8 @@ import static dev.pcvolkmer.onco.datamapper.mapper.MapperUtils.getPatientReferen
public class TherapieplanDataMapper implements DataMapper<MtbCarePlan> { public class TherapieplanDataMapper implements DataMapper<MtbCarePlan> {
private final TherapieplanCatalogue therapieplanCatalogue; private final TherapieplanCatalogue therapieplanCatalogue;
private final RebiopsieCatalogue rebiopsieCatalogue;
private final ReevaluationCatalogue reevaluationCatalogue;
private final PropertyCatalogue propertyCatalogue; private final PropertyCatalogue propertyCatalogue;
private final EinzelempfehlungProzedurDataMapper einzelempfehlungProzedurDataMapper; private final EinzelempfehlungProzedurDataMapper einzelempfehlungProzedurDataMapper;
@ -29,14 +30,18 @@ public class TherapieplanDataMapper implements DataMapper<MtbCarePlan> {
public TherapieplanDataMapper( public TherapieplanDataMapper(
final TherapieplanCatalogue therapieplanCatalogue, final TherapieplanCatalogue therapieplanCatalogue,
final RebiopsieCatalogue rebiopsieCatalogue,
final ReevaluationCatalogue reevaluationCatalogue,
final EinzelempfehlungCatalogue einzelempfehlungCatalogue, final EinzelempfehlungCatalogue einzelempfehlungCatalogue,
final PropertyCatalogue propertyCatalogue final PropertyCatalogue propertyCatalogue
) { ) {
this.therapieplanCatalogue = therapieplanCatalogue; this.therapieplanCatalogue = therapieplanCatalogue;
this.rebiopsieCatalogue = rebiopsieCatalogue;
this.reevaluationCatalogue = reevaluationCatalogue;
this.propertyCatalogue = propertyCatalogue; this.propertyCatalogue = propertyCatalogue;
this.einzelempfehlungProzedurDataMapper = new EinzelempfehlungProzedurDataMapper(einzelempfehlungCatalogue); this.einzelempfehlungProzedurDataMapper = new EinzelempfehlungProzedurDataMapper(einzelempfehlungCatalogue);
this.einzelempfehlungWirkstoffDataMapper = new EinzelempfehlungWirkstoffDataMapper(einzelempfehlungCatalogue); this.einzelempfehlungWirkstoffDataMapper = new EinzelempfehlungWirkstoffDataMapper(einzelempfehlungCatalogue, propertyCatalogue);
this.einzelempfehlungStudieDataMapper = new EinzelempfehlungStudieDataMapper(einzelempfehlungCatalogue); this.einzelempfehlungStudieDataMapper = new EinzelempfehlungStudieDataMapper(einzelempfehlungCatalogue);
} }
@ -55,6 +60,16 @@ public class TherapieplanDataMapper implements DataMapper<MtbCarePlan> {
.id(therapieplanData.getString("id")) .id(therapieplanData.getString("id"))
.patient(getPatientReference(therapieplanData.getString("patient_id"))) .patient(getPatientReference(therapieplanData.getString("patient_id")))
.issuedOn(therapieplanData.getDate("datum")) .issuedOn(therapieplanData.getDate("datum"))
.histologyReevaluationRequests(getHistologyReevaluationRequests(id))
.rebiopsyRequests(
getRebiopsyRequest(
id,
Reference.builder()
.id(therapieplanData.getString("ref_dnpm_klinikanamnese"))
.type("MTBDiagnosis")
.build()
)
)
; ;
if (therapieplanData.isTrue("mit_einzelempfehlung")) { if (therapieplanData.isTrue("mit_einzelempfehlung")) {
@ -137,4 +152,30 @@ public class TherapieplanDataMapper implements DataMapper<MtbCarePlan> {
return resultBuilder.build(); return resultBuilder.build();
} }
private List<RebiopsyRequest> getRebiopsyRequest(int parentId, Reference diagnosisReference) {
return this.rebiopsieCatalogue.getAllByParentId(parentId).stream()
.map(resultSet ->
RebiopsyRequest.builder()
.id(resultSet.getString("id"))
.patient(getPatientReference(resultSet.getString("patient_id")))
.issuedOn(resultSet.getDate("datum"))
.tumorEntity(diagnosisReference)
.build()
)
.collect(Collectors.toList());
}
private List<HistologyReevaluationRequest> getHistologyReevaluationRequests(int parentId) {
return this.reevaluationCatalogue.getAllByParentId(parentId).stream()
.map(resultSet ->
HistologyReevaluationRequest.builder()
.id(resultSet.getString("id"))
.patient(getPatientReference(resultSet.getString("patient_id")))
.issuedOn(resultSet.getDate("datum"))
.specimen(Reference.builder().id(resultSet.getString("ref_molekulargenetik")).build())
.build()
)
.collect(Collectors.toList());
}
} }

View File

@ -4,6 +4,8 @@ import dev.pcvolkmer.mv64e.mtb.*;
import dev.pcvolkmer.onco.datamapper.PropertyCatalogue; import dev.pcvolkmer.onco.datamapper.PropertyCatalogue;
import dev.pcvolkmer.onco.datamapper.ResultSet; import dev.pcvolkmer.onco.datamapper.ResultSet;
import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.EinzelempfehlungCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.RebiopsieCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.ReevaluationCatalogue;
import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapieplanCatalogue; import dev.pcvolkmer.onco.datamapper.datacatalogues.TherapieplanCatalogue;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -24,6 +26,8 @@ class TherapieplanDataMapperTest {
TherapieplanCatalogue therapieplanCatalogue; TherapieplanCatalogue therapieplanCatalogue;
EinzelempfehlungCatalogue einzelempfehlungCatalogue; EinzelempfehlungCatalogue einzelempfehlungCatalogue;
RebiopsieCatalogue rebiopsieCatalogue;
ReevaluationCatalogue reevaluationCatalogue;
PropertyCatalogue propertyCatalogue; PropertyCatalogue propertyCatalogue;
TherapieplanDataMapper dataMapper; TherapieplanDataMapper dataMapper;
@ -31,13 +35,23 @@ class TherapieplanDataMapperTest {
@BeforeEach @BeforeEach
void setUp( void setUp(
@Mock TherapieplanCatalogue therapieplanCatalogue, @Mock TherapieplanCatalogue therapieplanCatalogue,
@Mock RebiopsieCatalogue rebiopsieCatalogue,
@Mock ReevaluationCatalogue reevaluationCatalogue,
@Mock EinzelempfehlungCatalogue einzelempfehlungCatalogue, @Mock EinzelempfehlungCatalogue einzelempfehlungCatalogue,
@Mock PropertyCatalogue propertyCatalogue @Mock PropertyCatalogue propertyCatalogue
) { ) {
this.therapieplanCatalogue = therapieplanCatalogue; this.therapieplanCatalogue = therapieplanCatalogue;
this.rebiopsieCatalogue = rebiopsieCatalogue;
this.reevaluationCatalogue = reevaluationCatalogue;
this.einzelempfehlungCatalogue = einzelempfehlungCatalogue; this.einzelempfehlungCatalogue = einzelempfehlungCatalogue;
this.propertyCatalogue = propertyCatalogue; this.propertyCatalogue = propertyCatalogue;
this.dataMapper = new TherapieplanDataMapper(therapieplanCatalogue, einzelempfehlungCatalogue, propertyCatalogue); this.dataMapper = new TherapieplanDataMapper(
therapieplanCatalogue,
rebiopsieCatalogue,
reevaluationCatalogue,
einzelempfehlungCatalogue,
propertyCatalogue
);
} }
@Test @Test
@ -47,7 +61,8 @@ class TherapieplanDataMapperTest {
"patient_id", "42", "patient_id", "42",
"wirkstoffe_json", "[{\"code\":\"\",\"name\":\"PARP-Inhibierung\",\"system\":\"UNREGISTERED\"}]", "wirkstoffe_json", "[{\"code\":\"\",\"name\":\"PARP-Inhibierung\",\"system\":\"UNREGISTERED\"}]",
"protokollauszug", "Das ist ein Protokollauszug", "protokollauszug", "Das ist ein Protokollauszug",
"mit_einzelempfehlung", true "mit_einzelempfehlung", true,
"empfehlungskategorie", "systemisch"
); );
doAnswer(invocationOnMock -> { doAnswer(invocationOnMock -> {