#13377 - Updates the vaccination status handling#13944
Conversation
…panel for immunization status Refactors vaccination status handling to use a unified, derived model (VaccinationStatusData) based on immunization records, removing legacy dose-specific statuses and introducing explicit fields for number of doses and information reliability. Adds quick immunization entry, new API for status calculation, and Luxembourg-specific validity logic. Updates the UI with a dedicated vaccination status panel, prompts for status synchronization, and improves notification of unprocessed external message content. Aims to support national requirements, provide clearer vaccination tracking, and improve data consistency. Relates to #13377
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 Walkthrough<review_stack_artifact> </review_stack_artifact> ✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 14
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
sormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationStatus.java (1)
25-37:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReintroduce/normalize legacy vaccination enum values to avoid client/runtime incompatibility.
sormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationStatus.javaremovesVACCINATED_ONE_DOSE/VACCINATED_TWO_DOSEfrom the publicVaccinationStatusenum.sormas-rest/swagger.jsonandsormas-rest/swagger.yamlstill listVACCINATED_ONE_DOSE/VACCINATED_TWO_DOSEin the API schema enums, so integrations can continue sending/storing those values.- DB migration (
sormas-backend/src/main/resources/sql/sormas_schema.sql) collapses persisted legacy values toVACCINATED, but that doesn’t address runtime request/response deserialization boundaries.Keep deprecated enum aliases with normalization (or implement explicit deserialization remapping) and ensure the generated Swagger/OpenAPI matches the actual runtime accepted values (or document/enforce a hard migration boundary).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationStatus.java` around lines 25 - 37, The VaccinationStatus enum removed legacy constants causing runtime/schema mismatch; restore legacy enum entries VACCINATED_ONE_DOSE and VACCINATED_TWO_DOSE as deprecated aliases and normalize them to VACCINATED on deserialization/serialization: add the two constants back into the VaccinationStatus enum (mark with `@Deprecated` and a comment), implement a static factory/mapper in VaccinationStatus (e.g., a fromString/@JsonCreator method) that maps those legacy names to the VACCINATED value (and vice versa for serialization if needed), and regenerate the OpenAPI/Swagger so the schema matches the runtime accepted values; refer to the VaccinationStatus enum name and the fromString/@JsonCreator mapping function when making changes.
🟡 Minor comments (8)
sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/QuickImmunizationCreationForm.java-339-349 (1)
339-349:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winClamp invalid dose input before calling validity suggestion APIs.
parseNumberOfDosescurrently returns out-of-range integers, so suggestion calls can run with invalid values even though commit validation rejects them later.Suggested fix
private Integer parseNumberOfDoses() { String value = numberOfDoses.getValue(); if (value == null || value.trim().isEmpty()) { return null; } try { - return Integer.valueOf(value.trim()); + Integer parsed = Integer.valueOf(value.trim()); + return (parsed >= 1 && parsed <= 10) ? parsed : null; } catch (NumberFormatException e) { return null; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/QuickImmunizationCreationForm.java` around lines 339 - 349, parseNumberOfDoses currently returns parsed integers even if out of allowed range which lets suggestion APIs run with invalid doses; update parseNumberOfDoses to parse the value from numberOfDoses, return null for blank/parse errors, then clamp the parsed integer to the allowed min/max bounds used in validation (e.g., use the same constants or validation helpers as the commit path) before returning so suggestion calls always receive a valid in-range dose count.sormas-api/src/main/resources/captions.properties-2455-2455 (1)
2455-2455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove leading space in property value.
The value has an extra space before "Quick" which is inconsistent with other entries and may cause unintended spacing in the UI.
Suggested fix
-immunizationQuickNewImmunization= Quick new immunization +immunizationQuickNewImmunization=Quick new immunization🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/resources/captions.properties` at line 2455, The property immunizationQuickNewImmunization has a leading space in its value (" Quick new immunization"); remove the extra space so the value reads "Quick new immunization" to match other entries and avoid unintended UI spacing.sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java-390-391 (1)
390-391:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winValidate
numberOfDosesas non-negative.This field currently allows negative values, which makes the DTO contract accept invalid dose data.
Suggested fix
`@Outbreaks` + `@Min`(value = 0, message = Validations.numberTooSmall) private Integer numberOfDoses;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java` around lines 390 - 391, Add validation to ensure ContactDto.numberOfDoses cannot be negative: annotate the field ContactDto.numberOfDoses with a Bean Validation constraint such as `@Min`(0) (import javax.validation.constraints.Min) or add a defensive check in the setter/getter to throw/ignore negative values; update any unit tests if needed to assert non-negative behavior. Ensure the annotation is applied to the Integer numberOfDoses field in class ContactDto and imports are added accordingly.sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java-401-402 (1)
401-402:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEnforce non-negative dose counts in the API DTO.
numberOfDosesaccepts negative values right now, which allows invalid vaccination data to enter downstream logic.Suggested fix
`@Outbreaks` + `@Min`(value = 0, message = Validations.numberTooSmall) private Integer numberOfDoses;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java` around lines 401 - 402, The DTO field numberOfDoses in CaseDataDto currently allows negative values; prevent this by adding a non-negative validation and guarding the setter: annotate the numberOfDoses field with a bean-validation constraint such as `@Min`(0) (import from javax.validation.constraints.Min or jakarta.validation.constraints.Min) and update setNumberOfDoses(Integer numberOfDoses) to either coerce nulls or throw/ignore negative inputs (e.g., if (numberOfDoses != null && numberOfDoses < 0) throw new IllegalArgumentException(...) or set to 0), ensuring both the field and the setNumberOfDoses method enforce non-negative counts.sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantDto.java-102-103 (1)
102-103:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRestrict
numberOfDosesto non-negative values.Without a lower bound, invalid negative dose counts can be accepted.
Suggested fix
`@Outbreaks` + `@Min`(value = 0, message = Validations.numberTooSmall) private Integer numberOfDoses;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantDto.java` around lines 102 - 103, The numberOfDoses field in EventParticipantDto currently allows negative values; annotate the field (numberOfDoses) with a non-negative constraint such as `@Min`(0) (from javax.validation.constraints) while keeping the existing `@Outbreaks` annotation, and add the required import; alternatively enforce the same check in the setter/getValidation logic of EventParticipantDto to reject values < 0 (use `@Min`(0) on the Integer numberOfDoses field for the simplest fix).sormas-api/src/main/java/de/symeda/sormas/api/immunization/VaccinationStatusData.java-116-121 (1)
116-121:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGuard
isComparableVaccinationStatusDataEqualagainst null inputs.Current implementation throws NPE when either argument is null.
Proposed fix
public static boolean isComparableVaccinationStatusDataEqual(VaccinationStatusData caseData, VaccinationStatusData immunizationData) { + if (caseData == immunizationData) { + return true; + } + if (caseData == null || immunizationData == null) { + return false; + } return Objects.equals(caseData.getVaccinationStatus(), immunizationData.getVaccinationStatus()) && Objects.equals(caseData.getVaccinationStatusDetails(), immunizationData.getVaccinationStatusDetails()) && Objects.equals(caseData.getNumberOfDoses(), immunizationData.getNumberOfDoses()) && Objects.equals(caseData.getInformationReliability(), immunizationData.getInformationReliability()); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/java/de/symeda/sormas/api/immunization/VaccinationStatusData.java` around lines 116 - 121, isComparableVaccinationStatusDataEqual currently throws when either parameter is null; add a null guard at the start of the method in VaccinationStatusData.isComparableVaccinationStatusDataEqual: if both references are identical (caseData == immunizationData) return true; if one is null and the other is not (caseData == null || immunizationData == null) return false; then proceed with the existing field-wise Objects.equals checks.sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java-641-652 (1)
641-652:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winInclude
vaccinationStatusDetailsin the change detector.This block writes
vaccinationStatusDetails, but the guard only compares status, dose count, and reliability. If the derived status staysOTHERand only the free-text details change, the participant keeps stale details indefinitely.Suggested fix
if (data != null) { boolean statusChanged = data.getVaccinationStatus() != eventParticipant.getVaccinationStatus(); + boolean detailsChanged = + !java.util.Objects.equals(data.getVaccinationStatusDetails(), eventParticipant.getVaccinationStatusDetails()); boolean dosesChanged = !java.util.Objects.equals(data.getNumberOfDoses(), eventParticipant.getNumberOfDoses()); boolean reliabilityChanged = data.getInformationReliability() != eventParticipant.getInformationReliability(); - if (statusChanged || dosesChanged || reliabilityChanged) { + if (statusChanged || detailsChanged || dosesChanged || reliabilityChanged) { eventParticipant.setVaccinationStatus(data.getVaccinationStatus()); eventParticipant.setVaccinationStatusDetails(data.getVaccinationStatusDetails()); eventParticipant.setNumberOfDoses(data.getNumberOfDoses());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java` around lines 641 - 652, The change detector currently checks vaccination status, number of doses, and information reliability but omits vaccinationStatusDetails, so updates to the free-text details are ignored; add a comparison using java.util.Objects.equals(data.getVaccinationStatusDetails(), eventParticipant.getVaccinationStatusDetails()) (e.g. boolean detailsChanged) and include it in the if-condition alongside statusChanged, dosesChanged, and reliabilityChanged so that setVaccinationStatusDetails(...) runs when details differ.sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java-781-787 (1)
781-787:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReturn the requested reference window in the blank result.
When this fallback is hit with a non-null
fromDateand a null or lateruntilDate, the response currently reports both bounds fromuntilDate. That loses the caller's actual lower bound and makes the blankVaccinationStatusDatainconsistent with the method contract.Suggested fix
public VaccinationStatusData deriveVaccinationStatus(String personUuid, Disease disease, Date fromDate, Date untilDate) { if (personUuid == null || disease == null || fromDate == null) { + final Date effectiveUntilDate = untilDate != null ? untilDate : fromDate; return VaccinationStatusData.Builder.createBlank() .vaccinationStatus(VaccinationStatus.UNVACCINATED) .informationReliability(InformationReliability.UNKNOWN) - .referencePeriodFrom(untilDate) - .referencePeriodTo(untilDate) + .referencePeriodFrom(fromDate) + .referencePeriodTo(effectiveUntilDate) .build(); } final Date effectiveUntilDate = untilDate != null ? untilDate : fromDate;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java` around lines 781 - 787, The blank-result branch in ImmunizationService currently sets both referencePeriodFrom and referencePeriodTo to untilDate, losing a non-null fromDate; change the VaccinationStatusData.Builder invocation so referencePeriodFrom is fromDate if non-null (otherwise untilDate) and referencePeriodTo is untilDate if non-null (otherwise fromDate), i.e. referencePeriodFrom(fromDate != null ? fromDate : untilDate) and referencePeriodTo(untilDate != null ? untilDate : fromDate) to preserve the requested window.
🧹 Nitpick comments (4)
sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationController.java (1)
90-147: ⚡ Quick winConsolidate duplicated quick-create flow into a single implementation.
createQuick(..., Runnable)andbuildQuickCreateComponent(...)currently duplicate the same initialization/save/similar-popup logic, which is likely to drift.Suggested direction
`@Deprecated`(forRemoval = true) public void createQuick(PersonReferenceDto person, Disease disease, Runnable savedCallback) { - UserProvider currentUserProvider = UiUtil.getCurrentUserProvider(); - if (currentUserProvider == null) { - return; - } - ... - VaadinUiUtil.showModalPopupWindow(viewComponent, I18nProperties.getString(Strings.headingCreateQuickImmunization)); + CommitDiscardWrapperComponent<QuickImmunizationCreationForm> viewComponent = + buildQuickCreateComponent(person, disease, savedCallback); + if (viewComponent != null) { + VaadinUiUtil.showModalPopupWindow(viewComponent, I18nProperties.getString(Strings.headingCreateQuickImmunization)); + } }Also applies to: 149-206
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationController.java` around lines 90 - 147, The two flows createQuick(...) and buildQuickCreateComponent(...) duplicate initialization, pre-fill, commit handling and similar-immunization popup logic; extract the shared code into a single helper that (a) creates and prepares a QuickImmunizationCreationForm with pre-filled ImmunizationDto (use UiUtil.getCurrentUserProvider(), ImmunizationDto.build, setDisease, setReportingUser, setResponsibleRegion/setResponsibleDistrict using FacadeProvider.getRegionFacade()/getDistrictFacade().getDefaultInfrastructureReference()), (b) wraps it in CommitDiscardWrapperComponent and attaches one commit listener that calls FacadeProvider.getImmunizationFacade().saveQuickImmunization(...) then calls findSimilarImmunizations(...) and showSimilarImmunizationPopup(...) and finally invokes the provided savedCallback; then have both createQuick(...) and buildQuickCreateComponent(...) call that helper (or have buildQuickCreateComponent return the single reusable component) so the initialization/save/similar-popup logic exists only once.sormas-api/src/main/resources/captions.properties (1)
2446-2447: ⚡ Quick winInconsistent naming convention for property keys.
Lines 2446-2447 use underscore (
ImmunizationSidePanel_quickEntry,ImmunizationSidePanel_viewAll) while all other ImmunizationSidePanel entries (lines 2438-2445) use dot notation (e.g.,ImmunizationSidePanel.title). This inconsistency may cause confusion.Consider using dot notation for consistency:
Suggested fix for naming consistency
-ImmunizationSidePanel_quickEntry=Quick vaccination entry -ImmunizationSidePanel_viewAll=Show all immunizations +ImmunizationSidePanel.quickEntry=Quick vaccination entry +ImmunizationSidePanel.viewAll=Show all immunizations🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-api/src/main/resources/captions.properties` around lines 2446 - 2447, The two property keys ImmunizationSidePanel_quickEntry and ImmunizationSidePanel_viewAll use underscores and should be renamed to the dot-form used elsewhere (e.g., ImmunizationSidePanel.quickEntry and ImmunizationSidePanel.viewAll) to match the existing pattern such as ImmunizationSidePanel.title; update any code or templates that reference the old underscore keys to use the new dot keys so all lookups remain correct.sormas-backend/src/main/resources/sql/sormas_schema.sql (1)
16085-16103: ⚡ Quick winAdd guards for missing category and duplicate config value.
The DO block has two potential failure modes:
- If
GENERAL_CATEGORYdoesn't exist,general_category_idwill be NULL and the INSERT may fail on a NOT NULL or FK constraint, or worse, silently create an orphaned record.- If the migration is re-executed, a duplicate
config_keycould cause constraint violations.Based on learnings, the
systemconfigurationvaluetable is system-controlled and migrations should guard against duplicates.Proposed fix with guards
DO $$ DECLARE general_category_id integer; BEGIN SELECT id INTO general_category_id FROM systemconfigurationcategory WHERE name = 'GENERAL_CATEGORY'; +IF general_category_id IS NULL THEN + RAISE EXCEPTION 'GENERAL_CATEGORY not found in systemconfigurationcategory'; +END IF; + +IF NOT EXISTS (SELECT 1 FROM systemconfigurationvalue WHERE config_key = 'USE_QUICK_IMMUNIZATION_CREATION') THEN INSERT INTO systemconfigurationvalue(config_key, config_value, value_description, category_id, value_optional, value_pattern, value_encrypt, data_provider, validation_message, changedate, creationdate, id, uuid) VALUES ('USE_QUICK_IMMUNIZATION_CREATION', 'false', 'i18n/infoSystemConfigurationValueDescriptionUseQuickImmunizationCreation', general_category_id, true, '', false, 'de.symeda.sormas.api.systemconfiguration.SystemConfigurationValueBooleanProvider', 'i18n/systemConfigurationValueInvalidValue', now(), now(), nextval('entity_seq'), generate_base32_uuid()); +END IF; END $$ LANGUAGE plpgsql;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-backend/src/main/resources/sql/sormas_schema.sql` around lines 16085 - 16103, The DO block must guard against missing category and duplicate config keys: fetch the GENERAL_CATEGORY id into general_category_id and if it is NULL or NOT FOUND, abort the block with a NOTICE/RAISE and do not perform the INSERT; also check for an existing row in systemconfigurationvalue with config_key = 'USE_QUICK_IMMUNIZATION_CREATION' (or use INSERT ... ON CONFLICT DO NOTHING if a unique constraint exists) and skip the INSERT if a duplicate exists; update the block around systemconfigurationcategory, general_category_id, and the INSERT into systemconfigurationvalue (which uses nextval('entity_seq') and generate_base32_uuid()) to implement these guards.sormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjbTest.java (1)
124-125: ⚡ Quick winUse the lifelong-validity constant instead of hardcoded
9999-12-31.Line 124, Line 132, and Line 155 hardcode the sentinel date; use
ImmunizationValidityCalculator.LIFELONG_VALID_UNTILto avoid drift if the contract changes.♻️ Suggested refactor
+import de.symeda.sormas.api.immunization.ImmunizationValidityCalculator; @@ - assertEquals( - UtilDate.from(LocalDate.of(9999, 12, 31)), - getImmunizationFacade().suggestValidUntil(Disease.MEASLES, MeansOfImmunization.VACCINATION, validFrom, 2)); + assertEquals( + UtilDate.from(ImmunizationValidityCalculator.LIFELONG_VALID_UNTIL), + getImmunizationFacade().suggestValidUntil(Disease.MEASLES, MeansOfImmunization.VACCINATION, validFrom, 2)); @@ - assertEquals( - UtilDate.from(LocalDate.of(9999, 12, 31)), - getImmunizationFacade().suggestValidUntil(Disease.MEASLES, MeansOfImmunization.VACCINATION, defaultValidFrom, 2)); + assertEquals( + UtilDate.from(ImmunizationValidityCalculator.LIFELONG_VALID_UNTIL), + getImmunizationFacade().suggestValidUntil(Disease.MEASLES, MeansOfImmunization.VACCINATION, defaultValidFrom, 2)); @@ - assertEquals(UtilDate.from(LocalDate.of(9999, 12, 31)), saved.getValidUntil()); + assertEquals(UtilDate.from(ImmunizationValidityCalculator.LIFELONG_VALID_UNTIL), saved.getValidUntil());Also applies to: 132-133, 155-155
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjbTest.java` around lines 124 - 125, Replace hardcoded sentinel dates in the test with the shared constant: wherever the test calls getImmunizationFacade().suggestValidUntil(...) and asserts against UtilDate.from(LocalDate.of(9999, 12, 31)), use ImmunizationValidityCalculator.LIFELONG_VALID_UNTIL instead of the literal date (e.g., in ImmunizationFacadeEjbTest near the suggestValidUntil assertions at lines shown); update all occurrences (the ones at the three asserted locations) so the test compares to the constant to avoid drift if the contract changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@sormas-api/src/main/java/de/symeda/sormas/api/immunization/VaccinationStatusData.java`:
- Around line 426-436: The buildBlank() method currently returns the builder’s
current field values (same as build()) but should return a truly blank
VaccinationStatusData; modify VaccinationStatusData.Builder.buildBlank() so it
constructs and returns a new VaccinationStatusData with all fields set to their
blank/default values (e.g., null for object/reference fields like
vaccinationStatus, informationReliability, vaccinationStatusDetails,
dateOfLastDose, referencePeriodFrom, referencePeriodTo,
vaccinationStatusLastUpdated and a sensible default for numberOfDoses if it’s a
primitive wrapper—null or 0 as appropriate, or empty collections if any field is
a collection) instead of reusing the builder’s current state.
- Around line 143-161: VaccinationStatusData currently stores and exposes
java.util.Date fields by reference; update the constructor in
VaccinationStatusData, all Date-returning getters, and Builder.createFrom(...)
to defensively copy Date instances (use new Date(date.getTime()) or null-safe
equivalents) so callers cannot mutate internal state; also resolve the
Builder.buildBlank() vs Builder.build() duplication by either renaming
buildBlank to reflect identical behavior or implement true “blank” semantics
(i.e., do not populate existing fields) so the javadoc matches behavior;
finally, either add explicit null checks/handling in
isComparableVaccinationStatusDataEqual(...) or document its non-null
precondition to avoid NPEs when caseData or immunizationData may be null.
In
`@sormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationFacade.java`:
- Around line 108-112: The API method VaccinationFacade.createDoseEntries
currently allows zero or negative numberOfDoses; add an explicit precondition
check at the start of the implementation (and document it in the interface
javadoc) to require numberOfDoses > 0 and throw a suitable runtime exception
(e.g., IllegalArgumentException) when violated; ensure callers are updated or
validated accordingly and reference the method signature
createDoseEntries(ImmunizationReferenceDto, int numberOfDoses,
VaccinationInfoSource, Date) so the check is applied consistently where this
contract is implemented.
In `@sormas-api/src/main/resources/enum.properties`:
- Around line 2273-2274: The two enum keys VaccinationStatus.HAD_THE_DISEASE and
VaccinationStatus.RECOVERED currently map to the identical display text "Had the
disease"; update the mapping for VaccinationStatus.RECOVERED to a distinct,
correct label (e.g., "Recovered" or "Recovered from disease") so the UI can
distinguish them, or if they are truly equivalent remove one enum key and update
usages accordingly; locate the entries for VaccinationStatus.HAD_THE_DISEASE and
VaccinationStatus.RECOVERED in enum.properties and change the right-hand-side
string for RECOVERED (or remove the redundant key and refactor callers).
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java`:
- Around line 2380-2383: The updateVaccinationStatuses(ContactReferenceDto
contactRef) path updates and persists a Contact but doesn’t invoke the normal
contact-change hook, so call the existing onContactChanged(...) hook after
persisting to trigger share-propagation. Concretely, in
ContactFacadeEjb.updateVaccinationStatuses call
vaccinationFacade.updateVaccinationStatuses(contact), then
service.ensurePersisted(contact) (as now) and finally invoke
onContactChanged(contact) (or the class’ existing contact-change dispatcher) so
the standard propagation logic runs for vaccination-only syncs.
- Around line 1648-1655: The current else branch copies vaccination metadata
from the incoming DTO (source) which allows clients to overwrite server-owned
derived fields; instead, when vaccinationStatusManuallyUpdated is false do not
copy source.getVaccinationStatusLastUpdated(), source.getNumberOfDoses(), or
source.getInformationReliability() into the target — preserve the target's
existing values or recompute them server-side. Modify the logic in
ContactFacadeEjb (around vaccinationStatusManuallyUpdated and the
target.setVaccinationStatusLastUpdated / setNumberOfDoses /
setInformationReliability calls) to stop trusting source for these fields:
either remove those target.set... calls in the non-manual branch so the entity
values remain, or replace them with a call to a server-side recompute method
(e.g., computeVaccinationMetadata or similar) that sets these fields from
authoritative data.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java`:
- Around line 447-450: The updateVaccinationStatuses method currently persists
the EventParticipant via service.ensurePersisted(eventParticipant) but does not
notify the event propagation mechanism; after calling
vaccinationFacade.updateVaccinationStatuses(eventParticipant) and persisting,
invoke the event propagation handler (eventFacade.onEventChange(...)) with the
relevant event/participant so the existing share/update flow runs; locate
updateVaccinationStatuses, vaccinationFacade.updateVaccinationStatuses,
service.ensurePersisted and call eventFacade.onEventChange with the event (or
eventParticipant) after persistence to trigger propagation.
- Around line 1169-1176: The code in EventParticipantFacadeEjb copies derived
vaccination metadata from the DTO into the entity when
vaccinationStatusManuallyUpdated is false (calls to
target.setVaccinationStatusLastUpdated, setNumberOfDoses,
setInformationReliability) which allows stale/arbitrary values to be persisted;
remove that copy and do not overwrite the entity from the DTO in that
branch—either leave the existing target values unchanged or compute and set
these derived values server-side from immunization records instead; keep the
current behavior that only the manually-updated branch
(vaccinationStatusManuallyUpdated true) clears/overrides fields, and stop
assigning DTO-provided
vaccinationStatusLastUpdated/numberOfDoses/informationReliability back into the
entity.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java`:
- Around line 629-656: The method updateVaccinationInfoSourceFromVaccinations in
ImmunizationFacadeEjb currently bails out if
immunization.getVaccinationInfoSource() != null, leaving the parent value stale
when child Vaccination entries change; remove that early-return check so the
method always recomputes the aggregate from immunization.getVaccinations(), or
if you need support for manual overrides implement a separate override flag
(e.g., isVaccinationInfoSourceOverridden) and check that flag instead of the
vaccinationInfoSource value before returning. Ensure the rest of the logic
(collecting vaccinationInfoSources, detecting all unknown/null, deriving a
single common source or null) remains unchanged and is executed every time
unless the explicit override flag is set.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/LuxembourgImmunizationValidityCalculator.java`:
- Around line 88-99: The current calculateValidFrom/calculateValidUntil logic in
LuxembourgImmunizationValidityCalculator leaves recovery records with null
validFrom and any profile with vaccinationDurationDays == null with null
validUntil, causing ImmunizationService.deriveVaccinationStatus(...) to ignore
those windows; update calculateValidFrom to set a validFrom for recovery-based
MeansOfImmunization (use the immunizationDate or a configured
recoveryStartOffset if available) and update calculateValidUntil to return a
concrete end date when profile.vaccinationDurationDays is null (e.g., a
far-future expiry or a profile-specific fallback) so profiles like CORONAVIRUS,
MALARIA, POLIO, RABIES, and TUBERCULOSIS can produce selectable windows;
reference calculateValidFrom, calculateValidUntil, DISEASE_IMMUNITY_PROFILES,
MeansOfImmunization.isVaccination/isRecovery, and
ImmunizationService.deriveVaccinationStatus when making the changes.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.java`:
- Around line 143-145: The code calls
immunizationFacade.updateVaccinationInfoSourceFromVaccinations(immunization)
before the freshly built Vaccination is attached, so the aggregate source misses
the new dose; ensure the new Vaccination is added to its parent Immunization's
vaccination collection (e.g., immunization.getVaccinations().add(vaccination) or
equivalent) before calling updateVaccinationInfoSourceFromVaccinations and
before persisting; apply the same change for the other occurrence around lines
201-202 so the recalculation sees the new dose.
- Around line 505-512: When deriving vaccination status in VaccinationFacadeEjb,
don't fall back to reportDateTime when firstContactDate is null if
lastContactDate is available; change the logic setting fromDate so it prefers
contact.getLastContactDate() before contact.getReportDateTime() (e.g., fromDate
= firstContactDate != null ? firstContactDate : (lastContactDate != null ?
lastContactDate : reportDateTime)), keep untilDate as lastContactDate != null ?
lastContactDate : fromDate, and then call
immunizationService.deriveVaccinationStatus with the corrected
fromDate/untilDate.
In `@sormas-backend/src/main/resources/sql/sormas_schema.sql`:
- Around line 16058-16059: The migration adds vaccinationstatusdetails columns
without IF NOT EXISTS which breaks idempotency; update the ALTER TABLE
statements for "ALTER TABLE contact ADD COLUMN vaccinationstatusdetails
character varying(255);" and "ALTER TABLE contact_history ADD COLUMN
vaccinationstatusdetails character varying(255);" (and the duplicate occurrences
noted later) to include IF NOT EXISTS so the statements become idempotent and
won’t fail if the columns already exist.
In
`@sormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjbTest.java`:
- Around line 119-127: The test mutates the global MockProducer property
ConfigFacadeEjb.COUNTRY_LOCALE in ImmunizationFacadeEjbTest and doesn't restore
it, causing test-order flakiness; update the test(s) that call
MockProducer.getProperties().setProperty(ConfigFacadeEjb.COUNTRY_LOCALE, ...) to
save the original value before changing and restore it after (either in a
finally block inside the test or centrally in an `@After` method), referencing the
same ConfigFacadeEjb.COUNTRY_LOCALE key and CountryHelper constants
(COUNTRY_CODE_LUXEMBOURG, COUNTRY_CODE_GERMANY) so subsequent tests see the
original locale.
---
Outside diff comments:
In `@sormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationStatus.java`:
- Around line 25-37: The VaccinationStatus enum removed legacy constants causing
runtime/schema mismatch; restore legacy enum entries VACCINATED_ONE_DOSE and
VACCINATED_TWO_DOSE as deprecated aliases and normalize them to VACCINATED on
deserialization/serialization: add the two constants back into the
VaccinationStatus enum (mark with `@Deprecated` and a comment), implement a static
factory/mapper in VaccinationStatus (e.g., a fromString/@JsonCreator method)
that maps those legacy names to the VACCINATED value (and vice versa for
serialization if needed), and regenerate the OpenAPI/Swagger so the schema
matches the runtime accepted values; refer to the VaccinationStatus enum name
and the fromString/@JsonCreator mapping function when making changes.
---
Minor comments:
In `@sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java`:
- Around line 401-402: The DTO field numberOfDoses in CaseDataDto currently
allows negative values; prevent this by adding a non-negative validation and
guarding the setter: annotate the numberOfDoses field with a bean-validation
constraint such as `@Min`(0) (import from javax.validation.constraints.Min or
jakarta.validation.constraints.Min) and update setNumberOfDoses(Integer
numberOfDoses) to either coerce nulls or throw/ignore negative inputs (e.g., if
(numberOfDoses != null && numberOfDoses < 0) throw new
IllegalArgumentException(...) or set to 0), ensuring both the field and the
setNumberOfDoses method enforce non-negative counts.
In `@sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java`:
- Around line 390-391: Add validation to ensure ContactDto.numberOfDoses cannot
be negative: annotate the field ContactDto.numberOfDoses with a Bean Validation
constraint such as `@Min`(0) (import javax.validation.constraints.Min) or add a
defensive check in the setter/getter to throw/ignore negative values; update any
unit tests if needed to assert non-negative behavior. Ensure the annotation is
applied to the Integer numberOfDoses field in class ContactDto and imports are
added accordingly.
In
`@sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantDto.java`:
- Around line 102-103: The numberOfDoses field in EventParticipantDto currently
allows negative values; annotate the field (numberOfDoses) with a non-negative
constraint such as `@Min`(0) (from javax.validation.constraints) while keeping the
existing `@Outbreaks` annotation, and add the required import; alternatively
enforce the same check in the setter/getValidation logic of EventParticipantDto
to reject values < 0 (use `@Min`(0) on the Integer numberOfDoses field for the
simplest fix).
In
`@sormas-api/src/main/java/de/symeda/sormas/api/immunization/VaccinationStatusData.java`:
- Around line 116-121: isComparableVaccinationStatusDataEqual currently throws
when either parameter is null; add a null guard at the start of the method in
VaccinationStatusData.isComparableVaccinationStatusDataEqual: if both references
are identical (caseData == immunizationData) return true; if one is null and the
other is not (caseData == null || immunizationData == null) return false; then
proceed with the existing field-wise Objects.equals checks.
In `@sormas-api/src/main/resources/captions.properties`:
- Line 2455: The property immunizationQuickNewImmunization has a leading space
in its value (" Quick new immunization"); remove the extra space so the value
reads "Quick new immunization" to match other entries and avoid unintended UI
spacing.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java`:
- Around line 641-652: The change detector currently checks vaccination status,
number of doses, and information reliability but omits vaccinationStatusDetails,
so updates to the free-text details are ignored; add a comparison using
java.util.Objects.equals(data.getVaccinationStatusDetails(),
eventParticipant.getVaccinationStatusDetails()) (e.g. boolean detailsChanged)
and include it in the if-condition alongside statusChanged, dosesChanged, and
reliabilityChanged so that setVaccinationStatusDetails(...) runs when details
differ.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java`:
- Around line 781-787: The blank-result branch in ImmunizationService currently
sets both referencePeriodFrom and referencePeriodTo to untilDate, losing a
non-null fromDate; change the VaccinationStatusData.Builder invocation so
referencePeriodFrom is fromDate if non-null (otherwise untilDate) and
referencePeriodTo is untilDate if non-null (otherwise fromDate), i.e.
referencePeriodFrom(fromDate != null ? fromDate : untilDate) and
referencePeriodTo(untilDate != null ? untilDate : fromDate) to preserve the
requested window.
In
`@sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/QuickImmunizationCreationForm.java`:
- Around line 339-349: parseNumberOfDoses currently returns parsed integers even
if out of allowed range which lets suggestion APIs run with invalid doses;
update parseNumberOfDoses to parse the value from numberOfDoses, return null for
blank/parse errors, then clamp the parsed integer to the allowed min/max bounds
used in validation (e.g., use the same constants or validation helpers as the
commit path) before returning so suggestion calls always receive a valid
in-range dose count.
---
Nitpick comments:
In `@sormas-api/src/main/resources/captions.properties`:
- Around line 2446-2447: The two property keys ImmunizationSidePanel_quickEntry
and ImmunizationSidePanel_viewAll use underscores and should be renamed to the
dot-form used elsewhere (e.g., ImmunizationSidePanel.quickEntry and
ImmunizationSidePanel.viewAll) to match the existing pattern such as
ImmunizationSidePanel.title; update any code or templates that reference the old
underscore keys to use the new dot keys so all lookups remain correct.
In `@sormas-backend/src/main/resources/sql/sormas_schema.sql`:
- Around line 16085-16103: The DO block must guard against missing category and
duplicate config keys: fetch the GENERAL_CATEGORY id into general_category_id
and if it is NULL or NOT FOUND, abort the block with a NOTICE/RAISE and do not
perform the INSERT; also check for an existing row in systemconfigurationvalue
with config_key = 'USE_QUICK_IMMUNIZATION_CREATION' (or use INSERT ... ON
CONFLICT DO NOTHING if a unique constraint exists) and skip the INSERT if a
duplicate exists; update the block around systemconfigurationcategory,
general_category_id, and the INSERT into systemconfigurationvalue (which uses
nextval('entity_seq') and generate_base32_uuid()) to implement these guards.
In
`@sormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjbTest.java`:
- Around line 124-125: Replace hardcoded sentinel dates in the test with the
shared constant: wherever the test calls
getImmunizationFacade().suggestValidUntil(...) and asserts against
UtilDate.from(LocalDate.of(9999, 12, 31)), use
ImmunizationValidityCalculator.LIFELONG_VALID_UNTIL instead of the literal date
(e.g., in ImmunizationFacadeEjbTest near the suggestValidUntil assertions at
lines shown); update all occurrences (the ones at the three asserted locations)
so the test compares to the constant to avoid drift if the contract changes.
In
`@sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationController.java`:
- Around line 90-147: The two flows createQuick(...) and
buildQuickCreateComponent(...) duplicate initialization, pre-fill, commit
handling and similar-immunization popup logic; extract the shared code into a
single helper that (a) creates and prepares a QuickImmunizationCreationForm with
pre-filled ImmunizationDto (use UiUtil.getCurrentUserProvider(),
ImmunizationDto.build, setDisease, setReportingUser,
setResponsibleRegion/setResponsibleDistrict using
FacadeProvider.getRegionFacade()/getDistrictFacade().getDefaultInfrastructureReference()),
(b) wraps it in CommitDiscardWrapperComponent and attaches one commit listener
that calls FacadeProvider.getImmunizationFacade().saveQuickImmunization(...)
then calls findSimilarImmunizations(...) and showSimilarImmunizationPopup(...)
and finally invokes the provided savedCallback; then have both createQuick(...)
and buildQuickCreateComponent(...) call that helper (or have
buildQuickCreateComponent return the single reusable component) so the
initialization/save/similar-popup logic exists only once.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f165431a-043d-49e9-b3e7-0ccedbbe381c
📒 Files selected for processing (56)
sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.javasormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.javasormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationInfoSource.javasormas-api/src/main/java/de/symeda/sormas/api/caze/VaccinationStatus.javasormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.javasormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.javasormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantDto.javasormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.javasormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.javasormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationDto.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationFacade.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationValidityCalculator.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/InformationReliability.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/MeansOfImmunization.javasormas-api/src/main/java/de/symeda/sormas/api/immunization/VaccinationStatusData.javasormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationFacade.javasormas-api/src/main/resources/captions.propertiessormas-api/src/main/resources/enum.propertiessormas-api/src/main/resources/strings.propertiessormas-backend/src/main/java/de/symeda/sormas/backend/caze/Case.javasormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.javasormas-backend/src/main/java/de/symeda/sormas/backend/contact/Contact.javasormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.javasormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipant.javasormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DefaultImmunizationValidityCalculator.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/LuxembourgImmunizationValidityCalculator.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/entity/BaseImmunization.javasormas-backend/src/main/java/de/symeda/sormas/backend/immunization/entity/Immunization.javasormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.javasormas-backend/src/main/resources/sql/sormas_schema.sqlsormas-backend/src/test/java/de/symeda/sormas/backend/immunization/DefaultImmunizationValidityCalculatorTest.javasormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjbTest.javasormas-backend/src/test/java/de/symeda/sormas/backend/immunization/ImmunizationServiceDeriveStatusTest.javasormas-backend/src/test/java/de/symeda/sormas/backend/immunization/LuxembourgImmunizationValidityCalculatorTest.javasormas-backend/src/test/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjbDeterminedStatusTest.javasormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.javasormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.javasormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.javasormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.javasormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.javasormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantDataView.javasormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.javasormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationController.javasormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/ImmunizationDataForm.javasormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/QuickImmunizationCreationForm.javasormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/panel/VaccinationStatusPanel.javasormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationListComponent.javasormas-ui/src/main/java/de/symeda/sormas/ui/utils/FormComponent.java
…event participants, supporting bulk operations and UI integration for development and testing. Fix issues with tests and logic.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java`:
- Line 99: The deleteVaccinationStatuses() definition currently exposes an
undocumented, unscoped bulk delete; change it to accept a scope parameter (e.g.,
CaseReferenceDto caseRef or a criteria DTO) so the operation targets a specific
case or set of cases (match the pattern used by
updateVaccinationStatuses(CaseReferenceDto caseRef)), and add Javadoc on the
CaseFacade.deleteVaccinationStatuses(...) signature explaining the intended
scope, side effects and access constraints; ensure the service and
implementation methods that implement deleteVaccinationStatuses are updated to
use the new parameter and that any callers are adjusted accordingly.
In
`@sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java`:
- Around line 1743-1746: The deleteVaccinationStatuses method uses a broad
permission and performs a system-wide clear without audit or confirmation;
change the `@RightsAllowed` from UserRight._CASE_EDIT to a more restrictive right
(e.g., UserRight._SYSTEM or a new UserRight like _VACCINATION_STATUS_MANAGE),
add an audit entry when deleteVaccinationStatuses is invoked (use the project’s
audit/logging facility to record actor, timestamp, and number of affected
records) and implement a safety/preview step in the service call path (update
service.clearVaccinationStatuses to return a count or preview list so the facade
can log/confirm before performing the destructive delete).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3243e1c3-1996-47b7-bd1d-b5ee2d84ca69
📒 Files selected for processing (7)
sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.javasormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.javasormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.javasormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.javasormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.javasormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java
🚧 Files skipped from review as they are similar to previous changes (5)
- sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.java
- sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java
- sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java
- sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java
- sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java
|
Actionable comments posted: 0 |
|
Actionable comments posted: 0 |
…ationReferenceDto - Added dialogs to the reset buttons where user can input the UUID of Immunization entry.
Refactors vaccination status handling to use a unified, derived model (VaccinationStatusData) based on immunization records, removing legacy dose-specific statuses and introducing explicit fields for number of doses and information reliability.
Adds quick immunization entry, new API for status calculation, and Luxembourg-specific validity logic. Updates the UI with a dedicated vaccination status panel, prompts for status synchronization, and improves notification of unprocessed external message content.
Aims to support national requirements, provide clearer vaccination tracking, and improve data consistency.
Relates to #13377
Fixes #
Summary by CodeRabbit