Skip to content
Open
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: 1 addition & 1 deletion api-request/auth-service/login.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ POST http://localhost:4004/api/auth/login
Content-Type: application/json

{
"email": "test_email@gmail.com",
"email": "test_email3@gmail.com",
"password": "c++_4_life!"
}

Expand Down
2 changes: 1 addition & 1 deletion api-request/auth-service/register.http
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ POST http://localhost:4004/api/auth/register
Content-Type: application/json

{
"email": "test_email@gmail.com",
"email": "test_email3@gmail.com",
"password": "c++_4_life!"
}
Empty file.
2 changes: 2 additions & 0 deletions api-request/client-service/clients/get-clients-coaches.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET http://localhost:4004/api/clients/client/coaches
Authorization: Bearer {{token}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
POST http://localhost:4004/api/clients/client/schedule/workout
Authorization: Bearer {{token}}
Content-Type: application/json


{
"exercises" : [
{
"movement" : {
"id" : "{{created_movement_id}}"
},
"numSets" : "3",
"numReps" : "10",
"coachNotes" : "Take these easy if you need to."
}
],
"date" : "2025-10-20",
"workoutNotes" : "Hey this is the note. Do good.",
"isCompleted" : "False",
"trainingScheduleId" : ""
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DELETE http://localhost:4004/api/clients/client/schedule/workout/fde2ca82-1a26-4767-adc9-8fbbdfc119e0
Authorization: Bearer {{token}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Get request to get a users training schedule.
GET http://localhost:4004/api/clients/client/schedule
Authorization: Bearer {{token}}

> {% client.global.set("training_schedule_id", response.body.id) %}
Empty file.
Empty file.
5 changes: 2 additions & 3 deletions api-request/client-service/create-user.http
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
### Post request to create a user.
POST http://localhost:4004/api/clients
POST http://localhost:4004/api/clients/users
Authorization: Bearer {{token}}
X-AUTH-ID: a7920032-59cf-461f-a293-6944954d3747
Content-Type: application/json

{
"firstName": "Test",
"lastName": "User",
"email": "test_user@test.com",
"email": "test_user3@test.com",
"address": "123 Test-Request Ave, 493201, WA, USA.",
"dateOfBirth": "2000-01-01",
"registeredDate": "2025-01-01"
Expand Down
2 changes: 1 addition & 1 deletion api-request/client-service/delete-user.http
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
DELETE http://localhost:4004/api/clients/a526c437-cd19-48a2-9804-fdbe091c0b38
DELETE http://localhost:4004/api/clients/users/a526c437-cd19-48a2-9804-fdbe091c0b38
Authorization: Bearer {{token}}
2 changes: 1 addition & 1 deletion api-request/client-service/get-users.http
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
### GET request to get the users.
GET http://localhost:4004/api/clients
GET http://localhost:4004/api/clients/users
Authorization: Bearer {{token}}
10 changes: 10 additions & 0 deletions api-request/client-service/movements/create-movement.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
POST http://localhost:4004/api/clients/movements
Authorization: Bearer {{token}}
Content-Type: application/json

{
"name" : "Deadlift",
"description" : "Sumo or bust."
}

> {% client.global.set("created_movement_id", response.body.id) %}
2 changes: 2 additions & 0 deletions api-request/client-service/movements/get-movement.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET http://localhost:4004/api/clients/movements/{{created_movement_id}}
Authorization: Bearer {{token}}
2 changes: 1 addition & 1 deletion client-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN mvn dependency:go-offline -B

COPY src ./src

RUN mvn clean package
RUN mvn clean package -DskipTests

FROM openjdk:22-jdk AS runner

Expand Down
34 changes: 28 additions & 6 deletions client-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down Expand Up @@ -84,9 +80,34 @@
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>

</dependencies>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
Expand All @@ -97,4 +118,5 @@
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package com.cm.clientservice.controller;

import com.cm.clientservice.dto.UserResponseDTO;
import com.cm.clientservice.dto.contract.CoachClientAgreementResponseDto;
import com.cm.clientservice.dto.contract.ContractAgreementStatusRequestDto;
import com.cm.clientservice.dto.scheduling.TrainingScheduleDto;
import com.cm.clientservice.dto.scheduling.workout.WorkoutRequestDto;
import com.cm.clientservice.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/clients")
@RequestMapping("clients/client")
@Tag(name="client", description = "API for clients to manage their experience.")
public class ClientController {

private final UserService userService;
Expand All @@ -21,9 +24,51 @@ public ClientController(UserService userService){
}

@GetMapping("/coaches")
@Operation(summary = "Get all users")
public ResponseEntity<List<UserResponseDTO>> getAllCoachUsers(){
List<UserResponseDTO> users = userService.getAllCoachUsers();
return ResponseEntity.ok().body(users);
public ResponseEntity<List<UserResponseDTO>> getClientsCoaches(@RequestHeader("X-AUTH-ID") String authId){
List<UserResponseDTO> coaches = userService.getCoachesOfClient(UUID.fromString(authId));
return ResponseEntity.ok().body(coaches);
}

@GetMapping("/schedule")
public ResponseEntity<TrainingScheduleDto> getTrainingSchedule(@RequestHeader("X-AUTH-ID") String authId){
TrainingScheduleDto trainingScheduleDto = userService.getTrainingSchedule(UUID.fromString(authId));
return ResponseEntity.ok().body(trainingScheduleDto);
}

@DeleteMapping("/schedule/workout/{workoutId}")
public ResponseEntity<TrainingScheduleDto> deleteWorkoutFromSchedule(@RequestHeader("X-AUTH-ID") String authId,
@PathVariable String workoutId){

TrainingScheduleDto trainingScheduleDto =
userService.removeWorkoutFromSchedule(UUID.fromString(authId), UUID.fromString(workoutId));

return ResponseEntity.ok().body(trainingScheduleDto);
}

@PostMapping("/schedule/workout")
public ResponseEntity<TrainingScheduleDto> addWorkoutToSchedule(@RequestHeader("X-AUTH-ID") String authId,
@RequestBody WorkoutRequestDto workoutDto){
TrainingScheduleDto trainingScheduleDto =
userService.addWorkoutToSchedule(UUID.fromString(authId), workoutDto);

return ResponseEntity.ok().body(trainingScheduleDto);
}

@GetMapping("/agreements/pending")
public ResponseEntity<List<CoachClientAgreementResponseDto>> getPendingAgreements(@RequestHeader("X-AUTH-ID") String authId){
List<CoachClientAgreementResponseDto> dtos =
userService.getPendingAgreements(UUID.fromString(authId));

return ResponseEntity.ok().body(dtos);
}

@PutMapping("/agreements/{id}/status")
public ResponseEntity<CoachClientAgreementResponseDto> setAcceptanceStatusOfPendingAgreement(@RequestHeader("X-AUTH-ID") String authId,
@RequestBody ContractAgreementStatusRequestDto requestDto,
@PathVariable String id){
CoachClientAgreementResponseDto responseDto =
userService.setAcceptanceStatusOfPendingAgreement(UUID.fromString(authId), UUID.fromString(id), requestDto);

return ResponseEntity.ok().body(responseDto);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.cm.clientservice.controller;
import com.cm.clientservice.dto.UserResponseDTO;
import com.cm.clientservice.dto.contract.template.AgreementTemplateRequestDto;
import com.cm.clientservice.dto.contract.template.AgreementTemplateResponseDto;
import com.cm.clientservice.dto.contract.CoachClientAgreementRequestDto;
import com.cm.clientservice.dto.contract.CoachClientAgreementResponseDto;
import com.cm.clientservice.dto.scheduling.TrainingScheduleDto;
import com.cm.clientservice.dto.scheduling.workout.WorkoutRequestDto;
import com.cm.clientservice.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("clients/coaching")
@Tag(name = "coaching", description = "API for coaching management.")
public class CoachingController {

private final UserService userService;

public CoachingController(UserService userService){
this.userService = userService;
}

@GetMapping("/clients")
@Operation(summary= "")
public ResponseEntity<List<UserResponseDTO>> getClients(@RequestHeader("X-AUTH-ID") String authId){

List<UserResponseDTO> clients = userService.getClientsOfCoach(UUID.fromString(authId));
return ResponseEntity.ok().body(clients);
}

@GetMapping("/clients/{clientId}/schedule")
@Operation(summary = "Get the clients training schedule for the coach to view. ")
public ResponseEntity<TrainingScheduleDto> getClientSchedule(@RequestHeader("X-AUTH-ID") String authId,
@PathVariable String clientId){

TrainingScheduleDto trainingScheduleDto =
userService.getClientTrainingSchedule(UUID.fromString(clientId), UUID.fromString(authId));

return ResponseEntity.ok().body(trainingScheduleDto);
}

@DeleteMapping("/clients/{clientId}/schedule/workout/{id}")
public ResponseEntity<TrainingScheduleDto> deleteWorkoutFromClientSchedule(@RequestHeader("X-AUTH-ID") String authId,
@PathVariable String clientId,
@PathVariable String id){

TrainingScheduleDto trainingScheduleDto =
userService.removeWorkoutFromClientSchedule(UUID.fromString(authId), UUID.fromString(clientId), UUID.fromString(id));

return ResponseEntity.ok().body(trainingScheduleDto);
}

@PostMapping("/clients/{clientId}/schedule/workout")
public ResponseEntity<TrainingScheduleDto> addWorkoutToClientSchedule(@RequestHeader("X-AUTH-ID") String authId,
@PathVariable String clientId,
@RequestBody WorkoutRequestDto workoutDto){
TrainingScheduleDto trainingScheduleDto =
userService.addWorkoutToClientsSchedule(UUID.fromString(authId), UUID.fromString(clientId), workoutDto);

return ResponseEntity.ok().body(trainingScheduleDto);
}


@PostMapping("/agreement/{clientId}")
public ResponseEntity<CoachClientAgreementResponseDto> proposeClientAgreement(@RequestHeader("X-AUTH-ID") String coachAuthId,
@PathVariable String clientId,
@RequestBody CoachClientAgreementRequestDto coachClientAgreement){
CoachClientAgreementResponseDto dto =
userService.proposeCoachClientAgreement(UUID.fromString(coachAuthId),
UUID.fromString(clientId),
coachClientAgreement);

return ResponseEntity.ok().body(dto);
}

@PutMapping("/agreement/withdraw/{agreementId}")
public ResponseEntity<CoachClientAgreementResponseDto> withdrawCoachesAgreementAcceptance(@RequestHeader("X-AUTH-ID") String coachAuthId,
@PathVariable String agreementId){
//TODO: Alert user of withdrawal.

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment
//TODO: Alert billing service of end of contract.

Check notice

Code scanning / devskim

A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note

Suspicious comment

CoachClientAgreementResponseDto dto =
userService.withdrawCoachesAgreementAcceptance(UUID.fromString(coachAuthId), UUID.fromString(agreementId));

return ResponseEntity.ok().body(dto);
}

@PostMapping("/templates")
public ResponseEntity<AgreementTemplateResponseDto> createAgreementTemplate(@RequestHeader("X-AUTH-ID") String coachAuthId,
@RequestBody AgreementTemplateRequestDto templateRequestDto){
AgreementTemplateResponseDto dto =
userService.createAgreementTemplate(UUID.fromString(coachAuthId), templateRequestDto);

return ResponseEntity.ok().body(dto);
}

@GetMapping("/templates")
public ResponseEntity<List<AgreementTemplateResponseDto>> getCoachesAgreementTemplates(@RequestHeader("X-AUTH-ID") String coachAuthId){
List<AgreementTemplateResponseDto> dtoList =
userService.getCoachAgreementTemplates(UUID.fromString(coachAuthId));

return ResponseEntity.ok().body(dtoList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.cm.clientservice.controller;
import com.cm.clientservice.dto.scheduling.movement.MovementCreateRequestDto;
import com.cm.clientservice.dto.scheduling.movement.MovementResponseDto;
import com.cm.clientservice.service.MovementService;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.UUID;

@RestController
@RequestMapping("/clients/movements")
@Tag(name="movements", description = "API for management of movements. ")
public class MovementController {

private final MovementService movementService;
public MovementController(MovementService movementService){
this.movementService = movementService;
}

@PostMapping
public ResponseEntity<MovementResponseDto> createMovement(@RequestBody MovementCreateRequestDto movementCreateRequestDto){
MovementResponseDto movementResponseDto =
movementService.createMovement(movementCreateRequestDto);

return ResponseEntity.ok().body(movementResponseDto);
}

@GetMapping("/{movementId}")
public ResponseEntity<MovementResponseDto> getMovementById(@PathVariable String movementId){
MovementResponseDto movementResponseDto =
movementService.getMovementById(UUID.fromString(movementId));

return ResponseEntity.ok().body(movementResponseDto);
}
}
Loading
Loading