Skip to content
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
2 changes: 2 additions & 0 deletions src/main/java/com/soupulsar/SouPulsarMonolithApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.web.config.EnableSpringDataWebSupport;

@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO)
@SpringBootApplication
public class SouPulsarMonolithApplication {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.soupulsar.api.controllers;

import com.soupulsar.application.dto.request.GetAllSpecialistRequest;
import com.soupulsar.application.dto.response.DailyAvailabilityResponse;
import com.soupulsar.application.dto.response.GetAllSpecialistsResponse;
import com.soupulsar.application.dto.response.SpecialistDetailsResponse;
import com.soupulsar.application.usecase.specialist.GetAllSpecialistsUseCase;
import com.soupulsar.application.usecase.specialist.GetDailyAvailabilityUseCase;
import com.soupulsar.application.usecase.specialist.GetSpecialistDetailsUseCase;
import com.soupulsar.domain.model.enums.SpecialistType;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.UUID;

@RestController
@RequestMapping("/api/specialists")
@RequiredArgsConstructor
public class SpecialistsController {

private final GetAllSpecialistsUseCase getAllSpecialistsUseCase;
private final GetSpecialistDetailsUseCase getSpecialistDetailsUseCase;
private final GetDailyAvailabilityUseCase getDailyAvailabilityUseCase;

@GetMapping
public ResponseEntity<Page<GetAllSpecialistsResponse>> getAllSpecialists(
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size,
@RequestParam(required = false) SpecialistType specialistType,
@RequestParam(required = false) BigDecimal minPrice,
@RequestParam(required = false) BigDecimal maxPrice
) {
return ResponseEntity.ok(getAllSpecialistsUseCase.execute(GetAllSpecialistRequest.of(specialistType, minPrice, maxPrice, page, size)));
}

@GetMapping("/{specialistId}")
public ResponseEntity<SpecialistDetailsResponse> getSpecialistDetails(@PathVariable UUID specialistId) {
var response = getSpecialistDetailsUseCase.execute(specialistId);
return ResponseEntity.ok(response);
}

@GetMapping("/{specialistId}/availability/{date}")
public ResponseEntity<DailyAvailabilityResponse> getSpecialistDailyAvailability(@PathVariable UUID specialistId, @PathVariable LocalDate date) {
var response =getDailyAvailabilityUseCase.execute(specialistId, date);
return ResponseEntity.ok(response);
}
}
65 changes: 65 additions & 0 deletions src/main/java/com/soupulsar/api/controllers/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.soupulsar.api.controllers;

import com.soupulsar.application.dto.request.ChangePasswordRequest;
import com.soupulsar.application.dto.request.GetAllUsersRequest;
import com.soupulsar.application.dto.request.UpdateUserProfileRequest;
import com.soupulsar.application.dto.response.UserProfileResponse;
import com.soupulsar.application.dto.response.UserResponse;
import com.soupulsar.application.usecase.*;
import com.soupulsar.domain.model.enums.UserRole;
import com.soupulsar.domain.model.enums.UserStatus;
import com.soupulsar.domain.model.user.User;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {

private final GetAllUsersUseCase getAllUsersUseCase;
private final GetUserByIdUseCase getUserByIdUseCase;
private final GetUserProfileUseCase getUserProfileUseCase;
private final UpdateUserProfileUseCase updateUserProfileUseCase;
private final ChangePasswordUseCase changePasswordUseCase;

@GetMapping("/{userId}")
public ResponseEntity<UserResponse> getUserById(@PathVariable UUID userId) {
var response = getUserByIdUseCase.execute(userId);
return ResponseEntity.ok(response);
}

@GetMapping
public ResponseEntity<Page<User>> getAllUsers(
@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer size,
@RequestParam(required = false) UserStatus status,
@RequestParam(required = false) UserRole role
) {

return ResponseEntity.ok(getAllUsersUseCase.execute(GetAllUsersRequest.of(page, size, status, role)));
}

@GetMapping("/me")
public ResponseEntity<UserProfileResponse> getProfile() {
var response = getUserProfileUseCase.execute();
return ResponseEntity.ok(response);

}

@PatchMapping("/me")
public ResponseEntity<Void> updateProfile(@RequestBody UpdateUserProfileRequest request) {
updateUserProfileUseCase.execute(request);
return ResponseEntity.noContent().build();
}

@PutMapping("/me/password")
public ResponseEntity<Void> updatePassword(@RequestBody ChangePasswordRequest request) {
changePasswordUseCase.execute(request);
return ResponseEntity.ok().build();
}
}
62 changes: 60 additions & 2 deletions src/main/java/com/soupulsar/application/config/UseCaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

import com.soupulsar.application.security.JwtService;
import com.soupulsar.application.security.PasswordHasher;
import com.soupulsar.application.usecase.AuthenticateUserUseCase;
import com.soupulsar.application.usecase.RegistrationUseCase;
import com.soupulsar.application.usecase.*;
import com.soupulsar.application.usecase.availability.CreateAvailabilityUseCase;
import com.soupulsar.application.usecase.session.CancelSessionUseCase;
import com.soupulsar.application.usecase.session.CompleteSessionUseCase;
import com.soupulsar.application.usecase.session.ConfirmSessionUseCase;
import com.soupulsar.application.usecase.session.ScheduleSessionUseCase;
import com.soupulsar.application.usecase.specialist.GetAllSpecialistsUseCase;
import com.soupulsar.application.usecase.specialist.GetDailyAvailabilityUseCase;
import com.soupulsar.application.usecase.specialist.GetSpecialistDetailsUseCase;
import com.soupulsar.application.utils.SecurityUtils;
import com.soupulsar.domain.repository.*;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class UseCaseConfig {
Expand Down Expand Up @@ -51,4 +55,58 @@ public RegistrationUseCase registrationUseCase(UserRepository userRepository, Cl
SpecialistProfileRepository specialistProfileRepository, PasswordHasher passwordHasher) {
return new RegistrationUseCase(userRepository, clientProfileRepository, specialistProfileRepository,passwordHasher);
}
@Bean
public GetAllUsersUseCase getAllUsersUseCase(UserRepository userRepository) {
return new GetAllUsersUseCase(userRepository);
}

@Bean
public GetUserByIdUseCase getUserByIdUseCase(UserRepository userRepository) {
return new GetUserByIdUseCase(userRepository);
}

@Bean
public GetAllSpecialistsUseCase getAllSpecialistsUseCase(SpecialistProfileRepository specialistProfileRepository,
UserRepository userRepository,
SessionRepository sessionRepository) {
return new GetAllSpecialistsUseCase(specialistProfileRepository, userRepository, sessionRepository);
}

@Bean
GetSpecialistDetailsUseCase getSpecialistDetailsUseCase(SpecialistProfileRepository specialistRepository,
UserRepository userRepository,
SessionRepository sessionRepository) {
return new GetSpecialistDetailsUseCase(specialistRepository, userRepository, sessionRepository);
}

@Bean
GetDailyAvailabilityUseCase getDailyAvailabilityUseCase(SessionRepository sessionRepository,
AvailabilityRepository availabilityRepository) {
return new GetDailyAvailabilityUseCase(sessionRepository, availabilityRepository);
}

@Bean
public GetUserProfileUseCase getUserProfileUseCase(ClientProfileRepository clientProfileRepository,
SpecialistProfileRepository specialistProfileRepository,
UserRepository userRepository,
SecurityUtils securityUtils) {
return new GetUserProfileUseCase(clientProfileRepository, specialistProfileRepository, userRepository, securityUtils);
}

@Bean
public UpdateUserProfileUseCase updateUserProfileUseCase(ClientProfileRepository clientProfileRepository,
UserRepository userRepository,
SecurityUtils securityUtils) {
return new UpdateUserProfileUseCase(userRepository, clientProfileRepository, securityUtils);
}

@Bean
public SecurityUtils securityUtils(UserRepository userRepository) {
return new SecurityUtils(userRepository);
}

@Bean
public ChangePasswordUseCase changePasswordUseCase(UserRepository userRepository, PasswordEncoder passwordEncoder, SecurityUtils securityUtils) {
return new ChangePasswordUseCase(userRepository, passwordEncoder, securityUtils);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.soupulsar.application.dto.request;

public record ChangePasswordRequest(
String currentPassword,
String newPassword
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.soupulsar.application.dto.request;

import com.soupulsar.domain.model.enums.SpecialistType;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;

public record GetAllSpecialistRequest(
SpecialistType specialistType,
BigDecimal minPrice,
BigDecimal maxPrice,
Integer page,
Integer size
) {

public static GetAllSpecialistRequest of(SpecialistType specialistType, BigDecimal minPrice, BigDecimal maxPrice, Integer page, Integer size) {
return new GetAllSpecialistRequest(specialistType, minPrice, maxPrice, page, size);
}

public Pageable toPageable() {
int pageNumber = (page != null && page > 0) ? page : 0;
int pageSize = (size != null && size > 0) ? size : 10;
return PageRequest.of(pageNumber, pageSize);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.soupulsar.application.dto.request;


import com.soupulsar.domain.model.enums.UserRole;
import com.soupulsar.domain.model.enums.UserStatus;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

public record GetAllUsersRequest(

Integer page,
Integer size,
UserStatus status,
UserRole role
) {

public static GetAllUsersRequest of(Integer page, Integer size, UserStatus status, UserRole role) {
return new GetAllUsersRequest(page, size, status, role);
}

public Pageable toPageable(){
int pageNumber = (page != null && page > 0) ? page : 0;
int pageSize = (size != null && size > 0) ? size : 10;
return PageRequest.of(pageNumber, pageSize);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.soupulsar.application.dto.request;

import com.soupulsar.domain.model.enums.SpecialistType;
import com.soupulsar.domain.model.enums.UserRole;
import com.soupulsar.domain.model.vo.Address;
import com.soupulsar.domain.model.vo.EmergencyContact;
Expand All @@ -8,6 +9,7 @@
import jakarta.validation.constraints.NotNull;
import org.hibernate.validator.constraints.br.CPF;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

Expand Down Expand Up @@ -35,6 +37,8 @@ public record RegistrationRequest(
EmergencyContact emergencyContact,

// Specialist info
SpecialistType specialistType,
BigDecimal sessionPrice,
String registrationNumber,
Presentation presentation,
List<String> formations,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.soupulsar.application.dto.request;

import com.soupulsar.domain.model.vo.Address;
import com.soupulsar.domain.model.vo.EmergencyContact;
import jakarta.validation.constraints.Email;

public record UpdateUserProfileRequest(

String name,
String phone,
Address address,
EmergencyContact emergencyContact,
@Email
String email
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.soupulsar.application.dto.response;

import com.soupulsar.domain.model.vo.Address;
import lombok.Builder;

@Builder
public record AddressResponse(

String street,
String city,
String state,
String zipcode,
String neighbourhood

) {

public static AddressResponse toResponse(Address address) {
return AddressResponse.builder()
.street(address.getStreet())
.city(address.getCity())
.state(address.getState())
.zipcode(address.getZipCode())
.neighbourhood(address.getNeighbourhood())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.soupulsar.application.dto.response;

import com.soupulsar.domain.model.vo.EmergencyContact;
import lombok.Builder;

import java.util.Date;

@Builder
public record ClientProfileResponse(
String name,
String email,
String telephone,
Date birthday,
EmergencyContact emergencyContact,
AddressResponse addressResponse
) implements UserProfileResponse {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.soupulsar.application.dto.response;

import java.time.LocalDate;
import java.util.List;

public record DailyAvailabilityResponse(
LocalDate date,
List<TimeSlot> slots
) {
}
Loading