Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5a28f4b
Update application.properties
SauravBizbRolly Nov 26, 2025
ea12e3e
add column in create BeneficiaryModel
SauravBizbRolly Nov 26, 2025
50c5952
Elasticsearch implementation for Beneficiary Search (#324)
vanitha1822 Dec 18, 2025
1bc9298
variable added
sac2kadam Dec 31, 2025
4b975ff
Merge pull request #330 from PSMRI/add_ci_docker_properties
drtechie Dec 31, 2025
c501e80
update language
SauravBizbRolly Jan 7, 2026
ec3aac3
update language
SauravBizbRolly Jan 7, 2026
bafc879
Downgrade version from 3.6.1 to 3.6.0
SauravBizbRolly Jan 7, 2026
65efdc7
Elastic Search Implementation for Advanced Search (#327)
vanitha1822 Jan 8, 2026
38a4147
Remove empty line in application.properties
SauravBizbRolly Jan 8, 2026
17620d3
fix:signature check for mmu
vishwab1 Jan 9, 2026
68b246e
Merge pull request #335 from PSMRI/release-3.6.1-sign
snehar-nd Jan 9, 2026
9c1493a
Update application.properties
SauravBizbRolly Jan 9, 2026
984d533
Update application.properties
SauravBizbRolly Jan 9, 2026
c3bc3cb
fix: retrive any user without deleted
vishwab1 Jan 13, 2026
8dcdfc3
Merge pull request #336 from PSMRI/release-3.6.1-sign
snehar-nd Jan 13, 2026
5190737
implement state wise hide un hide form fields
SauravBizbRolly Jan 14, 2026
b5f0670
Merge pull request #337 from PSMRI/feature/hide_feilds_state_wise
SauravBizbRolly Jan 14, 2026
4d20b8c
implement state wise hide un hide form fields
SauravBizbRolly Jan 14, 2026
bed849b
implement state wise hide un hide form fields
SauravBizbRolly Jan 16, 2026
dd2c323
enhance welcome sms code
SauravBizbRolly Jan 18, 2026
6d224eb
Merge pull request #338 from PSMRI/feature/manage_upload_file
SauravBizbRolly Jan 18, 2026
4104ad0
fix hide unhide form issue
SauravBizbRolly Jan 18, 2026
c162bcc
Merge pull request #340 from PSMRI/fix_form_feilds_issue
SauravBizbRolly Jan 18, 2026
fdbc9b7
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
0c64cef
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
b3a1922
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
c4c1d48
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
f10f37c
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
b3da893
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
f94d0b0
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
be7889e
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
0022329
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
ba824be
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
c0c5333
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
2e18fdd
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
acd9d8e
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
475a4ac
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
f952708
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
64b2a7e
fix hide unhide form issue
SauravBizbRolly Jan 21, 2026
97f7d5f
Merge branch 'release-3.6.1' into feature/form_validation
SauravBizbRolly Jan 21, 2026
cb1b06e
Merge pull request #343 from PSMRI/feature/form_validation
SauravBizbRolly Jan 21, 2026
f487978
Move code to 3.6.1 to 3.8.0 (#372)
vishwab1 Mar 12, 2026
1cc3888
fix: add OTP rate limiting to prevent OTP flooding on sendConsent end…
vishwab1 Mar 12, 2026
eec7cfe
docs: add CLAUDE.md for Claude Code guidance
snehar-nd Mar 30, 2026
6902ae8
Fix issue for translation in hint
SauravBizbRolly Apr 2, 2026
a5918e3
fix dropdown translation
SauravBizbRolly Apr 6, 2026
b166ceb
fix dropdown translation
SauravBizbRolly Apr 6, 2026
9a472d3
fix dropdown translation
SauravBizbRolly Apr 7, 2026
72f0c28
Fix the OpenKM Issue (#389)
vanitha1822 Apr 7, 2026
ec30247
Merge branch 'release-3.6.2' into bug/drop_down_translation
SauravBizbRolly Apr 7, 2026
39f069d
fix dropdown translation
SauravBizbRolly Apr 7, 2026
05113c5
Merge branch 'release-3.8.1' into bug/drop_down_translation
SauravBizbRolly Apr 7, 2026
fc21d64
fix dropdown translation
SauravBizbRolly Apr 7, 2026
eb4d9b1
fix dropdown translation
SauravBizbRolly Apr 7, 2026
79b050d
Fix ConfigProperties to resolve env variable placeholders via Spring …
vishwab1 Apr 7, 2026
bded02e
fix: async notation (#392)
vanitha1822 Apr 8, 2026
5a2be7f
Merge remote-tracking branch 'upstream/release-3.6.2' into bug/drop_d…
SauravBizbRolly Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# CLAUDE.md - Common-API

## Project Overview

Common-API is the gateway microservice for the AMRIT healthcare platform. It provides shared APIs consumed by all frontend UIs including authentication, beneficiary registration, call handling, location masters, notifications, feedback, reporting, and integrations with external systems (c-Zentrix CTI, Everwell, eAusadha, eSanjeevani, ABDM, Firebase, Honeywell POCT devices).

## Tech Stack

- Java 17
- Spring Boot 3.2.2
- Spring Data JPA / Hibernate
- MySQL 8.0
- Redis (session management, caching)
- MongoDB (optional, for specific integrations)
- Maven (build tool)
- Swagger/OpenAPI (API documentation)
- Lombok, MapStruct
- CryptoJS-compatible AES encryption
- Firebase Admin SDK
- WAR packaging (deploys to Wildfly)

## Build and Run

```bash
# Build
mvn clean install -DENV_VAR=local

# Run locally (start Redis first)
mvn spring-boot:run -DENV_VAR=local

# Package WAR
mvn -B package --file pom.xml -P <profile> # profiles: dev, local, test, ci, uat

# Run tests
mvn test
```

### Configuration

- Copy `src/main/environment/common_example.properties` to `common_local.properties` and edit.
- Environment selected via `-DENV_VAR=<env>`.
- Swagger UI: `http://localhost:8083/swagger-ui.html`

## Package Structure

Base package: `com.iemr.common`

| Layer | Package | Description |
|-------|---------|-------------|
| Controllers | `controller.*` | REST endpoints (40+ sub-packages) |
| Services | `service.*` | Business logic |
| Repositories | `repository.*`, `repo.*` | JPA repositories |
| Entities | `data.*` | JPA entity classes |
| DTOs | `model.*` | Transfer objects |
| Mappers | `mapper.*` | Object mapping |
| Config | `config.*` | Swagger, encryption, Firebase, Quartz, prototypes |
| Constants | `constant` | Application constants |
| Utils | `utils.*` | Redis, HTTP, session, validation, exception |

## Key Functional Domains

- **Authentication/Authorization**: `controller.users` - login, session, user management
- **Beneficiary Registration**: `controller.beneficiary` - create, search, update beneficiaries
- **Call Handling**: `controller.callhandling` - CTI integration, call lifecycle
- **Feedback/Grievance**: `controller.feedback`, `controller.grievance` - feedback and complaint management
- **Location**: `controller.location` - state, district, block, village masters
- **Notifications**: `controller.notification` - alerts, SMS, email, Firebase push
- **Reporting**: `controller.report`, `controller.secondaryReport` - CRM reports
- **Helpline 104**: `controller.helpline104history` - medical advice history
- **COVID**: `controller.covid` - vaccination status
- **CTI Integration**: `controller.cti` - c-Zentrix computer telephony
- **External Integrations**: `controller.eausadha`, `controller.esanjeevani`, `controller.everwell`, `controller.honeywell`, `controller.brd`, `controller.carestream`
- **ABDM**: `controller.abdmfacility` - Ayushman Bharat Digital Mission
- **KM File Management**: `controller.kmfilemanager` - OpenKM document management
- **OTP/SMS**: `controller.otp`, `controller.sms` (via SMS gateway)
- **Scheduling**: `controller.questionconfig`, `controller.scheme`
- **Door-to-Door App**: `controller.door_to_door_app` - field worker support
- **NHM Dashboard**: `controller.nhmdashboard` - National Health Mission integration

## Architecture Notes

- Entry point: `CommonMain.java` (main class in `utils` package)
- Acts as the API gateway; all frontend UIs authenticate through Common-API
- Session management via Redis with 27-minute timeout
- HTTP interceptors attach `Authorization` and `ServerAuthorization` headers
- Status code `5002` signals session expiration to frontends
- AES + PBKDF2 encryption for password handling (`config.encryption`)
- Firebase integration for push notifications (`config.firebase`)
- Quartz scheduler for background jobs (`config.quartz`)
- Extensive test coverage with unit tests under `src/test/`

## CI/CD

- GitHub Actions: `package.yml`, `build-on-pull-request.yml`, `sast.yml`, `commit-lint.yml`, `codeql.yml`
- Conventional Commits enforced via Husky + commitlint
- Checkstyle configuration in `checkstyle.xml`
- JaCoCo for code coverage, SonarQube integration configured
- Dockerfile for containerized deployment
2 changes: 2 additions & 0 deletions src/main/java/com/iemr/common/CommonApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;

Expand All @@ -40,6 +41,7 @@

@SpringBootApplication
@EnableScheduling
@EnableAsync(proxyTargetClass = true)
public class CommonApplication extends SpringBootServletInitializer {

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

import org.springframework.stereotype.Service;

@Service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,6 @@ public ResponseEntity<ApiResponse<?>> getStructuredForm(@PathVariable String for
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public class FormField {
@Column(name = "created_at")
private LocalDateTime createdAt = LocalDateTime.now();

@Column(name = "option_key")
private String optionKey;



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.iemr.common.data.dynamic_from;

import jakarta.persistence.*;
import lombok.Data;

@Entity
@Table(name = "form_field_options")
@Data
public class FormFieldOption {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@Column(name = "option_key")
private String optionKey;

@Column(name = "value")
private String value;

@Column(name = "label_en")
private String labelEn;

@Column(name = "label_hi")
private String labelHi;

@Column(name = "label_as")
private String labelAs;

@Column(name = "sort_order")
private Integer sortOrder;

// getters/setters
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ public class Translation {
private String assameseTranslation;
@Column(name = "is_active")
private Boolean isActive;

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
private Integer sequence;
private Boolean isEditable;
private Integer stateCode;
private List<String> options;
public List<Map<String, Object>> options;

Check warning on line 23 in src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make options a static final constant or non-public and provide accessors if needed.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oFEBG6AnbEIDJiTwV&open=AZ1oFEBG6AnbEIDJiTwV&pullRequest=391
private Map<String, Object> validation;
private Map<String, Object> conditional;
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ public class BeneficiaryModel implements Comparable<BeneficiaryModel> {
private Boolean isMarried;

@Expose
private Integer doYouHavechildren;
private boolean doYouHavechildren;

@Expose
private Integer noOfchildren;

@Expose
private Integer noofAlivechildren;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@
@Repository
public interface FieldRepository extends JpaRepository<FormField, Long> {
List<FormField> findByForm_FormIdOrderBySequenceAsc(String formId);
List<FormField> findByForm_FormIdAndStateCodeOrderBySequenceAsc(
String formId,
Integer stateCode
);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iemr.common.repository.dynamic_form;
import com.iemr.common.data.dynamic_from.FormFieldOption;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface FormFieldOptionRepository
extends JpaRepository<FormFieldOption, Integer> {

List<FormFieldOption> findByOptionKeyOrderBySortOrderAsc(String optionKey);

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public interface TranslationRepo extends JpaRepository<Translation, Long> {

Optional<Translation> findByLabelKeyAndIsActive(String labelKey, boolean isActive);


}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch;
import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService;
Expand Down Expand Up @@ -120,7 +121,7 @@
}
}

@Async
// @Async
@Override
public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String auth) throws IEMRException {
Integer updatedRows = 0;
Expand Down Expand Up @@ -188,7 +189,7 @@
}

@Override
public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servletRequest) throws Exception {

Check failure on line 192 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 24 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWt&open=AZ1oGoVkxaCleYMjbuWt&pullRequest=391

logger.info("benificiaryDetails: " + beneficiaryModel);

Expand Down Expand Up @@ -224,9 +225,27 @@
} else {
return response.toString();
}
if(beneficiary!=null){
if(beneficiary.getBenPhoneMaps().get(0).getPhoneNo()!=null){
welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiary.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID());
// ========== SEND SMS BUT DON'T FAIL IF IT ERRORS ==========
if (beneficiary != null && beneficiary.getBenPhoneMaps() != null && !beneficiary.getBenPhoneMaps().isEmpty()) {
String phoneNo = beneficiary.getBenPhoneMaps().get(0).getPhoneNo();

if (phoneNo != null && !phoneNo.trim().isEmpty()) {
String beneficiaryName = (beneficiary.getFirstName() != null ? beneficiary.getFirstName() : "") + " " +
(beneficiary.getLastName() != null ? beneficiary.getLastName() : "");

try {
logger.info("[SMS] Attempting to send welcome SMS to: " + phoneNo);

Check warning on line 237 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Format specifiers should be used instead of string concatenation.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWu&open=AZ1oGoVkxaCleYMjbuWu&pullRequest=391

Check warning on line 237 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the built-in formatting to construct this argument.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWr&open=AZ1oGoVkxaCleYMjbuWr&pullRequest=391
String smsResult = welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(
phoneNo,
beneficiaryName.trim(),
beneficiary.getBeneficiaryID()
);
logger.info("[SMS] Result: " + smsResult);

Check warning on line 243 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Format specifiers should be used instead of string concatenation.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWv&open=AZ1oGoVkxaCleYMjbuWv&pullRequest=391

Check warning on line 243 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the built-in formatting to construct this argument.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWs&open=AZ1oGoVkxaCleYMjbuWs&pullRequest=391
} catch (Exception smsError) {
// SMS failed but beneficiary is already created - don't fail the request
logger.warn("[SMS] Failed to send SMS: " + smsError.getMessage() +
" - But beneficiary already created successfully");

Check warning on line 247 in src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Format specifiers should be used instead of string concatenation.

See more on https://sonarcloud.io/project/issues?id=PSMRI_Common-API&issues=AZ1oGoVkxaCleYMjbuWw&open=AZ1oGoVkxaCleYMjbuWw&pullRequest=391
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -90,6 +91,7 @@ public class CTIServiceImpl implements CTIService {
@Autowired
private BeneficiaryCallRepository beneficiaryCallRepository;

@Lazy
@Autowired
private CTIService ctiService;

Expand Down
Loading
Loading