Skip to content

Conversation

@ymahtat-dev
Copy link

@ymahtat-dev ymahtat-dev commented Oct 7, 2025

When saving a Holiday for the same (holidayDate, locationCode) in a new language,
reuse the existing group’s holidayId (and isActive) instead of allocating a new id.
This aligns creation with the backend missing-IDs anti-join (by id) and prevents
other languages rows from staying “missing” after cloning to any secondary language.

Changes:

  • HolidayServiceImpl.saveHoliday(): if any Holiday exists for (date, location), reuse its holidayId/isActive; else allocate next id.
  • HolidayRepository: add/find helper for (holidayDate, locationCode).
  • Tests: add saveHoliday_reusesExistingHolidayId_whenSameDateAndLocationDifferentLanguage.

No API changes. Backward compatible.

Summary by CodeRabbit

  • New Features

    • Holiday creation now reuses existing holiday identifiers for entries with the same date and location across different languages, improving data consistency.
    • Added a lookup to support selecting non-deleted holiday records by date and location.
  • Tests

    • Added tests covering multi-language holiday scenarios and the repository/service interaction ensuring identifier reuse.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

Adds a repository query to fetch holidays by date and location (no language filter) and updates saveHoliday to reuse an existing holiday's holidayId and isActive when the same date and location exist in another language; tests added to verify this reuse behavior.

Changes

Cohort / File(s) Summary
Repository Enhancement
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/repository/HolidayRepository.java
Added Optional<Holiday> findFirstByHolidayDateAndLocationCode(LocalDate holidayDate, String locationCode) with @Query to return non-deleted holiday by date and location (no lang filter).
Service Logic Update
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java
Modified saveHoliday to call the new repository method; if an existing holiday for the same date and location exists, reuse its holidayId and isActive; otherwise generate a new ID via findMaxHolidayId() before saving.
Test Coverage
admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java
Added mocks and test saveHoliday_reusesExistingHolidayId_whenSameDateAndLocationDifferentLanguage to assert repository call sequence and verify holidayId reuse across language variants.

Sequence Diagram

sequenceDiagram
    participant Client
    participant HolidayServiceImpl
    participant HolidayRepository
    participant Database

    Client->>HolidayServiceImpl: saveHoliday(holidayDto)
    HolidayServiceImpl->>HolidayRepository: findFirstByHolidayByHolidayDateLocationCodeLangCode(date, loc, lang)
    alt No existing row for same date+loc+lang
        HolidayServiceImpl->>HolidayRepository: findFirstByHolidayDateAndLocationCode(date, loc)
        HolidayRepository->>Database: Query by date & location (non-deleted)
        Database-->>HolidayRepository: existingHoliday? 
        alt existingHoliday found
            HolidayServiceImpl->>HolidayServiceImpl: reuse holidayId & isActive
        else no existingHoliday
            HolidayServiceImpl->>HolidayRepository: findMaxHolidayId()
            HolidayRepository-->>HolidayServiceImpl: maxId
            HolidayServiceImpl->>HolidayServiceImpl: assign new holidayId = maxId + 1
        end
    end
    HolidayServiceImpl->>HolidayRepository: save(holiday)
    HolidayRepository->>Database: persist
    Database-->>HolidayRepository: persisted entity
    HolidayRepository-->>HolidayServiceImpl: saved entity
    HolidayServiceImpl-->>Client: result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review conditional ID assignment in HolidayServiceImpl (ensure correct reuse of holidayId and isActive semantics).
  • Verify repository query correctness and @Query filters (non-deleted condition).
  • Inspect new test for accurate mocking and expected repository call order.

Poem

🐇 I sniffed the date, I scoped the place,

Found kin in another language's space.
I kept the ID, I kept the cheer,
One holiday shared, for all who're near. 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: fixing false positives by reusing existing holidayId when creating holidays for the same date/location in different languages.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ase-101
Copy link
Contributor

ase-101 commented Nov 15, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1)

259-268: Consider removing the large commented-out block

The long commented block after holidayRepository.save(entity) adds noise to an already busy method. If this logic is no longer needed, consider deleting it (or moving it to documentation/ADR) to keep saveHoliday easier to read and maintain.

admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java (1)

147-148: Optional: Use a fixed LocalDate in the test for determinism

The test uses LocalDate.now() for date. While this works, using a fixed constant (e.g., LocalDate.of(2025, 1, 1)) would make the test fully deterministic and a bit easier to reason about over time.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab9433f and ddd7a74.

📒 Files selected for processing (3)
  • admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/repository/HolidayRepository.java (1 hunks)
  • admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1 hunks)
  • admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java (4 hunks)
🔇 Additional comments (3)
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1)

246-255: ID reuse logic across languages looks correct

The new existingSameHoliday branch correctly reuses the holidayId and isActive of any existing holiday with the same (holidayDate, locationCode) and falls back to findMaxHolidayId() + 1 only when no such record exists. This matches the described fix and keeps the empty-table (count() <= 0) behavior intact.

admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/repository/HolidayRepository.java (1)

166-168: Repository helper for cross-language lookup is well-scoped

The new findFirstByHolidayDateAndLocationCode query cleanly exposes the “same date and location, any language, non-deleted” lookup that saveHoliday needs, and its Optional<Holiday> return type matches the conditional reuse logic in the service.

admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java (1)

3-4: New test setup correctly validates holidayId reuse across languages

The added imports, mocks, and the saveHoliday_reusesExistingHolidayId_whenSameDateAndLocationDifferentLanguage test form a solid, focused regression test:

  • Mocks HolidayRepository, LocationRepository, and AuditUtil just enough for the saveHoliday path.
  • Simulates an existing holiday in one language and a new DTO in another for the same (holidayDate, locationCode).
  • Asserts that the saved entity and returned HolidayIDDto reuse the existing holidayId and isActive, and verifies that findMaxHolidayId() is never called while the expected repository methods are invoked.

This gives good coverage of the new ID-reuse behavior and guards against regressions.

Also applies to: 9-15, 19-22, 32-32, 41-48, 139-236

…xisting holidayId on create

Signed-off-by: Youssef MAHTAT <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1)

259-267: Consider removing commented-out code.

The commented block appears to be obsolete logic. Since version control preserves the history, it's cleaner to remove dead code rather than leave it commented out.

Apply this diff to remove the commented-out code:

 		holiday = holidayRepository.save(entity);
-		/*
-		 * if (holiday.getIsActive() == true &&
-		 * supportedLang.contains(holiday.getLangCode())) { Holiday
-		 * primholiday=holidayRepository.
-		 * findHolidayByHolidayNameHolidayDateLocationCodeLangCode(holiday.
-		 * getHolidayName(),holiday.getHolidayDate(),
-		 * holiday.getLocationCode(),primaryLang); primholiday.setIsActive(true);
-		 * holidayRepository.update(primholiday); }
-		 */
 		MapperUtils.map(holiday, holidayId);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddd7a74 and 4ad49d1.

📒 Files selected for processing (3)
  • admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/repository/HolidayRepository.java (1 hunks)
  • admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1 hunks)
  • admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/repository/HolidayRepository.java
  • admin/kernel-masterdata-service/src/test/java/io/mosip/kernel/masterdata/test/service/HolidayServiceImplTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (1)
admin/admin-service/src/main/java/io/mosip/admin/config/MapperUtils.java (1)
  • MapperUtils (15-150)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-maven-admin-services / maven-build
  • GitHub Check: build-maven-apitest-masterdata / maven-build
🔇 Additional comments (2)
admin/kernel-masterdata-service/src/main/java/io/mosip/kernel/masterdata/service/impl/HolidayServiceImpl.java (2)

246-255: Repository method verified—logic correctly addresses the PR objective.

The repository method findFirstByHolidayDateAndLocationCode exists and is properly implemented with the correct @query annotation at line 167 of HolidayRepository.java. The query filters by date and location without a language filter, which is the intended behavior for reusing holidayId and isActive across language variants and eliminating "Missing Data" false positives.

The new conditional logic (lines 246-255) correctly implements the stated PR objective by falling back to this language-agnostic lookup when an exact language-specific match is not found.


254-254: Verify concurrent safety of ID generation in high-concurrency scenarios.

The pattern findMaxHolidayId() + 1 is vulnerable to race conditions: two concurrent requests could fetch the same max ID and attempt simultaneous inserts with identical IDs. While the holidayId field has a unique constraint (@Column(unique = true)), this prevents data corruption but causes exceptions rather than preventing the race condition.

The condition at line 254 is reached only after checking for existing holidays by (date, location, lang-code) and (date, location), so duplicate scenarios should be rare. However, in high-concurrency environments, consider verifying:

  • Whether the current transaction isolation level and unique constraint are sufficient for your deployment.
  • If this pattern has caused issues in production (constraint violation exceptions on concurrent creates).
  • Whether a database sequence or transactional lock would better suit your requirements.

Note: This is a pre-existing pattern, not introduced by this PR. The original review comment's claim about other usages appears inaccurate—only this single usage was found in the codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants