Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2b23cd6
Enable SMS Functionality in MMU App to Send Prescriptions (#325)
vishwab1 Dec 18, 2025
a1a0027
Merge pull request #317 from PSMRI/release-3.6.0
5Amogh Jan 7, 2026
5c72753
implement translation in dynamic form
SauravBizbRolly Jan 8, 2026
c472421
Merge branch 'release-3.6.0' into feature/language_translation
SauravBizbRolly Jan 8, 2026
02f209d
Merge pull request #333 from toarunmishra/feature/language_translation
SauravBizbRolly Jan 8, 2026
7280c42
docs: add DeepWiki badge and documentation link
DurgaPrasad-54 Jan 19, 2026
61c89c4
Add DeepWiki badge to README
DurgaPrasad-54 Jan 19, 2026
caf5523
Merge pull request #342 from DurgaPrasad-54/main
drtechie Jan 19, 2026
134fa75
fix: update KM filepath
vanitha1822 Jan 29, 2026
c6e42d9
FLW-713 Remove All File Upload Options (#350)
SauravBizbRolly Jan 30, 2026
799236e
Add SMS functionality in release-3.6.1 (#358)
vanitha1822 Feb 9, 2026
f60f36e
chore(swagger): automate swagger sync to amrit-docs (#354)
DurgaPrasad-54 Feb 10, 2026
3c1ef4b
Update the swagger json github workflow (#359)
DurgaPrasad-54 Feb 17, 2026
a12c8ad
Add /health endpoint and standardize /version response (#331)
vaishnavbhosale Feb 22, 2026
d6991ed
Restrict user when account is locked
SauravBizbRolly Feb 24, 2026
4b44045
Add advance health check for database (#361)
DurgaPrasad-54 Mar 2, 2026
217b9e0
Merge pull request #364 from PSMRI/bug/account-lock-restriction
SauravBizbRolly Mar 12, 2026
2b00191
Cherry-pick health and version API enhancements to release-3.6.1 (#371)
DurgaPrasad-54 Mar 12, 2026
4542c21
Release 3.6.1 (#374)
DurgaPrasad-54 Mar 16, 2026
231773e
Merge Release-3.8.0 (3.6.1) to Main (#379)
vanitha1822 Mar 19, 2026
84034a6
fix: merge 3.7.0 to main
vanitha1822 Mar 24, 2026
e349006
Merge branch 'main' into rebase-3.7.0
vanitha1822 Mar 26, 2026
f3364e9
fix: merge with 3.6.1
vanitha1822 Mar 26, 2026
b804de1
Merge pull request #384 from PSMRI/rebase-3.7.0
snehar-nd Mar 26, 2026
1fe1024
fix: get file from km
vanitha1822 Apr 1, 2026
d59a16f
fix: KM issue
vanitha1822 Apr 2, 2026
46be4cb
fix: logger km url
vanitha1822 Apr 6, 2026
5a52dae
fix: update properties
vanitha1822 Apr 6, 2026
48bf49b
fix: property issue
vanitha1822 Apr 6, 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
109 changes: 109 additions & 0 deletions .github/workflows/swagger-json.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Sync Swagger to AMRIT-Docs

on:
push:
branches: [ main ]
workflow_dispatch:

jobs:
swagger-sync:
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout API repo
uses: actions/checkout@v4

- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: maven

- name: Build API (skip tests)
run: mvn -B clean package -DskipTests

- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq

- name: Run API in swagger profile
run: |
mvn spring-boot:run \
-Dspring-boot.run.profiles=swagger \
-Dspring-boot.run.arguments=--server.port=9090 \
> app.log 2>&1 &
echo $! > api_pid.txt

- name: Wait for API & fetch Swagger
run: |
for i in {1..40}; do
CODE=$(curl --connect-timeout 2 --max-time 5 -s -o swagger_raw.json -w "%{http_code}" http://localhost:9090/v3/api-docs || true)

if [ "$CODE" = "200" ]; then
jq . swagger_raw.json > common-api.json || {
echo "Swagger JSON invalid"
cat swagger_raw.json
exit 1
}

if [ "$(jq '.paths | length' common-api.json)" -eq 0 ]; then
echo "Swagger paths empty – failing"
exit 1
fi

echo "Swagger generated successfully"
exit 0
fi

echo "Waiting for API... ($i)"
sleep 4
done

echo "Swagger not generated"
cat app.log || true
exit 1

- name: Stop API
if: always()
run: |
# Graceful shutdown of the process group
sleep 5
# Force kill the process group if still running
if [ -f api_pid.txt ]; then
PID=$(cat api_pid.txt)
kill -TERM -- -"$PID" 2>/dev/null || true
sleep 2
kill -9 -- -"$PID" 2>/dev/null || true
fi
# Fallback: kill any remaining java process on port 9090
fuser -k 9090/tcp 2>/dev/null || true

- name: Checkout AMRIT-Docs
uses: actions/checkout@v4
with:
repository: PSMRI/AMRIT-Docs
token: ${{ secrets.DOCS_REPO_TOKEN }}
path: amrit-docs
fetch-depth: 0

- name: Copy Swagger JSON
run: |
mkdir -p amrit-docs/docs/swagger
cp common-api.json amrit-docs/docs/swagger/common-api.json

# Use a fixed branch name for PRs to avoid accumulating stale PRs.
# This ensures only one open PR is updated per run; delete-branch: true cleans up after merge.
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.DOCS_REPO_TOKEN }}
path: amrit-docs
branch: auto/swagger-update-common-api
base: main
commit-message: "chore(docs): auto-update Common-API swagger"
title: "chore(docs): auto-update Common-API swagger"
delete-branch: true
body: |
This PR automatically updates Common-API Swagger JSON
from the latest main branch build.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.compile.nullAnalysis.mode": "automatic"
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# AMRIT - Common Service
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ![branch parameter](https://github.com/PSMRI/Common-API/actions/workflows/sast-and-package.yml/badge.svg)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![DeepWiki](https://img.shields.io/badge/DeepWiki-PSMRI/Common--API-blue)](https://deepwiki.com/PSMRI/Common-API)


Common API is a microservice whch acts as a gateway for AMRIT. There are many APIs that are exposed by Common-API. It contains APIs of common integrators like c-Zentrix, Everwell, Openkm and some master APIs like location master, alerts, notification,language and location messages.
Expand Down Expand Up @@ -87,4 +88,3 @@ If you encounter any issues, bugs, or have feature requests, please file them in

We’d love to have you join our community discussions and get real-time support!
Join our [Discord server](https://discord.gg/FVQWsf5ENS) to connect with contributors, ask questions, and stay updated.

34 changes: 33 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.iemr.common-API</groupId>
<artifactId>common-api</artifactId>
<version>3.6.1</version>
<version>3.7.0</version>
<packaging>war</packaging>

<name>Common-API</name>
Expand Down Expand Up @@ -54,6 +54,12 @@
</repository>
</repositories>
<dependencies>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -520,6 +526,32 @@
<build>
<finalName>${artifactId}-${version}</finalName>
<plugins>
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
<version>9.0.2</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
<phase>initialize</phase>
</execution>
</executions>
<configuration>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<includeOnlyProperties>
<property>^git.branch$</property>
<property>^git.commit.id.abbrev$</property>
<property>^git.build.version$</property>
<property>^git.build.time$</property>
</includeOnlyProperties>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
<failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions src/main/environment/common_ci.properties
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,9 @@ platform.feedback.ratelimit.day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT
platform.feedback.ratelimit.user-day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT@
platform.feedback.ratelimit.fail-window-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES@
platform.feedback.ratelimit.backoff-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES@
otp.ratelimit.enabled=@env.OTP_RATELIMIT_ENABLED@
otp.ratelimit.minute-limit=@env.OTP_RATELIMIT_MINUTE_LIMIT@
otp.ratelimit.hour-limit=@env.OTP_RATELIMIT_HOUR_LIMIT@
otp.ratelimit.day-limit=@env.OTP_RATELIMIT_DAY_LIMIT@
generateBeneficiaryIDs-api-url=@env.GEN_BENEFICIARY_IDS_API_URL@

4 changes: 4 additions & 0 deletions src/main/environment/common_docker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,8 @@ platform.feedback.ratelimit.day-limit=${PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT}
platform.feedback.ratelimit.user-day-limit=${PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT}
platform.feedback.ratelimit.fail-window-minutes=${PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES}
platform.feedback.ratelimit.backoff-minutes=${PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES}
otp.ratelimit.enabled=${OTP_RATELIMIT_ENABLED}
otp.ratelimit.minute-limit=${OTP_RATELIMIT_MINUTE_LIMIT}
otp.ratelimit.hour-limit=${OTP_RATELIMIT_HOUR_LIMIT}
otp.ratelimit.day-limit=${OTP_RATELIMIT_DAY_LIMIT}
generateBeneficiaryIDs-api-url={GEN_BENEFICIARY_IDS_API_URL}
7 changes: 7 additions & 0 deletions src/main/environment/common_example.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ km-root-path=/okm:personal/users/
km-guest-user=guest
km-guest-password=guest

tempFilePath=/tmp

# CTI Config
cti-server-ip=10.208.122.99
cti-logger_base_url=http://10.208.122.99/logger
Expand Down Expand Up @@ -224,5 +226,10 @@ platform.feedback.ratelimit.user-day-limit=50
platform.feedback.ratelimit.fail-window-minutes=5
platform.feedback.ratelimit.backoff-minutes=15

# --- OTP Rate Limiting (per mobile number) ---
otp.ratelimit.minute-limit=3
otp.ratelimit.hour-limit=10
otp.ratelimit.day-limit=20

### generate Beneficiary IDs URL
generateBeneficiaryIDs-api-url=/generateBeneficiaryController/generateBeneficiaryIDs
4 changes: 3 additions & 1 deletion src/main/java/com/iemr/common/config/PrimaryDBConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.context.annotation.Profile;

import com.iemr.common.utils.config.ConfigProperties;

Expand All @@ -47,7 +48,8 @@
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = { "com.iemr.common.repository",
"com.iemr.common.repo", "com.iemr.common.notification.agent", "com.iemr.common.covidVaccination", "com.iemr.common.repository.everwell.*", "com.iemr.common.data.grievance", "com.iemr.common.repository.users" })
"com.iemr.common.repo", "com.iemr.common.notification.agent", "com.iemr.common.covidVaccination", "com.iemr.common.repository.everwell.*", "com.iemr.common.data.grievance", "com.iemr.common.repository.users" })
@Profile("!swagger")
public class PrimaryDBConfig {

Logger logger = LoggerFactory.getLogger(this.getClass().getName());
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/iemr/common/config/SecondaryDBConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@

import jakarta.persistence.EntityManagerFactory;

import org.springframework.context.annotation.Profile;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager", basePackages = {
"com.iemr.common.secondary.repository.callreport" })
"com.iemr.common.secondary.repository.callreport" })
@Profile("!swagger")
public class SecondaryDBConfig {

Logger logger = LoggerFactory.getLogger(this.getClass().getName());
Expand Down
26 changes: 18 additions & 8 deletions src/main/java/com/iemr/common/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
Expand All @@ -11,14 +12,23 @@

@Configuration
public class SwaggerConfig {

@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().info(new
Info().title("Common API").version("version").description("A microservice for the creation and management of beneficiaries."))
.addSecurityItem(new SecurityRequirement().addList("my security"))
.components(new Components().addSecuritySchemes("my security",
new SecurityScheme().name("my security").type(SecurityScheme.Type.HTTP).scheme("bearer")));
private static final String DEFAULT_SERVER_URL = "http://localhost:9090";

@Bean
public OpenAPI customOpenAPI(Environment env) {
String devUrl = env.getProperty("api.dev.url", DEFAULT_SERVER_URL);
String uatUrl = env.getProperty("api.uat.url", DEFAULT_SERVER_URL);
String demoUrl = env.getProperty("api.demo.url", DEFAULT_SERVER_URL);
return new OpenAPI()
.info(new Info().title("Common API").version("version").description("A microservice for the creation and management of beneficiaries."))
.addSecurityItem(new SecurityRequirement().addList("my security"))
.components(new Components().addSecuritySchemes("my security",
new SecurityScheme().name("my security").type(SecurityScheme.Type.HTTP).scheme("bearer")))
.servers(java.util.Arrays.asList(
new io.swagger.v3.oas.models.servers.Server().url(devUrl).description("Dev"),
new io.swagger.v3.oas.models.servers.Server().url(uatUrl).description("UAT"),
new io.swagger.v3.oas.models.servers.Server().url(demoUrl).description("Demo")
));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
import org.springframework.transaction.annotation.Transactional;

import com.iemr.common.service.nhm_dashboard.NHM_DashboardService;
import org.springframework.context.annotation.Profile;

@Service
@Transactional
@Profile("!swagger")
public class ScheduleJobForNHMDashboardData implements Job {
private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.context.annotation.Profile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
Expand Down Expand Up @@ -83,6 +84,7 @@

@RequestMapping({ "/beneficiary" })
@RestController
@Profile("!swagger")
public class BeneficiaryRegistrationController {

private InputMapper inputMapper = new InputMapper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package com.iemr.common.controller.beneficiaryConsent;

import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest;
import com.iemr.common.exception.OtpRateLimitException;
import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler;
import com.iemr.common.utils.mapper.InputMapper;
import com.iemr.common.utils.response.OutputResponse;
Expand Down Expand Up @@ -58,7 +59,9 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody
logger.info(success.toString());
response.setResponse(success);


} catch (OtpRateLimitException e) {
logger.warn("OTP rate limit hit for sendConsent: " + e.getMessage());
response.setError(429, e.getMessage());
} catch (Exception e) {
response.setError(500, "error : " + e);
}
Expand Down Expand Up @@ -105,6 +108,9 @@ public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBod
else
response.setError(500, "failure");

} catch (OtpRateLimitException e) {
logger.warn("OTP rate limit hit for resendConsent: " + e.getMessage());
response.setError(429, e.getMessage());
} catch (Exception e) {
logger.error("error in re-sending Consent : " + e);
response.setError(500, "error : " + e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ public ResponseEntity<ApiResponse<?>> deleteField(@PathVariable Long fieldId) {
}

@GetMapping(value = "form/{formId}/fields")
public ResponseEntity<ApiResponse<?>> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang) {
public ResponseEntity<ApiResponse<?>> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang,@RequestHeader(value = "jwttoken") String token) {
try {
Object result = formMasterService.getStructuredFormByFormId(formId,lang);
Object result = formMasterService.getStructuredFormByFormId(formId,lang,token);
return ResponseEntity.status(HttpStatus.OK)
.body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result));
} catch (Exception e) {
Expand Down
Loading