diff --git a/src/main/java/com/iemr/flw/config/PrimaryDBConfig.java b/src/main/java/com/iemr/flw/config/PrimaryDBConfig.java index 7561e72a..bdb76101 100644 --- a/src/main/java/com/iemr/flw/config/PrimaryDBConfig.java +++ b/src/main/java/com/iemr/flw/config/PrimaryDBConfig.java @@ -57,10 +57,10 @@ public class PrimaryDBConfig { @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { PoolConfiguration p = new PoolProperties(); - p.setMaxActive(30); - p.setMaxIdle(15); - p.setMinIdle(5); - p.setInitialSize(5); + p.setMaxActive(100); + p.setMaxIdle(50); + p.setMinIdle(10); + p.setInitialSize(10); p.setMaxWait(10000); p.setMinEvictableIdleTimeMillis(15000); p.setRemoveAbandoned(true); diff --git a/src/main/java/com/iemr/flw/config/SecondaryDBConfig.java b/src/main/java/com/iemr/flw/config/SecondaryDBConfig.java index d4ca4a4b..f3fc7829 100644 --- a/src/main/java/com/iemr/flw/config/SecondaryDBConfig.java +++ b/src/main/java/com/iemr/flw/config/SecondaryDBConfig.java @@ -55,10 +55,10 @@ public class SecondaryDBConfig { @ConfigurationProperties(prefix = "secondary.datasource") public DataSource dataSource() { PoolConfiguration p = new PoolProperties(); - p.setMaxActive(30); - p.setMaxIdle(15); - p.setMinIdle(5); - p.setInitialSize(5); + p.setMaxActive(100); + p.setMaxIdle(50); + p.setMinIdle(10); + p.setInitialSize(10); p.setMaxWait(10000); p.setMinEvictableIdleTimeMillis(15000); p.setRemoveAbandoned(true); diff --git a/src/main/java/com/iemr/flw/dto/iemr/QuestionAnswerRequest.java b/src/main/java/com/iemr/flw/dto/iemr/QuestionAnswerRequest.java index 8ee08c45..ad314ba5 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/QuestionAnswerRequest.java +++ b/src/main/java/com/iemr/flw/dto/iemr/QuestionAnswerRequest.java @@ -33,6 +33,7 @@ * A single question's answer within a section answer request. * Exactly one of optionValue, optionValues, answerText, or answerDate should be set per question type: * RADIO → optionValue (single string) + * CHECKBOX → optionValue (single string, e.g. "CHECKED") * MCQ → optionValues (list of strings, one row saved per element) * TEXT/AUTO_FILL → answerText * DATE → answerDate (ISO date string) or answerText diff --git a/src/main/java/com/iemr/flw/dto/iemr/QuestionResponseDTO.java b/src/main/java/com/iemr/flw/dto/iemr/QuestionResponseDTO.java index f5f76d63..98557c10 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/QuestionResponseDTO.java +++ b/src/main/java/com/iemr/flw/dto/iemr/QuestionResponseDTO.java @@ -40,7 +40,7 @@ public class QuestionResponseDTO { private Long questionResponseId; private Long questionId; - /** Populated for RADIO and MCQ answers. */ + /** Populated for RADIO, MCQ, and CHECKBOX answers. */ private Long optionId; /** Populated for TEXT, DATE, AUTO_FILL answers. */ private String answerText; diff --git a/src/main/java/com/iemr/flw/masterEnum/QuestionType.java b/src/main/java/com/iemr/flw/masterEnum/QuestionType.java index 0af07aa1..82308544 100644 --- a/src/main/java/com/iemr/flw/masterEnum/QuestionType.java +++ b/src/main/java/com/iemr/flw/masterEnum/QuestionType.java @@ -32,8 +32,8 @@ public enum QuestionType { RADIO, /** Multi-select from a predefined list of options. */ MCQ, - /** Single boolean checkbox — checked or unchecked. May carry options for display - * purposes; answers are still stored as free text. */ + /** Single boolean checkbox — checked or unchecked. Resolved like RADIO: submit + * optionValue to select it, omit to leave unanswered. */ CHECKBOX, /** Free-text input. */ TEXT, diff --git a/src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java index 829f9486..597abf5a 100644 --- a/src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java @@ -358,6 +358,25 @@ private String getMappingsForAddressIDs(List addressLi if (benDetailsRMNCH_OBJ.getGpsLongitude() != null) benDetailsRMNCH_OBJ.setLongitude(BigDecimal.valueOf(benDetailsRMNCH_OBJ.getGpsLongitude())); + // GPS fallback: if not in RMNCH details (syncdatatoamrti not yet called), + // pull from i_beneficiaryaddress (saved during TM-API registration) + if (benDetailsRMNCH_OBJ.getGpsLatitude() == null && benAddressOBJ.getGpsLatitude() != null) + benDetailsRMNCH_OBJ.setGpsLatitude(benAddressOBJ.getGpsLatitude()); + if (benDetailsRMNCH_OBJ.getGpsLongitude() == null && benAddressOBJ.getGpsLongitude() != null) + benDetailsRMNCH_OBJ.setGpsLongitude(benAddressOBJ.getGpsLongitude()); + if (benDetailsRMNCH_OBJ.getDigipin() == null && benAddressOBJ.getDigipin() != null) + benDetailsRMNCH_OBJ.setDigipin(benAddressOBJ.getDigipin()); + if (benDetailsRMNCH_OBJ.getGpsTimestamp() == null && benAddressOBJ.getGpsTimestamp() != null) + benDetailsRMNCH_OBJ.setGpsTimestamp(benAddressOBJ.getGpsTimestamp()); + if (benDetailsRMNCH_OBJ.getIsGpsUnavailable() == null && benAddressOBJ.getIsGpsUnavailable() != null) + benDetailsRMNCH_OBJ.setIsGpsUnavailable(benAddressOBJ.getIsGpsUnavailable()); + + // Map GPS double fields to the exposed latitude/longitude BigDecimal fields for response + if (benDetailsRMNCH_OBJ.getGpsLatitude() != null) + benDetailsRMNCH_OBJ.setLatitude(BigDecimal.valueOf(benDetailsRMNCH_OBJ.getGpsLatitude())); + if (benDetailsRMNCH_OBJ.getGpsLongitude() != null) + benDetailsRMNCH_OBJ.setLongitude(BigDecimal.valueOf(benDetailsRMNCH_OBJ.getGpsLongitude())); + // ----------------------------------------------------------------------------- // related benids diff --git a/src/main/java/com/iemr/flw/service/impl/DynamicFormResponseServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/DynamicFormResponseServiceImpl.java index 64f405b9..a36710a5 100644 --- a/src/main/java/com/iemr/flw/service/impl/DynamicFormResponseServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DynamicFormResponseServiceImpl.java @@ -37,6 +37,7 @@ import com.iemr.flw.dto.iemr.SectionResponseDTO; import com.iemr.flw.domain.iemr.DynamicForm; import com.iemr.flw.masterEnum.FormResponseStatus; +import com.iemr.flw.masterEnum.FormResponseStatus; import com.iemr.flw.masterEnum.FormType; import com.iemr.flw.repo.iemr.DynamicFormRepo; import com.iemr.flw.repo.iemr.FormResponseRepo; @@ -388,7 +389,7 @@ private List processAnswers( // Delete any existing answers for this question in this section (handles re-saves) questionResponseRepo.deleteByQuestionIdAndSectionResponseId(questionId, sectionResponseId); - if (type == QuestionType.RADIO) { + if (type == QuestionType.RADIO || type == QuestionType.CHECKBOX) { if (answer.getOptionValue() != null) { QuestionOption opt = resolveOption( optionsByQuestion, questionId, answer.getOptionValue(), answer.getQuestionUuid()); diff --git a/src/main/java/com/iemr/flw/service/impl/FormResponseItemSaver.java b/src/main/java/com/iemr/flw/service/impl/FormResponseItemSaver.java index 4767f505..4ff8ca07 100644 --- a/src/main/java/com/iemr/flw/service/impl/FormResponseItemSaver.java +++ b/src/main/java/com/iemr/flw/service/impl/FormResponseItemSaver.java @@ -328,7 +328,7 @@ private List processAnswers( questionResponseRepo.deleteByQuestionIdAndSectionResponseId(questionId, sectionResponseId); - if (type == QuestionType.RADIO) { + if (type == QuestionType.RADIO || type == QuestionType.CHECKBOX) { if (answer.getOptionValue() != null) { QuestionOption opt = resolveOption(optionsByQuestion, questionId, answer.getOptionValue(), answer.getQuestionUuid()); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 84cca481..1d5221e9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,9 @@ +# Response compression — shrinks large JSON responses (e.g. getAll-style endpoints) over the +# wire without changing the API contract; honors the Accept-Encoding: gzip clients already send. +server.compression.enabled=true +server.compression.mime-types=application/json,application/xml,text/html,text/plain,text/css,application/javascript +server.compression.min-response-size=1024 + spring.main.banner-mode=off spring.data.jpa.repositories.enabled=true spring.jpa.hibernate.ddl-auto=create