Feedback system design#578
Conversation
Implement API for Community, Mentorship and Mentor feedback.
Add feedback migration file.
Update migration file name.
- Accepted mentorship cycle implementation from main - Resolved GlobalExceptionHandler conflict - Feedback system integrated with cycle tracking - Fixed V34 migration to reference mentorship_cycles table - All 15 mentorship cycle files accepted from main
Update/add mentor.json, feedback.json, mentee.json
|
I will remove two admin files that were updated by accident. |
| feedback.getIsApproved()); | ||
|
|
||
| // Return the last inserted ID | ||
| return jdbc.queryForObject("SELECT LASTVAL()", Long.class); |
There was a problem hiding this comment.
I am not sure that is the best way to get the id of the feedback I would play safe, make void and if we need the id later it should be made select to get the id. If there are concurrency, this could be incorrect.
There was a problem hiding this comment.
@dricazenck The id is needed in order to return feedback object when creating it, like in MemberMapper here
| @@ -0,0 +1,8 @@ | |||
| { | |||
| "reviewerId": 1, | |||
There was a problem hiding this comment.
[WARNING] Debug/test file committed to the repository root
feedback-post-request.json looks like a local Swagger/curl test file that was accidentally included. It should not be committed — it adds noise to the repo and would need maintenance as the API evolves.
Please delete this file before merging.
| @Override | ||
| public Feedback update(final Long id, final Feedback entity) { | ||
| feedbackMapper.updateFeedback(entity, id); | ||
| return entity; |
There was a problem hiding this comment.
[WARNING] update() returns the passed-in entity, not what is in the database
After updateFeedback() runs, the returned entity object will not have the updated_at timestamp set (it comes from CURRENT_TIMESTAMP in SQL), and reviewerName/revieweeName are not persisted at all. Callers of updateFeedback will see stale metadata in the response.
Consider re-fetching after update, similar to what create() already does:
@Override
public Feedback update(final Long id, final Feedback entity) {
feedbackMapper.updateFeedback(entity, id);
return findById(id).orElseThrow();
}| import static org.hamcrest.Matchers.is; | ||
| import static org.mockito.ArgumentMatchers.any; | ||
| import static org.mockito.ArgumentMatchers.argThat; | ||
| import static org.mockito.ArgumentMatchers.eq; |
There was a problem hiding this comment.
[WARNING] Tests are missing @DisplayName — project convention
Per the project conventions in CLAUDE.md, all tests should use @DisplayName with Given-When-Then format:
@Test
@DisplayName("Given a valid MENTOR_REVIEW DTO, when createFeedback is called, then it returns HTTP 201 with the created feedback")
void testCreateFeedbackReturnsCreated() { ... }This applies to all test methods in FeedbackControllerTest, FeedbackDtoValidationTest, FeedbackServiceTest, PostgresFeedbackRepositoryTest, and FeedbackMapperTest. Also, test method names could follow the should prefix convention (e.g., shouldReturnCreatedWhenFeedbackIsValid).
womencodingcommunity
left a comment
There was a problem hiding this comment.
Great effort on this feature — the architecture is well-thought-out, the layered structure is clean, and the custom @ValidFeedback constraint is a nice pattern. The test coverage is a solid start too. There are three critical issues that need to be resolved before merging, and a few warnings worth addressing:
Must fix before merge:
@Validmissing on@RequestBody— neither field-level nor class-level validation triggers without it (createFeedback,updateFeedback)SELECT LASTVAL()race condition — useRETURNING idin the INSERT insteadFeedbackType.fromId()silent fallback — throwsIllegalArgumentExceptioninstead of returningCOMMUNITY_GENERALfor unknown IDs
Should address:
feedback-post-request.jsoncommitted to repo root — please remove- DB
rating CHECK >= 0vs Java@Min(1)inconsistency; missing DB constraint forMENTORSHIP_PROGRAMrequiringmentorship_cycle_id update()returns in-memory entity —updated_atand names will be stale in responsereviewerName/revieweeNameset in service but not persisted or joined on read — they will always benullfromGETendpointsisAnonymousprivacy logic not enforced on GET responses- All test methods need
@DisplayNamewith Given-When-Then format (project convention)
The TODO items in the PR description (PATCH methods, more Swagger testing, reaching 70% coverage) should be tracked as follow-up issues before this is considered production-ready.
Update Feedback.java and FeedbackSearchCriteria to use only needed lombok annotations Update FeedbackController.java - use Patch instead of Put for approveFeedback and setFeedbackAnonymousStatus Update/Add tests Feedback coverage is above 70% threshold. Implement PMD suggestions.
"chore: rename feedback migration to V36 to maintain chronological order after main merge"
# Conflicts: # src/main/java/com/wcc/platform/configuration/GlobalExceptionHandler.java
Fix SonarQube issues.
Implement PR suggestions - add @Valid to FeedbackDTO create and update - add @DsiaplyName to tests - update FeedbackMapper addFeedback() to query database instead of using SELECT LASTVAL() when returning values. - update tests - Update FeedbackType to throw exception if nonexisting typeId passed to fromId() function - Fix PostgresFeedbackRepository update() to return feedback object from database and not just the same entity that is passed to update() as arg.
- Update of migration file. Change rating range and add constraint.
Update FeedbackMapper - set reviewer and reviewee names instead of nulls. Update FeedbackMapper tests. Update Feedback - Remove Setter for Reviewer Name and Reviewee Name. Update PostgresFeedbackRepository SELECT sql queries to join members and feedback to retrieve member's names. Update tests to reflect join between members and feedback tables. Update application.yml to contain also option to host admin app on 3001 port.
Implement PMD suggestions.
Implement PMD suggestions.
Implement PMD suggestions.
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
- change dev amd start scripts to "dev": "next dev -p 3001" and start": "next start -p 3001",
| package com.wcc.platform.repository.postgres.constants; | ||
|
|
||
| /** Constants related to Feedback entity. */ | ||
| @SuppressWarnings({"PMD.DataClass", "PMD.LongVariable"}) |
There was a problem hiding this comment.
don't suppress warnings, they are here for a good reason. Please fix them ;)
| public static final String COLUMN_REVIEWER_NAME = "reviewer_name"; | ||
| public static final String COLUMN_REVIEWEE_NAME = "reviewee_name"; | ||
| public static final String COLUMN_MENTORSHIP_CYCLE_ID = "mentorship_cycle_id"; | ||
| public static final String COLUMN_FEEDBACK_TYPE_ID = "feedback_type_id"; |
There was a problem hiding this comment.
For example:
| public static final String COLUMN_FEEDBACK_TYPE_ID = "feedback_type_id"; | |
| public static final String COL_FEEDBACK_TP = "feedback_type_id"; |
|
|
||
| /** Constants related to Feedback entity. */ | ||
| @SuppressWarnings({"PMD.DataClass", "PMD.LongVariable"}) | ||
| public final class FeedbackConstants { |
There was a problem hiding this comment.
this can be a record ;)
There was a problem hiding this comment.
@dricazenck I have chated with Claude. The suggestion is to keep DataClass. MemberConstants and MentorConstants in the same package are final class as well. What do you think?
| * the result sets to Feedback objects with the help of FeedbackRowMapper. | ||
| */ | ||
| @Repository | ||
| @Primary |
There was a problem hiding this comment.
No need to add primary, when only one class implements the interface ;)
| @@ -0,0 +1,49 @@ | |||
| -- Table for feedback types | |||
| CREATE TABLE IF NOT EXISTS feedback_types | |||
There was a problem hiding this comment.
make sure to review the data and version of the migration to avoid conflicts in case anyone create another migration, otherwise this migration won't work.
- Restrict Year parameter to min and max range (2000 - 2100). Validate Year already in controller. Update tests. - Shorter names for feedback column names constants - Remove Primary from PostgresFeedbackRepository class
- fix PMD warnings
|
@ Feedback is ready for merge.
|
# Conflicts: # src/main/resources/init-data/mentor.json
|
|
@dricazenck @goelsonali @Sowmiya07 Ladies, just a litte reminder for this PR. It is completed. Some time has passed so I will have to do changes (at least in the migration). Pleas just give me green light, so we can merge. |



Description
Implement feedback APIs.
Three Feedback Types:
Architecture
Tables Created
1. feedback_types (Lookup Table)
2. feedback (Main Table)
Constraints
Data Privacy
isAnonymous=true→reviewerNamenot shown when feedback is published.Protects reviewer identity
Reviewer can toggle anonymity
Default:
isApproved=falseOnly approved feedback visible to public
Admin controls publication
Feedback API Coverage Analysis Report
Generated: April 6, 2026
Source: build/reports/jacoco/test/jacocoTestReport.xml
Executive Summary
✅ PASS: Feedback API meets 70% coverage threshold on all metrics!
The Feedback API implementation has excellent test coverage across all layers:
TODO:
Related Issue
Please link to the issue here
Change Type
Screenshots
Pull request checklist
Please check if your PR fulfills the following requirements: