-
Notifications
You must be signed in to change notification settings - Fork 56
Feedback system design #578
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
Open
nverbic
wants to merge
25
commits into
Women-Coding-Community:main
Choose a base branch
from
nverbic:feedback-system-design
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
a4a1986
Feedback API
nverbic d088391
Feedback API
nverbic 409fb56
Feedback API
nverbic e7c257a
Merge main into feedback-system-design
nverbic 8f4a5ab
Feedback API
nverbic de1fee3
Feedback API
nverbic c8cb676
Feedback API
nverbic aedc0b6
Merge branch 'main' into feedback-system-design
nverbic 144af13
Feedback API
nverbic 07d3614
Feedback API
nverbic 267cd09
Feedback API
nverbic 85c8cb7
Merge branch 'main' into feedback-system-design
nverbic cc261de
Feedback API
nverbic 71343cc
Feedback API
nverbic dd08294
Feedback API
nverbic cb42ef7
Feedback API
nverbic f2e8da5
Merge branch 'main' into feedback-system-design
nverbic 725032c
fix: Change package.json to Use Fixed Port and works on all environments
nverbic 5d1e8f1
Merge branch 'main' into feedback-system-design
nverbic d27fdbd
feat: Feedback - small updates
nverbic 80f682a
feat: Feedback - small updates
nverbic 3f363b6
Merge branch 'main' into feedback-system-design
nverbic 3074aea
Merge branch 'main' into feedback-system-design
nverbic 319d8ff
Merge branch 'main' into feedback-system-design
nverbic c980481
Revert package.json changes
nverbic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
179 changes: 179 additions & 0 deletions
179
src/main/java/com/wcc/platform/controller/FeedbackController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| package com.wcc.platform.controller; | ||
|
|
||
| import com.wcc.platform.domain.platform.feedback.Feedback; | ||
| import com.wcc.platform.domain.platform.feedback.FeedbackDto; | ||
| import com.wcc.platform.domain.platform.feedback.FeedbackSearchCriteria; | ||
| import com.wcc.platform.domain.platform.type.FeedbackType; | ||
| import com.wcc.platform.service.FeedbackService; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.security.SecurityRequirement; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import jakarta.validation.Valid; | ||
| import jakarta.validation.constraints.Max; | ||
| import jakarta.validation.constraints.Min; | ||
| import java.util.List; | ||
| import lombok.AllArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.validation.annotation.Validated; | ||
| import org.springframework.web.bind.annotation.DeleteMapping; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PatchMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.PutMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.ResponseStatus; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| /** Rest controller for feedback APIs. */ | ||
| @RestController | ||
| @RequestMapping("/api/platform/v1/feedback") | ||
| @SecurityRequirement(name = "apiKey") | ||
| @Tag(name = "Feedback", description = "Feedback management APIs") | ||
| @AllArgsConstructor | ||
| @Validated | ||
| public class FeedbackController { | ||
|
|
||
| private final FeedbackService feedbackService; | ||
|
|
||
| /** | ||
| * API to retrieve all feedback with optional filters. | ||
| * | ||
| * @param reviewerId Filter by reviewer ID | ||
| * @param revieweeId Filter by reviewee I) | ||
| * @param mentorshipCycleId Filter by mentorship cycle ID | ||
| * @param feedbackType Filter by feedback type | ||
| * @param year Filter by year | ||
| * @param isAnonymous Filter by anonymous status | ||
| * @param isApproved Filter by approval status | ||
| * @return List of feedback matching the criteria | ||
| */ | ||
| @GetMapping | ||
| @Operation(summary = "Get all feedback with optional filters") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public ResponseEntity<List<Feedback>> getAllFeedback( | ||
| @Parameter(description = "Reviewer ID") @RequestParam(required = false) final Long reviewerId, | ||
| @Parameter(description = "Reviewee ID") @RequestParam(required = false) final Long revieweeId, | ||
| @Parameter(description = "Mentorship Cycle ID") @RequestParam(required = false) | ||
| final Long mentorshipCycleId, | ||
| @Parameter(description = "Feedback Type") @RequestParam(required = false) | ||
| final FeedbackType feedbackType, | ||
| @Parameter(description = "Year") @RequestParam(required = false) @Min(2000) @Max(2100) | ||
| final Integer year, | ||
| @Parameter(description = "Anonymous status") @RequestParam(required = false) | ||
| final Boolean isAnonymous, | ||
| @Parameter(description = "Approved status") @RequestParam(required = false) | ||
| final Boolean isApproved) { | ||
| final FeedbackSearchCriteria criteria = | ||
| FeedbackSearchCriteria.builder() | ||
| .reviewerId(reviewerId) | ||
| .revieweeId(revieweeId) | ||
| .mentorshipCycleId(mentorshipCycleId) | ||
| .feedbackType(feedbackType) | ||
| .year(year) | ||
| .isAnonymous(isAnonymous) | ||
| .isApproved(isApproved) | ||
| .build(); | ||
|
|
||
| final List<Feedback> feedback = feedbackService.getAllFeedback(criteria); | ||
| return ResponseEntity.ok(feedback); | ||
| } | ||
|
|
||
| /** | ||
| * API to retrieve feedback by ID. | ||
| * | ||
| * @param feedbackId ID of the feedback | ||
| * @return Feedback details | ||
| */ | ||
| @GetMapping("/{feedbackId}") | ||
| @Operation(summary = "Get feedback by ID") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public ResponseEntity<Feedback> getFeedbackById( | ||
| @Parameter(description = "ID of the feedback") @PathVariable final Long feedbackId) { | ||
| final Feedback feedback = feedbackService.getFeedbackById(feedbackId); | ||
| return ResponseEntity.ok(feedback); | ||
| } | ||
|
|
||
| /** | ||
| * API to create feedback. | ||
| * | ||
| * @param feedbackDto DTO containing feedback data | ||
| * @return Created feedback | ||
| */ | ||
| @PostMapping | ||
| @Operation(summary = "Create feedback") | ||
| @ResponseStatus(HttpStatus.CREATED) | ||
| public ResponseEntity<Feedback> createFeedback( | ||
| @Valid @RequestBody final FeedbackDto feedbackDto) { | ||
| final Feedback feedback = feedbackService.createFeedback(feedbackDto); | ||
| return new ResponseEntity<>(feedback, HttpStatus.CREATED); | ||
| } | ||
|
|
||
| /** | ||
| * API to update feedback. | ||
| * | ||
| * @param feedbackId ID of the feedback to update | ||
| * @param feedbackDto DTO with updated feedback data | ||
| * @return Updated feedback | ||
| */ | ||
| @PutMapping("/{feedbackId}") | ||
| @Operation(summary = "Update feedback") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public ResponseEntity<Feedback> updateFeedback( | ||
| @Parameter(description = "ID of the feedback") @PathVariable final Long feedbackId, | ||
| @Valid @RequestBody final FeedbackDto feedbackDto) { | ||
| final Feedback feedback = feedbackService.updateFeedback(feedbackId, feedbackDto); | ||
| return ResponseEntity.ok(feedback); | ||
| } | ||
|
|
||
| /** | ||
| * API to approve feedback (admin only). | ||
| * | ||
| * @param feedbackId ID of the feedback to approve | ||
| * @return No content | ||
| */ | ||
| @PatchMapping("/{feedbackId}/approve") | ||
| @Operation(summary = "Approve feedback (admin only)") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public ResponseEntity<Void> approveFeedback( | ||
| @Parameter(description = "ID of the feedback") @PathVariable final Long feedbackId) { | ||
| feedbackService.approveFeedback(feedbackId); | ||
| return ResponseEntity.ok().build(); | ||
| } | ||
|
|
||
| /** | ||
| * API to set feedback anonymous status (to hide/show reviewer name). | ||
| * | ||
| * @param feedbackId ID of the feedback | ||
| * @param isAnonymous true to hide reviewer name, false to show reviewer name | ||
| * @return No content | ||
| */ | ||
| @PatchMapping("/{feedbackId}/anonymous-status") | ||
| @Operation(summary = "Update feedback anonymous status (to hide/show reviewer name)") | ||
| @ResponseStatus(HttpStatus.OK) | ||
| public ResponseEntity<Void> updateFeedbackAnonymousStatus( | ||
| @Parameter(description = "ID of the feedback") @PathVariable final Long feedbackId, | ||
| @Parameter(description = "Is anonymous") @RequestParam final Boolean isAnonymous) { | ||
| feedbackService.updateFeedbackAnonymousStatus(feedbackId, isAnonymous); | ||
| return ResponseEntity.ok().build(); | ||
| } | ||
|
|
||
| /** | ||
| * API to delete feedback. | ||
| * | ||
| * @param feedbackId ID of the feedback to delete | ||
| * @return No content | ||
| */ | ||
| @DeleteMapping("/{feedbackId}") | ||
| @Operation(summary = "Delete feedback") | ||
| @ResponseStatus(HttpStatus.NO_CONTENT) | ||
| public ResponseEntity<Void> deleteFeedback( | ||
| @Parameter(description = "ID of the feedback") @PathVariable final Long feedbackId) { | ||
| feedbackService.deleteFeedback(feedbackId); | ||
| return ResponseEntity.noContent().build(); | ||
| } | ||
| } | ||
16 changes: 16 additions & 0 deletions
16
src/main/java/com/wcc/platform/domain/exceptions/FeedbackNotFoundException.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.wcc.platform.domain.exceptions; | ||
|
|
||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| /** Platform Feedback not found exception. */ | ||
| @Slf4j | ||
| public class FeedbackNotFoundException extends RuntimeException { | ||
|
|
||
| public FeedbackNotFoundException(final Long feedbackId) { | ||
| super("Feedback with id: " + feedbackId + " not found."); | ||
| } | ||
|
|
||
| public FeedbackNotFoundException(final String message) { | ||
| super("Feedback not found: " + message); | ||
| } | ||
| } |
48 changes: 48 additions & 0 deletions
48
src/main/java/com/wcc/platform/domain/platform/feedback/Feedback.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.wcc.platform.domain.platform.feedback; | ||
|
|
||
| import com.wcc.platform.domain.platform.type.FeedbackType; | ||
| import jakarta.validation.constraints.Max; | ||
| import jakarta.validation.constraints.Min; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.NotNull; | ||
| import java.time.OffsetDateTime; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.EqualsAndHashCode; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
| import lombok.Setter; | ||
| import lombok.ToString; | ||
|
|
||
| /** Feedback for tracking member feedback. */ | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| @ToString | ||
| @EqualsAndHashCode | ||
| @Getter | ||
| @Builder(toBuilder = true) | ||
| public class Feedback { | ||
|
|
||
| @Setter private Long id; | ||
| @NotNull private Long reviewerId; | ||
| private String reviewerName; | ||
| private Long revieweeId; // For MENTOR_REVIEW | ||
| private String revieweeName; | ||
| private Long mentorshipCycleId; // For MENTORSHIP_PROGRAM | ||
| @NotNull private FeedbackType feedbackType; | ||
|
|
||
| @Min(1) | ||
| @Max(5) | ||
| private Integer rating; | ||
|
|
||
| @NotBlank private String feedbackText; | ||
|
|
||
| @Min(2000) | ||
| @Max(2100) | ||
| private Integer year; | ||
|
|
||
| @Setter private Boolean isAnonymous; | ||
| @Setter private Boolean isApproved; | ||
| private OffsetDateTime createdAt; | ||
| private OffsetDateTime updatedAt; | ||
| } |
58 changes: 58 additions & 0 deletions
58
src/main/java/com/wcc/platform/domain/platform/feedback/FeedbackDto.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package com.wcc.platform.domain.platform.feedback; | ||
|
|
||
| import com.wcc.platform.domain.platform.feedback.validation.ValidFeedback; | ||
| import com.wcc.platform.domain.platform.type.FeedbackType; | ||
| import jakarta.validation.constraints.Max; | ||
| import jakarta.validation.constraints.Min; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.NotNull; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| /** DTO for feedback creation/update - uses IDs for member identification. */ | ||
| @Getter | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| @Builder | ||
| @ValidFeedback | ||
| public class FeedbackDto { | ||
| private Long id; | ||
| @NotNull private Long reviewerId; | ||
| private Long revieweeId; | ||
| private Long mentorshipCycleId; | ||
| @NotNull private FeedbackType feedbackType; | ||
|
|
||
| @Min(1) | ||
| @Max(5) | ||
| private Integer rating; | ||
|
|
||
| @NotBlank private String feedbackText; | ||
|
|
||
| @Min(2000) | ||
| @Max(2100) | ||
| private Integer year; | ||
|
|
||
| @NotNull private Boolean isAnonymous; | ||
|
|
||
| /** | ||
| * Convert to domain object. | ||
| * | ||
| * @return Feedback domain entity | ||
| */ | ||
| public Feedback merge() { | ||
| return Feedback.builder() | ||
| .id(id) | ||
| .reviewerId(reviewerId) | ||
| .revieweeId(revieweeId) | ||
| .mentorshipCycleId(mentorshipCycleId) | ||
| .feedbackType(feedbackType) | ||
| .rating(rating) | ||
| .feedbackText(feedbackText) | ||
| .year(year) | ||
| .isAnonymous(isAnonymous) | ||
| .isApproved(false) // Default - requires admin approval | ||
| .build(); | ||
| } | ||
| } |
25 changes: 25 additions & 0 deletions
25
src/main/java/com/wcc/platform/domain/platform/feedback/FeedbackSearchCriteria.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package com.wcc.platform.domain.platform.feedback; | ||
|
|
||
| import com.wcc.platform.domain.platform.type.FeedbackType; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.EqualsAndHashCode; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
| import lombok.ToString; | ||
|
|
||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| @ToString | ||
| @EqualsAndHashCode | ||
| @Getter | ||
| @Builder | ||
| public class FeedbackSearchCriteria { | ||
| private Long reviewerId; | ||
| private Long revieweeId; | ||
| private Long mentorshipCycleId; | ||
| private FeedbackType feedbackType; | ||
| private Integer year; | ||
| private Boolean isAnonymous; | ||
| private Boolean isApproved; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.