Skip to content

feat: Mentee registration end-to-end#541

Merged
dricazenck merged 20 commits intoWomen-Coding-Community:mainfrom
dricazenck:fix_mentee_registration
Mar 7, 2026
Merged

feat: Mentee registration end-to-end#541
dricazenck merged 20 commits intoWomen-Coding-Community:mainfrom
dricazenck:fix_mentee_registration

Conversation

@dricazenck
Copy link
Collaborator

@dricazenck dricazenck commented Mar 5, 2026

Description

Implements the full mentee registration flow, including mentor validation,
duplicate handling, cycle resolution, and role provisioning.

Key changes:

Registration logic (MenteeService):

  • Validate mentor existence before saving any application
  • Default cycleYear to current year when omitted in the request
  • Resolve mentee identity by ID (with stale-ID fallback) or email lookup
  • Preserve existing member types when promoting a member to mentee
  • Filter out duplicate mentor applications already registered in the cycle
  • Validate unique priority order within the request and against existing
    applications (DuplicatedPriorityException → 409 Conflict)
  • Ensure provisionUserRole is called in all registration paths, including
    when the mentee already has applications in the cycle

Repository fixes:

  • PostgresCountryRepository: throw ContentNotFoundException instead of
    silently returning a default ID when a country code is not found
  • PostgresMemberMemberTypeRepository: replace SELECT COUNT + INSERT with
    INSERT ... ON CONFLICT DO NOTHING to eliminate the race condition
  • PostgresMenteeApplicationRepository: add @transactional to create to
    make the duplicate-check and insert atomic
  • PostgresMentorRepository: fix misleading exception messages (use ID
    not object toString; distinguish save failure from not-found)

Exception hierarchy:

  • Introduce DuplicatedException as a common base for all duplicated-record
    exceptions, reducing import count in GlobalExceptionHandler

Quality and tooling:

  • Add PMD pre-commit hook with custom rulesets for main and test sources
  • Fix pre-push hook to use git merge-base for safe base-ref resolution
  • Update long-term mentorship timeline JSON to 2026 cycle dates
  • Add unit tests for PostgresCountryRepository, expand MenteeServiceTest
    with duplicate priority and existing-application scenarios
  • Refactor MenteeServiceIntegrationTest for clearer coverage

Change Type

  • Bug Fix
  • Refactor

Pull request checklist

Please check if your PR fulfills the following requirements:

…andling

- Added logic to handle mentee updates or creation based on registration inputs.
- Introduced duplicate application detection and suppression during registration.
- Updated test cases to validate the new behaviors, including integration tests.
- Eliminated unused `menteeId` parameter from `MenteeApplicationDto`.
- Updated integration, unit tests, and serialization logic to reflect the change.
- Added `@Schema` annotation to auto-generate member ID with a description in `Member`.
- ensure Mentee exists before persistency
- Added unit tests to verify fallback to existing member by email when the provided ID does not exist during mentee registration.
- Included test to ensure existing mentee is used directly if the ID exists, avoiding unnecessary email lookups.
…and mentor operations

- Added checks to reuse existing mentors and mentees by ID or email before creation.
- Updated repositories to handle null or empty query results gracefully, defaulting values when necessary.
- Introduced new custom exceptions for clearer error messages (e.g., MentorNotFoundException, ContentNotFoundException).
- Enhanced test coverage for updated repository behavior, including fallback scenarios and null-handling logic.
- Replaced deprecated JdbcTemplate methods with more resilient query implementations.
- Minor refactors for code readability and maintenance.
Remove unused Image and ImageType imports that became stale after earlier
refactoring. Replace hardcoded image fixtures with empty lists since
image create/update behaviour is out of scope for this test and tracked
separately. Add isWomen field to the update member builder to align with
the current Member schema.
These changes address PMD static analysis violations across several
repository and exception classes. Ternary expressions inside
ResultSetExtractor lambdas are expanded to block statements to comply
with PMD rules, a `final` modifier is added to a method parameter in
MentorNotFoundException, and `!isPresent()` is replaced with the more
idiomatic `isEmpty()` in PostgresMenteeRepository. A
`@SuppressWarnings("PMD.TooManyMethods")` annotation is added to
PostgresMentorshipMatchRepository where the method count is
architecturally justified. CLAUDE.md is updated to document the
pre-commit hook and PMD checklist for future contributors.
The pre-commit hook was incomplete — it only handled frontend lint-staged
but did not enforce Java code quality checks. This adds automated PMD
analysis on staged Java files, blocking commits when violations are found.
README and CLAUDE.md are updated to document the hook.

MenteeService gets a class-level Javadoc. MenteeServiceIntegrationTest is
refactored to extract shared setup/assertion helpers, eliminate duplication,
and use named constants for years and limits, improving readability.
@dricazenck dricazenck changed the title feat: Add check if mentor exists for mentee registration feat: Mentee registration end2end Mar 7, 2026
@dricazenck dricazenck changed the title feat: Mentee registration end2end feat: Mentee registration End to End Mar 7, 2026
@dricazenck dricazenck changed the title feat: Mentee registration End to End feat: Mentee registration end-to-end Mar 7, 2026
The cycleYear field in MenteeRegistration was annotated with @NotNull,
which prevented registrations without an explicit year. This change
removes the @NotNull constraint and adds a fallback in MenteeService to
use the current year when cycleYear is null, making the field optional
for clients. A unit test is added to verify the default year behaviour.
The inline mentee persistence logic in saveRegistration was complex and
did not preserve existing member types when a member with other roles
(e.g. MENTOR) registered as a mentee. Extracting into dedicated private
methods (createOrUpdateMentee, handleMenteeWithId, handleMenteeWithoutId,
mergeMemberTypes) improves readability and correctness. A test covering
the member-type merge scenario is added to prevent regressions. PMD
thresholds for TooManyMethods and CouplingBetweenObjects are relaxed to
accommodate the grown service and test class.
The comment "Check if member exists and preserve member types" restated
what the surrounding code already made clear through its structure and
variable names. Removing it keeps the codebase consistent with the
project convention of avoiding obvious inline comments.
…lure

The findCountryIdByCode method was silently returning a hardcoded default
ID of 1L when a country code was not found, which could cause incorrect
data associations downstream. Replace this with a proper ContentNotFoundException
to surface the error early. Add a full unit test suite for
PostgresCountryRepositoryTest covering all CRUD operations and the new
exception behaviour, fixing an InvalidUseOfMatchersException caused by
using ArgumentMatchers.any() in a static field initializer outside of a
Mockito stubbing context.
Prevents mentees from submitting applications with duplicate priority
orders, both within a single request and against existing applications
in the same mentorship cycle. Introduces DuplicatedPriorityException,
registers it in GlobalExceptionHandler to return 409 Conflict, and
covers both scenarios with unit tests.

Also introduces DuplicatedException as a common base class for all
duplicated-record exceptions to reduce coupling in GlobalExceptionHandler.
- Fix misleading MentorNotFoundException messages in PostgresMentorRepository:
  create now says "not found after save for id" and update uses mentorId not the object
- Replace SELECT COUNT + INSERT with INSERT ON CONFLICT DO NOTHING in
  PostgresMemberMemberTypeRepository to eliminate the race condition
- Ensure provisionUserRole is called even when mentee already has applications
  in the cycle (early-return path previously skipped role provisioning)
- Remove no-op toRegistration() from MenteeRegistration record
- Fix PostgresCountryRepositoryTest to invoke the actual ResultSetExtractor lambda
  via doAnswer so the not-found code path is properly exercised
The timelineLongTermPage.json had stale 2025 dates; updated to reflect
the 2026 mentorship cycle with more flexible/accurate durations. Also
adds @transactional to PostgresMenteeApplicationRepository.create to
ensure the duplicate-check and insert run atomically, preventing
a partial state if the insert fails after the check succeeds.
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 7, 2026

@dricazenck dricazenck merged commit 9c6a386 into Women-Coding-Community:main Mar 7, 2026
3 checks passed
@dricazenck dricazenck deleted the fix_mentee_registration branch March 7, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants