Add facility hierarchy creation with village and parent-child mapping#121
Add facility hierarchy creation with village and parent-child mapping#121vishwab1 merged 8 commits intorelease-3.8.1from
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds facility-hierarchy functionality: new controller endpoints for facility-type and store operations, new DTOs/entities for facility levels and village mappings, repository query methods (including modifying and custom queries), and service implementations to create/update facilities with village and child-facility mappings. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Controller as rgba(52,152,219,0.5)
participant Service as rgba(46,204,113,0.5)
participant FacilityRepo as rgba(155,89,182,0.5)
participant MappingRepo as rgba(241,196,15,0.5)
participant Database as rgba(127,140,141,0.5)
Client->>Controller: POST /createFacilityWithHierarchy (facility, villageIDs, childFacilityIDs)
Controller->>Service: createFacilityWithHierarchy(facility, villageIDs, childFacilityIDs)
Service->>FacilityRepo: save or update M_Facility
FacilityRepo->>Database: INSERT/UPDATE M_Facility
Database-->>FacilityRepo: persisted facility (id)
FacilityRepo-->>Service: returned facility
loop each villageID
Service->>MappingRepo: save new FacilityVillageMapping(facilityID, districtBranchID)
MappingRepo->>Database: INSERT facility_village_mapping
end
loop each childFacilityID
Service->>FacilityRepo: update childFacility.parentFacilityID = facilityID
FacilityRepo->>Database: UPDATE M_Facility SET ParentFacilityID
end
Service-->>Controller: return saved facility and mappings
Controller-->>Client: JSON response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@vishwab1 release numbers have changed. |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)
111-113:⚠️ Potential issue | 🔴 CriticalBug: Self-assignment in setter does nothing.
The setter assigns the parameter to itself instead of to the instance field. This is a no-op and leaves
facilityTypeIDunchanged after callingsetFacilityTypeID().🐛 Fix the setter
public void setFacilityTypeID(Integer facilityTypeID) { - facilityTypeID = facilityTypeID; + this.facilityTypeID = facilityTypeID; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around lines 111 - 113, The setter setFacilityTypeID currently self-assigns the parameter; change it to assign the instance field by setting this.facilityTypeID = facilityTypeID so the class field is actually updated when setFacilityTypeID(Integer facilityTypeID) is called; locate the facilityTypeID field in M_facilitytype to confirm the correct field name and use this. to reference it.
🧹 Nitpick comments (4)
src/main/java/com/iemr/admin/data/store/M_Facility.java (1)
219-249: Redundant accessors due to@Dataannotation.The class already uses Lombok
@Data(line 40), which generates getters/setters automatically. These explicit accessors are redundant. This appears to be an existing pattern in the file, but for new fields, you could omit them.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/data/store/M_Facility.java` around lines 219 - 249, The explicit getters/setters getStateID, setStateID, getDistrictID, setDistrictID, getBlockID, setBlockID, getParentFacilityID and setParentFacilityID are redundant because the class is annotated with Lombok's `@Data`; remove these explicit accessor methods (unless any contain custom logic—if so, preserve that method and delete only the redundant ones) so Lombok can provide the boilerplate automatically and avoid duplication.src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java (1)
31-35: Consider usingListas return type and review package placement.
- Using
List<M_FacilityLevel>instead ofArrayList<M_FacilityLevel>follows interface-based programming best practices.- Since
M_FacilityLevelresides incom.iemr.admin.data.store, this repository might be better placed incom.iemr.admin.repository.storefor consistency.♻️ Suggested change for return type
- ArrayList<M_FacilityLevel> findByDeletedFalseOrderByLevelName(); + List<M_FacilityLevel> findByDeletedFalseOrderByLevelName();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java` around lines 31 - 35, The repository M_FacilityLevelRepo currently returns a concrete ArrayList from findByDeletedFalseOrderByLevelName; change the method signature to return the interface type List<M_FacilityLevel> to follow interface-based programming (replace ArrayList<M_FacilityLevel> with List<M_FacilityLevel> in M_FacilityLevelRepo). Also consider moving the repository package to com.iemr.admin.repository.store to match the M_FacilityLevel entity package (com.iemr.admin.data.store) for consistent package structure; update the package declaration and imports accordingly.src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)
70-72: AddclearAutomatically = trueto the@Modifyingannotation to follow Spring Data best practices.The service method
updateFacilityWithHierarchyis properly annotated with@Transactional, so the persistence context contains the entities during execution. AddingclearAutomatically = trueensures the session cache is cleared after the bulk update, preventing potential stale data issues in the persistence context.♻️ Suggested fix
- `@Modifying` + `@Modifying`(clearAutomatically = true) `@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID") int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around lines 70 - 72, The `@Modifying` annotation on the repository method clearParentFacilityID should include clearAutomatically = true to avoid stale persistence context after the bulk update; update the annotation on the method clearParentFacilityID in MainStoreRepo to `@Modifying`(clearAutomatically = true) while keeping the existing `@Query` and `@Param` signatures intact so the transactional service method updateFacilityWithHierarchy will see a cleared session after the bulk operation.src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (1)
258-266: Consider batching village-mapping inserts.Current per-row
save(...)loops are fine functionally but will scale poorly for larger mapping sets.💡 Suggested refactor
- for (Integer villageID : villageIDs) { + List<FacilityVillageMapping> mappingsToSave = new ArrayList<>(); + for (Integer villageID : villageIDs) { FacilityVillageMapping mapping = new FacilityVillageMapping(); mapping.setFacilityID(savedFacility.getFacilityID()); mapping.setDistrictBranchID(villageID); mapping.setCreatedBy(facility.getCreatedBy()); mapping.setDeleted(false); - facilityVillageMappingRepo.save(mapping); + mappingsToSave.add(mapping); } + facilityVillageMappingRepo.saveAll(mappingsToSave);Also applies to: 320-327
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around lines 258 - 266, The per-entity persistence inside the loop (creating FacilityVillageMapping and calling facilityVillageMappingRepo.save(mapping)) will not scale; instead build a List<FacilityVillageMapping> (populate facilityID from savedFacility.getFacilityID(), districtBranchID from villageID, createdBy from facility.getCreatedBy(), deleted=false) and call facilityVillageMappingRepo.saveAll(list) or your repository's bulk insert method; apply the same change to the other loop that does per-row saves (the similar block around the later village-mapping insertion).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 356-363: The controller method createFacilityWithHierarchy
currently uses reqObj and reqObj.getFacility() without validating them; before
calling storeService.createFacilityWithHierarchy (and in the similar block
around the other method using reqObj at 425-432), add null checks for reqObj and
reqObj.getFacility() and short-circuit with a controlled validation
OutputResponse (set an error message and appropriate status/code) instead of
invoking the service; ensure you check both the request body parse result and
that the Facility object is present, returning the validation response
immediately when missing.
In `@src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java`:
- Around line 1-21: Add the standard GPL license header to the top of this file
so it matches other files in the PR; open FacilityHierarchyRequest (class
FacilityHierarchyRequest in package com.iemr.admin.data.store) and insert the
project's standard multi-line GPL header comment block immediately above the
package declaration so the file begins with the exact license header used
elsewhere in the repo.
In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 46-47: The Deleted field in FacilityVillageMapping is marked
`@Column`(insertable = false) so calls to mapping.setDeleted(false) in the service
won't persist; either remove the insertable = false attribute on the deleted
field in class FacilityVillageMapping so the JPA entity can insert the value, or
if you must keep insertable=false, ensure the DB column
facility_village_mapping.Deleted has an explicit DEFAULT (e.g., DEFAULT FALSE)
and/or initialize the entity field (private Boolean deleted = false) so new rows
are not NULL; update whichever approach you choose and verify
findByFacilityIDAndDeletedFalse() returns the new mappings.
In
`@src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java`:
- Around line 45-47: The JPQL query in findByProviderServiceMapIDAndRuralUrban
returns soft-deleted rows because it lacks a deleted=false predicate; update the
query string in M_facilitytypeRepo (the `@Query` on
findByProviderServiceMapIDAndRuralUrban) to include "AND f.deleted = false"
(keeping the existing WHERE clauses and ORDER BY f.facilityTypeName) so only
non-deleted M_facilitytype records are returned.
- Around line 55-56: The repository query in M_facilitytypeRepo's findByStateID
method can return soft-deleted rows because it lacks a deleted flag filter;
update the JPQL in the `@Query` on method findByStateID to include "AND f.deleted
= false" (i.e., WHERE f.stateID = :stateID AND f.deleted = false ORDER BY
f.facilityTypeName) so only non-deleted M_facilitytype entities are returned,
keeping the `@Param`("stateID") binding unchanged.
In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 18-21: The JPQL in FacilityVillageMappingRepo's
findMappedVillageIDsByBlockID can return duplicate IDs; update the query to
select DISTINCT fvm.districtBranchID so the method returns unique village IDs
(modify the `@Query` on findMappedVillageIDsByBlockID to use DISTINCT in the
SELECT clause).
In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Line 60: The repository method findByBlockIDOrderByFacilityName lacks the
deleted=false filter and can return soft-deleted facilities; update the
repository to exclude deleted rows by changing the method to include the deleted
flag (e.g., rename/replace with findByBlockIDAndDeletedFalseOrderByFacilityName
or add the equivalent `@Query` condition) so it behaves consistently with
getAllMainFacility and getChildFacility and only returns non-deleted M_Facility
records.
In
`@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java`:
- Around line 56-58: Method addAllFicilityData in M_facilitytypeServiceImpl
currently unsafely casts the result of m_facilitytypeRepo.saveAll(...) to
ArrayList, which is unsafe because CrudRepository.saveAll returns Iterable;
replace the cast by converting the Iterable to a concrete List/ArrayList
explicitly (e.g., collect the Iterable into a new ArrayList or change the return
type to List<M_facilitytype> and construct/return a List from the Iterable) so
that m_facilitytypeRepo.saveAll(...) is not directly cast to ArrayList and no
ClassCastException can occur.
In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 269-276: In StoreServiceImpl where childFacilityIDs are processed
(calls to mainStoreRepo.findByFacilityID and child.setParentFacilityID on
M_Facility), validate each childID before updating: if findByFacilityID returns
null, either log/collect and throw a validation exception instead of silently
ignoring; also explicitly check that childID != savedFacility.getFacilityID()
and reject or skip with an error if equal to prevent self-parenting; ensure you
use facility.getCreatedBy()/setModifiedBy only after validation and persist only
validated children (or abort the update with a clear validation error listing
invalid or self-referencing IDs).
---
Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: The setter setFacilityTypeID currently self-assigns the
parameter; change it to assign the instance field by setting this.facilityTypeID
= facilityTypeID so the class field is actually updated when
setFacilityTypeID(Integer facilityTypeID) is called; locate the facilityTypeID
field in M_facilitytype to confirm the correct field name and use this. to
reference it.
---
Nitpick comments:
In `@src/main/java/com/iemr/admin/data/store/M_Facility.java`:
- Around line 219-249: The explicit getters/setters getStateID, setStateID,
getDistrictID, setDistrictID, getBlockID, setBlockID, getParentFacilityID and
setParentFacilityID are redundant because the class is annotated with Lombok's
`@Data`; remove these explicit accessor methods (unless any contain custom
logic—if so, preserve that method and delete only the redundant ones) so Lombok
can provide the boilerplate automatically and avoid duplication.
In
`@src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java`:
- Around line 31-35: The repository M_FacilityLevelRepo currently returns a
concrete ArrayList from findByDeletedFalseOrderByLevelName; change the method
signature to return the interface type List<M_FacilityLevel> to follow
interface-based programming (replace ArrayList<M_FacilityLevel> with
List<M_FacilityLevel> in M_FacilityLevelRepo). Also consider moving the
repository package to com.iemr.admin.repository.store to match the
M_FacilityLevel entity package (com.iemr.admin.data.store) for consistent
package structure; update the package declaration and imports accordingly.
In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The `@Modifying` annotation on the repository method
clearParentFacilityID should include clearAutomatically = true to avoid stale
persistence context after the bulk update; update the annotation on the method
clearParentFacilityID in MainStoreRepo to `@Modifying`(clearAutomatically = true)
while keeping the existing `@Query` and `@Param` signatures intact so the
transactional service method updateFacilityWithHierarchy will see a cleared
session after the bulk operation.
In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 258-266: The per-entity persistence inside the loop (creating
FacilityVillageMapping and calling facilityVillageMappingRepo.save(mapping))
will not scale; instead build a List<FacilityVillageMapping> (populate
facilityID from savedFacility.getFacilityID(), districtBranchID from villageID,
createdBy from facility.getCreatedBy(), deleted=false) and call
facilityVillageMappingRepo.saveAll(list) or your repository's bulk insert
method; apply the same change to the other loop that does per-row saves (the
similar block around the later village-mapping insertion).
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.javasrc/main/java/com/iemr/admin/controller/store/StoreController.javasrc/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.javasrc/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.javasrc/main/java/com/iemr/admin/data/store/FacilityVillageMapping.javasrc/main/java/com/iemr/admin/data/store/M_Facility.javasrc/main/java/com/iemr/admin/data/store/M_FacilityLevel.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.javasrc/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.javasrc/main/java/com/iemr/admin/repository/store/MainStoreRepo.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.javasrc/main/java/com/iemr/admin/service/store/StoreService.javasrc/main/java/com/iemr/admin/service/store/StoreServiceImpl.java
src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java
Show resolved
Hide resolved
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)
111-113:⚠️ Potential issue | 🟠 MajorBug: Setter does not assign to field.
The setter assigns the parameter to itself instead of the instance field. This means
setFacilityTypeID()has no effect.🐛 Fix the assignment
public void setFacilityTypeID(Integer facilityTypeID) { - facilityTypeID = facilityTypeID; + this.facilityTypeID = facilityTypeID; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around lines 111 - 113, The setter setFacilityTypeID currently assigns the parameter to itself (facilityTypeID = facilityTypeID) so the instance field is never updated; fix it by assigning the parameter to the instance field (use this.facilityTypeID = facilityTypeID or rename the parameter and assign accordingly) in the M_facilitytype class so the field is properly set by setFacilityTypeID().
♻️ Duplicate comments (1)
src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java (1)
1-23:⚠️ Potential issue | 🟡 MinorMissing GPL license header.
This file is missing the standard GPL license header that is present in other files in this PR (e.g.,
M_FacilityLevelRepo.java,M_FacilityLevel.java). For consistency and compliance, consider adding the license header.📄 Add license header
+/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ package com.iemr.admin.repository.store;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java` around lines 1 - 23, The file lacks the project's standard GPL license header; add the same GPL header block used in other files (e.g., M_FacilityLevelRepo.java, M_FacilityLevel.java) to the top of this file before the package declaration so FacilityVillageMappingRepo (interface) and its imports are covered by the license comment; ensure the header text and year/owner match the project's existing header exactly for consistency and compliance.
🧹 Nitpick comments (5)
src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)
70-72: Consider addingclearAutomatically = trueto avoid stale entity cache.The
@Modifyingquery updates entities directly in the database. If the persistence context contains any of the affectedM_Facilityentities, they will become stale after this bulk update.♻️ Suggested improvement
`@Modifying` - `@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID") + `@Modifying`(clearAutomatically = true) + `@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID") int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around lines 70 - 72, The bulk update in clearParentFacilityID (method clearParentFacilityID in MainStoreRepo) uses `@Modifying` and may leave stale M_Facility entities in the persistence context; modify the annotation to `@Modifying`(clearAutomatically = true) so the persistence context is cleared after the update (keep the existing `@Query` and `@Param` usage unchanged).src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (2)
302-305: Consider using a more specific exception type.
RuntimeExceptionis generic and doesn't convey semantic meaning. The codebase hasIEMRExceptionavailable (imported at line 43) which would be more appropriate for domain-specific errors.💡 Suggested fix
M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID()); if (existing == null) { - throw new RuntimeException("Facility not found"); + throw new IEMRException("Facility not found"); }Note: This would require updating the method signature to declare
throws IEMRException.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around lines 302 - 305, Replace the generic RuntimeException thrown when a facility isn't found with the domain-specific IEMRException: where you check M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID()) and currently throw new RuntimeException("Facility not found"), throw a new IEMRException with the same (or more descriptive) message; also update the enclosing method signature to declare throws IEMRException so callers handle the specific exception type.
312-328: Document the semantic difference betweennulland empty list forvillageIDs.The current logic treats
null(no change to mappings) differently from an empty list (clears all mappings). This is a reasonable design but could be confusing for API consumers.
villageIDs == null: Skip village mapping update entirelyvillageIDsis empty list: Soft-delete all existing mappings, add noneConsider adding a code comment or API documentation to clarify this behavior.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around lines 312 - 328, The block in StoreServiceImpl that updates facility-village mappings (using facilityVillageMappingRepo, oldMappings loop, and the villageIDs loop) treats null as "leave mappings unchanged" and an empty list as "soft-delete all mappings and add none"; add a concise inline code comment above this conditional explaining the semantic difference (null = no change, empty list = clear mappings), and update the method Javadoc or API docs for the method that handles facility updates to document this behavior for API consumers so callers know how to intentionally clear versus retain mappings.src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java (1)
31-31: Remove unused imports.
GetMappingandRequestParamare imported but not used in this file. ThegetFacilityLevelsendpoint uses@RequestMappingwithRequestMethod.GETinstead of@GetMapping.🧹 Suggested fix
-import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;Also applies to: 35-35
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java` at line 31, Remove the unused imports org.springframework.web.bind.annotation.GetMapping and org.springframework.web.bind.annotation.RequestParam from FacilitytypeController.java; locate the FacilitytypeController class (and the getFacilityLevels method which currently uses `@RequestMapping`(method = RequestMethod.GET)) and either switch that method to use `@GetMapping` or simply delete the unused import lines so there are no unused import warnings.src/main/java/com/iemr/admin/controller/store/StoreController.java (1)
341-344: Consider using a dedicated DTO orM_Facilityinstead ofM_facilitytypefor parsing the request.This endpoint parses the request as
M_facilitytypeto extractblockIDandfacilityLevelID, but the endpoint operates on facilities, not facility types. UsingM_facilitytypehere is semantically confusing and couples this endpoint to an unrelated domain object.💡 Suggested fix
Consider creating a simple request DTO or using
FacilityHierarchyRequest(already imported) with the required fields:public String getFacilitiesByBlockAndLevel(`@RequestBody` String request) { OutputResponse response = new OutputResponse(); try { - com.iemr.admin.data.facilitytype.M_facilitytype reqObj = InputMapper.gson().fromJson(request, - com.iemr.admin.data.facilitytype.M_facilitytype.class); - ArrayList<M_Facility> data = storeService.getFacilitiesByBlockAndLevel(reqObj.getBlockID(), - reqObj.getFacilityLevelID()); + M_Facility reqObj = InputMapper.gson().fromJson(request, M_Facility.class); + ArrayList<M_Facility> data = storeService.getFacilitiesByBlockAndLevel(reqObj.getBlockID(), + reqObj.getFacilityLevelID()); response.setResponse(data.toString());This requires ensuring
M_FacilityhasfacilityLevelIDfield, or creating a dedicated request DTO.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/controller/store/StoreController.java` around lines 341 - 344, The controller is deserializing the request into com.iemr.admin.data.facilitytype.M_facilitytype even though the endpoint is fetching facilities; change the parsing to use a dedicated request DTO (e.g., FacilityHierarchyRequest) or a new FacilityLookupRequest with blockID and facilityLevelID, and pass those values to storeService.getFacilitiesByBlockAndLevel instead of reading them from M_facilitytype; update the parsing call in StoreController (replace InputMapper.gson().fromJson(..., M_facilitytype.class)) to deserialize into the chosen DTO and ensure the DTO field names match reqObj.getBlockID() and reqObj.getFacilityLevelID() accessors (or add accessors) so getFacilitiesByBlockAndLevel receives the correct IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 37-39: The `@Formula` on the villageName field is referencing
districtBranchID directly which Hibernate cannot resolve; update the Formula on
facility's villageName to use Hibernate's {alias} placeholder so the owning
entity's column is referenced (e.g., change the WHERE to use
{alias}.DistrictBranchID) when querying m_DistrictBranchMapping.VillageName.
---
Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: The setter setFacilityTypeID currently assigns the
parameter to itself (facilityTypeID = facilityTypeID) so the instance field is
never updated; fix it by assigning the parameter to the instance field (use
this.facilityTypeID = facilityTypeID or rename the parameter and assign
accordingly) in the M_facilitytype class so the field is properly set by
setFacilityTypeID().
---
Duplicate comments:
In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 1-23: The file lacks the project's standard GPL license header;
add the same GPL header block used in other files (e.g.,
M_FacilityLevelRepo.java, M_FacilityLevel.java) to the top of this file before
the package declaration so FacilityVillageMappingRepo (interface) and its
imports are covered by the license comment; ensure the header text and
year/owner match the project's existing header exactly for consistency and
compliance.
---
Nitpick comments:
In
`@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java`:
- Line 31: Remove the unused imports
org.springframework.web.bind.annotation.GetMapping and
org.springframework.web.bind.annotation.RequestParam from
FacilitytypeController.java; locate the FacilitytypeController class (and the
getFacilityLevels method which currently uses `@RequestMapping`(method =
RequestMethod.GET)) and either switch that method to use `@GetMapping` or simply
delete the unused import lines so there are no unused import warnings.
In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 341-344: The controller is deserializing the request into
com.iemr.admin.data.facilitytype.M_facilitytype even though the endpoint is
fetching facilities; change the parsing to use a dedicated request DTO (e.g.,
FacilityHierarchyRequest) or a new FacilityLookupRequest with blockID and
facilityLevelID, and pass those values to
storeService.getFacilitiesByBlockAndLevel instead of reading them from
M_facilitytype; update the parsing call in StoreController (replace
InputMapper.gson().fromJson(..., M_facilitytype.class)) to deserialize into the
chosen DTO and ensure the DTO field names match reqObj.getBlockID() and
reqObj.getFacilityLevelID() accessors (or add accessors) so
getFacilitiesByBlockAndLevel receives the correct IDs.
In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The bulk update in clearParentFacilityID (method
clearParentFacilityID in MainStoreRepo) uses `@Modifying` and may leave stale
M_Facility entities in the persistence context; modify the annotation to
`@Modifying`(clearAutomatically = true) so the persistence context is cleared
after the update (keep the existing `@Query` and `@Param` usage unchanged).
In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 302-305: Replace the generic RuntimeException thrown when a
facility isn't found with the domain-specific IEMRException: where you check
M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID())
and currently throw new RuntimeException("Facility not found"), throw a new
IEMRException with the same (or more descriptive) message; also update the
enclosing method signature to declare throws IEMRException so callers handle the
specific exception type.
- Around line 312-328: The block in StoreServiceImpl that updates
facility-village mappings (using facilityVillageMappingRepo, oldMappings loop,
and the villageIDs loop) treats null as "leave mappings unchanged" and an empty
list as "soft-delete all mappings and add none"; add a concise inline code
comment above this conditional explaining the semantic difference (null = no
change, empty list = clear mappings), and update the method Javadoc or API docs
for the method that handles facility updates to document this behavior for API
consumers so callers know how to intentionally clear versus retain mappings.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.javasrc/main/java/com/iemr/admin/controller/store/StoreController.javasrc/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.javasrc/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.javasrc/main/java/com/iemr/admin/data/store/FacilityVillageMapping.javasrc/main/java/com/iemr/admin/data/store/M_Facility.javasrc/main/java/com/iemr/admin/data/store/M_FacilityLevel.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.javasrc/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.javasrc/main/java/com/iemr/admin/repository/store/MainStoreRepo.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.javasrc/main/java/com/iemr/admin/service/store/StoreService.javasrc/main/java/com/iemr/admin/service/store/StoreServiceImpl.java
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)
111-113:⚠️ Potential issue | 🟠 MajorBug:
setFacilityTypeIDdoes not update the field.The setter assigns the parameter to itself instead of to the instance field. This means calling
setFacilityTypeID()has no effect.🐛 Proposed fix
public void setFacilityTypeID(Integer facilityTypeID) { - facilityTypeID = facilityTypeID; + this.facilityTypeID = facilityTypeID; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around lines 111 - 113, In M_facilitytype the setter method setFacilityTypeID(Integer facilityTypeID) is assigning the parameter to itself instead of updating the instance field; change the assignment to set the class field (e.g., this.facilityTypeID = facilityTypeID or the appropriate field name) inside setFacilityTypeID so the instance value is updated when the setter is called.
🧹 Nitpick comments (6)
src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java (1)
1-21: Missing GPL license header.This file is missing the standard GPL license header present in other files in this PR. Consider adding it for consistency and compliance.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java` around lines 1 - 21, Add the project's standard GPL license header to the top of this source file so it matches other files in the PR; specifically insert the same GPL comment block used across the project before the package declaration in FacilityVillageMapping (class FacilityVillageMapping in src/main/java/com/iemr/admin/data/store) so licensing is consistent and compliant.src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)
70-72: Consider filtering out soft-deleted facilities in the bulk update.The
clearParentFacilityIDmethod updates all facilities with a matchingparentFacilityID, including soft-deleted ones. If only active facilities should be detached, add adeleted = falsecondition.♻️ Optional fix to exclude soft-deleted records
`@Modifying` -@Query("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID") +@Query("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID AND f.deleted = false") int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around lines 70 - 72, The bulk update in clearParentFacilityID currently affects all M_Facility rows (including soft-deleted ones); modify the JPQL query in the clearParentFacilityID repository method to only target non-deleted facilities by adding a condition such as "AND f.deleted = false" (or the actual soft-delete flag name) so the WHERE clause becomes f.parentFacilityID = :parentFacilityID AND f.deleted = false; keep the method signature (clearParentFacilityID) and parameters unchanged and ensure the `@Modifying` `@Query` annotation on the MainStoreRepo method references the updated JPQL.src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java (1)
1-23: Missing GPL license header.This file is missing the standard GPL license header that is present in other repository files (e.g.,
MainStoreRepo.java,M_facilitytypeRepo.java). Consider adding it for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java` around lines 1 - 23, Add the project's standard GPL license header to this file to match other repository files; open the FacilityVillageMappingRepo interface (public interface FacilityVillageMappingRepo extends CrudRepository) and insert the same GPL comment block used in MainStoreRepo.java and M_facilitytypeRepo.java at the top of the file above the package declaration, preserving formatting and year/owner info as in other files so the file header is consistent with the repository.src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java (1)
43-43: Consider adding an import forM_FacilityLevelinstead of using the fully qualified name.Using
com.iemr.admin.data.store.M_FacilityLevelinline is functional but inconsistent with theM_facilitytypeimport at line 27.Suggested fix
Add to imports:
import com.iemr.admin.data.store.M_FacilityLevel;Then change line 43 to:
ArrayList<M_FacilityLevel> getFacilityLevels();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java` at line 43, Add an import for com.iemr.admin.data.store.M_FacilityLevel and replace the fully-qualified type in the getFacilityLevels() signature with the short name; specifically, add "import com.iemr.admin.data.store.M_FacilityLevel;" alongside the existing M_facilitytype import and change the method declaration "ArrayList<com.iemr.admin.data.store.M_FacilityLevel> getFacilityLevels();" to "ArrayList<M_FacilityLevel> getFacilityLevels();" to keep imports consistent.src/main/java/com/iemr/admin/controller/store/StoreController.java (1)
341-344: Consider using a dedicated DTO orM_Facilityfor the request parsing.Using
M_facilitytypeto extractblockIDandfacilityLevelIDworks but is semantically confusing since this endpoint returns facilities, not facility types. A more intuitive approach would be to useM_Facility(if it has these fields) or create a simple request DTO.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/controller/store/StoreController.java` around lines 341 - 344, The request is currently parsed into com.iemr.admin.data.facilitytype.M_facilitytype which is semantically misleading; change the deserialization to a more appropriate type that represents the request (either com.iemr.admin.data.facility.M_Facility if it contains blockID and facilityLevelID, or create a small request DTO like FacilityLookupRequest with those two fields) and update the local variable name accordingly; ensure the call to storeService.getFacilitiesByBlockAndLevel(req.getBlockID(), req.getFacilityLevelID()) uses the new DTO or M_Facility getters and adjust any imports/usages of M_facilitytype in this method.src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (1)
302-305: Consider using a more specific exception type.
RuntimeException("Facility not found")is generic. A domain-specific exception (e.g.,EntityNotFoundExceptionor a customFacilityNotFoundException) would provide better semantics and enable more granular exception handling at the controller layer if needed in the future.Example
M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID()); if (existing == null) { - throw new RuntimeException("Facility not found"); + throw new IllegalArgumentException("Facility not found with ID: " + facility.getFacilityID()); }Or use a custom exception if one exists in the codebase (e.g.,
IEMRException).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around lines 302 - 305, Replace the generic RuntimeException thrown when no facility is found in the block that calls mainStoreRepo.findByFacilityID(facility.getFacilityID()) with a more specific domain exception; for example throw new EntityNotFoundException("Facility not found: " + facility.getFacilityID()) or a custom FacilityNotFoundException/IEMRException if that exists in the codebase, so update the check around M_Facility existing = mainStoreRepo.findByFacilityID(...) to throw the chosen specific exception type with contextual message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java`:
- Line 35: Remove the unused import of RequestParam from the
FacilitytypeController class: delete the line importing
org.springframework.web.bind.annotation.RequestParam since no methods in
FacilitytypeController reference `@RequestParam`; after removal, run a quick
compile to ensure no other code in that class depends on RequestParam and clean
up any unused imports using your IDE's organize/imports feature.
In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 41-43: The field providerServiceMapID in FacilityVillageMapping
should not default to 0 because that persists an invalid FK; remove the "= 0"
default so the Integer is null by default, or alternatively ensure
StoreServiceImpl always assigns a valid providerServiceMapID before calling
save; update FacilityVillageMapping (providerServiceMapID) to have no default
and/or modify the service (StoreServiceImpl where new FacilityVillageMapping
instances are created) to set providerServiceMapID from the incoming DTO/params
prior to persistence.
---
Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: In M_facilitytype the setter method
setFacilityTypeID(Integer facilityTypeID) is assigning the parameter to itself
instead of updating the instance field; change the assignment to set the class
field (e.g., this.facilityTypeID = facilityTypeID or the appropriate field name)
inside setFacilityTypeID so the instance value is updated when the setter is
called.
---
Nitpick comments:
In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 341-344: The request is currently parsed into
com.iemr.admin.data.facilitytype.M_facilitytype which is semantically
misleading; change the deserialization to a more appropriate type that
represents the request (either com.iemr.admin.data.facility.M_Facility if it
contains blockID and facilityLevelID, or create a small request DTO like
FacilityLookupRequest with those two fields) and update the local variable name
accordingly; ensure the call to
storeService.getFacilitiesByBlockAndLevel(req.getBlockID(),
req.getFacilityLevelID()) uses the new DTO or M_Facility getters and adjust any
imports/usages of M_facilitytype in this method.
In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 1-21: Add the project's standard GPL license header to the top of
this source file so it matches other files in the PR; specifically insert the
same GPL comment block used across the project before the package declaration in
FacilityVillageMapping (class FacilityVillageMapping in
src/main/java/com/iemr/admin/data/store) so licensing is consistent and
compliant.
In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 1-23: Add the project's standard GPL license header to this file
to match other repository files; open the FacilityVillageMappingRepo interface
(public interface FacilityVillageMappingRepo extends CrudRepository) and insert
the same GPL comment block used in MainStoreRepo.java and
M_facilitytypeRepo.java at the top of the file above the package declaration,
preserving formatting and year/owner info as in other files so the file header
is consistent with the repository.
In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The bulk update in clearParentFacilityID currently affects
all M_Facility rows (including soft-deleted ones); modify the JPQL query in the
clearParentFacilityID repository method to only target non-deleted facilities by
adding a condition such as "AND f.deleted = false" (or the actual soft-delete
flag name) so the WHERE clause becomes f.parentFacilityID = :parentFacilityID
AND f.deleted = false; keep the method signature (clearParentFacilityID) and
parameters unchanged and ensure the `@Modifying` `@Query` annotation on the
MainStoreRepo method references the updated JPQL.
In `@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java`:
- Line 43: Add an import for com.iemr.admin.data.store.M_FacilityLevel and
replace the fully-qualified type in the getFacilityLevels() signature with the
short name; specifically, add "import
com.iemr.admin.data.store.M_FacilityLevel;" alongside the existing
M_facilitytype import and change the method declaration
"ArrayList<com.iemr.admin.data.store.M_FacilityLevel> getFacilityLevels();" to
"ArrayList<M_FacilityLevel> getFacilityLevels();" to keep imports consistent.
In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 302-305: Replace the generic RuntimeException thrown when no
facility is found in the block that calls
mainStoreRepo.findByFacilityID(facility.getFacilityID()) with a more specific
domain exception; for example throw new EntityNotFoundException("Facility not
found: " + facility.getFacilityID()) or a custom
FacilityNotFoundException/IEMRException if that exists in the codebase, so
update the check around M_Facility existing =
mainStoreRepo.findByFacilityID(...) to throw the chosen specific exception type
with contextual message.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.javasrc/main/java/com/iemr/admin/controller/store/StoreController.javasrc/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.javasrc/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.javasrc/main/java/com/iemr/admin/data/store/FacilityVillageMapping.javasrc/main/java/com/iemr/admin/data/store/M_Facility.javasrc/main/java/com/iemr/admin/data/store/M_FacilityLevel.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.javasrc/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.javasrc/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.javasrc/main/java/com/iemr/admin/repository/store/MainStoreRepo.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.javasrc/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.javasrc/main/java/com/iemr/admin/service/store/StoreService.javasrc/main/java/com/iemr/admin/service/store/StoreServiceImpl.java
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java
Outdated
Show resolved
Hide resolved
src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
Outdated
Show resolved
Hide resolved
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
|
@drtechie |
|



📋 Description
JIRA ID: AMM-2169 and AMM-2171
Please provide a summary of the change and the motivation behind it. Include relevant context and details.
Summary
m_facility_leveland mapping tablefacility_village_mappingNew API Endpoints
StoreController
/createFacilityWithHierarchy/updateFacilityWithHierarchy/getFacilitiesByBlock/getFacilitiesByBlockAndLevel/getMappedVillageIDs/getVillageMappingsByFacility/getChildFacilitiesByParentFacilitytypeController
/getFacilityTypesByRuralUrban/getFacilityLevels/getFacilityTypesByBlock/getFacilityTypesByState/checkFacilityTypeNameDatabase Changes
m_facility_level(FacilityLevelID, LevelName, LevelDescription, LevelValue)facility_village_mapping(FacilityVillageMappingID, FacilityID, DistrictBranchID)m_facility— added columns:StateID,DistrictID,BlockID,ParentFacilityIDm_facilitytype— added columns:RuralUrban,FacilityLevelID,StateIDTest Plan
createFacilityWithHierarchycreates facility, maps villages, and links child facilities in a single transactionupdateFacilityWithHierarchyreplaces village mappings and child links correctlygetMappedVillageIDsreturns only villages mapped to non-deleted facilities in the blockgetFacilitiesByBlockAndLevelreturns only facilities with no parent assignedcheckFacilityTypeNamecorrectly detects duplicates within the same state✅ Type of Change
ℹ️ Additional Information
Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.
Summary by CodeRabbit