diff --git a/.gitignore b/.gitignore index 55608a8..dffd48a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ bin/ out/ !**/src/main/**/out/ !**/src/test/**/out/ +**/logs/** ### NetBeans ### /nbproject/private/ diff --git a/src/main/java/com/example/spring/controller/CompanyController.java b/src/main/java/com/example/spring/app/company/CompanyController.java similarity index 80% rename from src/main/java/com/example/spring/controller/CompanyController.java rename to src/main/java/com/example/spring/app/company/CompanyController.java index 17ec807..6ffde36 100644 --- a/src/main/java/com/example/spring/controller/CompanyController.java +++ b/src/main/java/com/example/spring/app/company/CompanyController.java @@ -1,14 +1,11 @@ -package com.example.spring.controller; - -import com.example.spring.dto.CompanyDetails; -import com.example.spring.dto.CompanyDtoWithStatusDTO; -import com.example.spring.dto.CompanyFilterRequest; -import com.example.spring.dto.company.CompanyDTO; -import com.example.spring.model.Company; -import com.example.spring.model.UserCompanyStatus; -import com.example.spring.service.CompanyService; -import com.example.spring.service.UserCompanyStatusService; -import com.example.spring.utils.CompanyUtil; +package com.example.spring.app.company; + +import com.example.spring.app.company.dto.CompanyDTO; +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.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; @@ -38,7 +35,7 @@ public class CompanyController { public CompanyDtoWithStatusDTO getCompanyById(@PathVariable("id") Integer id) { String userId = parseUserIdFromHeader(); CompanyDTO companyDto = companyService.getCompanyById(id).toCompanyDTO(); - UserCompanyStatus userCompanyStatus = userCompanyStatusService + UserCompanyStatusModel userCompanyStatus = userCompanyStatusService .getOneUserCompanyStatusByUserIdAndCompanyId(userId, id); return CompanyUtil.fillCompanyDtoWithStatusDto(companyDto, userCompanyStatus); @@ -50,12 +47,12 @@ public Page getCompaniesSeenByUser(@RequestParam(defaul @RequestParam(defaultValue = "10") int size) { Pageable pageable = PageRequest.of(page, size); String userId = parseUserIdFromHeader(); - Page companies = companyService.getCompaniesSeenByUser(userId, pageable); + Page companies = companyService.getCompaniesSeenByUser(userId, pageable); - List userCompanyStatuses = userCompanyStatusService + List userCompanyStatuses = userCompanyStatusService .getMultipleUserCompanyStatusByUserIdAndCompanyIds(userId, companies.getContent() .stream() - .map(Company::getId) + .map(CompanyModel::getId) .toList()); return CompanyUtil.fillPaginationCompanyDtoWithStatusDto(companies, userCompanyStatuses); @@ -77,7 +74,7 @@ public Page getCompaniesByFilters( String userId = parseUserIdFromHeader(); Pageable pageable = PageRequest.of(filterRequest.getPage(), filterRequest.getSize()); - Page companies = companyService.findCompaniesByFilters( + Page companies = companyService.findCompaniesByFilters( filterRequest.getRegionNames(), filterRequest.getCityNames(), filterRequest.getIndustrySectorNames(), @@ -90,10 +87,10 @@ public Page getCompaniesByFilters( pageable ); - List userCompanyStatuses = userCompanyStatusService + List userCompanyStatuses = userCompanyStatusService .getMultipleUserCompanyStatusByUserIdAndCompanyIds(userId, companies.getContent() .stream() - .map(Company::getId) + .map(CompanyModel::getId) .toList()); return CompanyUtil.fillPaginationCompanyDtoWithStatusDto(companies, userCompanyStatuses); @@ -105,11 +102,11 @@ public Page getRandomUnseenCompanies(@RequestParam(defa @RequestParam(defaultValue = "10") int size) { Pageable pageable = PageRequest.of(page, size); String userId = parseUserIdFromHeader(); - Page companies = companyService.findRandomUnseenCompanies(userId, pageable); - List userCompanyStatuses = userCompanyStatusService + Page companies = companyService.findRandomUnseenCompanies(userId, pageable); + List userCompanyStatuses = userCompanyStatusService .getMultipleUserCompanyStatusByUserIdAndCompanyIds(userId, companies.getContent() .stream() - .map(Company::getId) + .map(CompanyModel::getId) .toList()); return CompanyUtil.fillPaginationCompanyDtoWithStatusDto(companies, userCompanyStatuses); @@ -119,7 +116,7 @@ public Page getRandomUnseenCompanies(@RequestParam(defa // Example: http://localhost:8080/api/v1/company/scrap?companyId=1 @GetMapping("/scrap") public CompanyDTO scrapCompany(@RequestParam Integer companyId) { - Company company = companyService.getCompanyById(companyId); + CompanyModel company = companyService.getCompanyById(companyId); if (company == null) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Company not found"); } @@ -131,7 +128,7 @@ public CompanyDTO scrapCompany(@RequestParam Integer companyId) { throw new ResponseStatusException(HttpStatus.TOO_EARLY, "The company was scrapped less than 1 day ago"); } - Company companyScraped = companyService.scrapCompany(company); + CompanyModel companyScraped = companyService.scrapCompany(company); company.updateFrom(companyScraped); companyService.saveCompany(company); @@ -153,7 +150,7 @@ public Page getCompaniesOnLandingByFilters( Pageable pageable = PageRequest.of(0, 10); // First try to get companies that the user has not seen yet - Page companiesPage = companyService.findCompaniesByFilters(null, cityNames, industrySectorNames, null, + Page companiesPage = companyService.findCompaniesByFilters(null, cityNames, industrySectorNames, null, null, null, null, false, null, pageable); // If there are not enough unseen companies, get seen companies to fill the page @@ -164,8 +161,8 @@ public Page getCompaniesOnLandingByFilters( return new PageImpl<>( companiesPage.getContent().stream() - .peek(Company::obstructCompany) - .map(Company::toCompanyDTO) + .peek(CompanyModel::obstructCompany) + .map(CompanyModel::toCompanyDTO) .collect(Collectors.toList()), companiesPage.getPageable(), companiesPage.getTotalElements() diff --git a/src/main/java/com/example/spring/model/Company.java b/src/main/java/com/example/spring/app/company/CompanyModel.java similarity index 93% rename from src/main/java/com/example/spring/model/Company.java rename to src/main/java/com/example/spring/app/company/CompanyModel.java index cfcd63f..8b3fc2b 100644 --- a/src/main/java/com/example/spring/model/Company.java +++ b/src/main/java/com/example/spring/app/company/CompanyModel.java @@ -1,6 +1,8 @@ -package com.example.spring.model; +package com.example.spring.app.company; -import com.example.spring.dto.company.CompanyDTO; +import com.example.spring.app.company.dto.CompanyDTO; +import com.example.spring.app.company.objects.ContactDTO; +import com.example.spring.app.company.objects.SocialMediaDTO; import io.hypersistence.utils.hibernate.type.json.JsonBinaryType; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -13,8 +15,8 @@ import java.time.LocalDate; import java.util.Map; -import static com.example.spring.mapper.FinancialPeriodMapper.toFinancialPeriodDTOList; -import static com.example.spring.utils.CompanyUtil.maskData; +import static com.example.spring.app.company.financial.FinancialPeriodMapper.toFinancialPeriodDTOList; +import static com.example.spring.app.company.CompanyUtil.maskData; @Builder @NoArgsConstructor @@ -22,7 +24,7 @@ @Data @Entity @Table(name = "companies") -public class Company { +public class CompanyModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @@ -161,7 +163,7 @@ public class Company { private Integer numberOfEmployee; private String companyCategory; - public void updateFrom(Company other) { + public void updateFrom(CompanyModel other) { this.phoneNumber = other.getPhoneNumber(); this.website = other.getWebsite(); this.instagram = other.getInstagram(); @@ -207,7 +209,7 @@ public CompanyDTO toCompanyDTO() { .reviews(this.getReviews()) .schedule(this.getSchedule()) .socialMedia( - com.example.spring.dto.company.SocialMedia.builder() + SocialMediaDTO.builder() .instagram(this.getInstagram()) .facebook(this.getFacebook()) .twitter(this.getTwitter()) @@ -216,7 +218,7 @@ public CompanyDTO toCompanyDTO() { .build() ) .contact( - com.example.spring.dto.company.Contact.builder() + ContactDTO.builder() .email(this.getEmail()) .phoneNumber(this.getPhoneNumber()) .website(this.getWebsite()) diff --git a/src/main/java/com/example/spring/repository/CompanyRepository.java b/src/main/java/com/example/spring/app/company/CompanyRepository.java similarity index 59% rename from src/main/java/com/example/spring/repository/CompanyRepository.java rename to src/main/java/com/example/spring/app/company/CompanyRepository.java index ba74050..f63176d 100644 --- a/src/main/java/com/example/spring/repository/CompanyRepository.java +++ b/src/main/java/com/example/spring/app/company/CompanyRepository.java @@ -1,7 +1,6 @@ -package com.example.spring.repository; +package com.example.spring.app.company; -import com.example.spring.dto.CompanyDetails; -import com.example.spring.model.Company; +import com.example.spring.app.company.dto.CompanyDetails; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; @@ -10,27 +9,27 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface CompanyRepository extends JpaRepository, JpaSpecificationExecutor { +public interface CompanyRepository extends JpaRepository, JpaSpecificationExecutor { - Company findCompanyById(Integer id); + CompanyModel findCompanyById(Integer id); - @Query("SELECT new com.example.spring.dto.CompanyDetails(c.id, c.companyName, c.industrySector, c.city, c.region) " + - "FROM Company c WHERE LOWER(c.companyName) LIKE LOWER(CONCAT(:companyName, '%'))") + @Query("SELECT new com.example.spring.app.company.dto.CompanyDetails(c.id, c.companyName, c.industrySector, c.city, c.region) " + + "FROM CompanyModel c WHERE LOWER(c.companyName) LIKE LOWER(CONCAT(:companyName, '%'))") Page findCompanyDetailsByCompanyName(@Param("companyName") String companyName, Pageable pageable); // Specification - Page findAll(Specification specification, Pageable pageable); + Page findAll(Specification specification, Pageable pageable); @Query(value = "SELECT c.* FROM companies c " + "WHERE c.phone_number IS NOT NULL AND NOT " + "EXISTS (SELECT 1 FROM user_company_status ucs " + "WHERE ucs.company_id = c.id AND ucs.user_id = :userId)", nativeQuery = true) - Page findRandomUnseenCompanies(@Param("userId") String userId, Pageable pageable); + Page findRandomUnseenCompanies(@Param("userId") String userId, Pageable pageable); @Query(value = "SELECT c.* FROM companies c " + "INNER JOIN user_company_status ucs ON c.id = ucs.company_id " + "WHERE ucs.user_id = :userId", nativeQuery = true) - Page findCompaniesSeenByUser(@Param("userId") String userId, Pageable pageable); + Page findCompaniesSeenByUser(@Param("userId") String userId, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/com/example/spring/service/CompanyService.java b/src/main/java/com/example/spring/app/company/CompanyService.java similarity index 78% rename from src/main/java/com/example/spring/service/CompanyService.java rename to src/main/java/com/example/spring/app/company/CompanyService.java index f3a3666..55482ca 100644 --- a/src/main/java/com/example/spring/service/CompanyService.java +++ b/src/main/java/com/example/spring/app/company/CompanyService.java @@ -1,12 +1,9 @@ -package com.example.spring.service; - -import com.example.spring.dto.CompanyDetails; -import com.example.spring.dto.NumberOfEmployeeFilter; -import com.example.spring.dto.company.Contact; -import com.example.spring.dto.company.SocialMedia; -import com.example.spring.model.Company; -import com.example.spring.repository.CompanyRepository; -import com.example.spring.specification.CompanySpecification; +package com.example.spring.app.company; + +import com.example.spring.app.company.dto.CompanyDetails; +import com.example.spring.app.company.dto.NumberOfEmployeeFilterDTO; +import com.example.spring.app.company.objects.ContactDTO; +import com.example.spring.app.company.objects.SocialMediaDTO; import com.example.spring.utils.LogUtil; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -30,7 +27,7 @@ import java.util.List; import java.util.Map; -import static com.example.spring.utils.CompanyUtil.setIfNotEmpty; +import static com.example.spring.app.company.CompanyUtil.setIfNotEmpty; @Service public class CompanyService { @@ -38,11 +35,11 @@ public class CompanyService { @Autowired private CompanyRepository companyRepository; - public Company getCompanyById(Integer id) { + public CompanyModel getCompanyById(Integer id) { return companyRepository.findCompanyById(id); } - public Page getCompaniesSeenByUser(String userId, Pageable pageable) { + public Page getCompaniesSeenByUser(String userId, Pageable pageable) { return companyRepository.findCompaniesSeenByUser(userId, pageable); } @@ -51,11 +48,11 @@ public Page searchCompanies(String companyName, Pageable pageabl return companyRepository.findCompanyDetailsByCompanyName(companyName, pageable); } - public Page findCompaniesByFilters(List regionNames, List cityNames, List industrySectorNames, List legalFormNames, - NumberOfEmployeeFilter numberOfEmployeeFilter, SocialMedia socials, Contact contacts, Boolean isCompanySeen, - String userId, Pageable pageable) { + public Page findCompaniesByFilters(List regionNames, List cityNames, List industrySectorNames, List legalFormNames, + NumberOfEmployeeFilterDTO numberOfEmployeeFilter, SocialMediaDTO socials, ContactDTO contacts, Boolean isCompanySeen, + String userId, Pageable pageable) { - Specification specification = Specification.where(CompanySpecification.regionsIn(regionNames)) + Specification specification = Specification.where(CompanySpecification.regionsIn(regionNames)) .and(CompanySpecification.citiesIn(cityNames)) .and(CompanySpecification.industrySectorsIn(industrySectorNames)) .and(CompanySpecification.legalFormsIn(legalFormNames)) @@ -69,9 +66,9 @@ public Page findCompaniesByFilters(List regionNames, List regionNames, List cityNames, List industrySectorNames, List legalFormNames, - NumberOfEmployeeFilter numberOfEmployeeFilter, SocialMedia socials, Contact contacts) { + NumberOfEmployeeFilterDTO numberOfEmployeeFilter, SocialMediaDTO socials, ContactDTO contacts) { - Specification specification = Specification.where(CompanySpecification.regionsIn(regionNames)) + Specification specification = Specification.where(CompanySpecification.regionsIn(regionNames)) .and(CompanySpecification.citiesIn(cityNames)) .and(CompanySpecification.industrySectorsIn(industrySectorNames)) .and(CompanySpecification.legalFormsIn(legalFormNames)) @@ -83,12 +80,12 @@ public long countCompaniesByFilters(List regionNames, List cityN return companyRepository.count(specification); } - public Page findRandomUnseenCompanies(String userId, Pageable pageable) { + public Page findRandomUnseenCompanies(String userId, Pageable pageable) { return companyRepository.findRandomUnseenCompanies(userId, pageable); } @RateLimiter(name = "scrapService") - public Company scrapCompany(Company company) { + public CompanyModel scrapCompany(CompanyModel company) { try { HttpResponse response; try (HttpClient client = HttpClient.newHttpClient()) { @@ -110,7 +107,7 @@ public Company scrapCompany(Company company) { ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(response.body()); - Company companyScrapped = new Company(); + CompanyModel companyScrapped = new CompanyModel(); // TODO: Verify what's ifNotEmpty means. Currently it still updates the values even if they are empty in the response setIfNotEmpty(jsonNode, "companyName", companyScrapped::setCompanyName); @@ -135,7 +132,7 @@ public Company scrapCompany(Company company) { } @CacheEvict(value = "companyCounts", allEntries = true) - public void saveCompany(Company company) { + public void saveCompany(CompanyModel company) { companyRepository.save(company); } diff --git a/src/main/java/com/example/spring/specification/CompanySpecification.java b/src/main/java/com/example/spring/app/company/CompanySpecification.java similarity index 76% rename from src/main/java/com/example/spring/specification/CompanySpecification.java rename to src/main/java/com/example/spring/app/company/CompanySpecification.java index f3f1a65..ae6d496 100644 --- a/src/main/java/com/example/spring/specification/CompanySpecification.java +++ b/src/main/java/com/example/spring/app/company/CompanySpecification.java @@ -1,11 +1,10 @@ -package com.example.spring.specification; - -import com.example.spring.dto.NumberOfEmployeeFilter; -import com.example.spring.dto.company.Contact; -import com.example.spring.dto.company.SocialMedia; -import com.example.spring.enums.SignComparator; -import com.example.spring.model.Company; -import com.example.spring.model.UserCompanyStatus; +package com.example.spring.app.company; + +import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel; +import com.example.spring.app.company.dto.NumberOfEmployeeFilterDTO; +import com.example.spring.app.company.objects.ContactDTO; +import com.example.spring.app.company.objects.SocialMediaDTO; +import com.example.spring.app.filters.autocomplete.SignComparator; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Subquery; @@ -15,27 +14,27 @@ public class CompanySpecification { - public static Specification regionsIn(List regionNames) { + public static Specification regionsIn(List regionNames) { return (root, query, builder) -> (regionNames == null || regionNames.isEmpty()) ? null : root.get("region").in(regionNames); } - public static Specification citiesIn(List cityNames) { + public static Specification citiesIn(List cityNames) { return (root, query, builder) -> (cityNames == null || cityNames.isEmpty()) ? null : root.get("city").in(cityNames); } - public static Specification industrySectorsIn(List industrySectorNames) { + public static Specification industrySectorsIn(List industrySectorNames) { return (root, query, builder) -> (industrySectorNames == null || industrySectorNames.isEmpty()) ? null : root.get("industrySector").in(industrySectorNames); } - public static Specification legalFormsIn(List legalFormNames) { + public static Specification legalFormsIn(List legalFormNames) { return (root, query, builder) -> (legalFormNames == null || legalFormNames.isEmpty()) ? null : root.get("legalForm").in(legalFormNames); } - public static Specification employeeComparator(NumberOfEmployeeFilter numberOfEmployeeFilter) { + public static Specification employeeComparator(NumberOfEmployeeFilterDTO numberOfEmployeeFilter) { return (root, query, builder) -> { if (numberOfEmployeeFilter == null) { return null; @@ -53,7 +52,7 @@ public static Specification employeeComparator(NumberOfEmployeeFilter n }; } - public static Specification socialMediaNotNull(SocialMedia socials) { + public static Specification socialMediaNotNull(SocialMediaDTO socials) { return (root, query, builder) -> { if (socials == null) { return null; @@ -79,7 +78,7 @@ public static Specification socialMediaNotNull(SocialMedia socials) { }; } - public static Specification contactInfoNotNull(Contact contacts) { + public static Specification contactInfoNotNull(ContactDTO contacts) { return (root, query, builder) -> { if (contacts == null) { return null; @@ -99,7 +98,7 @@ public static Specification contactInfoNotNull(Contact contacts) { }; } - public static Specification notSeenByUser(Boolean isCompanySeen, String userId) { + public static Specification notSeenByUser(Boolean isCompanySeen, String userId) { return (root, query, builder) -> { if (isCompanySeen == null || userId == null) { return null; @@ -107,7 +106,7 @@ public static Specification notSeenByUser(Boolean isCompanySeen, String // Create subquery to select company IDs that have been seen by the user Subquery subquery = query.subquery(Long.class); - Root userCompanyStatusRoot = subquery.from(UserCompanyStatus.class); + Root userCompanyStatusRoot = subquery.from(UserCompanyStatusModel.class); subquery.select(userCompanyStatusRoot.get("companyId")) .where(builder.equal(userCompanyStatusRoot.get("userId"), userId)); diff --git a/src/main/java/com/example/spring/utils/CompanyUtil.java b/src/main/java/com/example/spring/app/company/CompanyUtil.java similarity index 83% rename from src/main/java/com/example/spring/utils/CompanyUtil.java rename to src/main/java/com/example/spring/app/company/CompanyUtil.java index 6b03ce5..c2732d5 100644 --- a/src/main/java/com/example/spring/utils/CompanyUtil.java +++ b/src/main/java/com/example/spring/app/company/CompanyUtil.java @@ -1,9 +1,8 @@ -package com.example.spring.utils; +package com.example.spring.app.company; -import com.example.spring.dto.CompanyDtoWithStatusDTO; -import com.example.spring.dto.company.CompanyDTO; -import com.example.spring.model.Company; -import com.example.spring.model.UserCompanyStatus; +import com.example.spring.app.company.dto.CompanyDTO; +import com.example.spring.app.company.dto.CompanyDtoWithStatusDTO; +import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel; import com.fasterxml.jackson.databind.JsonNode; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -26,7 +25,7 @@ public static void setIfNotEmpty(JsonNode jsonNode, String fieldName, Consumer fillPaginationCompanyDtoWithStatusDto(Page companiesPage, List userCompanyStatuses) { + public static Page fillPaginationCompanyDtoWithStatusDto(Page companiesPage, List userCompanyStatuses) { // Fill the CompanyWithStatusDTO with the company and its status Page companyDTOWithStatusDTOS; @@ -46,7 +45,7 @@ public static Page fillPaginationCompanyDtoWithStatusDt return companyDTOWithStatusDTOS; } - public static CompanyDtoWithStatusDTO fillCompanyDtoWithStatusDto(CompanyDTO companyDTO, UserCompanyStatus userCompanyStatus) { + public static CompanyDtoWithStatusDTO fillCompanyDtoWithStatusDto(CompanyDTO companyDTO, UserCompanyStatusModel userCompanyStatus) { return new CompanyDtoWithStatusDTO(companyDTO, userCompanyStatus); } } diff --git a/src/main/java/com/example/spring/dto/company/CompanyDTO.java b/src/main/java/com/example/spring/app/company/dto/CompanyDTO.java similarity index 74% rename from src/main/java/com/example/spring/dto/company/CompanyDTO.java rename to src/main/java/com/example/spring/app/company/dto/CompanyDTO.java index 05c62d6..2c241ee 100644 --- a/src/main/java/com/example/spring/dto/company/CompanyDTO.java +++ b/src/main/java/com/example/spring/app/company/dto/CompanyDTO.java @@ -1,6 +1,9 @@ -package com.example.spring.dto.company; +package com.example.spring.app.company.dto; -import com.example.spring.dto.company.financial.FinancialPeriodDTO; +import com.example.spring.app.company.objects.ContactDTO; +import com.example.spring.app.company.objects.SocialMediaDTO; +import com.example.spring.app.company.financial.FinancialPeriodDTO; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -14,6 +17,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@Schema(name = "Company") public class CompanyDTO { private Integer id; private String companyName; @@ -34,8 +38,8 @@ public class CompanyDTO { private String industrySector; private Map reviews; private String schedule; - private SocialMedia socialMedia; - private Contact contact; + private SocialMediaDTO socialMedia; + private ContactDTO contact; private LocalDate scrapingDate; private LocalDate dateCreation; private LocalDate lastProcessingDate; diff --git a/src/main/java/com/example/spring/dto/CompanyDetails.java b/src/main/java/com/example/spring/app/company/dto/CompanyDetails.java similarity index 90% rename from src/main/java/com/example/spring/dto/CompanyDetails.java rename to src/main/java/com/example/spring/app/company/dto/CompanyDetails.java index fc19c40..be72369 100644 --- a/src/main/java/com/example/spring/dto/CompanyDetails.java +++ b/src/main/java/com/example/spring/app/company/dto/CompanyDetails.java @@ -1,4 +1,4 @@ -package com.example.spring.dto; +package com.example.spring.app.company.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/example/spring/dto/CompanyDtoWithStatusDTO.java b/src/main/java/com/example/spring/app/company/dto/CompanyDtoWithStatusDTO.java similarity index 58% rename from src/main/java/com/example/spring/dto/CompanyDtoWithStatusDTO.java rename to src/main/java/com/example/spring/app/company/dto/CompanyDtoWithStatusDTO.java index f0f1238..407b3e1 100644 --- a/src/main/java/com/example/spring/dto/CompanyDtoWithStatusDTO.java +++ b/src/main/java/com/example/spring/app/company/dto/CompanyDtoWithStatusDTO.java @@ -1,7 +1,6 @@ -package com.example.spring.dto; +package com.example.spring.app.company.dto; -import com.example.spring.dto.company.CompanyDTO; -import com.example.spring.model.UserCompanyStatus; +import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -12,9 +11,10 @@ @Builder @NoArgsConstructor @AllArgsConstructor +@Schema(name = "CompanyWithStatus") public class CompanyDtoWithStatusDTO implements Serializable { private CompanyDTO companyDTO; @Schema(nullable = true) - private UserCompanyStatus userCompanyStatus; + private UserCompanyStatusModel userCompanyStatus; } diff --git a/src/main/java/com/example/spring/dto/CompanyFilterRequest.java b/src/main/java/com/example/spring/app/company/dto/CompanyFilterRequest.java similarity index 57% rename from src/main/java/com/example/spring/dto/CompanyFilterRequest.java rename to src/main/java/com/example/spring/app/company/dto/CompanyFilterRequest.java index 6bdb3ee..293550b 100644 --- a/src/main/java/com/example/spring/dto/CompanyFilterRequest.java +++ b/src/main/java/com/example/spring/app/company/dto/CompanyFilterRequest.java @@ -1,7 +1,7 @@ -package com.example.spring.dto; +package com.example.spring.app.company.dto; -import com.example.spring.dto.company.Contact; -import com.example.spring.dto.company.SocialMedia; +import com.example.spring.app.company.objects.ContactDTO; +import com.example.spring.app.company.objects.SocialMediaDTO; import lombok.*; import java.util.List; @@ -16,9 +16,9 @@ public class CompanyFilterRequest { private List cityNames; private List industrySectorNames; private List legalFormNames; - private NumberOfEmployeeFilter numberOfEmployeeFilter; - private SocialMedia socials; - private Contact contacts; + private NumberOfEmployeeFilterDTO numberOfEmployeeFilter; + private SocialMediaDTO socials; + private ContactDTO contacts; private Boolean isCompanySeen; private Integer page; private Integer size; diff --git a/src/main/java/com/example/spring/dto/NumberOfEmployeeFilter.java b/src/main/java/com/example/spring/app/company/dto/NumberOfEmployeeFilterDTO.java similarity index 57% rename from src/main/java/com/example/spring/dto/NumberOfEmployeeFilter.java rename to src/main/java/com/example/spring/app/company/dto/NumberOfEmployeeFilterDTO.java index 9452be1..d102e4e 100644 --- a/src/main/java/com/example/spring/dto/NumberOfEmployeeFilter.java +++ b/src/main/java/com/example/spring/app/company/dto/NumberOfEmployeeFilterDTO.java @@ -1,6 +1,6 @@ -package com.example.spring.dto; +package com.example.spring.app.company.dto; -import com.example.spring.enums.SignComparator; +import com.example.spring.app.filters.autocomplete.SignComparator; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -8,7 +8,7 @@ @Getter @Setter @Schema(nullable = true) -public class NumberOfEmployeeFilter { +public class NumberOfEmployeeFilterDTO { Integer numberOfEmployee; SignComparator signComparator; } diff --git a/src/main/java/com/example/spring/enums/Status.java b/src/main/java/com/example/spring/app/company/enums/Status.java similarity index 55% rename from src/main/java/com/example/spring/enums/Status.java rename to src/main/java/com/example/spring/app/company/enums/Status.java index f8e2580..04079e9 100644 --- a/src/main/java/com/example/spring/enums/Status.java +++ b/src/main/java/com/example/spring/app/company/enums/Status.java @@ -1,4 +1,4 @@ -package com.example.spring.enums; +package com.example.spring.app.company.enums; public enum Status { NOT_DONE, diff --git a/src/main/java/com/example/spring/app/company/financial/FinancialPeriod.java b/src/main/java/com/example/spring/app/company/financial/FinancialPeriod.java new file mode 100644 index 0000000..50b9937 --- /dev/null +++ b/src/main/java/com/example/spring/app/company/financial/FinancialPeriod.java @@ -0,0 +1,5 @@ +package com.example.spring.app.company.financial; + +public enum FinancialPeriod { + P1, P2, P3 +} diff --git a/src/main/java/com/example/spring/dto/company/financial/FinancialPeriodDTO.java b/src/main/java/com/example/spring/app/company/financial/FinancialPeriodDTO.java similarity index 74% rename from src/main/java/com/example/spring/dto/company/financial/FinancialPeriodDTO.java rename to src/main/java/com/example/spring/app/company/financial/FinancialPeriodDTO.java index 6e3eb04..e9ba226 100644 --- a/src/main/java/com/example/spring/dto/company/financial/FinancialPeriodDTO.java +++ b/src/main/java/com/example/spring/app/company/financial/FinancialPeriodDTO.java @@ -1,5 +1,6 @@ -package com.example.spring.dto.company.financial; +package com.example.spring.app.company.financial; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,6 +13,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder +@Schema(name = "FinancialPeriod") public class FinancialPeriodDTO { private FinancialYear year; private FinancialPeriod period; diff --git a/src/main/java/com/example/spring/mapper/FinancialPeriodMapper.java b/src/main/java/com/example/spring/app/company/financial/FinancialPeriodMapper.java similarity index 82% rename from src/main/java/com/example/spring/mapper/FinancialPeriodMapper.java rename to src/main/java/com/example/spring/app/company/financial/FinancialPeriodMapper.java index c77835f..278fcaa 100644 --- a/src/main/java/com/example/spring/mapper/FinancialPeriodMapper.java +++ b/src/main/java/com/example/spring/app/company/financial/FinancialPeriodMapper.java @@ -1,9 +1,6 @@ -package com.example.spring.mapper; +package com.example.spring.app.company.financial; -import com.example.spring.dto.company.financial.FinancialPeriod; -import com.example.spring.dto.company.financial.FinancialPeriodDTO; -import com.example.spring.dto.company.financial.FinancialYear; -import com.example.spring.model.Company; +import com.example.spring.app.company.CompanyModel; import java.lang.reflect.Method; import java.time.LocalDate; @@ -12,7 +9,7 @@ public class FinancialPeriodMapper { - public static List toFinancialPeriodDTOList(Company company) { + public static List toFinancialPeriodDTOList(CompanyModel company) { List periods = new ArrayList<>(); for (FinancialYear year : FinancialYear.values()) { @@ -40,7 +37,7 @@ public static List toFinancialPeriodDTOList(Company company) return periods; } - private static Object invokeGetter(Company company, String methodName) { + private static Object invokeGetter(CompanyModel company, String methodName) { try { Method method = company.getClass().getMethod(methodName); return method.invoke(company); diff --git a/src/main/java/com/example/spring/dto/company/financial/FinancialYear.java b/src/main/java/com/example/spring/app/company/financial/FinancialYear.java similarity index 60% rename from src/main/java/com/example/spring/dto/company/financial/FinancialYear.java rename to src/main/java/com/example/spring/app/company/financial/FinancialYear.java index 1e2dc34..13b6940 100644 --- a/src/main/java/com/example/spring/dto/company/financial/FinancialYear.java +++ b/src/main/java/com/example/spring/app/company/financial/FinancialYear.java @@ -1,4 +1,4 @@ -package com.example.spring.dto.company.financial; +package com.example.spring.app.company.financial; public enum FinancialYear { Y2018, Y2019, Y2020, Y2021, Y2022, Y2023 diff --git a/src/main/java/com/example/spring/dto/company/Contact.java b/src/main/java/com/example/spring/app/company/objects/ContactDTO.java similarity index 73% rename from src/main/java/com/example/spring/dto/company/Contact.java rename to src/main/java/com/example/spring/app/company/objects/ContactDTO.java index 22b9724..9ea3577 100644 --- a/src/main/java/com/example/spring/dto/company/Contact.java +++ b/src/main/java/com/example/spring/app/company/objects/ContactDTO.java @@ -1,4 +1,4 @@ -package com.example.spring.dto.company; +package com.example.spring.app.company.objects; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; @@ -7,7 +7,7 @@ @Getter @Builder @Schema(nullable = true) -public class Contact { +public class ContactDTO { String email; String phoneNumber; String website; diff --git a/src/main/java/com/example/spring/dto/company/SocialMedia.java b/src/main/java/com/example/spring/app/company/objects/SocialMediaDTO.java similarity index 76% rename from src/main/java/com/example/spring/dto/company/SocialMedia.java rename to src/main/java/com/example/spring/app/company/objects/SocialMediaDTO.java index 784f50b..efeafdc 100644 --- a/src/main/java/com/example/spring/dto/company/SocialMedia.java +++ b/src/main/java/com/example/spring/app/company/objects/SocialMediaDTO.java @@ -1,4 +1,4 @@ -package com.example.spring.dto.company; +package com.example.spring.app.company.objects; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -6,7 +6,7 @@ @Getter @Builder @Schema(nullable = true) -public class SocialMedia { +public class SocialMediaDTO { private String instagram; private String facebook; private String twitter; diff --git a/src/main/java/com/example/spring/controller/ConfigurationController.java b/src/main/java/com/example/spring/app/configuration/ConfigurationController.java similarity index 90% rename from src/main/java/com/example/spring/controller/ConfigurationController.java rename to src/main/java/com/example/spring/app/configuration/ConfigurationController.java index 669b424..7387e91 100644 --- a/src/main/java/com/example/spring/controller/ConfigurationController.java +++ b/src/main/java/com/example/spring/app/configuration/ConfigurationController.java @@ -1,7 +1,6 @@ -package com.example.spring.controller; +package com.example.spring.app.configuration; import com.example.spring.config.EnvConfig; -import com.example.spring.dto.Configuration; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -18,8 +17,8 @@ public ConfigurationController(EnvConfig envConfig) { // Make sure to flush the cache when updating the env variables @Cacheable(value = "configCache", unless = "#result == null") @GetMapping("/configuration") - public Configuration getEnv() { - return Configuration.builder() + public ConfigurationDTO getEnv() { + return ConfigurationDTO.builder() .oauthBaseUrl(envConfig.getOAUTH_BASE_URL()) .oauthSignInUrl(envConfig.getOAUTH_SIGN_IN_URL()) .oauthSignOutUrl(envConfig.getOAUTH_SIGN_OUT_URL()) diff --git a/src/main/java/com/example/spring/dto/Configuration.java b/src/main/java/com/example/spring/app/configuration/ConfigurationDTO.java similarity index 74% rename from src/main/java/com/example/spring/dto/Configuration.java rename to src/main/java/com/example/spring/app/configuration/ConfigurationDTO.java index 63dd683..a6bde4e 100644 --- a/src/main/java/com/example/spring/dto/Configuration.java +++ b/src/main/java/com/example/spring/app/configuration/ConfigurationDTO.java @@ -1,5 +1,6 @@ -package com.example.spring.dto; +package com.example.spring.app.configuration; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -9,7 +10,8 @@ @Getter @Setter @Builder -public class Configuration implements Serializable { +@Schema(name = "Configuration") +public class ConfigurationDTO implements Serializable { private String oauthBaseUrl; private String oauthSignInUrl; private String oauthSignOutUrl; diff --git a/src/main/java/com/example/spring/enums/SignComparator.java b/src/main/java/com/example/spring/app/filters/autocomplete/SignComparator.java similarity index 92% rename from src/main/java/com/example/spring/enums/SignComparator.java rename to src/main/java/com/example/spring/app/filters/autocomplete/SignComparator.java index d527db8..7a840a9 100644 --- a/src/main/java/com/example/spring/enums/SignComparator.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/SignComparator.java @@ -1,4 +1,4 @@ -package com.example.spring.enums; +package com.example.spring.app.filters.autocomplete; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/example/spring/model/AutoComplete/City.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/City.java similarity index 86% rename from src/main/java/com/example/spring/model/AutoComplete/City.java rename to src/main/java/com/example/spring/app/filters/autocomplete/city/City.java index fc9e0fc..0552787 100644 --- a/src/main/java/com/example/spring/model/AutoComplete/City.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/City.java @@ -1,4 +1,4 @@ -package com.example.spring.model.AutoComplete; +package com.example.spring.app.filters.autocomplete.city; import jakarta.persistence.Entity; diff --git a/src/main/java/com/example/spring/controller/AutoComplete/CityController.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java similarity index 86% rename from src/main/java/com/example/spring/controller/AutoComplete/CityController.java rename to src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java index a761a48..c479473 100644 --- a/src/main/java/com/example/spring/controller/AutoComplete/CityController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityController.java @@ -1,7 +1,5 @@ -package com.example.spring.controller.AutoComplete; +package com.example.spring.app.filters.autocomplete.city; -import com.example.spring.model.AutoComplete.City; -import com.example.spring.service.AutoComplete.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/com/example/spring/repository/AutoComplete/CityRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java similarity index 84% rename from src/main/java/com/example/spring/repository/AutoComplete/CityRepository.java rename to src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java index 2c0ee0f..e8b1885 100644 --- a/src/main/java/com/example/spring/repository/AutoComplete/CityRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityRepository.java @@ -1,6 +1,5 @@ -package com.example.spring.repository.AutoComplete; +package com.example.spring.app.filters.autocomplete.city; -import com.example.spring.model.AutoComplete.City; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/example/spring/service/AutoComplete/CityService.java b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java similarity index 78% rename from src/main/java/com/example/spring/service/AutoComplete/CityService.java rename to src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java index a28ce60..b919624 100644 --- a/src/main/java/com/example/spring/service/AutoComplete/CityService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/city/CityService.java @@ -1,7 +1,5 @@ -package com.example.spring.service.AutoComplete; +package com.example.spring.app.filters.autocomplete.city; -import com.example.spring.model.AutoComplete.City; -import com.example.spring.repository.AutoComplete.CityRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/example/spring/model/AutoComplete/IndustrySector.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java similarity index 84% rename from src/main/java/com/example/spring/model/AutoComplete/IndustrySector.java rename to src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java index 9c7454c..7ef44b7 100644 --- a/src/main/java/com/example/spring/model/AutoComplete/IndustrySector.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySector.java @@ -1,4 +1,4 @@ -package com.example.spring.model.AutoComplete; +package com.example.spring.app.filters.autocomplete.industrySector; import jakarta.persistence.Entity; diff --git a/src/main/java/com/example/spring/controller/AutoComplete/IndustrySectorController.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java similarity index 87% rename from src/main/java/com/example/spring/controller/AutoComplete/IndustrySectorController.java rename to src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java index 491dd00..0ba1b1f 100644 --- a/src/main/java/com/example/spring/controller/AutoComplete/IndustrySectorController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorController.java @@ -1,7 +1,5 @@ -package com.example.spring.controller.AutoComplete; +package com.example.spring.app.filters.autocomplete.industrySector; -import com.example.spring.model.AutoComplete.IndustrySector; -import com.example.spring.service.AutoComplete.IndustrySectorService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/com/example/spring/repository/AutoComplete/IndustrySectorRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java similarity index 84% rename from src/main/java/com/example/spring/repository/AutoComplete/IndustrySectorRepository.java rename to src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java index 825c758..af12910 100644 --- a/src/main/java/com/example/spring/repository/AutoComplete/IndustrySectorRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorRepository.java @@ -1,6 +1,5 @@ -package com.example.spring.repository.AutoComplete; +package com.example.spring.app.filters.autocomplete.industrySector; -import com.example.spring.model.AutoComplete.IndustrySector; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/example/spring/service/AutoComplete/IndustrySectorService.java b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java similarity index 79% rename from src/main/java/com/example/spring/service/AutoComplete/IndustrySectorService.java rename to src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java index 7dc74d3..1359e78 100644 --- a/src/main/java/com/example/spring/service/AutoComplete/IndustrySectorService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/industrySector/IndustrySectorService.java @@ -1,7 +1,5 @@ -package com.example.spring.service.AutoComplete; +package com.example.spring.app.filters.autocomplete.industrySector; -import com.example.spring.model.AutoComplete.IndustrySector; -import com.example.spring.repository.AutoComplete.IndustrySectorRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/example/spring/model/AutoComplete/LegalForm.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java similarity index 85% rename from src/main/java/com/example/spring/model/AutoComplete/LegalForm.java rename to src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java index b409236..ebd96ff 100644 --- a/src/main/java/com/example/spring/model/AutoComplete/LegalForm.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalForm.java @@ -1,4 +1,4 @@ -package com.example.spring.model.AutoComplete; +package com.example.spring.app.filters.autocomplete.legalForm; import jakarta.persistence.Entity; diff --git a/src/main/java/com/example/spring/controller/AutoComplete/LegalFormController.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java similarity index 86% rename from src/main/java/com/example/spring/controller/AutoComplete/LegalFormController.java rename to src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java index f181ffb..b1b39f4 100644 --- a/src/main/java/com/example/spring/controller/AutoComplete/LegalFormController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormController.java @@ -1,7 +1,5 @@ -package com.example.spring.controller.AutoComplete; +package com.example.spring.app.filters.autocomplete.legalForm; -import com.example.spring.model.AutoComplete.LegalForm; -import com.example.spring.service.AutoComplete.LegalFormService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/com/example/spring/repository/AutoComplete/LegalFormRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java similarity index 84% rename from src/main/java/com/example/spring/repository/AutoComplete/LegalFormRepository.java rename to src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java index 9defbc3..0034975 100644 --- a/src/main/java/com/example/spring/repository/AutoComplete/LegalFormRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormRepository.java @@ -1,6 +1,5 @@ -package com.example.spring.repository.AutoComplete; +package com.example.spring.app.filters.autocomplete.legalForm; -import com.example.spring.model.AutoComplete.LegalForm; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/example/spring/service/AutoComplete/LegalFormService.java b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java similarity index 79% rename from src/main/java/com/example/spring/service/AutoComplete/LegalFormService.java rename to src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java index 52a22f0..329d125 100644 --- a/src/main/java/com/example/spring/service/AutoComplete/LegalFormService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/legalForm/LegalFormService.java @@ -1,7 +1,5 @@ -package com.example.spring.service.AutoComplete; +package com.example.spring.app.filters.autocomplete.legalForm; -import com.example.spring.model.AutoComplete.LegalForm; -import com.example.spring.repository.AutoComplete.LegalFormRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/example/spring/model/AutoComplete/Region.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java similarity index 85% rename from src/main/java/com/example/spring/model/AutoComplete/Region.java rename to src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java index c6c6ab4..2c7f259 100644 --- a/src/main/java/com/example/spring/model/AutoComplete/Region.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/Region.java @@ -1,4 +1,4 @@ -package com.example.spring.model.AutoComplete; +package com.example.spring.app.filters.autocomplete.region; import jakarta.persistence.Entity; diff --git a/src/main/java/com/example/spring/controller/AutoComplete/RegionController.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java similarity index 86% rename from src/main/java/com/example/spring/controller/AutoComplete/RegionController.java rename to src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java index 4e7a826..ce296a4 100644 --- a/src/main/java/com/example/spring/controller/AutoComplete/RegionController.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionController.java @@ -1,7 +1,5 @@ -package com.example.spring.controller.AutoComplete; +package com.example.spring.app.filters.autocomplete.region; -import com.example.spring.model.AutoComplete.Region; -import com.example.spring.service.AutoComplete.RegionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/src/main/java/com/example/spring/repository/AutoComplete/RegionRepository.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java similarity index 84% rename from src/main/java/com/example/spring/repository/AutoComplete/RegionRepository.java rename to src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java index 4a7bff9..5fb6d9f 100644 --- a/src/main/java/com/example/spring/repository/AutoComplete/RegionRepository.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionRepository.java @@ -1,6 +1,5 @@ -package com.example.spring.repository.AutoComplete; +package com.example.spring.app.filters.autocomplete.region; -import com.example.spring.model.AutoComplete.Region; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/example/spring/service/AutoComplete/RegionService.java b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java similarity index 78% rename from src/main/java/com/example/spring/service/AutoComplete/RegionService.java rename to src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java index 1e68121..bb27a6d 100644 --- a/src/main/java/com/example/spring/service/AutoComplete/RegionService.java +++ b/src/main/java/com/example/spring/app/filters/autocomplete/region/RegionService.java @@ -1,7 +1,5 @@ -package com.example.spring.service.AutoComplete; +package com.example.spring.app.filters.autocomplete.region; -import com.example.spring.model.AutoComplete.Region; -import com.example.spring.repository.AutoComplete.RegionRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/example/spring/controller/LeaderController.java b/src/main/java/com/example/spring/app/leader/LeaderController.java similarity index 65% rename from src/main/java/com/example/spring/controller/LeaderController.java rename to src/main/java/com/example/spring/app/leader/LeaderController.java index f14ac55..9bffa8d 100644 --- a/src/main/java/com/example/spring/controller/LeaderController.java +++ b/src/main/java/com/example/spring/app/leader/LeaderController.java @@ -1,7 +1,5 @@ -package com.example.spring.controller; +package com.example.spring.app.leader; -import com.example.spring.model.Leader; -import com.example.spring.service.LeaderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -21,22 +19,22 @@ public class LeaderController { // Example: http://localhost:8080/api/v1/leader/get-by-id/123 @GetMapping("/get-by-id/{id}") - public Leader getLeaderById(@PathVariable("id") Integer id) { + public LeaderModel getLeaderById(@PathVariable("id") Integer id) { return leaderService.getLeaderById(id); } // Example: http://localhost:8080/api/v1/leader/get-by-siren?siren=exemple @GetMapping("/get-by-siren/{siren}") - public List getLeaderBySiren(@PathVariable("siren") String siren) { + public List getLeaderBySiren(@PathVariable("siren") 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") - public Page getLeadersByName(@RequestParam("firstName") String firstName, - @RequestParam("lastName") String lastName, - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "10") int size) { + public Page getLeadersByName(@RequestParam("firstName") String firstName, + @RequestParam("lastName") String lastName, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size) { Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending()); return leaderService.getLeadersByFirstAndLastName(firstName, lastName, pageable); } diff --git a/src/main/java/com/example/spring/model/Leader.java b/src/main/java/com/example/spring/app/leader/LeaderModel.java similarity index 89% rename from src/main/java/com/example/spring/model/Leader.java rename to src/main/java/com/example/spring/app/leader/LeaderModel.java index 7e742d2..ee00030 100644 --- a/src/main/java/com/example/spring/model/Leader.java +++ b/src/main/java/com/example/spring/app/leader/LeaderModel.java @@ -1,4 +1,4 @@ -package com.example.spring.model; +package com.example.spring.app.leader; import jakarta.persistence.*; import lombok.Data; @@ -6,7 +6,7 @@ @Data @Entity @Table(name = "leaders") -public class Leader { +public class LeaderModel { @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Integer id; diff --git a/src/main/java/com/example/spring/app/leader/LeaderRepository.java b/src/main/java/com/example/spring/app/leader/LeaderRepository.java new file mode 100644 index 0000000..cfad7d2 --- /dev/null +++ b/src/main/java/com/example/spring/app/leader/LeaderRepository.java @@ -0,0 +1,13 @@ +package com.example.spring.app.leader; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface LeaderRepository extends JpaRepository { + LeaderModel findLeaderById(Integer id); + List findAllBySiren(String siren); + Page findByFirstNameLikeAndLastNameLike(String firstName, String lastName, Pageable pageable); +} \ No newline at end of file diff --git a/src/main/java/com/example/spring/service/LeaderService.java b/src/main/java/com/example/spring/app/leader/LeaderService.java similarity index 61% rename from src/main/java/com/example/spring/service/LeaderService.java rename to src/main/java/com/example/spring/app/leader/LeaderService.java index fe724be..836d136 100644 --- a/src/main/java/com/example/spring/service/LeaderService.java +++ b/src/main/java/com/example/spring/app/leader/LeaderService.java @@ -1,7 +1,5 @@ -package com.example.spring.service; +package com.example.spring.app.leader; -import com.example.spring.model.Leader; -import com.example.spring.repository.LeaderRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -16,15 +14,15 @@ public class LeaderService { @Autowired private LeaderRepository leaderRepository; - public Leader getLeaderById(Integer id) { + public LeaderModel getLeaderById(Integer id) { return leaderRepository.findLeaderById(id); } - public List getLeadersBySirens(String siren) { + public List getLeadersBySirens(String siren) { return leaderRepository.findAllBySiren(siren); } - public Page getLeadersByFirstAndLastName(String firstName, String lastName, Pageable pageable) { + public Page getLeadersByFirstAndLastName(String firstName, String lastName, Pageable pageable) { return leaderRepository.findByFirstNameLikeAndLastNameLike(firstName, lastName, pageable); } } \ No newline at end of file diff --git a/src/main/java/com/example/spring/utils/CustomerUtil.java b/src/main/java/com/example/spring/app/stripe/CustomerUtil.java similarity index 93% rename from src/main/java/com/example/spring/utils/CustomerUtil.java rename to src/main/java/com/example/spring/app/stripe/CustomerUtil.java index 30263c0..102c5f9 100644 --- a/src/main/java/com/example/spring/utils/CustomerUtil.java +++ b/src/main/java/com/example/spring/app/stripe/CustomerUtil.java @@ -1,6 +1,7 @@ -package com.example.spring.utils; +package com.example.spring.app.stripe; -import com.example.spring.dto.User; +import com.example.spring.app.user.UserDTO; +import com.example.spring.utils.LogUtil; import com.stripe.exception.StripeException; import com.stripe.model.Customer; import com.stripe.model.CustomerSearchResult; @@ -29,7 +30,7 @@ public static Customer findCustomerByEmail(String email) throws StripeException return !result.getData().isEmpty() ? result.getData().get(0) : null; } - public static Customer findOrCreateCustomer(User user) throws Exception { + public static Customer findOrCreateCustomer(UserDTO user) throws Exception { try { CustomerSearchParams params = CustomerSearchParams diff --git a/src/main/java/com/example/spring/controller/PaymentController.java b/src/main/java/com/example/spring/app/stripe/PaymentController.java similarity index 96% rename from src/main/java/com/example/spring/controller/PaymentController.java rename to src/main/java/com/example/spring/app/stripe/PaymentController.java index e898144..b3693db 100644 --- a/src/main/java/com/example/spring/controller/PaymentController.java +++ b/src/main/java/com/example/spring/app/stripe/PaymentController.java @@ -1,8 +1,7 @@ -package com.example.spring.controller; +package com.example.spring.app.stripe; -import com.example.spring.dto.User; -import com.example.spring.keycloakClient.UserResource; -import com.example.spring.utils.CustomerUtil; +import com.example.spring.app.user.UserDTO; +import com.example.spring.core.keycloakClient.UserResource; import com.example.spring.utils.LogUtil; import com.stripe.Stripe; import com.stripe.exception.StripeException; @@ -48,7 +47,7 @@ public ResponseEntity newSubscriptionWithTrial(@RequestHeader("X-priceId String userId = parseUserIdFromHeader(); // Find the user record from the database - User user = userResource.getUserById(userId); + UserDTO user = userResource.getUserById(userId); try { if (user != null && !user.isVerified()) { diff --git a/src/main/java/com/example/spring/controller/UserController.java b/src/main/java/com/example/spring/app/user/UserController.java similarity index 83% rename from src/main/java/com/example/spring/controller/UserController.java rename to src/main/java/com/example/spring/app/user/UserController.java index f521078..d0fb891 100644 --- a/src/main/java/com/example/spring/controller/UserController.java +++ b/src/main/java/com/example/spring/app/user/UserController.java @@ -1,7 +1,6 @@ -package com.example.spring.controller; +package com.example.spring.app.user; -import com.example.spring.dto.User; -import com.example.spring.keycloakClient.UserResource; +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.*; @@ -18,7 +17,7 @@ public class UserController { UserResource userResource; @GetMapping("/user") - public User getUser() { + public UserDTO getUser() { String userId = parseUserIdFromHeader(); return userResource.getUserById(userId); } @@ -31,9 +30,9 @@ public Response completeOnboarding() { } @PutMapping("/update-user") - public Response updateUser(@RequestParam User user) { + public Response updateUser(@RequestParam UserDTO user) { String id = parseUserIdFromHeader(); - User existingUser = userResource.getUserById(id); + UserDTO existingUser = userResource.getUserById(id); if (existingUser != null) { // Ensure that the user's ID and verified status are not changed diff --git a/src/main/java/com/example/spring/dto/User.java b/src/main/java/com/example/spring/app/user/UserDTO.java similarity index 83% rename from src/main/java/com/example/spring/dto/User.java rename to src/main/java/com/example/spring/app/user/UserDTO.java index 9c4019a..2cbbe05 100644 --- a/src/main/java/com/example/spring/dto/User.java +++ b/src/main/java/com/example/spring/app/user/UserDTO.java @@ -1,5 +1,6 @@ -package com.example.spring.dto; +package com.example.spring.app.user; +import com.example.spring.common.enums.TierUser; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -7,7 +8,7 @@ @Getter @Setter @ToString -public class User { +public class UserDTO { private String id; private String firstName; private String lastName; @@ -24,4 +25,3 @@ public class User { private boolean isVerified; private boolean hasCompletedOnboarding; } - diff --git a/src/main/java/com/example/spring/service/UserService.java b/src/main/java/com/example/spring/app/user/UserService.java similarity index 71% rename from src/main/java/com/example/spring/service/UserService.java rename to src/main/java/com/example/spring/app/user/UserService.java index 636d540..e19a4f2 100644 --- a/src/main/java/com/example/spring/service/UserService.java +++ b/src/main/java/com/example/spring/app/user/UserService.java @@ -1,9 +1,8 @@ -package com.example.spring.service; +package com.example.spring.app.user; -import com.example.spring.dto.User; -import com.example.spring.keycloakClient.UserResource; -import com.example.spring.model.UserQuota; -import com.example.spring.repository.UserQuotaRepository; +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.utils.LogUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; @@ -15,7 +14,7 @@ import java.util.Map; import java.util.Optional; -import static com.example.spring.utils.UserQuotaUtil.getRemainingSearchesBasedOnUserTier; +import static com.example.spring.core.userQuota.UserQuotaUtil.getRemainingSearchesBasedOnUserTier; @EnableScheduling @Service @@ -31,12 +30,12 @@ public class UserService { @Transactional public void assignQuotaToEmptyUsers() { try { - List users = userResource.getUsers(); + List users = userResource.getUsers(); - for (User user : users) { - Optional userQuota = userQuotaRepository.findByUserId(user.getId()); + for (UserDTO user : users) { + Optional userQuota = userQuotaRepository.findByUserId(user.getId()); if (userQuota.isEmpty()) { - UserQuota newUserQuota = new UserQuota(); + UserQuotaModel newUserQuota = new UserQuotaModel(); newUserQuota.setUserId(user.getId()); Integer quotaAllocated = getRemainingSearchesBasedOnUserTier(user); diff --git a/src/main/java/com/example/spring/controller/UserCompanyStatusController.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java similarity index 64% rename from src/main/java/com/example/spring/controller/UserCompanyStatusController.java rename to src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java index 49c322f..60e6ad2 100644 --- a/src/main/java/com/example/spring/controller/UserCompanyStatusController.java +++ b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusController.java @@ -1,8 +1,6 @@ -package com.example.spring.controller; +package com.example.spring.app.userCompanyStatus; -import com.example.spring.enums.Status; -import com.example.spring.model.UserCompanyStatus; -import com.example.spring.service.UserCompanyStatusService; +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; @@ -20,10 +18,10 @@ public class UserCompanyStatusController { private UserCompanyStatusService userCompanyStatusService; @PostMapping("/update-status") - public ResponseEntity updateStatus(@RequestParam Integer companyId, - @RequestParam Status status) { + public ResponseEntity updateStatus(@RequestParam Integer companyId, + @RequestParam Status status) { String userId = parseUserIdFromHeader(); - UserCompanyStatus updated = userCompanyStatusService.updateCompanyStatus(userId, companyId, status); + UserCompanyStatusModel updated = userCompanyStatusService.updateCompanyStatus(userId, companyId, status); if (updated == null) { return ResponseEntity.noContent().build(); // deleted or no-op diff --git a/src/main/java/com/example/spring/model/UserCompanyStatus.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusModel.java similarity index 80% rename from src/main/java/com/example/spring/model/UserCompanyStatus.java rename to src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusModel.java index cb8841d..da3344d 100644 --- a/src/main/java/com/example/spring/model/UserCompanyStatus.java +++ b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusModel.java @@ -1,6 +1,6 @@ -package com.example.spring.model; +package com.example.spring.app.userCompanyStatus; -import com.example.spring.enums.Status; +import com.example.spring.app.company.enums.Status; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -17,7 +17,7 @@ @Data @Entity @Table(name = "user_company_status") -public class UserCompanyStatus implements Serializable { +public class UserCompanyStatusModel implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; diff --git a/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusRepository.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusRepository.java new file mode 100644 index 0000000..01639f1 --- /dev/null +++ b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusRepository.java @@ -0,0 +1,11 @@ +package com.example.spring.app.userCompanyStatus; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface UserCompanyStatusRepository extends JpaRepository { + UserCompanyStatusModel findUserCompanyStatusByUserIdAndCompanyId(String userId, Integer companyId); + + List findByUserIdAndCompanyIdIn(String userId, List companyIds); +} diff --git a/src/main/java/com/example/spring/service/UserCompanyStatusService.java b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java similarity index 60% rename from src/main/java/com/example/spring/service/UserCompanyStatusService.java rename to src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java index 19ac684..506b6e1 100644 --- a/src/main/java/com/example/spring/service/UserCompanyStatusService.java +++ b/src/main/java/com/example/spring/app/userCompanyStatus/UserCompanyStatusService.java @@ -1,8 +1,6 @@ -package com.example.spring.service; +package com.example.spring.app.userCompanyStatus; -import com.example.spring.enums.Status; -import com.example.spring.model.UserCompanyStatus; -import com.example.spring.repository.UserCompanyStatusRepository; +import com.example.spring.app.company.enums.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -14,24 +12,24 @@ public class UserCompanyStatusService { @Autowired private UserCompanyStatusRepository userCompanyStatusRepository; - public UserCompanyStatus getOneUserCompanyStatusByUserIdAndCompanyId(String userId, Integer companyId) { + public UserCompanyStatusModel getOneUserCompanyStatusByUserIdAndCompanyId(String userId, Integer companyId) { return userCompanyStatusRepository.findUserCompanyStatusByUserIdAndCompanyId(userId, companyId); } - public List getMultipleUserCompanyStatusByUserIdAndCompanyIds(String userId, List companyId) { + public List getMultipleUserCompanyStatusByUserIdAndCompanyIds(String userId, List companyId) { return userCompanyStatusRepository.findByUserIdAndCompanyIdIn(userId, companyId); } //@CacheEvict(value = "statuses", key = "#userId") - public UserCompanyStatus updateCompanyStatus(String userId, Integer companyId, Status status) { - UserCompanyStatus uc = userCompanyStatusRepository.findUserCompanyStatusByUserIdAndCompanyId(userId, companyId); + public UserCompanyStatusModel updateCompanyStatus(String userId, Integer companyId, Status status) { + UserCompanyStatusModel uc = userCompanyStatusRepository.findUserCompanyStatusByUserIdAndCompanyId(userId, companyId); if (uc == null) { if (status == Status.NOT_DONE) { return null; // nothing to persist } - UserCompanyStatus userCompanyStatus = UserCompanyStatus.builder() + UserCompanyStatusModel userCompanyStatus = UserCompanyStatusModel.builder() .userId(userId) .status(status) .companyId(companyId) diff --git a/src/main/java/com/example/spring/controller/WebHookController.java b/src/main/java/com/example/spring/app/webhook/WebHookController.java similarity index 89% rename from src/main/java/com/example/spring/controller/WebHookController.java rename to src/main/java/com/example/spring/app/webhook/WebHookController.java index 7fcdd91..18d4e98 100644 --- a/src/main/java/com/example/spring/controller/WebHookController.java +++ b/src/main/java/com/example/spring/app/webhook/WebHookController.java @@ -1,10 +1,10 @@ -package com.example.spring.controller; +package com.example.spring.app.webhook; -import com.example.spring.dto.TierUser; -import com.example.spring.dto.User; -import com.example.spring.keycloakClient.RoleResource; -import com.example.spring.keycloakClient.UserResource; -import com.example.spring.service.UserQuotaService; +import com.example.spring.common.enums.TierUser; +import com.example.spring.app.user.UserDTO; +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.utils.LogUtil; import com.google.gson.JsonSyntaxException; import com.stripe.exception.SignatureVerificationException; @@ -19,8 +19,8 @@ import java.util.Map; -import static com.example.spring.utils.CustomerUtil.retrieveCustomerById; -import static com.example.spring.utils.UserQuotaUtil.*; +import static com.example.spring.app.stripe.CustomerUtil.retrieveCustomerById; +import static com.example.spring.core.userQuota.UserQuotaUtil.*; @RestController @CrossOrigin @@ -96,7 +96,7 @@ private void handleSubscriptionCreated(Event event) throws StripeException { TierUser tierUser = getQuotaBasedOnTier(tier); Customer customer = retrieveCustomerById(subscription.getCustomer()); - User user = userResource.getUserByEmail(customer.getEmail()); + UserDTO user = userResource.getUserByEmail(customer.getEmail()); user.setTier(tierUser); user.setVerified(true); user.setHasCompletedOnboarding(false); @@ -119,7 +119,7 @@ private void handleSubscriptionUpdated(Event event) throws StripeException { )); Customer customer = retrieveCustomerById(subscription.getCustomer()); - User user = userResource.getUserByEmail(customer.getEmail()); + UserDTO user = userResource.getUserByEmail(customer.getEmail()); switch (subscription.getStatus()) { case "canceled": @@ -154,7 +154,7 @@ public void handleSubscriptionDeleted(Event event) throws StripeException { )); Customer customer = retrieveCustomerById(subscription.getCustomer()); - User user = userResource.getUserByEmail(customer.getEmail()); + UserDTO user = userResource.getUserByEmail(customer.getEmail()); roleResource.removeRoleFromUser(user.getId(), "verified"); user.setVerified(false); userResource.updateUser(user); diff --git a/src/main/java/com/example/spring/aspect/QuotaAspect.java b/src/main/java/com/example/spring/aspect/QuotaAspect.java deleted file mode 100644 index 655e1ee..0000000 --- a/src/main/java/com/example/spring/aspect/QuotaAspect.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.example.spring.aspect; - -import com.example.spring.model.UserQuota; -import com.example.spring.service.UserQuotaService; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ResponseStatusException; - -import static com.example.spring.utils.HeadersUtil.parseUserIdFromHeader; - -@Aspect -@Component -public class QuotaAspect { - - @Autowired - UserQuotaService userQuotaService; - - // Pointcut that matches all methods within CompanyController - @Pointcut("within(com.example.spring.controller.CompanyController)") - public void allMethodsInCompanyController() {} - - // Pointcut that matches the excluded methods - @Pointcut("execution(* com.example.spring.controller.CompanyController.searchCompaniesByName(..)) || " + - "execution(* com.example.spring.controller.CompanyController.scrapCompany(..)) || " + - "execution(* com.example.spring.controller.CompanyController.getCompaniesOnLandingByFilters(..))") - public void excludedMethods() {} - - // Combined pointcut that includes all methods except the excluded ones - @Pointcut("allMethodsInCompanyController() && !excludedMethods()") - public void allMethodsExceptExcluded() {} - - @Around("allMethodsExceptExcluded()") - public Object checkQuota(ProceedingJoinPoint joinPoint) throws Throwable { - String userId = parseUserIdFromHeader(); - - UserQuota userQuota = userQuotaService.getQuotaForUser(userId); - - if (userQuota.getQuotaUsed() < userQuota.getQuotaAllocated()) { - synchronized (this) { - if (userQuota.getQuotaUsed() < userQuota.getQuotaAllocated()) { - userQuotaService.updateQuotaForUser(userId, userQuota.getQuotaUsed() + 1); - return joinPoint.proceed(); - } - } - } - throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS, "Quota exceeded for user"); - } -} diff --git a/src/main/java/com/example/spring/dto/TierUser.java b/src/main/java/com/example/spring/common/enums/TierUser.java similarity index 63% rename from src/main/java/com/example/spring/dto/TierUser.java rename to src/main/java/com/example/spring/common/enums/TierUser.java index daff6dd..8870f1a 100644 --- a/src/main/java/com/example/spring/dto/TierUser.java +++ b/src/main/java/com/example/spring/common/enums/TierUser.java @@ -1,4 +1,4 @@ -package com.example.spring.dto; +package com.example.spring.common.enums; public enum TierUser { FREE, TIER1, TIER2, ENTERPRISE, UNLIMITED diff --git a/src/main/java/com/example/spring/model/Config.java b/src/main/java/com/example/spring/core/appSettings/AppSettings.java similarity index 82% rename from src/main/java/com/example/spring/model/Config.java rename to src/main/java/com/example/spring/core/appSettings/AppSettings.java index 0040602..5b6c0fd 100644 --- a/src/main/java/com/example/spring/model/Config.java +++ b/src/main/java/com/example/spring/core/appSettings/AppSettings.java @@ -1,4 +1,4 @@ -package com.example.spring.model; +package com.example.spring.core.appSettings; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -10,7 +10,7 @@ @Data @Entity -public class Config { +public class AppSettings { @GeneratedValue(strategy = GenerationType.IDENTITY) @Id private Integer id; diff --git a/src/main/java/com/example/spring/core/appSettings/AppSettingsRepository.java b/src/main/java/com/example/spring/core/appSettings/AppSettingsRepository.java new file mode 100644 index 0000000..2e24f08 --- /dev/null +++ b/src/main/java/com/example/spring/core/appSettings/AppSettingsRepository.java @@ -0,0 +1,9 @@ +package com.example.spring.core.appSettings; + +import org.springframework.data.repository.CrudRepository; + +import java.util.Optional; + +public interface AppSettingsRepository extends CrudRepository { + Optional findTopByOrderByIdDesc(); +} diff --git a/src/main/java/com/example/spring/utils/KeycloakSecurityUtil.java b/src/main/java/com/example/spring/core/keycloakClient/KeycloakInstance.java similarity index 92% rename from src/main/java/com/example/spring/utils/KeycloakSecurityUtil.java rename to src/main/java/com/example/spring/core/keycloakClient/KeycloakInstance.java index fa44069..395d796 100644 --- a/src/main/java/com/example/spring/utils/KeycloakSecurityUtil.java +++ b/src/main/java/com/example/spring/core/keycloakClient/KeycloakInstance.java @@ -1,4 +1,4 @@ -package com.example.spring.utils; +package com.example.spring.core.keycloakClient; import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.Keycloak; @@ -7,7 +7,7 @@ import org.springframework.stereotype.Component; @Component -public class KeycloakSecurityUtil { +public class KeycloakInstance { Keycloak keycloak; diff --git a/src/main/java/com/example/spring/core/keycloakClient/RoleResource.java b/src/main/java/com/example/spring/core/keycloakClient/RoleResource.java new file mode 100644 index 0000000..b50d064 --- /dev/null +++ b/src/main/java/com/example/spring/core/keycloakClient/RoleResource.java @@ -0,0 +1,31 @@ +package com.example.spring.core.keycloakClient; + +import jakarta.ws.rs.core.Response; +import org.keycloak.admin.client.Keycloak; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Collections; + +@Component +public class RoleResource { + + @Autowired + KeycloakInstance keycloakUtil; + + @Value("${KEYCLOAK_REALM}") + private String realm; + + public void addRoleToUser(String userId, String roleName) { + Keycloak keycloak = keycloakUtil.getKeycloakInstance(); + keycloak.realm(realm).users().get(userId).roles().realmLevel().add(Collections.singletonList(keycloak.realm(realm).roles().get(roleName).toRepresentation())); + Response.ok().build(); + } + + public void removeRoleFromUser(String userId, String roleName) { + Keycloak keycloak = keycloakUtil.getKeycloakInstance(); + keycloak.realm(realm).users().get(userId).roles().realmLevel().remove(Collections.singletonList(keycloak.realm(realm).roles().get(roleName).toRepresentation())); + Response.ok().build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/spring/keycloakClient/UserResource.java b/src/main/java/com/example/spring/core/keycloakClient/UserResource.java similarity index 78% rename from src/main/java/com/example/spring/keycloakClient/UserResource.java rename to src/main/java/com/example/spring/core/keycloakClient/UserResource.java index 7e06ce6..0ad6691 100644 --- a/src/main/java/com/example/spring/keycloakClient/UserResource.java +++ b/src/main/java/com/example/spring/core/keycloakClient/UserResource.java @@ -1,14 +1,11 @@ -package com.example.spring.keycloakClient; +package com.example.spring.core.keycloakClient; -import com.example.spring.dto.Role; -import com.example.spring.dto.TierUser; -import com.example.spring.dto.User; -import com.example.spring.utils.KeycloakSecurityUtil; +import com.example.spring.app.user.UserDTO; +import com.example.spring.common.enums.TierUser; import jakarta.ws.rs.core.Response; import org.keycloak.admin.client.Keycloak; import org.keycloak.common.util.CollectionUtil; import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -17,29 +14,29 @@ import java.util.*; -import static com.example.spring.utils.UserQuotaUtil.getQuotaBasedOnTier; +import static com.example.spring.core.userQuota.UserQuotaUtil.getQuotaBasedOnTier; @Service public class UserResource { @Autowired - KeycloakSecurityUtil keycloakUtil; + KeycloakInstance keycloakUtil; @Value("${KEYCLOAK_REALM}") private String realm; - public List getUsers() { + public List getUsers() { Keycloak keycloak = keycloakUtil.getKeycloakInstance(); List userRepresentations = keycloak.realm(realm).users().list(); return mapUsers(userRepresentations); } - public User getUserById(String id) { + public UserDTO getUserById(String id) { Keycloak keycloak = keycloakUtil.getKeycloakInstance(); return mapUser(keycloak.realm(realm).users().get(id).toRepresentation()); } - public User getUserByEmail(String email) { + public UserDTO getUserByEmail(String email) { if (email == null || email.isEmpty()) { throw new IllegalArgumentException("Email cannot be null or empty"); } @@ -55,7 +52,13 @@ public User getUserByEmail(String email) { return mapUser(userRepresentation); } - public Response createUser(User user) { + /** + * We should not use this method to create users. + * The flow is: UserDTO registers via Keycloak registration page, + * then, when trying to access our services, we redirect them to complete their profile. + * When user has paid subscription, we update their profile with the webhook from Stripe. + */ + public Response createUser(UserDTO user) { user.setTier(TierUser.FREE); user.setVerified(true); // To change UserRepresentation userRep = mapUserRep(user); @@ -64,7 +67,7 @@ public Response createUser(User user) { return Response.ok(user).build(); } - public void updateUser(User user) { + public void updateUser(UserDTO user) { UserRepresentation userRep = mapUserRep(user); Keycloak keycloak = keycloakUtil.getKeycloakInstance(); keycloak.realm(realm).users().get(user.getId()).update(userRep); @@ -77,22 +80,8 @@ public Response deleteUser(@PathVariable("id") String id) { return Response.ok().build(); } - public List getRoles(@PathVariable("id") String id) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - return RoleResource.mapRoles(keycloak.realm(realm).users() - .get(id).roles().realmLevel().listAll()); - } - - public Response createRole(@PathVariable("id") String id, - @PathVariable("roleName") String roleName) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - RoleRepresentation role = keycloak.realm(realm).roles().get(roleName).toRepresentation(); - keycloak.realm(realm).users().get(id).roles().realmLevel().add(Arrays.asList(role)); - return Response.ok().build(); - } - public void completeOnboarding(String userId) { - User user = getUserById(userId); + UserDTO user = getUserById(userId); if (!user.isHasCompletedOnboarding()) { user.setHasCompletedOnboarding(true); @@ -100,14 +89,8 @@ public void completeOnboarding(String userId) { } } - /* - public String returnRegistrationEndpoint() { - return keycloakUtil.returnRegistrationPage(); - } - */ - - private List mapUsers(List userRepresentations) { - List users = new ArrayList<>(); + private List mapUsers(List userRepresentations) { + List users = new ArrayList<>(); if (CollectionUtil.isNotEmpty(userRepresentations)) { userRepresentations.forEach(userRep -> { users.add(mapUser(userRep)); @@ -116,8 +99,8 @@ private List mapUsers(List userRepresentations) { return users; } - private User mapUser(UserRepresentation userRep) { - User user = new User(); + private UserDTO mapUser(UserRepresentation userRep) { + UserDTO user = new UserDTO(); user.setId(userRep.getId()); user.setFirstName(userRep.getFirstName()); user.setLastName(userRep.getLastName()); @@ -135,7 +118,7 @@ private User mapUser(UserRepresentation userRep) { return user; } - private UserRepresentation mapUserRep(User user) { + private UserRepresentation mapUserRep(UserDTO user) { UserRepresentation userRep = new UserRepresentation(); userRep.setId(user.getId()); userRep.setUsername(user.getUserName()); diff --git a/src/main/java/com/example/spring/core/userQuota/UserQuotaAspect.java b/src/main/java/com/example/spring/core/userQuota/UserQuotaAspect.java new file mode 100644 index 0000000..d81db96 --- /dev/null +++ b/src/main/java/com/example/spring/core/userQuota/UserQuotaAspect.java @@ -0,0 +1,90 @@ +package com.example.spring.core.userQuota; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ResponseStatusException; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +import static com.example.spring.utils.HeadersUtil.parseUserIdFromHeader; + +@Aspect +@Component +public class UserQuotaAspect { + + @Autowired + UserQuotaService userQuotaService; + + // Per-user lock management + private final ConcurrentHashMap userLocks = new ConcurrentHashMap<>(); + private final ScheduledExecutorService lockCleanupExecutor = Executors.newSingleThreadScheduledExecutor(); + + // Pointcut that matches all methods within CompanyController + @Pointcut("within(com.example.spring.app.company.CompanyController)") + public void allMethodsInCompanyController() {} + + // Pointcut that matches the excluded methods + @Pointcut("execution(* com.example.spring.app.company.CompanyController.searchCompaniesByName(..)) || " + + "execution(* com.example.spring.app.company.CompanyController.scrapCompany(..)) || " + + "execution(* com.example.spring.app.company.CompanyController.getCompaniesOnLandingByFilters(..))") + public void excludedMethods() {} + + // Combined pointcut that includes all methods except the excluded ones + @Pointcut("allMethodsInCompanyController() && !excludedMethods()") + public void allMethodsExceptExcluded() {} + + @PostConstruct + public void initCleanup() { + // Schedule lock cleanup every 10 minutes + lockCleanupExecutor.scheduleAtFixedRate( + this::cleanupUnusedLocks, + 10, 10, TimeUnit.MINUTES + ); + } + + @PreDestroy + public void shutdown() { + lockCleanupExecutor.shutdown(); + } + + private void cleanupUnusedLocks() { + // Remove locks that are not currently held and have no waiting threads + userLocks.entrySet().removeIf(entry -> { + ReentrantLock lock = entry.getValue(); + return !lock.isLocked() && !lock.hasQueuedThreads(); + }); + } + + @Around("allMethodsExceptExcluded()") + public Object checkQuota(ProceedingJoinPoint joinPoint) throws Throwable { + String userId = parseUserIdFromHeader(); + + // Get or create lock for this specific user + ReentrantLock userLock = userLocks.computeIfAbsent(userId, k -> new ReentrantLock()); + + userLock.lock(); + try { + UserQuotaModel userQuota = userQuotaService.getQuotaForUser(userId); + + if (userQuota.getQuotaUsed() < userQuota.getQuotaAllocated()) { + userQuotaService.updateQuotaForUser(userId, userQuota.getQuotaUsed() + 1); + return joinPoint.proceed(); + } + + throw new ResponseStatusException(HttpStatus.TOO_MANY_REQUESTS, "Quota exceeded for user"); + } finally { + userLock.unlock(); + } + } +} diff --git a/src/main/java/com/example/spring/model/UserQuota.java b/src/main/java/com/example/spring/core/userQuota/UserQuotaModel.java similarity index 61% rename from src/main/java/com/example/spring/model/UserQuota.java rename to src/main/java/com/example/spring/core/userQuota/UserQuotaModel.java index 140d951..3254905 100644 --- a/src/main/java/com/example/spring/model/UserQuota.java +++ b/src/main/java/com/example/spring/core/userQuota/UserQuotaModel.java @@ -1,4 +1,4 @@ -package com.example.spring.model; +package com.example.spring.core.userQuota; import jakarta.persistence.*; import lombok.Getter; @@ -7,7 +7,8 @@ @Setter @Getter @Entity -public class UserQuota { +@Table(name = "user_quota") +public class UserQuotaModel { // Getters and setters @Id @@ -15,9 +16,9 @@ public class UserQuota { private Integer quotaAllocated; private Integer quotaUsed; - public UserQuota() {} + public UserQuotaModel() {} - public UserQuota(String userId, Integer quotaAllocated, Integer quotaUsed) { + public UserQuotaModel(String userId, Integer quotaAllocated, Integer quotaUsed) { this.userId = userId; this.quotaAllocated = quotaAllocated; this.quotaUsed = quotaUsed; diff --git a/src/main/java/com/example/spring/repository/UserQuotaRepository.java b/src/main/java/com/example/spring/core/userQuota/UserQuotaRepository.java similarity index 50% rename from src/main/java/com/example/spring/repository/UserQuotaRepository.java rename to src/main/java/com/example/spring/core/userQuota/UserQuotaRepository.java index 1e09329..013e8a0 100644 --- a/src/main/java/com/example/spring/repository/UserQuotaRepository.java +++ b/src/main/java/com/example/spring/core/userQuota/UserQuotaRepository.java @@ -1,9 +1,8 @@ -package com.example.spring.repository; +package com.example.spring.core.userQuota; -import com.example.spring.model.UserQuota; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; -public interface UserQuotaRepository extends JpaRepository { - Optional findByUserId(String userId); +public interface UserQuotaRepository extends JpaRepository { + Optional findByUserId(String userId); } diff --git a/src/main/java/com/example/spring/service/UserQuotaService.java b/src/main/java/com/example/spring/core/userQuota/UserQuotaService.java similarity index 82% rename from src/main/java/com/example/spring/service/UserQuotaService.java rename to src/main/java/com/example/spring/core/userQuota/UserQuotaService.java index 5646d6f..e0391d5 100644 --- a/src/main/java/com/example/spring/service/UserQuotaService.java +++ b/src/main/java/com/example/spring/core/userQuota/UserQuotaService.java @@ -1,9 +1,7 @@ -package com.example.spring.service; +package com.example.spring.core.userQuota; -import com.example.spring.model.Config; -import com.example.spring.model.UserQuota; -import com.example.spring.repository.ConfigRepository; -import com.example.spring.repository.UserQuotaRepository; +import com.example.spring.core.appSettings.AppSettings; +import com.example.spring.core.appSettings.AppSettingsRepository; import com.example.spring.utils.LogUtil; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; @@ -27,18 +25,18 @@ public class UserQuotaService { @Autowired - ConfigRepository configRepository; + AppSettingsRepository configRepository; @Autowired UserQuotaRepository userQuotaRepository; - private final Cache quotaCache; - private final Map dirtyQuotas; + private final Cache quotaCache; + private final Map dirtyQuotas; private final Lock readLock; private final Lock writeLock; @Autowired - public UserQuotaService(ConfigRepository configRepository, UserQuotaRepository userQuotaRepository) { + public UserQuotaService(AppSettingsRepository configRepository, UserQuotaRepository userQuotaRepository) { this.configRepository = configRepository; this.userQuotaRepository = userQuotaRepository; long cacheExpireAfterWrite = 30; @@ -53,7 +51,7 @@ public UserQuotaService(ConfigRepository configRepository, UserQuotaRepository u this.writeLock = lock.writeLock(); } - public UserQuota getQuotaForUser(String userId) { + public UserQuotaModel getQuotaForUser(String userId) { readLock.lock(); try { return quotaCache.get(userId, this::loadQuotaFromDatabase); @@ -63,19 +61,19 @@ public UserQuota getQuotaForUser(String userId) { } public void createQuotaForUser(String userId, Integer quotaAllocated) { - UserQuota userQuota = new UserQuota(userId, quotaAllocated, 0); + UserQuotaModel userQuota = new UserQuotaModel(userId, quotaAllocated, 0); userQuotaRepository.save(userQuota); quotaCache.put(userId, userQuota); } - private UserQuota loadQuotaFromDatabase(String userId) { + private UserQuotaModel loadQuotaFromDatabase(String userId) { return userQuotaRepository.findByUserId(userId).orElse(null); } public void updateQuotaForUser(String userId, Integer quotaUsed) { writeLock.lock(); try { - UserQuota userQuota = getQuotaForUser(userId); + UserQuotaModel userQuota = getQuotaForUser(userId); userQuota.setQuotaUsed(quotaUsed); dirtyQuotas.put(userId, userQuota); quotaCache.put(userId, userQuota); @@ -112,7 +110,7 @@ public void resetMonthlyQuotas() { public void resetAllQuotas() { LocalDate now = LocalDate.now(ZoneId.systemDefault()); LocalDate lastResetDate = configRepository.findTopByOrderByIdDesc().get().getLastResetQuotaDate(); - Iterable allQuotas = userQuotaRepository.findAll(); + Iterable allQuotas = userQuotaRepository.findAll(); LogUtil.info("Resetting all quotas. Last reset date: ", Map.of( "last_reset_date", lastResetDate )); @@ -121,7 +119,7 @@ public void resetAllQuotas() { try { // Check if it has already been this day if (now.isAfter(lastResetDate)) { - for (UserQuota quota : allQuotas) { + for (UserQuotaModel quota : allQuotas) { quota.setQuotaUsed(0); quotaCache.put(quota.getUserId(), quota); dirtyQuotas.put(quota.getUserId(), quota); @@ -149,9 +147,9 @@ public void init() { public void updateQuotasWithDefaultLastResetDate() { LocalDate defaultDate = LocalDate.now(ZoneId.systemDefault()); - Config config = configRepository.findTopByOrderByIdDesc().orElse(null); + AppSettings config = configRepository.findTopByOrderByIdDesc().orElse(null); if (config == null) { - config = new Config(); + config = new AppSettings(); config.setLastResetQuotaDate(defaultDate); configRepository.save(config); } @@ -166,7 +164,7 @@ public void checkAndResetQuotasIfNecessary() { } private void updateLastResetQuotaDate(LocalDate date) { - Config config = configRepository.findTopByOrderByIdDesc().get(); + AppSettings config = configRepository.findTopByOrderByIdDesc().get(); config.setLastResetQuotaDate(date); configRepository.save(config); } diff --git a/src/main/java/com/example/spring/utils/UserQuotaUtil.java b/src/main/java/com/example/spring/core/userQuota/UserQuotaUtil.java similarity index 92% rename from src/main/java/com/example/spring/utils/UserQuotaUtil.java rename to src/main/java/com/example/spring/core/userQuota/UserQuotaUtil.java index 535b879..0bbeb29 100644 --- a/src/main/java/com/example/spring/utils/UserQuotaUtil.java +++ b/src/main/java/com/example/spring/core/userQuota/UserQuotaUtil.java @@ -1,7 +1,7 @@ -package com.example.spring.utils; +package com.example.spring.core.userQuota; -import com.example.spring.dto.TierUser; -import com.example.spring.dto.User; +import com.example.spring.common.enums.TierUser; +import com.example.spring.app.user.UserDTO; import com.example.spring.config.StripeConfig; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +51,7 @@ public static String getTierBasedOnPriceId(String priceId) { } } - public static Integer getRemainingSearchesBasedOnUserTier(User user) { + public static Integer getRemainingSearchesBasedOnUserTier(UserDTO user) { return switch (user.getTier()) { case FREE -> 15; case TIER1 -> 100; diff --git a/src/main/java/com/example/spring/dto/Role.java b/src/main/java/com/example/spring/dto/Role.java deleted file mode 100644 index 92c7799..0000000 --- a/src/main/java/com/example/spring/dto/Role.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.spring.dto; - -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class Role { - - private String id; - - private String name; -} \ No newline at end of file diff --git a/src/main/java/com/example/spring/dto/company/financial/FinancialPeriod.java b/src/main/java/com/example/spring/dto/company/financial/FinancialPeriod.java deleted file mode 100644 index 3aff91f..0000000 --- a/src/main/java/com/example/spring/dto/company/financial/FinancialPeriod.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.spring.dto.company.financial; - -public enum FinancialPeriod { - P1, P2, P3 -} diff --git a/src/main/java/com/example/spring/exception/DuplicatedUserInfoException.java b/src/main/java/com/example/spring/exception/DuplicatedUserInfoException.java deleted file mode 100644 index faac5cc..0000000 --- a/src/main/java/com/example/spring/exception/DuplicatedUserInfoException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.spring.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(HttpStatus.CONFLICT) -public class DuplicatedUserInfoException extends RuntimeException { - public DuplicatedUserInfoException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/spring/exception/GlobalException.java b/src/main/java/com/example/spring/exception/GlobalException.java deleted file mode 100644 index 7bcd924..0000000 --- a/src/main/java/com/example/spring/exception/GlobalException.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.spring.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import java.io.Serial; - -@RestControllerAdvice -public class GlobalException { - @ResponseStatus(value = HttpStatus.NOT_FOUND) - public static class ResourceNotFoundException extends RuntimeException { - @Serial - private static final long serialVersionUID = 1L; - - public ResourceNotFoundException(String message) { - super(message); - } - } - - @ExceptionHandler(QuotaExceededException.class) - public ResponseEntity handleQuotaExceededException(QuotaExceededException e) { - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); - } -} diff --git a/src/main/java/com/example/spring/exception/QuotaExceededException.java b/src/main/java/com/example/spring/exception/QuotaExceededException.java deleted file mode 100644 index 4efefc5..0000000 --- a/src/main/java/com/example/spring/exception/QuotaExceededException.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.spring.exception; - -public class QuotaExceededException extends RuntimeException { - - public QuotaExceededException() { - super(); - } - - public QuotaExceededException(String message) { - super(message); - } - - public QuotaExceededException(String message, Throwable cause) { - super(message, cause); - } - - public QuotaExceededException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/com/example/spring/exception/UserNotFoundException.java b/src/main/java/com/example/spring/exception/UserNotFoundException.java deleted file mode 100644 index 0cc0250..0000000 --- a/src/main/java/com/example/spring/exception/UserNotFoundException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.spring.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(HttpStatus.NOT_FOUND) -public class UserNotFoundException extends RuntimeException { - public UserNotFoundException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/spring/keycloakClient/RoleResource.java b/src/main/java/com/example/spring/keycloakClient/RoleResource.java deleted file mode 100644 index 5f6a62c..0000000 --- a/src/main/java/com/example/spring/keycloakClient/RoleResource.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.example.spring.keycloakClient; - -import com.example.spring.dto.Role; -import com.example.spring.utils.KeycloakSecurityUtil; -import jakarta.ws.rs.core.Response; -import org.keycloak.admin.client.Keycloak; -import org.keycloak.common.util.CollectionUtil; -import org.keycloak.representations.idm.RoleRepresentation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Component -public class RoleResource { - - @Autowired - KeycloakSecurityUtil keycloakUtil; - - @Value("${KEYCLOAK_REALM}") - private String realm; - - public List getRoles() { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - List roleRepresentations = keycloak.realm(realm).roles().list(); - return mapRoles(roleRepresentations); - } - - public Role getRole(String roleName) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - return mapRole(keycloak.realm(realm).roles().get(roleName).toRepresentation()); - } - - public Response createRole(Role role) { - RoleRepresentation roleRep = mapRoleRep(role); - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - keycloak.realm(realm).roles().create(roleRep); - return Response.ok(role).build(); - } - - public Response updateRole(Role role) { - RoleRepresentation roleRep = mapRoleRep(role); - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - keycloak.realm(realm).roles().get(role.getName()).update(roleRep); - return Response.ok(role).build(); - } - - public Response deleteUser(String roleName) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - keycloak.realm(realm).roles().deleteRole(roleName); - return Response.ok().build(); - } - - public void addRoleToUser(String userId, String roleName) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - keycloak.realm(realm).users().get(userId).roles().realmLevel().add(Collections.singletonList(keycloak.realm(realm).roles().get(roleName).toRepresentation())); - Response.ok().build(); - } - - public void removeRoleFromUser(String userId, String roleName) { - Keycloak keycloak = keycloakUtil.getKeycloakInstance(); - keycloak.realm(realm).users().get(userId).roles().realmLevel().remove(Collections.singletonList(keycloak.realm(realm).roles().get(roleName).toRepresentation())); - Response.ok().build(); - } - - public static List mapRoles(List representations) { - List roles = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(representations)) { - representations.forEach(roleRep -> roles.add(mapRole(roleRep))); - } - return roles; - } - - public static Role mapRole(RoleRepresentation roleRep) { - Role role = new Role(); - role.setId(roleRep.getId()); - role.setName(roleRep.getName()); - return role; - } - - public RoleRepresentation mapRoleRep(Role role) { - RoleRepresentation roleRep = new RoleRepresentation(); - roleRep.setName(role.getName()); - return roleRep; - } -} \ No newline at end of file diff --git a/src/main/java/com/example/spring/repository/ConfigRepository.java b/src/main/java/com/example/spring/repository/ConfigRepository.java deleted file mode 100644 index e8e3e54..0000000 --- a/src/main/java/com/example/spring/repository/ConfigRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.example.spring.repository; - -import com.example.spring.model.Config; -import org.springframework.data.repository.CrudRepository; - -import java.util.Optional; - -public interface ConfigRepository extends CrudRepository { - Optional findTopByOrderByIdDesc(); -} diff --git a/src/main/java/com/example/spring/repository/LeaderRepository.java b/src/main/java/com/example/spring/repository/LeaderRepository.java deleted file mode 100644 index 5b8bc7b..0000000 --- a/src/main/java/com/example/spring/repository/LeaderRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.example.spring.repository; - -import com.example.spring.model.Leader; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface LeaderRepository extends JpaRepository { - Leader findLeaderById(Integer id); - List findAllBySiren(String siren); - Page findByFirstNameLikeAndLastNameLike(String firstName, String lastName, Pageable pageable); -} \ No newline at end of file diff --git a/src/main/java/com/example/spring/repository/UserCompanyStatusRepository.java b/src/main/java/com/example/spring/repository/UserCompanyStatusRepository.java deleted file mode 100644 index 3947bae..0000000 --- a/src/main/java/com/example/spring/repository/UserCompanyStatusRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.example.spring.repository; - -import com.example.spring.model.UserCompanyStatus; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface UserCompanyStatusRepository extends JpaRepository { - UserCompanyStatus findUserCompanyStatusByUserIdAndCompanyId(String userId, Integer companyId); - - List findByUserIdAndCompanyIdIn(String userId, List companyIds); -} diff --git a/src/main/java/com/example/spring/service/ConfigService.java b/src/main/java/com/example/spring/service/ConfigService.java deleted file mode 100644 index e922994..0000000 --- a/src/main/java/com/example/spring/service/ConfigService.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.example.spring.service; - -import com.example.spring.model.Config; -import com.example.spring.repository.ConfigRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.time.LocalDate; -import java.time.ZoneId; - -@Service -public class ConfigService { - - private final ConfigRepository configRepository; - - @Autowired - public ConfigService(ConfigRepository configRepository) { - this.configRepository = configRepository; - } - - public Config getLastConfig() { - return configRepository.findTopByOrderByIdDesc() - .orElseGet(this::createDefaultConfig); - } - - private Config createDefaultConfig() { - Config defaultConfig = new Config(); - // Set default values here - defaultConfig.setLastResetQuotaDate(LocalDate.now(ZoneId.systemDefault())); - configRepository.save(defaultConfig); - return defaultConfig; - } -}