Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add matching search #146

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ public ResponseEntity<MatchingProfileDto> createMatchingProfileFromScratch(@Requ
return ResponseEntity.ok(matchingProfileService.createMatchingProfileFromScratch(request, userDetails.getUsername()));
}

/***
* Gets all matching profiles including own profile. For developments purposes only.
* This method is deprecated and will be removed in the future.
* @deprecated
* @param pageable
* @return
*/
@GetMapping("/all")
@Deprecated(forRemoval = true)
public ResponseEntity<Page<MatchingProfileDto>> getAllMatchingProfiles(Pageable pageable) {
return ResponseEntity.ok(matchingProfileQueryService.getAllMatchingProfiles(pageable));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package meowhub.backend.matching.controllers;

import lombok.Builder;
import lombok.RequiredArgsConstructor;
import meowhub.backend.matching.dtos.MatchingProfileDto;
import meowhub.backend.matching.services.MatchingProfileQueryService;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/matching-search")
@RequiredArgsConstructor
public class MatchingSearchController {
private final MatchingProfileQueryService queryService;

@GetMapping
public ResponseEntity<Page<MatchingProfileDto>> searchMatchingProfiles(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, @AuthenticationPrincipal UserDetails userDetails) {
return ResponseEntity.ok(queryService.search(page, size, userDetails.getUsername()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import jakarta.validation.constraints.Min;
import lombok.Getter;
import lombok.Setter;
import meowhub.backend.constants.Genders;
import meowhub.backend.matching.constants.LookingFor;
import meowhub.backend.matching.constants.Sexuality;
import meowhub.backend.matching.models.MatchingProfile;

@Setter
Expand All @@ -32,7 +32,7 @@ public class MatchingProfilePreferencesDto {
@Nullable
private Short ageTo;

private Sexuality sexuality;
private Genders gender;

private LookingFor lookingFor;

Expand All @@ -42,7 +42,7 @@ public static MatchingProfilePreferencesDto createFromMatchingProfilePreferences
matchingProfilePreferencesDto.setHeightTo(matchingProfile.getPHeightTo());
matchingProfilePreferencesDto.setAgeFrom(matchingProfile.getPAgeFrom());
matchingProfilePreferencesDto.setAgeTo(matchingProfile.getPAgeTo());
matchingProfilePreferencesDto.setSexuality(Sexuality.valueOf(matchingProfile.getPSexuality().getCode()));
matchingProfilePreferencesDto.setGender(Genders.valueOf(matchingProfile.getPGender().getCode()));
matchingProfilePreferencesDto.setLookingFor(LookingFor.valueOf(matchingProfile.getPLookingFor().getCode()));
return matchingProfilePreferencesDto;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,38 +47,6 @@ public class MatchingProfile {
@Column(name = "PROFILE_DETAILS_HTML", length = 2000)
private String profileDetailsHtml;

@Column(name = "CREATED_AT")
private LocalDateTime createdAt;

@Size(max = 36)
@Column(name = "CREATED_BY", length = 36)
private String createdBy;

@Column(name = "MODIFIED_AT")
private LocalDateTime modifiedAt;

@Size(max = 36)
@Column(name = "MODIFIED_BY", length = 36)
private String modifiedBy;

@OneToMany(mappedBy = "receiver")
private Set<Liked> likedReceiver = new LinkedHashSet<>();

@OneToMany(mappedBy = "sender")
private Set<Liked> likedSender = new LinkedHashSet<>();

@OneToMany(mappedBy = "sender")
private Set<MatchingChat> matchingChatsSender = new LinkedHashSet<>();

@OneToMany(mappedBy = "receiver")
private Set<MatchingChat> matchingChatsReceiver = new LinkedHashSet<>();

@OneToMany(mappedBy = "matchingProfile")
private Set<MatchingChatMessage> matchingChatMessages = new LinkedHashSet<>();

@OneToMany(mappedBy = "matchingProfile")
private Set<MatchingProfilePicture> matchingProfilePictures = new LinkedHashSet<>();

@Size(max = 40)
@NotNull
@Column(name = "NAME", nullable = false, length = 40)
Expand All @@ -88,6 +56,10 @@ public class MatchingProfile {
@Column(name = "BIRTHDATE", nullable = false)
private LocalDate birthdate;

@NotNull
@Column(name = "AGE", nullable = false)
private Short age;

@NotNull
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.RESTRICT)
Expand Down Expand Up @@ -134,8 +106,8 @@ public class MatchingProfile {

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.RESTRICT)
@JoinColumn(name = "P_SEXUALITY_ID")
private Sexuality pSexuality;
@JoinColumn(name = "P_GENDER_ID")
private Gender pGender;

@ManyToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.RESTRICT)
Expand All @@ -162,6 +134,38 @@ public class MatchingProfile {
@Column(name = "P_HEIGHT_TO")
private Short pHeightTo;

@Column(name = "CREATED_AT")
private LocalDateTime createdAt;

@Size(max = 36)
@Column(name = "CREATED_BY", length = 36)
private String createdBy;

@Column(name = "MODIFIED_AT")
private LocalDateTime modifiedAt;

@Size(max = 36)
@Column(name = "MODIFIED_BY", length = 36)
private String modifiedBy;

@OneToMany(mappedBy = "receiver")
private Set<Liked> likedReceiver = new LinkedHashSet<>();

@OneToMany(mappedBy = "sender")
private Set<Liked> likedSender = new LinkedHashSet<>();

@OneToMany(mappedBy = "sender")
private Set<MatchingChat> matchingChatsSender = new LinkedHashSet<>();

@OneToMany(mappedBy = "receiver")
private Set<MatchingChat> matchingChatsReceiver = new LinkedHashSet<>();

@OneToMany(mappedBy = "matchingProfile")
private Set<MatchingChatMessage> matchingChatMessages = new LinkedHashSet<>();

@OneToMany(mappedBy = "matchingProfile")
private Set<MatchingProfilePicture> matchingProfilePictures = new LinkedHashSet<>();

/*
TODO [Reverse Engineering] create field to map the 'GEOLOCALIZATION' column
Available actions: Define target Java type | Uncomment as is | Remove column mapping
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
package meowhub.backend.matching.repositories;

import meowhub.backend.matching.models.MatchingProfile;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;


public interface MatchingProfileRepository extends JpaRepository<MatchingProfile, String> {
boolean existsByUserLogin(String login);
Optional<MatchingProfile> findByUserLogin(String login);

@Query("""
SELECT mp
FROM MatchingProfile mp,
MatchingProfile filters
WHERE mp.user.login != :login
AND filters.user.login = :login
AND mp.height BETWEEN COALESCE(filters.pHeightFrom, mp.height) AND COALESCE(filters.pHeightTo, mp.height)
AND mp.age BETWEEN COALESCE(filters.pAgeFrom, mp.age) AND COALESCE(filters.pAgeTo, mp.age)
AND mp.lookingFor.id = COALESCE(filters.pLookingFor.id, mp.lookingFor.id)
AND mp.gender.id = COALESCE(filters.pGender.id, mp.gender.id)
""")
Page<MatchingProfile> search(@Param("login") String login, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ public interface MatchingProfileQueryService {
Optional<MatchingProfile> findMatchingProfileByLogin(String login);

MatchingProfilePreferencesDto getPreferences(String login);

Page<MatchingProfileDto> search(int page, int size, String login);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,10 @@ public MatchingProfilePreferencesDto getPreferences(String login) {
.map(MatchingProfilePreferencesDto::createFromMatchingProfilePreferencesFromMatchingProfile)
.orElseThrow();
}

@Override
public Page<MatchingProfileDto> search(int page, int size, String login) {
Pageable pageable = Pageable.ofSize(size).withPage(page);
return matchingProfileRepository.search(login, pageable).map(MatchingProfileDto::createFromMatchingProfile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ public void updateMatchingProfilePreferences(MatchingProfilePreferencesDto prefe
matchingProfile.setPHeightTo(preferences.getHeightTo());
matchingProfile.setPAgeFrom(preferences.getAgeFrom());
matchingProfile.setPAgeTo(preferences.getAgeTo());
matchingProfile.setPSexuality(sexualityRepository.findByCode(preferences.getSexuality().name())
.orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Sexuality", "code", preferences.getSexuality().name()))));
matchingProfile.setPGender(genderRepository.findByCode(preferences.getGender().name())
.orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Gender", "code", preferences.getGender().name()))));
matchingProfile.setPLookingFor(lookingForRepository.findByCode(preferences.getLookingFor().name())
.orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Looking for", "code", preferences.getLookingFor().name()))));
matchingProfileRepository.save(matchingProfile);
Expand Down
3 changes: 2 additions & 1 deletion database/scripts/120_create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ CREATE TABLE mh_matching.Matching_Profiles
profile_details_html varchar2(2000) NULL,
name varchar2(40) NOT NULL,
birthdate date NOT NULL,
age number(3) NOT NULL, --updated by UPDATE_AGE_JOB everyday at midnight
Gender_id varchar2(36) NOT NULL,
height number(3) NULL,
Sexuality_id varchar2(36) NULL,
Expand All @@ -359,7 +360,7 @@ CREATE TABLE mh_matching.Matching_Profiles
p_age_from number(3) NULL,
p_age_to number(3) NULL,
p_looking_for_id varchar2(36) NULL,
p_sexuality_id varchar2(36) NULL,
p_gender_id varchar2(36) NULL,
created_at date NOT NULL,
created_by varchar2(36) NOT NULL,
modified_at date NULL,
Expand Down
13 changes: 7 additions & 6 deletions database/scripts/130_grant_references.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
-- grant references to users.users
GRANT REFERENCES ON mh_users.users TO mh_chats;
GRANT REFERENCES ON mh_users.users TO mh_posts;
GRANT REFERENCES ON mh_users.users TO mh_groups;
GRANT REFERENCES ON mh_users.users TO mh_user_relations;
GRANT REFERENCES ON mh_users.users TO mh_matching;
GRANT REFERENCES ON mh_users.users TO mh_profiles;
GRANT REFERENCES ON mh_users.users TO mh_chats;
GRANT REFERENCES ON mh_users.users TO mh_posts;
GRANT REFERENCES ON mh_users.users TO mh_groups;
GRANT REFERENCES ON mh_users.users TO mh_user_relations;
GRANT REFERENCES ON mh_users.users TO mh_matching;
GRANT REFERENCES ON mh_users.genders TO mh_matching;
GRANT REFERENCES ON mh_users.users TO mh_profiles;
14 changes: 10 additions & 4 deletions database/scripts/140_create_references.sql
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,17 @@ ALTER TABLE mh_matching.Matching_Profiles
REFERENCES mh_users.Users (id)
ON DELETE CASCADE;

-- Reference: p_sexuality_Profile_Users (table: Matching_Profiles)
-- Reference: gender_Profile_Users (table: Matching_Profiles)
ALTER TABLE mh_matching.Matching_Profiles
ADD CONSTRAINT p_sexuality_matching_profiles
FOREIGN KEY (p_sexuality_id)
REFERENCES mh_matching.sexuality (id);
ADD CONSTRAINT gender_matching_profiles
FOREIGN KEY (gender_id)
REFERENCES mh_users.Genders (id);

-- Reference: p_gender_Profile_Users (table: Matching_Profiles)
ALTER TABLE mh_matching.Matching_Profiles
ADD CONSTRAINT p_gender_matching_profiles
FOREIGN KEY (p_gender_id)
REFERENCES mh_users.Genders (id);

-- Reference: sexuality_matching_profiles (table: sexuality)
ALTER TABLE mh_matching.matching_profiles
Expand Down
21 changes: 21 additions & 0 deletions database/scripts/330_mh_matching_set_age_job.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'UPDATE_AGE_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN
UPDATE mh_matching.Matching_Profiles
SET age = TRUNC(MONTHS_BETWEEN(SYSDATE, birthdate) / 12);
END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY; BYHOUR=0;',
enabled => TRUE
);
END;
/

--tu run the job manually use the following command:
-- BEGIN
-- DBMS_SCHEDULER.run_job('UPDATE_AGE_JOB');
-- END;
-- /

1 change: 1 addition & 0 deletions database/scripts/400_create_audit_triggers.sql
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ CREATE OR REPLACE TRIGGER mh_matching.matching_profiles_audit_trg
FOR EACH ROW
BEGIN
IF INSERTING THEN
:NEW.age := TRUNC(MONTHS_BETWEEN(SYSDATE, :NEW.birthdate) / 12);
:NEW.created_at := CURRENT_TIMESTAMP;
:NEW.created_by := mh_meowhub.get_user_id;
ELSIF UPDATING THEN
Expand Down