From 7a51be811feecca9ca1f088495037907e3329120 Mon Sep 17 00:00:00 2001 From: Matithieu Date: Sun, 4 Jan 2026 17:58:58 +0100 Subject: [PATCH 1/3] refactor: controller paths + autocompletes logic --- .../spring/app/company/CompanyController.java | 50 ++++++++----- .../ConfigurationController.java | 4 +- .../autocomplete/city/CityController.java | 23 ++---- .../city/{City.java => CityModel.java} | 8 +-- .../autocomplete/city/CityRepository.java | 10 +-- .../autocomplete/city/CityService.java | 12 ++-- .../IndustrySectorController.java | 23 ++---- ...rySector.java => IndustrySectorModel.java} | 8 +-- .../IndustrySectorRepository.java | 17 ++--- .../industrySector/IndustrySectorService.java | 12 ++-- .../legalForm/LegalFormController.java | 23 ++---- .../{LegalForm.java => LegalFormModel.java} | 8 +-- .../legalForm/LegalFormRepository.java | 17 ++--- .../legalForm/LegalFormService.java | 12 ++-- .../autocomplete/region/RegionController.java | 23 ++---- .../region/{Region.java => RegionModel.java} | 8 +-- .../autocomplete/region/RegionRepository.java | 14 ++-- .../autocomplete/region/RegionService.java | 12 ++-- .../spring/app/leader/LeaderController.java | 12 ++-- .../example/spring/app/llm/LLMController.java | 70 +++++++++---------- .../spring/app/stripe/PaymentController.java | 2 +- .../spring/app/user/UserController.java | 6 +- .../UserCompanyStatusController.java | 32 --------- .../spring/app/webhook/WebHookController.java | 4 +- .../example/spring/security/CorsConfig.java | 15 +--- .../security/JwtAuthenticationFilter.java | 3 +- .../spring/security/SecurityConfig.java | 19 +++-- 27 files changed, 187 insertions(+), 260 deletions(-) rename src/main/java/com/example/spring/app/filters/autocomplete/city/{City.java => CityModel.java} (58%) rename src/main/java/com/example/spring/app/filters/autocomplete/industrySector/{IndustrySector.java => IndustrySectorModel.java} (58%) rename src/main/java/com/example/spring/app/filters/autocomplete/legalForm/{LegalForm.java => LegalFormModel.java} (58%) rename src/main/java/com/example/spring/app/filters/autocomplete/region/{Region.java => RegionModel.java} (58%) delete mode 100644 src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java diff --git a/src/main/java/com/example/spring/app/company/CompanyController.java b/src/main/java/com/example/spring/app/company/CompanyController.java index 20df4ad..c8af1fb 100644 --- a/src/main/java/com/example/spring/app/company/CompanyController.java +++ b/src/main/java/com/example/spring/app/company/CompanyController.java @@ -4,11 +4,13 @@ import com.example.spring.app.company.dto.CompanyDetails; import com.example.spring.app.company.dto.CompanyDtoWithStatusDTO; import com.example.spring.app.company.dto.CompanyFilterRequest; +import com.example.spring.app.company.enums.Status; import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel; import com.example.spring.app.userCompanyStatus.UserCompanyStatusService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; @@ -20,7 +22,7 @@ @CrossOrigin @RestController -@RequestMapping("/v1/company") +@RequestMapping("/v1/companies") public class CompanyController { @Autowired @@ -29,8 +31,16 @@ public class CompanyController { @Autowired private UserCompanyStatusService userCompanyStatusService; - // Example: http://localhost:8080/api/v1/company/get-by-id/123 - @GetMapping("/get-by-id/{id}") + // Example: http://localhost:8080/api/v1/company/search-by-name?companyName=ExampleCompany&page=0 + @GetMapping("/") + public Page searchCompaniesByName(@RequestParam("companyName") String companyName, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size) { + Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); + return companyService.searchCompanies(companyName, pageable); + } + + @GetMapping("/{id}") public CompanyDtoWithStatusDTO getCompanyById(@PathVariable("id") Integer id) { String userId = extractUserIdFromHeader(); CompanyDTO companyDto = companyService.getCompanyById(id).toCompanyDTO(); @@ -41,7 +51,7 @@ public CompanyDtoWithStatusDTO getCompanyById(@PathVariable("id") Integer id) { } // Example: http://localhost:8080/api/v1/company/get-seen-by-user?page=0 - @GetMapping("/get-seen-by-user") + @GetMapping("/seen") public Page getCompaniesSeenByUser(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { Pageable pageable = PageRequest.of(page, size); @@ -57,17 +67,8 @@ public Page getCompaniesSeenByUser(@RequestParam(defaul return CompanyUtil.fillPaginationCompanyDtoWithStatusDto(companies, userCompanyStatuses); } - // Example: http://localhost:8080/api/v1/company/search-by-name?companyName=ExampleCompany&page=0 - @GetMapping("/search-by-name") - public Page searchCompaniesByName(@RequestParam("companyName") String companyName, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "10") int size) { - Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); - return companyService.searchCompanies(companyName, pageable); - } - // Example: http://localhost:8080/api/v1/company/filter-by-parameters?regions=region1,region2&cities=city1,city2&industrySectors=sector1,sector2&legalForms=form1,form2&page=0 - @PostMapping("/filter-by-parameters") + @PostMapping("/filter") public Page getCompaniesByFilters( @RequestBody(required = false) CompanyFilterRequest filterRequest) { String userId = extractUserIdFromHeader(); @@ -96,7 +97,7 @@ public Page getCompaniesByFilters( } // Example: http://localhost:8080/api/v1/company/random-unseen?page=0 - @GetMapping("/random-unseen") + @GetMapping("/random") public Page getRandomUnseenCompanies(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { Pageable pageable = PageRequest.of(page, size); @@ -113,8 +114,8 @@ public Page getRandomUnseenCompanies(@RequestParam(defa // Make a request to the scrap API // Example: http://localhost:8080/api/v1/company/scrap?companyId=1 - @GetMapping("/scrap") - public CompanyDTO scrapCompany(@RequestParam Integer companyId) { + @GetMapping("/{id}/scrap") + public CompanyDTO scrapCompany(@PathVariable("id") Integer companyId) { CompanyModel company = companyService.getCompanyById(companyId); if (company == null) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Company not found"); @@ -136,7 +137,7 @@ public CompanyDTO scrapCompany(@RequestParam Integer companyId) { // Example: http://localhost:8080/api/v1/company/filter-by-parameters?regions=region1,region2&cities=city1,city2&industrySectors=sector1,sector2&legalForms=form1,form2&page=0 - @GetMapping("/landing-filter") + @GetMapping("/landing") public Page getCompaniesOnLandingByFilters( //@RequestParam(required = false) List regions, @RequestParam(required = false) List cityNames, @@ -167,4 +168,17 @@ public Page getCompaniesOnLandingByFilters( companiesPage.getTotalElements() ); } + + @PostMapping("/{id}/status") + public ResponseEntity updateStatus(@PathVariable("id") Integer companyId, + @RequestParam Status status) { + String userId = extractUserIdFromHeader(); + UserCompanyStatusModel updated = userCompanyStatusService.updateCompanyStatus(userId, companyId, status); + + if (updated == null) { + return ResponseEntity.noContent().build(); // deleted or no-op + } + + return ResponseEntity.ok(updated); + } } diff --git a/src/main/java/com/example/spring/app/configuration/ConfigurationController.java b/src/main/java/com/example/spring/app/configuration/ConfigurationController.java index 7387e91..d618f9d 100644 --- a/src/main/java/com/example/spring/app/configuration/ConfigurationController.java +++ b/src/main/java/com/example/spring/app/configuration/ConfigurationController.java @@ -3,9 +3,11 @@ import com.example.spring.config.EnvConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@RequestMapping("/v1/configuration") public class ConfigurationController { private final EnvConfig envConfig; @@ -16,7 +18,7 @@ public ConfigurationController(EnvConfig envConfig) { // Make sure to flush the cache when updating the env variables @Cacheable(value = "configCache", unless = "#result == null") - @GetMapping("/configuration") + @GetMapping("/") public ConfigurationDTO getEnv() { return ConfigurationDTO.builder() .oauthBaseUrl(envConfig.getOAUTH_BASE_URL()) diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java index c479473..69838a1 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java @@ -1,33 +1,24 @@ package com.example.spring.app.filters.autocomplete.city; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/v1/autocomplete") +@RequestMapping("/v1/autocomplete/cities") public class CityController { @Autowired private CityService cityService; - // Example: http://localhost:8080/api/v1/autocomplete/city?query=New - @GetMapping("/city") - public List autocompleteCitiesByName(@RequestParam String query) { - return cityService.searchCitiesByName(query); - } - - @GetMapping("/city/ids") - public List autocompleteCitiesByIds(@RequestParam List query) { + @PostMapping("/ids") + public List autocompleteCitiesByIds(@RequestBody List query) { return cityService.searchCitiesByIds(query); } - @GetMapping("/cities") - public List autocompleteCitiesByNames(@RequestParam List query) { - return cityService.searchCitiesByNames(query); + @PostMapping("/names") + public List autocompleteCitiesByNames(@RequestBody List query) { + return cityService.searchCitiesByNameContainingIgnoreCaseAny(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/City.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityModel.java similarity index 58% rename from src/main/java/com/example/spring/app/filters/autocomplete/city/City.java rename to src/main/java/com/example/spring/app/filters/autocomplete/city/CityModel.java index 0552787..7fcf7f3 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/City.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityModel.java @@ -1,17 +1,15 @@ package com.example.spring.app.filters.autocomplete.city; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Setter @Getter @Entity -public class City { +@Table(name = "city") +public class CityModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java index e8b1885..8fbb777 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java @@ -5,16 +5,16 @@ import java.util.List; -public interface CityRepository extends JpaRepository { +public interface CityRepository extends JpaRepository { - @Query("SELECT c FROM City c " + + @Query("SELECT c FROM CityModel c " + "WHERE LOWER(c.name) " + "LIKE LOWER(CONCAT('%', :query, '%')) " + "ORDER BY c.name " + "ASC LIMIT 25") - List findByNameContainingIgnoreCase(String query); + List findByNameContainingIgnoreCase(String query); - List findByNameIn(List names); + List findByNameIn(List names); - List findByIdIn(List ids); + List findByIdIn(List ids); } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java index b919624..54b5e9e 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java @@ -11,15 +11,15 @@ public class CityService { @Autowired private CityRepository cityRepository; - public List searchCitiesByName(String query) { - return cityRepository.findByNameContainingIgnoreCase(query); - } + public List searchCitiesByNameContainingIgnoreCaseAny(List query) { + if (query.size() > 1) { + return cityRepository.findByNameIn(query); + } - public List searchCitiesByNames(List query) { - return cityRepository.findByNameIn(query); + return cityRepository.findByNameContainingIgnoreCase(query.getFirst()); } - public List searchCitiesByIds(List query) { + public List searchCitiesByIds(List query) { return cityRepository.findByIdIn(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java index 0ba1b1f..0605d9e 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java @@ -1,33 +1,24 @@ package com.example.spring.app.filters.autocomplete.industrySector; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/v1/autocomplete") +@RequestMapping("/v1/autocomplete/industry-sectors") public class IndustrySectorController { @Autowired private IndustrySectorService industrySectorService; - // Example: http://localhost:8080/api/v1/autocomplete/industrySector?query=New - @GetMapping("/industrySector") - public List autocompleteIndustrySectorsByName(@RequestParam String query) { - return industrySectorService.searchIndustrySectorsByName(query); - } - - @GetMapping("/industrySector/ids") - public List autocompleteIndustrySectorsByIds(@RequestParam List query) { + @PostMapping("/ids") + public List autocompleteIndustrySectorsByIds(@RequestBody List query) { return industrySectorService.searchIndustrySectorsByIds(query); } - @GetMapping("/industrySectors") - public List autocompleteIndustrySectorsByNames(@RequestParam List query) { - return industrySectorService.searchIndustrySectorsByNames(query); + @PostMapping("/names") + public List autocompleteIndustrySectorsByNames(@RequestBody List query) { + return industrySectorService.searchIndustrySectorsByNameContainingIgnoreCase(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorModel.java similarity index 58% rename from src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java rename to src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorModel.java index 7ef44b7..b948c7b 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorModel.java @@ -1,17 +1,15 @@ package com.example.spring.app.filters.autocomplete.industrySector; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Setter @Getter @Entity -public class IndustrySector { +@Table(name = "industry_sector") +public class IndustrySectorModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java index af12910..d959e09 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java @@ -2,19 +2,20 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; -public interface IndustrySectorRepository extends JpaRepository { +public interface IndustrySectorRepository extends JpaRepository { - @Query("SELECT c FROM IndustrySector c " + - "WHERE LOWER(c.name) " + + @Query("SELECT i FROM IndustrySectorModel i " + + "WHERE LOWER(i.name) " + "LIKE LOWER(CONCAT('%', :query, '%')) " + - "ORDER BY c.name " + - "ASC LIMIT 20") - List findByNameContainingIgnoreCase(String query); + "ORDER BY i.name " + + "ASC LIMIT 25") + List findByNameContainingIgnoreCase(String query); - List findByNameIn(List names); + List findByNameIn(List names); - List findByIdIn(List ids); + List findByIdIn(List ids); } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java index 1359e78..3cd3dc6 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java @@ -11,15 +11,15 @@ public class IndustrySectorService { @Autowired private IndustrySectorRepository industrySectorRepository; - public List searchIndustrySectorsByName(String query) { - return industrySectorRepository.findByNameContainingIgnoreCase(query); - } + public List searchIndustrySectorsByNameContainingIgnoreCase(List query) { + if (query.size() > 1) { + return industrySectorRepository.findByNameIn(query); + } - public List searchIndustrySectorsByNames(List query) { - return industrySectorRepository.findByNameIn(query); + return industrySectorRepository.findByNameContainingIgnoreCase(query.getFirst()); } - public List searchIndustrySectorsByIds(List query) { + public List searchIndustrySectorsByIds(List query) { return industrySectorRepository.findByIdIn(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java index b1b39f4..dfb5bc0 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java @@ -1,32 +1,23 @@ package com.example.spring.app.filters.autocomplete.legalForm; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/v1/autocomplete") +@RequestMapping("/v1/autocomplete/legal-forms") public class LegalFormController { @Autowired private LegalFormService legalFormService; - // Example: http://localhost:8080/api/v1/autocomplete/legalForm?query=New - @GetMapping("/legalForm") - public List autocompleteLegalFormsByName(@RequestParam String query) { - return legalFormService.searchLegalFormsByName(query); - } - - @GetMapping("/legalForm/ids") - public List autocompleteLegalFormsByIds(@RequestParam List query) { + @PostMapping("/ids") + public List autocompleteLegalFormsByIds(@RequestBody List query) { return legalFormService.searchLegalFormsByIds(query); } - @GetMapping("/legalForms") - public List autocompleteLegalFormsByNames(@RequestParam List query) { - return legalFormService.searchLegalFormsByNames(query); + @PostMapping("/names") + public List autocompleteLegalFormsByNames(@RequestBody List query) { + return legalFormService.searchLegalFormsByNamesContainingIgnoreCase(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormModel.java similarity index 58% rename from src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java rename to src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormModel.java index ebd96ff..e4308d2 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormModel.java @@ -1,17 +1,15 @@ package com.example.spring.app.filters.autocomplete.legalForm; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Setter @Getter @Entity -public class LegalForm { +@Table(name = "legal_form") +public class LegalFormModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java index 0034975..0a9cc29 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java @@ -2,19 +2,20 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; -public interface LegalFormRepository extends JpaRepository { +public interface LegalFormRepository extends JpaRepository { - @Query("SELECT c FROM LegalForm c " + - "WHERE LOWER(c.name) " + + @Query("SELECT l FROM LegalFormModel l " + + "WHERE LOWER(l.name) " + "LIKE LOWER(CONCAT('%', :query, '%')) " + - "ORDER BY c.name " + - "ASC LIMIT 20") - List findByNameContainingIgnoreCase(String query); + "ORDER BY l.name " + + "ASC LIMIT 25") + List findByNameContainingIgnoreCase(String query); - List findByNameIn(List names); + List findByNameIn(List names); - List findByIdIn(List ids); + List findByIdIn(List ids); } \ No newline at end of file diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java index 329d125..fa21b9b 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java @@ -11,15 +11,15 @@ public class LegalFormService { @Autowired private LegalFormRepository legalFormRepository; - public List searchLegalFormsByName(String query) { - return legalFormRepository.findByNameContainingIgnoreCase(query); - } + public List searchLegalFormsByNamesContainingIgnoreCase(List query) { + if (query.size() > 1) { + return legalFormRepository.findByNameIn(query); + } - public List searchLegalFormsByNames(List query) { - return legalFormRepository.findByNameIn(query); + return legalFormRepository.findByNameContainingIgnoreCase(query.getFirst()); } - public List searchLegalFormsByIds(List query) { + public List searchLegalFormsByIds(List query) { return legalFormRepository.findByIdIn(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java index ce296a4..9d7b612 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java @@ -1,33 +1,24 @@ package com.example.spring.app.filters.autocomplete.region; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("/v1/autocomplete") +@RequestMapping("/v1/autocomplete/regions") public class RegionController { @Autowired private RegionService regionService; - // Example: http://localhost:8080/api/v1/autocomplete/region?query=New - @GetMapping("/region") - public List autocompleteRegionsByName(@RequestParam String query) { - return regionService.searchRegionsByName(query); - } - - @GetMapping("/region/ids") - public List autocompleteRegionsByIds(@RequestParam List query) { + @PostMapping("/ids") + public List autocompleteRegionsByIds(@RequestBody List query) { return regionService.searchRegionsByIds(query); } - @GetMapping("/regions") - public List autocompleteRegionsByNames(@RequestParam List query) { - return regionService.searchRegionsByNames(query); + @PostMapping("/names") + public List autocompleteRegionsByNames(@RequestBody List query) { + return regionService.searchRegionsByNamesContainingIgnoreCase(query); } } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionModel.java similarity index 58% rename from src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java rename to src/main/java/com/example/spring/app/filters/autocomplete/region/RegionModel.java index 2c7f259..a37c274 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionModel.java @@ -1,17 +1,15 @@ package com.example.spring.app.filters.autocomplete.region; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Setter @Getter @Entity -public class Region { +@Table(name = "region") +public class RegionModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java index 5fb6d9f..ed091ec 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java @@ -5,16 +5,16 @@ import java.util.List; -public interface RegionRepository extends JpaRepository { +public interface RegionRepository extends JpaRepository { - @Query("SELECT c FROM Region c " + - "WHERE LOWER(c.name) " + + @Query("SELECT r FROM RegionModel r " + + "WHERE LOWER(r.name) " + "LIKE LOWER(CONCAT('%', :query, '%')) " + - "ORDER BY c.name " + + "ORDER BY r.name " + "ASC LIMIT 25") - List findByNameContainingIgnoreCase(String query); + List findByNameContainingIgnoreCase(String query); - List findByNameIn(List names); + List findByNameIn(List names); - List findByIdIn(List ids); + List findByIdIn(List ids); } diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java index bb27a6d..66d060f 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java @@ -11,15 +11,15 @@ public class RegionService { @Autowired private RegionRepository regionRepository; - public List searchRegionsByName(String query) { - return regionRepository.findByNameContainingIgnoreCase(query); - } + public List searchRegionsByNamesContainingIgnoreCase(List query) { + if (query.size() > 1) { + return regionRepository.findByNameIn(query); + } - public List searchRegionsByNames(List query) { - return regionRepository.findByNameIn(query); + return regionRepository.findByNameContainingIgnoreCase(query.getFirst()); } - public List searchRegionsByIds(List query) { + public List searchRegionsByIds(List query) { return regionRepository.findByIdIn(query); } } diff --git a/src/main/java/com/example/spring/app/leader/LeaderController.java b/src/main/java/com/example/spring/app/leader/LeaderController.java index fe188fe..c9bfdf4 100644 --- a/src/main/java/com/example/spring/app/leader/LeaderController.java +++ b/src/main/java/com/example/spring/app/leader/LeaderController.java @@ -11,26 +11,26 @@ @CrossOrigin @RestController -@RequestMapping("/v1/leader") +@RequestMapping("/v1/leaders") public class LeaderController { @Autowired private LeaderService leaderService; // Example: http://localhost:8080/api/v1/leader/get-by-id/123 - @GetMapping("/get-by-id/{id}") - public LeaderModel getLeaderById(@PathVariable Integer id) { - return leaderService.getLeaderById(id); + @GetMapping("/{id}") + public LeaderModel getLeaderById(@PathVariable("id") Integer leaderId) { + return leaderService.getLeaderById(leaderId); } // Example: http://localhost:8080/api/v1/leader/get-by-siren?siren=exemple - @GetMapping("/get-by-siren/{siren}") + @GetMapping("/by-siren/{siren}") public List getLeaderBySiren(@PathVariable String siren) { return leaderService.getLeadersBySirens(siren); } // Example: http://localhost:8080/api/v1/leader/get-by-first-and-last-name?firstName=exemple&lastName=exemple&page=0 - @GetMapping("/get-by-first-and-last-name") + @GetMapping("/search") public Page getLeadersByName(@RequestParam("firstName") String firstName, @RequestParam("lastName") String lastName, @RequestParam(defaultValue = "0") int page, diff --git a/src/main/java/com/example/spring/app/llm/LLMController.java b/src/main/java/com/example/spring/app/llm/LLMController.java index ebb38f5..534c221 100644 --- a/src/main/java/com/example/spring/app/llm/LLMController.java +++ b/src/main/java/com/example/spring/app/llm/LLMController.java @@ -20,7 +20,7 @@ @CrossOrigin @RestController -@RequestMapping("/v1/chat") +@RequestMapping("/v1/conversations") public class LLMController { private final ChatClient titleClient; @@ -35,35 +35,29 @@ public LLMController(ChatClient titleClient, ChatClient chatClient, UserConversa this.springAiChatMemoryService = springAiChatMemoryService; } - @PostMapping(value = "/{conversationId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux streamGeneration(@PathVariable String conversationId, @RequestBody LLMRequest request) { + @GetMapping("/") + public List getAllUserConversations() { String userId = extractUserIdFromHeader(); - String userInput = wrapUserInputWithConversationContext(request.userInput()); - boolean isNewConversation = conversationId.equals("new"); - String conversationTitle = isNewConversation - ? titleClient.prompt().user(userInput).call().content() - : null; + List conversations = userConversationService.getAllConversationsForUser(userId); - UserConversationModel conversation = - isNewConversation - ? userConversationService.createNewConversationForUser(userId, conversationTitle) - : userConversationService.getUserConversation(conversationId, userId); + return conversations.stream() + .map(conv -> new ConversationDTO(conv.getConversationId(), conv.getTitle())) + .toList(); + } + @GetMapping("/{conversationId}") + public ConversationDTO getSingleConversation(@PathVariable String conversationId) { + String userId = extractUserIdFromHeader(); + UserConversationModel conversation = userConversationService.getUserConversation(conversationId, userId); if (conversation == null) { throw new RuntimeException("Conversation not found for user. Mismatched user or conversation ID."); } - return chatClient.prompt() - .user(userSpec -> userSpec.text(userInput)) - .advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, conversation.getConversationId())) - .stream() - .chatResponse() - .map(chatResponse -> new ChatStreamResponseDTO(conversation.getConversationId(), chatResponse, Instant.now().toEpochMilli())); + return new ConversationDTO(conversation.getConversationId(), conversation.getTitle()); } - // TODO: Add pagination to this endpoint - @GetMapping("/history/{conversationId}") + @GetMapping("/{conversationId}/messages") public List getConversationHistory(@PathVariable String conversationId) { String userId = extractUserIdFromHeader(); UserConversationModel conversation = userConversationService.getUserConversation(conversationId, userId); @@ -77,32 +71,36 @@ public List getConversationHistory(@PathVariable String conversation .toList(); } - // Issue with open-api generator which generates ENUM, and values are the sames - @DeleteMapping("/delete/{conversationId}") + @DeleteMapping("/{conversationId}") public void deleteConversation(@PathVariable String conversationId) { String userId = extractUserIdFromHeader(); springAiChatMemoryService.deleteAllByConversationId(conversationId); userConversationService.deleteUserConversation(conversationId, userId); } - @GetMapping("/single/{conversationId}") - public ConversationDTO getSingleConversation(@PathVariable String conversationId) { + @PostMapping(value = "/{conversationId}/messages", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux streamGeneration(@PathVariable String conversationId, @RequestBody LLMRequest request) { String userId = extractUserIdFromHeader(); - UserConversationModel conversation = userConversationService.getUserConversation(conversationId, userId); + String userInput = wrapUserInputWithConversationContext(request.userInput()); + boolean isNewConversation = conversationId.equals("new"); + String conversationTitle = isNewConversation + ? titleClient.prompt().user(userInput).call().content() + : null; + + UserConversationModel conversation = + isNewConversation + ? userConversationService.createNewConversationForUser(userId, conversationTitle) + : userConversationService.getUserConversation(conversationId, userId); + if (conversation == null) { throw new RuntimeException("Conversation not found for user. Mismatched user or conversation ID."); } - return new ConversationDTO(conversation.getConversationId(), conversation.getTitle()); - } - - @GetMapping("/all") - public List getAllUserConversations() { - String userId = extractUserIdFromHeader(); - List conversations = userConversationService.getAllConversationsForUser(userId); - - return conversations.stream() - .map(conv -> new ConversationDTO(conv.getConversationId(), conv.getTitle())) - .toList(); + return chatClient.prompt() + .user(userSpec -> userSpec.text(userInput)) + .advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, conversation.getConversationId())) + .stream() + .chatResponse() + .map(chatResponse -> new ChatStreamResponseDTO(conversation.getConversationId(), chatResponse, Instant.now().toEpochMilli())); } } diff --git a/src/main/java/com/example/spring/app/stripe/PaymentController.java b/src/main/java/com/example/spring/app/stripe/PaymentController.java index 4049dc7..f1497b8 100644 --- a/src/main/java/com/example/spring/app/stripe/PaymentController.java +++ b/src/main/java/com/example/spring/app/stripe/PaymentController.java @@ -24,7 +24,7 @@ @RestController @CrossOrigin -@RequestMapping("/v1/stripe") +@RequestMapping("/v1/payments") public class PaymentController { @Autowired diff --git a/src/main/java/com/example/spring/app/user/UserController.java b/src/main/java/com/example/spring/app/user/UserController.java index 861241d..857716f 100644 --- a/src/main/java/com/example/spring/app/user/UserController.java +++ b/src/main/java/com/example/spring/app/user/UserController.java @@ -9,14 +9,14 @@ @CrossOrigin @RestController -@RequestMapping("/v1/user") +@RequestMapping("/v1/users") public class UserController { @Autowired UserResource userResource; - @GetMapping("/get-user") + @GetMapping("/me") public UserDTO getUser() { String userId = extractUserIdFromHeader(); return userResource.getUserById(userId); @@ -29,7 +29,7 @@ public Response completeOnboarding() { return Response.ok().build(); } - @PutMapping("/update-user") + @PutMapping("/me") public Response updateUser(@RequestParam UserDTO user) { String id = extractUserIdFromHeader(); UserDTO existingUser = userResource.getUserById(id); diff --git a/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java deleted file mode 100644 index 956ad9d..0000000 --- a/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.spring.app.userCompanyStatus; - -import com.example.spring.app.company.enums.Status; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import static com.example.spring.common.utils.JwtUtil.extractUserIdFromHeader; - -@RestController -@RequestMapping("/v1/companies-status") -public class UserCompanyStatusController { - - @Autowired - private UserCompanyStatusService userCompanyStatusService; - - @PostMapping("/update-status") - public ResponseEntity updateStatus(@RequestParam Integer companyId, - @RequestParam Status status) { - String userId = extractUserIdFromHeader(); - UserCompanyStatusModel updated = userCompanyStatusService.updateCompanyStatus(userId, companyId, status); - - if (updated == null) { - return ResponseEntity.noContent().build(); // deleted or no-op - } - - return ResponseEntity.ok(updated); - } -} diff --git a/src/main/java/com/example/spring/app/webhook/WebHookController.java b/src/main/java/com/example/spring/app/webhook/WebHookController.java index 02c41e2..42b3a17 100644 --- a/src/main/java/com/example/spring/app/webhook/WebHookController.java +++ b/src/main/java/com/example/spring/app/webhook/WebHookController.java @@ -24,7 +24,7 @@ @RestController @CrossOrigin -@RequestMapping("/v1/stripe") +@RequestMapping("/webhook") public class WebHookController { @Autowired @@ -39,7 +39,7 @@ public class WebHookController { @Value("${STRIPE_WEBHOOK_SECRET}") private String STRIPE_WEBHOOK_SECRET; - @PostMapping("/webhook") + @PostMapping("/stripe") public ResponseEntity handleStripeWebhook(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) throws StripeException { Event event; diff --git a/src/main/java/com/example/spring/security/CorsConfig.java b/src/main/java/com/example/spring/security/CorsConfig.java index 9c96fa6..821876d 100644 --- a/src/main/java/com/example/spring/security/CorsConfig.java +++ b/src/main/java/com/example/spring/security/CorsConfig.java @@ -26,23 +26,12 @@ CorsConfigurationSource corsConfigurationSource() { "https://localhost", "http://localhost/**", "https://stripe.com/**", - "https://checkout.stripe.com/**", - "http://3.18.12.63", - "http://3.130.192.231", - "http://13.235.14.237", - "http://13.235.122.149", - "http://18.211.135.69", - "http://35.154.171.200", - "http://52.15.183.38", - "http://54.88.130.119", - "http://54.88.130.237", - "http://54.187.174.169", - "http://54.187.205.235", - "http://54.187.216.72" + "https://checkout.stripe.com/**" )); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.addAllowedHeader("*"); + // Apply CORS configuration to all paths UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; diff --git a/src/main/java/com/example/spring/security/JwtAuthenticationFilter.java b/src/main/java/com/example/spring/security/JwtAuthenticationFilter.java index c081c48..3d41577 100644 --- a/src/main/java/com/example/spring/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/example/spring/security/JwtAuthenticationFilter.java @@ -7,6 +7,7 @@ import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.checkerframework.checker.nullness.qual.NonNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -28,7 +29,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { String token = parseTokenFromHeader(); diff --git a/src/main/java/com/example/spring/security/SecurityConfig.java b/src/main/java/com/example/spring/security/SecurityConfig.java index 95623ab..15fce96 100644 --- a/src/main/java/com/example/spring/security/SecurityConfig.java +++ b/src/main/java/com/example/spring/security/SecurityConfig.java @@ -20,28 +20,25 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> { // Public endpoints are enabled through the OAuth proxy with allowed endpoints - // TOOD: Set a limit on the endpoint to avoid spamming + // TODO: Set a limit on the endpoint to avoid spamming with resilience4j.ratelimiter // Landing page - authorize.requestMatchers(HttpMethod.GET, "/v1/company/landing-filter").permitAll(); + authorize.requestMatchers(HttpMethod.GET, "/v1/companies/filter").permitAll(); // AutoComplete - authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/industrySector").permitAll(); - authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/industrySectors").permitAll(); - authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/city").permitAll(); - authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/cities").permitAll(); + authorize.requestMatchers(HttpMethod.POST, "/v1/autocomplete/industry-sectors/**").permitAll(); + authorize.requestMatchers(HttpMethod.POST, "/v1/autocomplete/cities/**").permitAll(); // Env - authorize.requestMatchers(HttpMethod.GET, "/configuration").permitAll(); + authorize.requestMatchers(HttpMethod.GET, "/v1/configuration/").permitAll(); // Stripe - authorize.requestMatchers(HttpMethod.POST, "/v1/stripe/webhook").permitAll(); + authorize.requestMatchers(HttpMethod.POST, "/webhook/stripe").permitAll(); // Health check authorize.requestMatchers(HttpMethod.GET, "/actuator/health").permitAll(); // Private endpoints are protected by the JWT authentication filter // Company - authorize.requestMatchers("/v1/company/**").hasRole("verified"); - authorize.requestMatchers("/v1/companies-status/**").hasRole("verified"); + authorize.requestMatchers("/v1/companies/**").hasRole("verified"); // Leader - authorize.requestMatchers("/v1/leader/**").hasRole("verified"); + authorize.requestMatchers("/v1/leaders/**").hasRole("verified"); // Swagger + OpenAPI - only in dev // To access Swagger UI and OpenAPI documentation on Docker From aef439fe8e6621ff74dd35221e1d661e8152ada1 Mon Sep 17 00:00:00 2001 From: Matithieu Date: Sun, 4 Jan 2026 18:22:01 +0100 Subject: [PATCH 2/3] refactor: remove autowired annotations --- .../spring/app/company/CompanyController.java | 12 +++++----- .../spring/app/company/CompanyService.java | 8 ++++--- .../autocomplete/city/CityController.java | 13 +++++++---- .../autocomplete/city/CityService.java | 8 ++++--- .../IndustrySectorController.java | 13 +++++++---- .../industrySector/IndustrySectorService.java | 8 ++++--- .../legalForm/LegalFormController.java | 14 ++++++++---- .../legalForm/LegalFormService.java | 8 ++++--- .../autocomplete/region/RegionController.java | 13 +++++++---- .../autocomplete/region/RegionService.java | 8 ++++--- .../spring/app/leader/LeaderController.java | 8 ++++--- .../spring/app/leader/LeaderService.java | 8 ++++--- .../SpringAiChatMemoryService.java | 9 +++++--- .../UserConversationService.java | 9 +++++--- .../spring/app/stripe/PaymentController.java | 5 +++-- .../spring/app/user/UserController.java | 8 ++++--- .../example/spring/app/user/UserService.java | 13 ++++++----- .../UserCompanyStatusService.java | 8 ++++--- .../spring/app/webhook/WebHookController.java | 22 +++++++++---------- 19 files changed, 122 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/example/spring/app/company/CompanyController.java b/src/main/java/com/example/spring/app/company/CompanyController.java index c8af1fb..b05c5c5 100644 --- a/src/main/java/com/example/spring/app/company/CompanyController.java +++ b/src/main/java/com/example/spring/app/company/CompanyController.java @@ -7,7 +7,6 @@ import com.example.spring.app.company.enums.Status; import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel; import com.example.spring.app.userCompanyStatus.UserCompanyStatusService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -25,11 +24,14 @@ @RequestMapping("/v1/companies") public class CompanyController { - @Autowired - private CompanyService companyService; + private final CompanyService companyService; + private final UserCompanyStatusService userCompanyStatusService; - @Autowired - private UserCompanyStatusService userCompanyStatusService; + public CompanyController(CompanyService companyService, + UserCompanyStatusService userCompanyStatusService) { + this.companyService = companyService; + this.userCompanyStatusService = userCompanyStatusService; + } // Example: http://localhost:8080/api/v1/company/search-by-name?companyName=ExampleCompany&page=0 @GetMapping("/") diff --git a/src/main/java/com/example/spring/app/company/CompanyService.java b/src/main/java/com/example/spring/app/company/CompanyService.java index d280b42..11a8787 100644 --- a/src/main/java/com/example/spring/app/company/CompanyService.java +++ b/src/main/java/com/example/spring/app/company/CompanyService.java @@ -9,7 +9,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.resilience4j.ratelimiter.annotation.RateLimiter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; @@ -32,8 +31,11 @@ @Service public class CompanyService { - @Autowired - private CompanyRepository companyRepository; + private final CompanyRepository companyRepository; + + public CompanyService(CompanyRepository companyRepository) { + this.companyRepository = companyRepository; + } public CompanyModel getCompanyById(Integer id) { return companyRepository.findCompanyById(id); diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java index 69838a1..228c2e1 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java @@ -1,7 +1,9 @@ package com.example.spring.app.filters.autocomplete.city; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -9,8 +11,11 @@ @RequestMapping("/v1/autocomplete/cities") public class CityController { - @Autowired - private CityService cityService; + private final CityService cityService; + + public CityController(CityService cityService) { + this.cityService = cityService; + } @PostMapping("/ids") public List autocompleteCitiesByIds(@RequestBody List query) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java index 54b5e9e..55b6d50 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java @@ -1,6 +1,5 @@ package com.example.spring.app.filters.autocomplete.city; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -8,8 +7,11 @@ @Service public class CityService { - @Autowired - private CityRepository cityRepository; + private final CityRepository cityRepository; + + public CityService(CityRepository cityRepository) { + this.cityRepository = cityRepository; + } public List searchCitiesByNameContainingIgnoreCaseAny(List query) { if (query.size() > 1) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java index 0605d9e..834a9e8 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java @@ -1,7 +1,9 @@ package com.example.spring.app.filters.autocomplete.industrySector; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -9,8 +11,11 @@ @RequestMapping("/v1/autocomplete/industry-sectors") public class IndustrySectorController { - @Autowired - private IndustrySectorService industrySectorService; + private final IndustrySectorService industrySectorService; + + public IndustrySectorController(IndustrySectorService industrySectorService) { + this.industrySectorService = industrySectorService; + } @PostMapping("/ids") public List autocompleteIndustrySectorsByIds(@RequestBody List query) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java index 3cd3dc6..39fe086 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java @@ -1,6 +1,5 @@ package com.example.spring.app.filters.autocomplete.industrySector; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -8,8 +7,11 @@ @Service public class IndustrySectorService { - @Autowired - private IndustrySectorRepository industrySectorRepository; + private final IndustrySectorRepository industrySectorRepository; + + public IndustrySectorService(IndustrySectorRepository repository) { + this.industrySectorRepository = repository; + } public List searchIndustrySectorsByNameContainingIgnoreCase(List query) { if (query.size() > 1) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java index dfb5bc0..bf06741 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java @@ -1,15 +1,21 @@ package com.example.spring.app.filters.autocomplete.legalForm; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/v1/autocomplete/legal-forms") public class LegalFormController { - @Autowired - private LegalFormService legalFormService; + + private final LegalFormService legalFormService; + + public LegalFormController(LegalFormService legalFormService) { + this.legalFormService = legalFormService; + } @PostMapping("/ids") public List autocompleteLegalFormsByIds(@RequestBody List query) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java index fa21b9b..c2426e8 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java @@ -1,6 +1,5 @@ package com.example.spring.app.filters.autocomplete.legalForm; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -8,8 +7,11 @@ @Service public class LegalFormService { - @Autowired - private LegalFormRepository legalFormRepository; + private final LegalFormRepository legalFormRepository; + + public LegalFormService(LegalFormRepository legalFormRepository) { + this.legalFormRepository = legalFormRepository; + } public List searchLegalFormsByNamesContainingIgnoreCase(List query) { if (query.size() > 1) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java index 9d7b612..7c3e69c 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java @@ -1,7 +1,9 @@ package com.example.spring.app.filters.autocomplete.region; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -9,8 +11,11 @@ @RequestMapping("/v1/autocomplete/regions") public class RegionController { - @Autowired - private RegionService regionService; + private final RegionService regionService; + + public RegionController(RegionService regionService) { + this.regionService = regionService; + } @PostMapping("/ids") public List autocompleteRegionsByIds(@RequestBody List query) { diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java index 66d060f..cc32908 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java @@ -1,6 +1,5 @@ package com.example.spring.app.filters.autocomplete.region; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -8,8 +7,11 @@ @Service public class RegionService { - @Autowired - private RegionRepository regionRepository; + private final RegionRepository regionRepository; + + public RegionService(RegionRepository regionRepository) { + this.regionRepository = regionRepository; + } public List searchRegionsByNamesContainingIgnoreCase(List query) { if (query.size() > 1) { diff --git a/src/main/java/com/example/spring/app/leader/LeaderController.java b/src/main/java/com/example/spring/app/leader/LeaderController.java index c9bfdf4..9fc74eb 100644 --- a/src/main/java/com/example/spring/app/leader/LeaderController.java +++ b/src/main/java/com/example/spring/app/leader/LeaderController.java @@ -1,6 +1,5 @@ package com.example.spring.app.leader; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -14,8 +13,11 @@ @RequestMapping("/v1/leaders") public class LeaderController { - @Autowired - private LeaderService leaderService; + private final LeaderService leaderService; + + public LeaderController(LeaderService leaderService) { + this.leaderService = leaderService; + } // Example: http://localhost:8080/api/v1/leader/get-by-id/123 @GetMapping("/{id}") diff --git a/src/main/java/com/example/spring/app/leader/LeaderService.java b/src/main/java/com/example/spring/app/leader/LeaderService.java index 836d136..645cdf4 100644 --- a/src/main/java/com/example/spring/app/leader/LeaderService.java +++ b/src/main/java/com/example/spring/app/leader/LeaderService.java @@ -1,6 +1,5 @@ package com.example.spring.app.leader; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -11,8 +10,11 @@ @Service public class LeaderService { - @Autowired - private LeaderRepository leaderRepository; + private final LeaderRepository leaderRepository; + + public LeaderService(LeaderRepository leaderRepository) { + this.leaderRepository = leaderRepository; + } public LeaderModel getLeaderById(Integer id) { return leaderRepository.findLeaderById(id); diff --git a/src/main/java/com/example/spring/app/llm/springAiChatMemory/SpringAiChatMemoryService.java b/src/main/java/com/example/spring/app/llm/springAiChatMemory/SpringAiChatMemoryService.java index 952e482..16f7c30 100644 --- a/src/main/java/com/example/spring/app/llm/springAiChatMemory/SpringAiChatMemoryService.java +++ b/src/main/java/com/example/spring/app/llm/springAiChatMemory/SpringAiChatMemoryService.java @@ -1,15 +1,18 @@ package com.example.spring.app.llm.springAiChatMemory; import jakarta.transaction.Transactional; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class SpringAiChatMemoryService { - @Autowired - private SpringAiChatMemoryRepository userConversationRepository; + + private final SpringAiChatMemoryRepository userConversationRepository; + + public SpringAiChatMemoryService(SpringAiChatMemoryRepository userConversationRepository) { + this.userConversationRepository = userConversationRepository; + } public List findAllByConversationId(String conversationId) { return userConversationRepository.findAllByConversationId(conversationId); diff --git a/src/main/java/com/example/spring/app/llm/userConversation/UserConversationService.java b/src/main/java/com/example/spring/app/llm/userConversation/UserConversationService.java index 87de83b..80f71b5 100644 --- a/src/main/java/com/example/spring/app/llm/userConversation/UserConversationService.java +++ b/src/main/java/com/example/spring/app/llm/userConversation/UserConversationService.java @@ -1,6 +1,5 @@ package com.example.spring.app.llm.userConversation; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -10,8 +9,12 @@ @Service public class UserConversationService { - @Autowired - private UserConversationRepository userConversationRepository; + + private final UserConversationRepository userConversationRepository; + + public UserConversationService(UserConversationRepository userConversationRepository) { + this.userConversationRepository = userConversationRepository; + } public UserConversationModel getUserConversation(String conversationId, String userId) { return userConversationRepository.findByConversationIdAndUserId(conversationId, userId); diff --git a/src/main/java/com/example/spring/app/stripe/PaymentController.java b/src/main/java/com/example/spring/app/stripe/PaymentController.java index f1497b8..3594179 100644 --- a/src/main/java/com/example/spring/app/stripe/PaymentController.java +++ b/src/main/java/com/example/spring/app/stripe/PaymentController.java @@ -1,13 +1,12 @@ package com.example.spring.app.stripe; import com.example.spring.app.user.UserDTO; -import com.example.spring.core.keycloakClient.UserResource; import com.example.spring.common.utils.LogUtil; +import com.example.spring.core.keycloakClient.UserResource; import com.stripe.Stripe; import com.stripe.exception.StripeException; import com.stripe.model.Customer; import com.stripe.model.checkout.Session; -import com.stripe.net.RequestOptions; import com.stripe.param.checkout.SessionCreateParams; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -124,9 +123,11 @@ public ResponseEntity newSubscriptionWithTrial(@RequestHeader("X-priceId ); } + /* RequestOptions requestOptions = RequestOptions.builder() .setIdempotencyKey(user.getId()) .build(); + */ Session session = Session.create(paramsBuilder.build()); diff --git a/src/main/java/com/example/spring/app/user/UserController.java b/src/main/java/com/example/spring/app/user/UserController.java index 857716f..06a5e2b 100644 --- a/src/main/java/com/example/spring/app/user/UserController.java +++ b/src/main/java/com/example/spring/app/user/UserController.java @@ -2,7 +2,6 @@ import com.example.spring.core.keycloakClient.UserResource; import jakarta.ws.rs.core.Response; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import static com.example.spring.common.utils.JwtUtil.extractUserIdFromHeader; @@ -13,8 +12,11 @@ public class UserController { - @Autowired - UserResource userResource; + private final UserResource userResource; + + public UserController(UserResource userResource) { + this.userResource = userResource; + } @GetMapping("/me") public UserDTO getUser() { diff --git a/src/main/java/com/example/spring/app/user/UserService.java b/src/main/java/com/example/spring/app/user/UserService.java index 8fc4427..a83407f 100644 --- a/src/main/java/com/example/spring/app/user/UserService.java +++ b/src/main/java/com/example/spring/app/user/UserService.java @@ -1,10 +1,9 @@ package com.example.spring.app.user; +import com.example.spring.common.utils.LogUtil; import com.example.spring.core.keycloakClient.UserResource; import com.example.spring.core.userQuota.UserQuotaModel; import com.example.spring.core.userQuota.UserQuotaRepository; -import com.example.spring.common.utils.LogUtil; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -20,11 +19,13 @@ @Service public class UserService { - @Autowired - private UserResource userResource; + private final UserResource userResource; + private final UserQuotaRepository userQuotaRepository; - @Autowired - private UserQuotaRepository userQuotaRepository; + public UserService(UserQuotaRepository userQuotaRepository, UserResource userResource) { + this.userQuotaRepository = userQuotaRepository; + this.userResource = userResource; + } @Scheduled(fixedRate = 1000 * 60 * 15) // 15 minutes @Transactional diff --git a/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java index 506b6e1..7958dbd 100644 --- a/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java +++ b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java @@ -1,7 +1,6 @@ package com.example.spring.app.userCompanyStatus; import com.example.spring.app.company.enums.Status; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -9,8 +8,11 @@ @Service public class UserCompanyStatusService { - @Autowired - private UserCompanyStatusRepository userCompanyStatusRepository; + private final UserCompanyStatusRepository userCompanyStatusRepository; + + public UserCompanyStatusService(UserCompanyStatusRepository userCompanyStatusRepository) { + this.userCompanyStatusRepository = userCompanyStatusRepository; + } public UserCompanyStatusModel getOneUserCompanyStatusByUserIdAndCompanyId(String userId, Integer companyId) { return userCompanyStatusRepository.findUserCompanyStatusByUserIdAndCompanyId(userId, companyId); diff --git a/src/main/java/com/example/spring/app/webhook/WebHookController.java b/src/main/java/com/example/spring/app/webhook/WebHookController.java index 42b3a17..c222250 100644 --- a/src/main/java/com/example/spring/app/webhook/WebHookController.java +++ b/src/main/java/com/example/spring/app/webhook/WebHookController.java @@ -1,17 +1,16 @@ package com.example.spring.app.webhook; -import com.example.spring.common.enums.TierUser; import com.example.spring.app.user.UserDTO; +import com.example.spring.common.enums.TierUser; +import com.example.spring.common.utils.LogUtil; import com.example.spring.core.keycloakClient.RoleResource; import com.example.spring.core.keycloakClient.UserResource; import com.example.spring.core.userQuota.UserQuotaService; -import com.example.spring.common.utils.LogUtil; import com.google.gson.JsonSyntaxException; import com.stripe.exception.SignatureVerificationException; import com.stripe.exception.StripeException; import com.stripe.model.*; import com.stripe.net.Webhook; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,18 +26,19 @@ @RequestMapping("/webhook") public class WebHookController { - @Autowired - private UserResource userResource; - - @Autowired - RoleResource roleResource; - - @Autowired - UserQuotaService userQuotaService; + private final UserResource userResource; + private final RoleResource roleResource; + private final UserQuotaService userQuotaService; @Value("${STRIPE_WEBHOOK_SECRET}") private String STRIPE_WEBHOOK_SECRET; + public WebHookController(UserResource userResource, RoleResource roleResource, UserQuotaService userQuotaService) { + this.userResource = userResource; + this.roleResource = roleResource; + this.userQuotaService = userQuotaService; + } + @PostMapping("/stripe") public ResponseEntity handleStripeWebhook(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) throws StripeException { Event event; From d359b8bbfcbe31484a3469e66ea52d7db8ff86b8 Mon Sep 17 00:00:00 2001 From: Matithieu Date: Sun, 4 Jan 2026 18:24:13 +0100 Subject: [PATCH 3/3] fix: some warnings --- .../spring/app/company/CompanyService.java | 25 ++----------------- .../IndustrySectorRepository.java | 1 - .../legalForm/LegalFormRepository.java | 1 - 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/example/spring/app/company/CompanyService.java b/src/main/java/com/example/spring/app/company/CompanyService.java index 11a8787..e8df74b 100644 --- a/src/main/java/com/example/spring/app/company/CompanyService.java +++ b/src/main/java/com/example/spring/app/company/CompanyService.java @@ -24,7 +24,6 @@ import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.util.List; -import java.util.Map; import static com.example.spring.app.company.CompanyUtil.setIfNotEmpty; @@ -66,22 +65,6 @@ public Page findCompaniesByFilters(List regionNames, List< return companyRepository.findAll(specification, pageable); } - @Cacheable(value = "companyCounts", key = "#root.methodName + #regionNames + #cityNames + #industrySectorNames + #legalFormNames + #numberOfEmployeeFilter + #socials + #contacts") - public long countCompaniesByFilters(List regionNames, List cityNames, List industrySectorNames, List legalFormNames, - NumberOfEmployeeFilterDTO numberOfEmployeeFilter, SocialMediaDTO socials, ContactDTO contacts) { - - Specification specification = Specification.where(CompanySpecification.regionsIn(regionNames)) - .and(CompanySpecification.citiesIn(cityNames)) - .and(CompanySpecification.industrySectorsIn(industrySectorNames)) - .and(CompanySpecification.legalFormsIn(legalFormNames)) - .and(CompanySpecification.employeeComparator(numberOfEmployeeFilter)) - .and(CompanySpecification.socialMediaNotNull(socials)) - .and(CompanySpecification.contactInfoNotNull(contacts)); - - // Run a custom count query that only calculates the total number of companies matching the filters - return companyRepository.count(specification); - } - public Page findRandomUnseenCompanies(String userId, Pageable pageable) { return companyRepository.findRandomUnseenCompanies(userId, pageable); } @@ -122,7 +105,8 @@ public CompanyModel scrapCompany(CompanyModel company) { setIfNotEmpty(jsonNode, "youtube", companyScrapped::setYoutube); setIfNotEmpty(jsonNode, "email", companyScrapped::setEmail); setIfNotEmpty(jsonNode, "scrapingDate", (value) -> companyScrapped.setScrapingDate(LocalDate.parse(value))); - setIfNotEmpty(jsonNode, "reviews", (value) -> companyScrapped.setReviews(new ObjectMapper().convertValue(jsonNode.get("reviews"), new TypeReference>() {}))); + setIfNotEmpty(jsonNode, "reviews", (value) -> companyScrapped.setReviews(new ObjectMapper().convertValue(jsonNode.get("reviews"), new TypeReference<>() { + }))); setIfNotEmpty(jsonNode, "schedule", companyScrapped::setSchedule); return companyScrapped; @@ -137,9 +121,4 @@ public CompanyModel scrapCompany(CompanyModel company) { public void saveCompany(CompanyModel company) { companyRepository.save(company); } - - @CacheEvict(value = "companyCounts", allEntries = true) - public void deleteCompany(Integer id) { - companyRepository.deleteById(id); - } } \ No newline at end of file diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java index d959e09..c3a4b93 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java @@ -2,7 +2,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import java.util.List; diff --git a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java index 0a9cc29..dbe8397 100644 --- a/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java @@ -2,7 +2,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import java.util.List;