mirror of
https://codeberg.org/jsilveira/br.dev.jsilveira.coresync.git
synced 2026-06-11 18:05:06 +00:00
Implement REST API controllers, web adapters, and API documentation
- Create UserController, WorkoutController, and SessionController to expose application use cases via REST endpoints - Add request and response DTOs alongside web mappers for the User, Workout, and Session domains - Introduce GlobalExceptionHandler to handle domain-specific exceptions and return HTTP 400 Bad Request responses - Add Springdoc OpenAPI and Scalar dependencies to build.gradle for API documentation - Configure OpenAPI and Scalar settings in the base and dev application properties
This commit is contained in:
parent
5c1b7bcdd2
commit
b2314bcf36
24 changed files with 506 additions and 0 deletions
|
|
@ -24,6 +24,12 @@ dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
|
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
|
||||||
implementation 'org.apache.groovy:groovy'
|
implementation 'org.apache.groovy:groovy'
|
||||||
|
|
||||||
|
// Source: https://mvnrepository.com/artifact/com.scalar.maven/scalar-webmvc
|
||||||
|
implementation 'com.scalar.maven:scalar-webmvc:0.6.37'
|
||||||
|
// Source: https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-scalar
|
||||||
|
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-scalar:3.0.3'
|
||||||
|
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
|
developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
|
||||||
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
|
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package br.dev.jsilveira.coresync.common.adapter.in.web
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.session.domain.exception.UserWorkoutSessionException
|
||||||
|
import br.dev.jsilveira.coresync.user.domain.exception.UserException
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.exception.WorkoutDayException
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.exception.WorkoutExerciseException
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.exception.WorkoutPlanException
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice
|
||||||
|
|
||||||
|
@RestControllerAdvice
|
||||||
|
class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(UserException)
|
||||||
|
ResponseEntity<Map> handleUserException(UserException ex) {
|
||||||
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body([error: ex.message])
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(WorkoutPlanException)
|
||||||
|
ResponseEntity<Map> handleWorkoutPlanException(WorkoutPlanException ex) {
|
||||||
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body([error: ex.message])
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(WorkoutDayException)
|
||||||
|
ResponseEntity<Map> handleWorkoutDayException(WorkoutDayException ex) {
|
||||||
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body([error: ex.message])
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(WorkoutExerciseException)
|
||||||
|
ResponseEntity<Map> handleWorkoutExerciseException(WorkoutExerciseException ex) {
|
||||||
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body([error: ex.message])
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(UserWorkoutSessionException)
|
||||||
|
ResponseEntity<Map> handleSessionException(UserWorkoutSessionException ex) {
|
||||||
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body([error: ex.message])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +1,24 @@
|
||||||
package br.dev.jsilveira.coresync.session.adapter.in.web
|
package br.dev.jsilveira.coresync.session.adapter.in.web
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.session.adapter.in.web.dto.UserWorkoutSessionResponse
|
||||||
|
import br.dev.jsilveira.coresync.session.adapter.in.web.mapper.SessionWebMapper
|
||||||
|
import br.dev.jsilveira.coresync.session.application.port.in.UpdateUserWorkoutSessionCompletedAtUseCase
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/sessions")
|
||||||
|
class SessionController {
|
||||||
|
|
||||||
|
private final UpdateUserWorkoutSessionCompletedAtUseCase updateUserWorkoutSessionCompletedAtUseCase
|
||||||
|
private final SessionWebMapper webMapper = new SessionWebMapper()
|
||||||
|
|
||||||
|
SessionController(UpdateUserWorkoutSessionCompletedAtUseCase updateUserWorkoutSessionCompletedAtUseCase) {
|
||||||
|
this.updateUserWorkoutSessionCompletedAtUseCase = updateUserWorkoutSessionCompletedAtUseCase
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/complete")
|
||||||
|
UserWorkoutSessionResponse complete(@PathVariable UUID id) {
|
||||||
|
def session = updateUserWorkoutSessionCompletedAtUseCase.execute(id)
|
||||||
|
return webMapper.toResponse(session)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package br.dev.jsilveira.coresync.session.adapter.in.web.dto
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
record UserWorkoutSessionResponse(
|
||||||
|
UUID id,
|
||||||
|
UUID userId,
|
||||||
|
UUID workoutDayId,
|
||||||
|
LocalDateTime startedAt,
|
||||||
|
LocalDateTime completedAt,
|
||||||
|
Boolean isCompleted,
|
||||||
|
Long durationInMinutes
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package br.dev.jsilveira.coresync.session.adapter.in.web.mapper
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.session.adapter.in.web.dto.UserWorkoutSessionResponse
|
||||||
|
import br.dev.jsilveira.coresync.session.domain.model.UserWorkoutSession
|
||||||
|
|
||||||
|
class SessionWebMapper {
|
||||||
|
UserWorkoutSessionResponse toResponse(UserWorkoutSession domain) {
|
||||||
|
return new UserWorkoutSessionResponse(
|
||||||
|
domain.id(),
|
||||||
|
domain.userId(),
|
||||||
|
domain.workoutDayId(),
|
||||||
|
domain.startedAt(),
|
||||||
|
domain.completedAt(),
|
||||||
|
domain.isCompleted(),
|
||||||
|
domain.getDurationInMinutes()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +1,79 @@
|
||||||
package br.dev.jsilveira.coresync.user.adapter.in.web
|
package br.dev.jsilveira.coresync.user.adapter.in.web
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.user.adapter.in.web.dto.CreateUserRequest
|
||||||
|
import br.dev.jsilveira.coresync.user.adapter.in.web.dto.UserResponse
|
||||||
|
import br.dev.jsilveira.coresync.user.adapter.in.web.mapper.UserWebMapper
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.CreateUserUseCase
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.DisableUserUseCase
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.EnableUserUseCase
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.UpdateUserEmailUseCase
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.UpdateUserImageUseCase
|
||||||
|
import br.dev.jsilveira.coresync.user.application.port.in.UpdateUserNameUseCase
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/users")
|
||||||
|
class UserController {
|
||||||
|
|
||||||
|
private final CreateUserUseCase createUserUseCase
|
||||||
|
private final EnableUserUseCase enableUserUseCase
|
||||||
|
private final DisableUserUseCase disableUserUseCase
|
||||||
|
private final UpdateUserNameUseCase updateUserNameUseCase
|
||||||
|
private final UpdateUserEmailUseCase updateUserEmailUseCase
|
||||||
|
private final UpdateUserImageUseCase updateUserImageUseCase
|
||||||
|
private final UserWebMapper webMapper = new UserWebMapper()
|
||||||
|
|
||||||
|
UserController(
|
||||||
|
CreateUserUseCase createUserUseCase,
|
||||||
|
EnableUserUseCase enableUserUseCase,
|
||||||
|
DisableUserUseCase disableUserUseCase,
|
||||||
|
UpdateUserNameUseCase updateUserNameUseCase,
|
||||||
|
UpdateUserEmailUseCase updateUserEmailUseCase,
|
||||||
|
UpdateUserImageUseCase updateUserImageUseCase
|
||||||
|
) {
|
||||||
|
this.createUserUseCase = createUserUseCase
|
||||||
|
this.enableUserUseCase = enableUserUseCase
|
||||||
|
this.disableUserUseCase = disableUserUseCase
|
||||||
|
this.updateUserNameUseCase = updateUserNameUseCase
|
||||||
|
this.updateUserEmailUseCase = updateUserEmailUseCase
|
||||||
|
this.updateUserImageUseCase = updateUserImageUseCase
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
UserResponse create(@RequestBody CreateUserRequest request) {
|
||||||
|
def user = createUserUseCase.execute(request.name(), request.email())
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/activate")
|
||||||
|
UserResponse activate(@PathVariable UUID id) {
|
||||||
|
def user = enableUserUseCase.execute(id)
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/deactivate")
|
||||||
|
UserResponse deactivate(@PathVariable UUID id) {
|
||||||
|
def user = disableUserUseCase.execute(id)
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/name")
|
||||||
|
UserResponse updateName(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def user = updateUserNameUseCase.execute(id, body.name as String)
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/email")
|
||||||
|
UserResponse updateEmail(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def user = updateUserEmailUseCase.execute(id, body.email as String)
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}/image")
|
||||||
|
UserResponse updateImage(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def user = updateUserImageUseCase.execute(id, body.image as String)
|
||||||
|
return webMapper.toResponse(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record CreateUserRequest(
|
||||||
|
String name,
|
||||||
|
String email
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record DisableUserEmailVerifiedRequest(
|
||||||
|
UUID id
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record DisableUserRequest(
|
||||||
|
UUID id
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record EnableUserEmailVerified(
|
||||||
|
UUID id
|
||||||
|
){}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record EnableUserRequest(
|
||||||
|
UUID id
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record UpdateUserEmailRequest(
|
||||||
|
UUID id,
|
||||||
|
String email
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record UpdateUserImageRequest (
|
||||||
|
UUID id,
|
||||||
|
String image
|
||||||
|
){}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
record UpdateUserNameRequest(
|
||||||
|
UUID id,
|
||||||
|
String name
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.dto
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
record UserResponse(
|
||||||
|
UUID id,
|
||||||
|
String name,
|
||||||
|
String email,
|
||||||
|
Boolean emailVerified,
|
||||||
|
String image,
|
||||||
|
LocalDateTime createdAt,
|
||||||
|
LocalDateTime updatedAt,
|
||||||
|
Boolean isActive
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package br.dev.jsilveira.coresync.user.adapter.in.web.mapper
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.user.adapter.in.web.dto.UserResponse
|
||||||
|
import br.dev.jsilveira.coresync.user.domain.model.User
|
||||||
|
|
||||||
|
class UserWebMapper {
|
||||||
|
UserResponse toResponse(User domain) {
|
||||||
|
return new UserResponse(
|
||||||
|
domain.id(),
|
||||||
|
domain.name(),
|
||||||
|
domain.email(),
|
||||||
|
domain.emailVerified(),
|
||||||
|
domain.image(),
|
||||||
|
domain.createdAt(),
|
||||||
|
domain.updatedAt(),
|
||||||
|
domain.isActive()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +1,101 @@
|
||||||
package br.dev.jsilveira.coresync.workout.adapter.in.web
|
package br.dev.jsilveira.coresync.workout.adapter.in.web
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.CreateWorkoutPlanRequest
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutDayResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutExerciseResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutPlanResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.mapper.WorkoutWebMapper
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.CreateWorkoutPlanUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.DisableWorkoutDayRestUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.DisableWorkoutPlanUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.EnableWorkoutDayRestUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.EnableWorkoutPlanUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.UpdateWorkoutDayNameUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.UpdateWorkoutExerciseNameUseCase
|
||||||
|
import br.dev.jsilveira.coresync.workout.application.port.in.UpdateWorkoutPlanNameUseCase
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/workouts")
|
||||||
|
class WorkoutController {
|
||||||
|
|
||||||
|
private final CreateWorkoutPlanUseCase createWorkoutPlanUseCase
|
||||||
|
private final EnableWorkoutPlanUseCase enableWorkoutPlanUseCase
|
||||||
|
private final DisableWorkoutPlanUseCase disableWorkoutPlanUseCase
|
||||||
|
private final UpdateWorkoutPlanNameUseCase updateWorkoutPlanNameUseCase
|
||||||
|
private final UpdateWorkoutDayNameUseCase updateWorkoutDayNameUseCase
|
||||||
|
private final EnableWorkoutDayRestUseCase enableWorkoutDayRestUseCase
|
||||||
|
private final DisableWorkoutDayRestUseCase disableWorkoutDayRestUseCase
|
||||||
|
private final UpdateWorkoutExerciseNameUseCase updateWorkoutExerciseNameUseCase
|
||||||
|
private final WorkoutWebMapper webMapper = new WorkoutWebMapper()
|
||||||
|
|
||||||
|
WorkoutController(
|
||||||
|
CreateWorkoutPlanUseCase createWorkoutPlanUseCase,
|
||||||
|
EnableWorkoutPlanUseCase enableWorkoutPlanUseCase,
|
||||||
|
DisableWorkoutPlanUseCase disableWorkoutPlanUseCase,
|
||||||
|
UpdateWorkoutPlanNameUseCase updateWorkoutPlanNameUseCase,
|
||||||
|
UpdateWorkoutDayNameUseCase updateWorkoutDayNameUseCase,
|
||||||
|
EnableWorkoutDayRestUseCase enableWorkoutDayRestUseCase,
|
||||||
|
DisableWorkoutDayRestUseCase disableWorkoutDayRestUseCase,
|
||||||
|
UpdateWorkoutExerciseNameUseCase updateWorkoutExerciseNameUseCase
|
||||||
|
) {
|
||||||
|
this.createWorkoutPlanUseCase = createWorkoutPlanUseCase
|
||||||
|
this.enableWorkoutPlanUseCase = enableWorkoutPlanUseCase
|
||||||
|
this.disableWorkoutPlanUseCase = disableWorkoutPlanUseCase
|
||||||
|
this.updateWorkoutPlanNameUseCase = updateWorkoutPlanNameUseCase
|
||||||
|
this.updateWorkoutDayNameUseCase = updateWorkoutDayNameUseCase
|
||||||
|
this.enableWorkoutDayRestUseCase = enableWorkoutDayRestUseCase
|
||||||
|
this.disableWorkoutDayRestUseCase = disableWorkoutDayRestUseCase
|
||||||
|
this.updateWorkoutExerciseNameUseCase = updateWorkoutExerciseNameUseCase
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/plans")
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
WorkoutPlanResponse createPlan(@RequestBody CreateWorkoutPlanRequest request) {
|
||||||
|
def plan = createWorkoutPlanUseCase.execute(request.name(), UUID.fromString(request.userId()))
|
||||||
|
return webMapper.toPlanResponse(plan)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/plans/{id}/activate")
|
||||||
|
WorkoutPlanResponse activatePlan(@PathVariable UUID id) {
|
||||||
|
def plan = enableWorkoutPlanUseCase.execute(id)
|
||||||
|
return webMapper.toPlanResponse(plan)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/plans/{id}/deactivate")
|
||||||
|
WorkoutPlanResponse deactivatePlan(@PathVariable UUID id) {
|
||||||
|
def plan = disableWorkoutPlanUseCase.execute(id)
|
||||||
|
return webMapper.toPlanResponse(plan)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/plans/{id}/name")
|
||||||
|
WorkoutPlanResponse updatePlanName(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def plan = updateWorkoutPlanNameUseCase.execute(id, body.name as String)
|
||||||
|
return webMapper.toPlanResponse(plan)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/days/{id}/name")
|
||||||
|
WorkoutDayResponse updateDayName(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def day = updateWorkoutDayNameUseCase.execute(id, body.name as String)
|
||||||
|
return webMapper.toDayResponse(day)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/days/{id}/rest")
|
||||||
|
WorkoutDayResponse enableDayRest(@PathVariable UUID id) {
|
||||||
|
def day = enableWorkoutDayRestUseCase.execute(id)
|
||||||
|
return webMapper.toDayResponse(day)
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/days/{id}/rest")
|
||||||
|
WorkoutDayResponse disableDayRest(@PathVariable UUID id) {
|
||||||
|
def day = disableWorkoutDayRestUseCase.execute(id)
|
||||||
|
return webMapper.toDayResponse(day)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/exercises/{id}/name")
|
||||||
|
WorkoutExerciseResponse updateExerciseName(@PathVariable UUID id, @RequestBody Map body) {
|
||||||
|
def exercise = updateWorkoutExerciseNameUseCase.execute(id, body.name as String)
|
||||||
|
return webMapper.toExerciseResponse(exercise)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package br.dev.jsilveira.coresync.workout.adapter.in.web.dto
|
||||||
|
|
||||||
|
record CreateWorkoutPlanRequest(
|
||||||
|
String name,
|
||||||
|
String userId
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package br.dev.jsilveira.coresync.workout.adapter.in.web.dto
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
record WorkoutDayResponse(
|
||||||
|
UUID id,
|
||||||
|
String name,
|
||||||
|
UUID workoutPlanId,
|
||||||
|
Boolean isRest,
|
||||||
|
String weekDay,
|
||||||
|
Integer estimatedDurationInSeconds,
|
||||||
|
LocalDateTime createdAt,
|
||||||
|
LocalDateTime updatedAt,
|
||||||
|
List<WorkoutExerciseResponse> workoutExercises
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package br.dev.jsilveira.coresync.workout.adapter.in.web.dto
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
record WorkoutExerciseResponse(
|
||||||
|
UUID id,
|
||||||
|
Integer order,
|
||||||
|
String name,
|
||||||
|
Integer sets,
|
||||||
|
Integer reps,
|
||||||
|
Integer restTimeInSeconds,
|
||||||
|
UUID workoutDayId,
|
||||||
|
LocalDateTime createdAt,
|
||||||
|
LocalDateTime updatedAt
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package br.dev.jsilveira.coresync.workout.adapter.in.web.dto
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
record WorkoutPlanResponse(
|
||||||
|
UUID id,
|
||||||
|
String name,
|
||||||
|
UUID userId,
|
||||||
|
Boolean isActive,
|
||||||
|
LocalDateTime createdAt,
|
||||||
|
LocalDateTime updateAt,
|
||||||
|
List<WorkoutDayResponse> workoutDays
|
||||||
|
) {}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package br.dev.jsilveira.coresync.workout.adapter.in.web.mapper
|
||||||
|
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutDayResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutExerciseResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.adapter.in.web.dto.WorkoutPlanResponse
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.model.WorkoutDay
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.model.WorkoutExercise
|
||||||
|
import br.dev.jsilveira.coresync.workout.domain.model.WorkoutPlan
|
||||||
|
|
||||||
|
class WorkoutWebMapper {
|
||||||
|
|
||||||
|
WorkoutPlanResponse toPlanResponse(WorkoutPlan domain) {
|
||||||
|
return new WorkoutPlanResponse(
|
||||||
|
domain.id(),
|
||||||
|
domain.name(),
|
||||||
|
domain.userId(),
|
||||||
|
domain.isActive(),
|
||||||
|
domain.createdAt(),
|
||||||
|
domain.updateAt(),
|
||||||
|
domain.workoutDays().collect { toDayResponse(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkoutDayResponse toDayResponse(WorkoutDay domain) {
|
||||||
|
return new WorkoutDayResponse(
|
||||||
|
domain.id(),
|
||||||
|
domain.name(),
|
||||||
|
domain.workoutPlanId(),
|
||||||
|
domain.isRest(),
|
||||||
|
domain.weekDay() ? domain.weekDay().name() : null,
|
||||||
|
domain.estimatedDurationInSeconds(),
|
||||||
|
domain.createdAt(),
|
||||||
|
domain.updatedAt(),
|
||||||
|
domain.workoutExercises().collect { toExerciseResponse(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkoutExerciseResponse toExerciseResponse(WorkoutExercise domain) {
|
||||||
|
return new WorkoutExerciseResponse(
|
||||||
|
domain.id(),
|
||||||
|
domain.order(),
|
||||||
|
domain.name(),
|
||||||
|
domain.sets(),
|
||||||
|
domain.reps(),
|
||||||
|
domain.restTimeInSeconds(),
|
||||||
|
domain.workoutDayId(),
|
||||||
|
domain.createdAt(),
|
||||||
|
domain.updatedAt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/main/resources/application-dev.properties
Normal file
26
src/main/resources/application-dev.properties
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
spring.application.name=coresync-dev
|
||||||
|
|
||||||
|
# springdoc gera o spec OpenAPI
|
||||||
|
springdoc.api-docs.path=/v3/api-docs
|
||||||
|
springdoc.swagger-ui.enabled=false
|
||||||
|
|
||||||
|
# Scalar consome o spec do springdoc
|
||||||
|
scalar.enabled=true
|
||||||
|
scalar.url=/v3/api-docs
|
||||||
|
scalar.path=/docs
|
||||||
|
scalar.pageTitle=CoreSync API
|
||||||
|
scalar.darkMode=true
|
||||||
|
scalar.layout= modern
|
||||||
|
scalar.theme=deep_space
|
||||||
|
scalar.hide-dark-mode-toggle=true
|
||||||
|
scalar.hide-models=true
|
||||||
|
scalar.hide-client-button=false
|
||||||
|
scalar.show-sidebar=true
|
||||||
|
scalar.show-developer-tools=localhost
|
||||||
|
scalar.operation-title-source=summary
|
||||||
|
scalar.persist-auth=false
|
||||||
|
scalar.telemetry=true
|
||||||
|
scalar.expand-all-model-sections=false
|
||||||
|
scalar.expand-all-responses=false
|
||||||
|
scalar.order-required-properties-first=true
|
||||||
|
scalar.dark-mode=true
|
||||||
|
|
@ -1 +1,26 @@
|
||||||
spring.application.name=coresync
|
spring.application.name=coresync
|
||||||
|
|
||||||
|
# springdoc gera o spec OpenAPI
|
||||||
|
springdoc.api-docs.path=/v3/api-docs
|
||||||
|
springdoc.swagger-ui.enabled=false
|
||||||
|
|
||||||
|
# Scalar consome o spec do springdoc
|
||||||
|
scalar.enabled=true
|
||||||
|
scalar.url=/v3/api-docs
|
||||||
|
scalar.path=/docs
|
||||||
|
scalar.pageTitle=CoreSync API
|
||||||
|
scalar.darkMode=true
|
||||||
|
scalar.layout= modern
|
||||||
|
scalar.theme=deep_space
|
||||||
|
scalar.hide-dark-mode-toggle=true
|
||||||
|
scalar.hide-models=true
|
||||||
|
scalar.hide-client-button=false
|
||||||
|
scalar.show-sidebar=true
|
||||||
|
scalar.show-developer-tools=localhost
|
||||||
|
scalar.operation-title-source=summary
|
||||||
|
scalar.persist-auth=false
|
||||||
|
scalar.telemetry=true
|
||||||
|
scalar.expand-all-model-sections=false
|
||||||
|
scalar.expand-all-responses=false
|
||||||
|
scalar.order-required-properties-first=true
|
||||||
|
scalar.dark-mode=true
|
||||||
Loading…
Reference in a new issue