-
Notifications
You must be signed in to change notification settings - Fork 0
Final Milestone Deliverables
Group Number: 7
Tracking issue: #424 Sub-issues: #413 #414 #415 #416 #417 #418 #419 #420 #421 #422 #423
- Weekly Meeting Notes: Weekly Meeting 1 | Weekly Meeting 2 | Weekly Meeting 3 | Weekly Meeting 4 | Weekly Meeting 5 | Weekly Meeting 6 | Weekly Meeting 7 | Weekly Meeting 8 | Weekly Meeting 9
- Lab Meeting Notes: Lab Meeting 1
- Customer Meeting: Customer Meeting #1
- Stakeholder Meeting: Stakeholder Meeting #1
- Final SRS: Requirements (wiki) — authoritative requirements document, last edited prior to the Final Milestone freeze.
-
Final Design — UML Diagrams (Final):
- Use Case Diagram (Final) — 5 actors + ~165 use cases verified against the deployed REST + scheduler surface
- Class Diagram (Final) — 6 bounded-context blocks (Identity & Profile, Mentorship Lifecycle, Social Feed, Messaging & Attachments, Notifications & Moderation, Key Services) covering ~56 JPA entities + 14 enums
- Sequence Diagrams (Final) — 12 end-to-end workflows: onboarding, cancel/ban/lift, post fanout, For-You + bandit, feed search + mute, mentor-pair messaging, scheduled auto-completion, report + admin resolve, meeting lifecycle (schedule → confirm/decline → reschedule → reminders → auto-cancel), end-mentorship + mentee rates mentor, task assign / submit / review cycle (APPROVED / NEEDS_REVISION), and follow + Neo4j projection sync + FCM push fanout
- Deployed Web App: https://mymentornet.org
- Mobile Release: GitHub Release — final-milestone
-
Project Status Summary:
MentorMatch is feature-complete and deployed. All core requirements from the SRS have been implemented across backend, web frontend, and mobile. The final milestone added advanced AI-powered mentor matching with OpenAI embeddings and LLM-generated explanations, a full social feed ecosystem (posts, likes, comments, reposts, bookmarks, image attachments, real-time updates), a reporting and moderation system, an admin console with ban management, profile visibility controls, and a significantly expanded mobile experience. The system is containerized, deployed on DigitalOcean, and accessible at the live URL above.
-
Deliverable Status:
Deliverable Status Software release (tag: final-milestone)✅ Completed — 12.05.2026 Deployed web application ✅ Running at live URL Mobile APK ✅ Attached to GitHub Release Final SRS ✅ Available on wiki UML Diagrams (Class, Use Case, Sequence) ✅ Available on wiki Meeting notes ✅ Available on wiki Test reports (backend, web, mobile) ✅ Available in repository Individual contributions ✅ All 8 members documented README with setup instructions ✅ Covers web, Docker, mobile, seeding -
Final Release Notes:
Release
1.0.0(final-milestone) ships the following major additions over the previous milestone:Backend: Advanced AI mentor ranker (OpenAI embeddings, 7 scoring signals, MMR diversity reranker, LLM prose explanations), Neo4j follow-graph mirror with Personalized PageRank, social feed lifecycle (create/edit/restore/soft-delete), image attachments, reposts, comment likes, trending hashtags, feed search/filter/mute, real-time STOMP fanout, feed engagement push notifications, reporting system with state machine and admin moderation queue, admin panel (user list, broadcast messaging, ban system), profile visibility toggle with masking, mentee affiliation field, rating endpoints, mentorship status filter, AS 2.0 / Schema.org JSON-LD on all feed endpoints.
Web: AI match factor chips and LLM explanation display, social feed with real-time updates, image attachments, repost/quote-share, edit history, comment likes, search/filter, trending hashtags, who-to-follow rail, reporting flows, admin console, profile visibility, ESCO/ISCED-F/Wikidata taxonomy autocomplete, hybrid location entry, mentor rating prompt, extend-mentorship modal, weekly calendar view, notification preferences.
Mobile: Social feed with full engagement (likes, comment likes, reposts, bookmarks, image attachments, edit history, real-time STOMP), blog/user posts screen, who-to-follow, trending hashtags, mentee affiliation, mentorship report modal, past mentorship stats, meeting session gating, ban handling, silent error suppression.
-
Process Improvements:
- Parallel feature development: Backend, web, and mobile teams worked on separate feature branches simultaneously, reducing blocking dependencies. This led to a higher merge volume but required more careful conflict resolution.
-
CI enforcement: Mobile, web, and backend CI pipelines were enforced on every PR. This caught a lint regression (
react/no-unescaped-entities), a missing brace in a test file, and several type errors before they reacheddev. -
Seed data automation: A Python seed script (
scripts/seed_local.py) was added to populate the database with realistic personas automatically, making local setup and demo preparation much faster. -
APK automation: A GitHub Actions workflow (
mobile-build-apk.yml) was added to build and upload the Android APK as a CI artifact on every push tomainordev. - Issue tracking: Each deliverable section was tracked via a parent issue (#424) with sub-issues per owner, making progress visible and reducing last-minute ambiguity.
-
Final Milestone Demo Reflections:
See Final Demo Notes and Final Demo Reflections wiki pages.
-
What Could Have Been Done Differently:
- Earlier API contract alignment between teams: Several integration bugs (e.g., incorrect field names, missing flags in responses) were discovered late because frontend and mobile started integrating before backend APIs were fully stable. Defining and freezing API contracts earlier — even as OpenAPI stubs — would have reduced rework.
-
Environment variable management: The
.env.examplefile was incomplete for much of the project, causing setup issues for new contributors. Maintaining it alongside feature development (not at submission time) would have saved time. - Test coverage for mobile: Mobile UI tests were added but coverage remained lower than backend and web. Establishing a mobile testing baseline earlier would have caught regressions sooner.
| Team Member | Subgroup | Contributions (Summary) | Major PRs/Issues |
|---|---|---|---|
| Amin Abu-Hilga | Web Lead / DevOps | Web app architecture & shared API client; web auth + session (#202, #205); profile system — device photo upload, ESCO/ISCED-F/Wikidata taxonomy autocomplete, hybrid location, visibility toggle (#359), notification preferences, posts-on-profile; chat & messaging (#121, #122, #287); social feed lifecycle — posts, edits, reposts, image attachments, real-time STOMP, bookmarks, trending hashtags, search/filter, edit-history (#339, #340); notifications page + engagement renderer (#292); weekly availability + meetings (#336, #337, #338); mentorship lifecycle UI — tasks (#125), milestones (#288), progress timeline (#126), cancel (#127), ratings, extend, ended-banner; admin console (#279) & reporting trio (#128, #358, #411); admin broadcast (#410); spam-bot defence frontend wiring (#345); advanced mentor search + 3-mentor comparison (#139); CI/CD — frontend pipeline (#148) + prod auto-deploy (#213, #138); CORS / verification-email backend fixes; web README rewrite + local-seed pipeline |
PRs: #150 (frontend CI pipeline), #224 (prod droplet auto-deploy on push to main), #564 (feed real-time STOMP + unread badge), #588 (reporting trio — post / mentor / mentorship), #590 (admin console — moderation + report queue), #592 (advanced mentor search + 3-mentor comparison modal) · Issues: #148 (Frontend Testing & CI Setup), #213 (Production Deployment — droplet, domain, CI/CD), #139 (Advanced Mentor Search Filters + Comparison View), #279 (Admin Panel — User Management & Report Review) |
| Övgü Su Afşar | Mobile | Second mobile developer (with Burak Ögüt) on the React Native / Expo app; mobile auth-recovery + email verification parity with web (#303); banned-user login handling; mentor availability editor refinement (#141); meeting-schedule + reschedule screen (#144); chat attachments + mentor-to-mentor messaging on mobile (#256); unread-state indicator in messaging; mobile social feed — post creation (#361), interactions (#362), feed tabs (#360); mobile task-detail + feedback flow (#263); mobile shared goals + milestones (#260); mentorship progress timeline + meeting-notes screen; mobile testing infrastructure (#257, #318) — Jest setup, critical-flow tests, screen-level tests; mobile accessibility audit (#259); native push notification setup (#249 — co-authored with Burak Ögüt); final-demo checklist (#269) | PRs: #374 (mobile Jest setup + auth-flow tests), #381 (mobile accessibility audit), #444 (mobile screen tests — messages / profile / feed), #502 (mentorship progress timeline + meeting notes + UX fixes), #306 (mobile auth recovery + verify-email parity), #398 (mobile social feed interactions) · Issues: #257 (Mobile Automated Testing Setup for Critical Flows), #259 (Mobile Accessibility Audit and Improvements), #303 (Mobile Auth Recovery and Email Verification Parity), #141 (Mentor Availability Editing Screen) |
| Muhammet Sami Çakmak | Web | Shared-goal flow, follow UI, feed interactions, profile fixes, seed data, notification UI, mentor capacity, dynamic dropdown | PR #481, PR #505, PR #457 |
| Beratcan Doğan | Backend | Mentorship lifecycle (cancellation, extend/end, auto-completion, ratings), admin ban/messaging, temporary ban system, FCM push notifications, follow recommendations, spam-bot defences, E2E test suite, production deployment | PR #439, PR #449, PR #443 |
| İbrahim Kayan | Backend | Meeting scheduling, task assignment, milestones, reminders, mentorship timeline preservation, author-based feed posts | PR #352, PR #370, PR #491 |
| Burak Ögüt | Mobile | Social feed (reposts, bookmarks, comment likes, STOMP, image attachments, edit history), blog screen, mentorship timeline, ban handling | PR #587, PR #526, PR #502 |
| Mehmet Bora Sarıoğlu | Backend (lead) & DevOps | Backend lead and project coordinator during the Final Milestone. Drove project planning and organisation across the lab cycle, represented the team in instructor and TA meetings, and performed the deployment plus dry-run for the Final Milestone presentation. Owned the implementation of the social feed end-to-end, the three advanced recommendation rankers , the polymorphic reporting and admin moderation lifecycle, the mentorship history and rating endpoints, profile-visibility masking, the reproducible demo-seed snapshot pipeline, and the production Neo4j compose. Reviewed every lab deliverable and checked the accepntence test and fixed and rewrote them. Also acted as the team communicator. | PR #604 reproducible demo seed (2026-05-13) · PR #599· PR #574· PR #500 feed soft-delete + edit-history + restore + trending (2026-05-12) · PR #497· PR #470 Issues: #135, #437, #438, #487, #424, #417, #416 |
Audit date: 13.05.2026
This section is the Final Milestone deliverable that records, for every functional and non-functional requirement listed on the project wiki, the implementation status in the codebase. Each row links the requirement text from the SRS to the concrete piece of code (controller / service / entity / Flyway migration / scheduler) that backs it. Rows that are not implemented in full carry a one-line reason explaining what is missing or why the row was descoped.
-
SRS reference:
Requirements.mdon the project wiki, revision3792b57fee707f65f8f151db7db0fb424679e53a(last edited prior to the Final Milestone freeze). -
Codebase reference: Spring Boot 3 backend at
backend/, React web client atfrontend/, Expo / React Native client atmobile-app/, production deployment viadocker-compose.prod.yml+.github/workflows/deploy.yml. -
Total requirements: 122 (111 functional leaf rows under 1.1.x and 1.2.x + 11 non-functional under 2.x). A handful of requirement IDs (1.1.1.2.7, 1.1.5.3, 1.1.7.4, 1.2.1.1, 2.3.1, 2.3.4) are reported with two rows each — one for the part that ships, one for the part that does not — so the table contains a few more rows than there are SRS IDs. Two additional rows (
2.xHA,1.2.3OAuth/SSO) are out-of-scope items called out for marker transparency and are not in the SRS.
Summary count (worst-case status per unique SRS ID, plus the two extra OOS rows): Completed: 114 / In Progress: 3 / Not Started: 4 / Out of Scope: 3 — 124 rows total (122 SRS IDs + 2 supplementary OOS rows). Both advanced recommendation pipelines (advanced For-You feed ranker with Thompson-sampling bandit, and advanced mentor matching ranker with LLM-grounded explanations) ship in main with full unit + integration coverage; they are wired and exercised end-to-end and the production operator-flag flip is a one-line .env change rather than missing work.
Status legend:
- ✅ Completed — implemented, tested, documented, and deployed.
- 🟡 In Progress — partial / merged but behind a feature flag / shipped but with caveats.
- ❌ Not Started — no implementation work has landed in the codebase.
- ⏸ Out of Scope — explicitly descoped during the project.
| # | Requirement (verbatim from SRS) | Status | Evidence / Notes |
|---|---|---|---|
| 1.1.1.1.1 | Mentees shall be able to create and edit their profile. | ✅ Completed |
AuthController.register + UserController.updateMentee (PATCH /api/users/me/mentee, @PreAuthorize("hasRole('MENTEE')")); Mentee entity persists via UserService. |
| 1.1.1.1.2 | Mentees shall be able to specify their goals, interests, and background information. | ✅ Completed |
MenteeProfileRequest fields (goals, interests, backgroundInfo, skills, career_interest); persisted on Mentee entity with ESCO/Wikidata-tagged terms via TaxonomyService. |
| 1.1.1.1.3 | Mentees shall be able to view recommended mentor profiles. | ✅ Completed |
MatchingController.getTopMentors (GET /api/matching/mentors) + MatchingService + MentorScoringPipeline (curated 5-slot page-zero + ranked tail). |
| 1.1.1.1.4 | Mentees shall be able to send mentorship requests to mentors. | ✅ Completed |
MentorshipRequestController.createRequest (POST /api/mentorship-requests) + MentorshipRequestService enforces capacity + cooldown via MentorshipCooldownPolicy. |
| 1.1.1.1.5 | Mentees shall be able to communicate with mentors through the in-app messaging system. | ✅ Completed |
MessageController.sendMessage (POST /api/conversations/{id}/messages) + STOMP fanout on /topic/conversation/{id} via ChatStompController; conversation created on accept by ConversationCreator. |
| 1.1.1.1.6 | Mentees shall be able to submit assignments or tasks assigned by their mentor. | ✅ Completed |
TaskController.submitTask (POST /api/tasks/{id}/submission) + TaskSubmission entity; supports attachmentIds for uploaded files. |
| 1.1.1.1.7 | Mentees shall be able to view feedback given by their mentor. | ✅ Completed |
TaskController.getTaskDetail (GET /api/tasks/{id}) returns submission history with feedback from Task.feedback set by PATCH /api/tasks/{id}/feedback. |
| 1.1.1.1.8 | Mentees shall be able to view scheduled meetings. | ✅ Completed |
MeetingController.listMeetings + MeetingController.getMeeting; Meeting entity with meetingLink, status, recurrence rule. |
| 1.1.1.1.9 | Mentees shall be limited to one active mentor at a time. | ✅ Completed |
Mentee.activeMentorId column (Flyway V4) + MentorshipPreconditions rejects new active requests when set; cleared by MentorshipCleanupService on termination. |
| 1.1.1.1.10 | Mentees shall be able to search for mentors using a keyword-based search bar. | ✅ Completed |
UserController.searchUsers (GET /api/users/search) + UserController.listMentors keyword filter; backed by UserRepository ILIKE indexes (Flyway V19). |
| 1.1.1.1.11 | Mentees shall be able to rate their mentor on a scale of 1 to 5 stars after the mentorship relationship ends. | ✅ Completed |
MentorshipController.rateMentor (POST /api/mentorships/{id}/rating) + MentorRatingService; 409 if mentorship still ACTIVE or already rated. Flyway V33. |
| 1.1.1.1.12 | Mentees shall be able to cancel the relationship before the duration ends. | ✅ Completed |
MentorshipController.cancelMentorship (POST /api/mentorships/{id}/cancel) + MentorshipService.cancelMentorship; records cancellation against BanService for the auto-ban escalation. |
| 1.1.1.1.13 | Mentees shall be able to report mentors by specifying a problem for admin investigation. | ✅ Completed |
ReportController.submitReport (POST /api/reports) with target_type=USER; admin sees them via AdminReportController. |
| 1.1.1.1.14 | Mentees shall be able to follow other users to see their posts in the Following feed. | ✅ Completed |
FollowController.followUser (POST /api/users/{id}/follow) + FeedReadController.following (GET /api/feed/following) reads via FeedReadService. |
| 1.1.1.1.15 | Mentees shall be able to unfollow users they previously followed. | ✅ Completed |
FollowController.unfollowUser (DELETE /api/users/{id}/follow); deletes Follow row, decrements counters. |
| 1.1.1.1.16 | Mentees shall be able to view a list of their active and past mentorships. | ✅ Completed |
MentorshipController.getActiveMentorships + getMentorshipsByStatus (GET /api/mentorships?status=ALL); paginated history (#521). |
| 1.1.1.2.1 | Mentors shall be able to create and edit their profile. | ✅ Completed |
UserController.updateMentor (PATCH /api/users/me/mentor, @PreAuthorize("hasRole('MENTOR')")); Mentor entity. |
| 1.1.1.2.2 | Mentors shall be able to define mentoring goals and preferred mentee criteria. | ✅ Completed |
MentorProfileRequest (mentoringGoals, preferredMenteeSkills, preferredMenteeMajor, etc.); persisted on Mentor entity. |
| 1.1.1.2.3 | Mentors shall be able to define their availability schedule. | ✅ Completed |
AvailabilityController (PUT /api/availability bulk + per-slot CRUD) + AvailabilityOverrideService for exceptions (Flyway V18); iCal export at /availability/{mentorId}/ical. |
| 1.1.1.2.4 | Mentors shall be able to view candidate mentee profiles (background, goals, interests). | ✅ Completed |
MatchingController.getCandidateMentees (GET /api/matching/mentees); returns MenteeCandidateResponse (privacy-safe — see 1.1.2.5). |
| 1.1.1.2.5 | Mentors shall be able to accept or reject mentorship requests. | ✅ Completed |
MentorshipRequestController.acceptRequest / rejectRequest (`PUT /api/mentorship-requests/{id}/accept |
| 1.1.1.2.6 | Mentors shall be able to initiate and maintain communication with mentees through the in-app messaging system. | ✅ Completed | Conversation seeded on accept by ConversationCreator; MessageController shared with mentees. |
| 1.1.1.2.8 | Mentors shall be able to assign weekly tasks to mentees. | ✅ Completed |
TaskController.assignTask (POST /api/mentorships/{id}/tasks); Task entity with dueDate. Weekly cadence is operator-driven, not enforced by the system. |
| 1.1.1.2.9 | Mentors shall be able to review submitted work and provide feedback. | ✅ Completed |
TaskController.reviewTask (PATCH /api/tasks/{id}/feedback) updates Task.feedback + status of latest TaskSubmission. |
| 1.1.1.2.10 | Mentors shall be able to manage multiple mentees simultaneously. | ✅ Completed |
Mentor.maxMenteeCapacity + Mentor.currentMenteeCount (Flyway V7); accept path increments counter only up to capacity. |
| 1.1.1.2.11 | Mentors shall be able to configure their maximum mentee capacity. | ✅ Completed |
MentorProfileRequest.maxMenteeCapacity (@Min(0)); enforced by MentorRepository filter and request-acceptance precondition. |
| 1.1.1.2.12 | Mentors shall choose a mentorship duration from predefined options (e.g., 1 month, 3 months, 6 months). | ✅ Completed |
AcceptRequestRequest.duration constrained to {1, 3, 6} (see also ExtendMentorshipRequest.ALLOWED = Set.of(1, 3, 6)). |
| 1.1.1.2.13 | Mentors shall be able to extend the mentorship duration if they wish to continue. | ✅ Completed |
MentorshipController.extendMentorship (PATCH /api/mentorships/{id}/extend) + audit log entry; only mentor. |
| 1.1.1.2.14 | Mentors shall be able to end the mentorship earlier than the set duration once the defined goal is reached. | ✅ Completed |
MentorshipController.endMentorship (PATCH /api/mentorships/{id}/end) + MentorshipService.endMentorship; mentor-only. |
| 1.1.1.2.15 | Mentors shall be able to follow other users to see their posts in the Following feed. | ✅ Completed | Same FollowController + FeedReadController.following used by mentees. |
| 1.1.1.2.16 | Mentors shall be able to unfollow users they previously followed. | ✅ Completed | Same FollowController.unfollowUser endpoint. |
| 1.1.1.2.17 | Mentors shall be able to view a list of their active and past mentorships. | ✅ Completed | Same MentorshipController listing endpoints (role-agnostic). |
| 1.1.1.3.1 | Admin users shall be able to investigate cases reported by mentees. | ✅ Completed |
AdminReportController (GET /api/admin/reports, /{id}, PATCH /{id}) + ReportStatusMachine; Flyway V54 reports table. |
| 1.1.1.3.2 | Admin users shall be able to read and review reports. | ✅ Completed | Same AdminReportController.getReport + paginated getReports with status + target-type filters. |
| 1.1.1.3.3 | Admin users shall be able to ban users from the system. | ✅ Completed |
AdminController.banUser (POST /api/admin/users/{userId}/ban) + BanService.adminBan; BanAdminController for lifting. Flyway V30. |
| 1.1.1.3.4 | Admin users shall be able to send in-app messages to users and other admins. | ✅ Completed |
AdminMessagingController.sendDirect (DM to a user) + broadcast (to all admins); AdminDirectMessageController lists inbound. Flyway V34. |
| 1.1.2.1 | The system shall recommend mentors to mentees based on interests, goals, availability, and background. | ✅ Completed | Two pipelines, both shipped: (a) MatchingService.getTopMentors + MentorScoringPipeline + RuleBasedMentorRanker with InterestOverlapSignal, MajorMatchSignal, AvailabilitySignal, SkillOverlapSignal — default in production; (b) AdvancedMentorRanker + seven scoring signals (semantic affinity via OpenAI embeddings, geographic distance, field overlap, availability, capacity, engagement, diversity) + MmrReranker + MatchExplanationService (LLM-grounded prose explanation) — wired and exercised by AdvancedMatchingIntegrationTest, gated by the advanced-ranker-check JaCoCo rule (≥ 90 % line / 80 % branch), activated by the MENTOR_ADVANCED_RANKER operator flag. |
| 1.1.2.2 | The system shall support location-based recommendations so that mentors and mentees in proximity can be paired for face-to-face meetings. | ✅ Completed |
User.latitude / longitude (Flyway V35) + LocationProximitySignal (great-circle, exp decay) + MentorScoringPipeline.computeDistance; maxDistanceKm filter on the matching endpoint. |
| 1.1.2.3 | The system shall occasionally recommend mentors outside the mentee's primary goals based on shared interests or skills, to encourage diverse mentorship experiences. | ✅ Completed |
MentorScoringPipeline slot 5 "diverse pick" using embedding centroid distance + pairwise MMR fallback (MmrReranker). |
| 1.1.2.4 | The system shall provide an explanation for each recommendation, stating which factors (e.g. proximity, shared interest, similar field) contributed to the suggestion. | ✅ Completed |
MentorMatchResponse.factors (deterministic strings, e.g. interest-match:AI, nearby:23km) + optional LLM explanation via service/explanation/. |
| 1.1.2.5 | When a mentor is viewing a candidate mentee profile, the system shall hide the mentee's surname and profile photo; only the first name shall be visible. | ✅ Completed |
MenteeCandidateResponse exposes only firstName (no lastName, no profile photo URL) — schema explicitly notes "last name hidden for privacy". |
| 1.1.2.6 | Mentees shall not be able to search for or find other mentees. | ✅ Completed |
UserService.searchUsers throws ProfileNotVisibleException("Mentees cannot search for other mentees") when caller is a mentee. |
| 1.1.2.7 | Mentors shall not accept mentees beyond their configured maximum mentee capacity. | ✅ Completed |
MentorshipRequestService.acceptRequest rejects on currentMenteeCount >= maxMenteeCapacity; MentorRepository ranking query also filters. |
| 1.1.2.8 | The system shall be able to recommend other users to follow based on shared interests, follow-graph connections, or recent social-feed engagement. | ✅ Completed |
FollowRecommendationController (GET /api/follow-recommendations) + FollowRecommendationService + RuleBasedFollowRanker (interests, second-hop, engagement); Neo4j follow graph indices Flyway V49. |
| 1.1.3.1 | The platform shall provide an in-app messaging system. | ✅ Completed |
MessageController + STOMP via WebSocketConfig + ChatStompController; pair-scoped MentorPairMessageController + admin DM channel. Flyway V14, V17. |
| 1.1.3.2 | Users shall receive notifications for new messages. | ✅ Completed |
MessageService.sendMessage publishes NotificationEventPublisher.messageSent; Notification row + FCM via FcmPushDeliveryService if device registered. |
| 1.1.3.3 | Users shall be able to maintain message history. | ✅ Completed |
Message entity persisted to Postgres; MessageController.listMessages paginates history. |
| 1.1.3.4 | Users shall be able to attach documents or links in messages. | ✅ Completed |
AttachmentController.upload + SendMessageRequest.attachmentId; MessageService.loadAndAuthorizeAttachment enforces uploader = sender. Flyway V15 attachments table. |
| 1.1.3.5 | Mentors shall be able to message other mentors. | ✅ Completed |
MentorPairMessageController + MentorPairInboxController; conversation kind MENTOR_PAIR. |
| 1.1.4.1 | Mentors shall be able to define weekly availability. | ✅ Completed |
AvailabilityController PUT /api/availability bulk + slot CRUD; AvailabilitySlot keyed on dayOfWeek + (start, end). |
| 1.1.4.3 | Mentors shall be able to create one-time meetings at arbitrary dates and times. | ✅ Completed |
MeetingController.createMeetings with recurring=false; MeetingCreateRequest.startTime/endTime are arbitrary OffsetDateTime. |
| 1.1.4.4 | Mentors shall be able to provide an external meeting link (e.g., Google Meet, Zoom) when creating a meeting. | ✅ Completed |
MeetingCreateRequest.meetingLink (required when meetingType=ONLINE); stored on Meeting.meetingLink. |
| 1.1.4.5 | The system shall display the meeting link in the meeting details view for mentors and mentees. | ✅ Completed |
MeetingDetailResponse.meetingLink returned by MeetingController.getMeeting; web + mobile clients render the link. |
| 1.1.4.6 | The system shall send a meeting confirmation request to the mentee when a mentor schedules a meeting. | ✅ Completed |
MeetingService.createMeetings sets status=PENDING_CONFIRMATION, sets confirmationDeadline, publishes NotificationEventPublisher.meetingPending. |
| 1.1.4.7 | The system shall notify the mentor if the mentee declines or does not confirm within a defined time window. | ✅ Completed | Decline path: MeetingController.declineMeeting notifies mentor. No-confirm path: MeetingScheduler.run sweeps confirmationDeadline past-due and MeetingSchedulerProcessor.processPending auto-expires + notifies. |
| 1.1.4.8 | The system shall send meeting reminders before scheduled meetings. | ✅ Completed |
MeetingSchedulerProcessor.sendReminders (5-min cron via MeetingScheduler) with idempotent MeetingReminderState table. |
| 1.1.4.9 | Mentors and mentees shall be able to request rescheduling of meetings; the other party shall approve or reject the request. | ✅ Completed |
MeetingController exposes the full lifecycle: POST /reschedule-requests, /approve, /reject; MeetingRescheduleRequest entity with MeetingRescheduleStatus. |
| 1.1.4.10 | The connection between mentor and mentee shall be terminated automatically when the set duration ends. | ✅ Completed |
MentorshipAutoCompletionScheduler (hourly UTC cron) + MentorshipAutoCompletionService.autoCompleteExpired flips ACTIVE → COMPLETED past endDate. |
| 1.1.4.11 | Mentors shall be able to cancel meetings. | ✅ Completed |
MeetingController.cancelMeeting (DELETE /api/meetings/{id}); transitions to CANCELLED + notifies mentee. |
| 1.1.5.1 | Mentors shall be able to assign tasks with deadlines. | ✅ Completed |
TaskCreateRequest.dueDate (required) + Task.dueDate; reminder firing keyed off this column. |
| 1.1.5.2 | Mentees shall be able to upload task submissions. | ✅ Completed |
TaskController.submitTask accepts text + attachmentIds; TaskSubmission entity. |
| 1.1.5.3 | Mentors shall be able to provide structured feedback. | ✅ Completed |
TaskController.reviewTask (PATCH /api/tasks/{id}/feedback) — feedback text + status (APPROVED / NEEDS_REVISION). |
| 1.1.5.4 | The system shall maintain task history for each mentorship relationship. | ✅ Completed |
Task rows linked to Mentorship FK; TaskSubmission rows preserve every submission. |
| 1.1.5.5 | The system shall track mentorship progress over time based on completed tasks, milestones, and assignment submissions. | ✅ Completed |
MentorshipProgressService.getProgress (GET /api/mentorships/{id}/progress) aggregates task + milestone completion rates. |
| 1.1.5.7 | The system shall support milestones within a mentorship that break down the overall goal into trackable stages. | ✅ Completed |
MilestoneController + Milestone entity (Flyway V25) with MilestoneActionItem children; MilestoneStatus lifecycle. |
| 1.1.5.8 | The system shall offer to send reminder notifications to mentors and mentees about pending tasks and upcoming milestones. | ✅ Completed |
ReminderNotificationScheduler (every 30 min) → ReminderNotificationProcessor with SentTaskReminder / SentMilestoneReminder dedup tables (Flyway V31). User-configurable via UserNotificationPreferencesController. |
| 1.1.5.9 | The system shall provide a mentorship timeline with start and end dates and a current date indicator. | ✅ Completed |
MentorshipController.getMentorshipTimeline (GET /api/mentorships/{id}/timeline) + MentorshipTimelineService returns TimelineResponse with startDate/endDate and items. |
| 1.1.5.10 | The system shall display milestones, meetings, and task deadlines on the mentorship timeline. | ✅ Completed |
MentorshipTimelineService.getTimeline merges Milestone, Meeting, Task rows into a single chronologically-sorted response. |
| 1.1.5.11 | The system shall add new meetings and tasks to the timeline automatically when they are created. | ✅ Completed | Timeline is computed live from the underlying tables — newly-persisted rows appear on next read without explicit timeline writes. |
| 1.1.5.12 | Only mentors shall be able to create, edit, or delete milestones. | ✅ Completed |
MilestoneController create/update/delete paths enforce mentor identity in MilestoneService (mentee gets 403); action-item completion can be toggled by either party. |
| 1.1.5.13 | Users shall be able to select timeline items (meeting, task, milestone) to view details. | ✅ Completed | Each item carries a typed id consumed by GET /api/meetings/{id}, GET /api/tasks/{id}, GET /api/milestones/{id}. |
| 1.1.6.1 | Users shall be able to report posts. | ✅ Completed |
ReportController.submitReport with target_type=POST; ReportTargetType.POST. |
| 1.1.6.2 | Users shall be able to create a report for their mentorships. | ✅ Completed |
target_type=MENTORSHIP; reporter must be a participant (enforced by ReportService). |
| 1.1.6.3 | Users shall be able to report other users. | ✅ Completed |
target_type=USER; covered by same ReportController.submitReport. |
| 1.1.6.4 | Reports shall be routed to platform admins for review. | ✅ Completed | All reports land in the reports table (Flyway V54); admin sees them via AdminReportController. Status transitions audited via ReportStatusMachine. |
| 1.1.7.1 | Both mentors and mentees shall be able to create posts in the social feed. | ✅ Completed |
FeedPostController.createPost (POST /api/feed/posts); no role restriction beyond authentication. |
| 1.1.7.2 | Feed posts shall support text content and hashtag tagging. | ✅ Completed |
CreateFeedPostRequest.body + hashtags (server normalises lowercase, dedupes, max 10); FeedPostHashtag join (Flyway V26). |
| 1.1.7.3 | The system shall provide a personalized "For You" feed tab with algorithmically recommended posts based on the user's interests, goals, and interaction history. | ✅ Completed | Two pipelines, both shipped: (a) FeedReadController.forYouFeed (GET /api/feed/for-you) + FeedReadService.getForYouFeed + InterestOverlapFeedRanker — default in production; (b) AdvancedForYouFeedRanker + ForYouScoringPipeline + FeedEngagementBanditListener + ThompsonSamplingService — fully wires the "interaction-history" signal via per-hashtag Beta posteriors, exercised by AdvancedForYouFeedIntegrationTest, gated by the advanced-ranker-check JaCoCo rule (≥ 90 % line / 80 % branch), activated by the FEED_ADVANCED_RANKER operator flag. |
| 1.1.7.4 | The system shall provide a "Following" feed tab displaying posts from users the viewer follows. | ✅ Completed |
FeedReadController.followingFeed (GET /api/feed/following); chronological by created_at DESC. |
| 1.1.7.5 | Users shall be able to like feed posts. | ✅ Completed |
FeedInteractionController.toggleLike (POST /api/feed/posts/{id}/like); FeedPostLike entity. |
| 1.1.7.6 | Users shall be able to comment on feed posts. | ✅ Completed |
FeedInteractionController.addComment + edit / delete / list; FeedPostComment + nested comment-like (FeedPostCommentLike, Flyway V51). |
| 1.1.7.7 | Users shall be able to search for feed posts using keywords and hashtags. | ✅ Completed |
FeedReadController.searchFeed (GET /api/feed/search) — keyword + hashtag + date range + language filters; tsvector indexes (Flyway V19, V50). |
| 1.1.7.8 | When creating a feed post, users shall be able to select topic tags or hashtags to categorize their post. | ✅ Completed | Same CreateFeedPostRequest.hashtags; HashtagNormalizer strips #, lowercases. |
| 1.1.7.9 | Users shall be able to edit their own feed posts. | ✅ Completed |
FeedPostController.updatePost (PATCH /api/feed/posts/{id}, author-only); FeedPostEditHistory records each edit (Flyway V44). |
| 1.1.7.10 | Users shall be able to delete their own feed posts. | ✅ Completed |
FeedPostController.deletePost (soft-delete, author-only); 30-day restore window via FeedPostController.restorePost; cleanup by FeedSoftDeleteCleanupScheduler. |
| 1.1.7.11 | Users shall be able to share feed posts. | ✅ Completed |
FeedInteractionController.recordShare (POST /api/feed/posts/{id}/share) + FeedInteractionController.repost quote-share (POST /api/feed/posts/{id}/reposts); FeedPostShare + repost columns (Flyway V40). |
| 1.1.7.12 | Users shall be able to save and bookmark feed posts. | ✅ Completed |
FeedInteractionController.toggleBookmark + GET /api/feed/me/bookmarks; FeedPostBookmark entity. |
| 1.2.1.1 | The system shall send push notifications for new recommendations. | ✅ Completed |
MatchNotificationScheduler (daily 09:00 UTC) → MatchNotificationProcessor.processMentee writes Notification (type MATCH_FOUND) + fires FCM via FcmPushDeliveryService; idempotent by LastMatchNotification (Flyway V20). |
| 1.2.1.2 | The system shall send push notifications for new messages. | ✅ Completed |
MessageService.sendMessage → NotificationEventPublisher.messageSent → FCM. Push registered via UserDeviceController (Flyway V24). |
| 1.2.1.3 | The system shall send notifications for meeting reminders. | ✅ Completed |
MeetingSchedulerProcessor.sendReminders publishes NotificationType.MEETING_REMINDER; FCM dispatched. |
| 1.2.1.4 | Notifications shall only be sent to relevant users. | ✅ Completed |
NotificationEventPublisher only emits to participants; UserNotificationPreferences gates by category (UserNotificationPreferencesController). |
| 1.2.1.5 | The system shall notify mentees when a mentor accepts their request. | ✅ Completed |
MentorshipRequestService.acceptRequest publishes REQUEST_ACCEPTED notification + FCM. |
| 1.2.1.6 | The system shall notify the user that a mentorship request was successfully submitted. | ✅ Completed |
MentorshipRequestService.createRequest writes REQUEST_SUBMITTED notification to the sender. |
| 1.2.1.7 | The system shall send notifications for task deadlines and milestone reminders. | ✅ Completed |
ReminderNotificationScheduler + ReminderNotificationProcessor; per-user opt-out via UserNotificationPreferences. |
| 1.2.2.1 | User profiles shall include background, goals, skills, and interests. | ✅ Completed |
Mentee / Mentor entities; ESCO/Wikidata-tagged via TaggedTerm. |
| 1.2.2.2 | Profiles shall display mentoring preferences. | ✅ Completed |
MentorResponse.mentoringGoals / preferredMenteeSkills / mentorshipDuration / meetingFreqPref; rendered on the mentor profile page. |
| 1.2.2.3 | Users shall be able to control profile visibility. | ✅ Completed |
Mentor.profileVisibility + Mentee.profileVisibility (Flyway V55); enforced by MentorRepository/MenteeRepository filter queries with :bypassVisibility override for the owner. |
| 1.2.2.4 | Mentor profiles shall display their published feed posts. | ✅ Completed |
FeedReadController.authorPosts (GET /api/feed/users/{authorId}/posts); web + mobile mentor profile screens consume it. |
| 1.2.2.5 | User profiles shall include a location field to support location-based recommendations. | ✅ Completed |
User.location (free-text) + latitude / longitude (Flyway V35); editable via MentorProfileRequest / MenteeProfileRequest. |
| 1.2.3.1 | Users shall register with real name, email, and password. | ✅ Completed |
AuthController.register + RegisterRequest (firstName, lastName, email, password); persisted via AuthService. |
| 1.2.3.2 | Email addresses shall be unique. | ✅ Completed |
users.email UNIQUE constraint (Flyway V1); AuthService.register returns 409 on duplicate. |
| 1.2.3.3 | Passwords shall meet defined security criteria. | ✅ Completed |
@ValidPassword + PasswordValidator enforce min length, mixed case, digit, special char on RegisterRequest.password and ResetPasswordRequest. |
| 1.2.3.4 | Email addresses shall be verified before account activation. | ✅ Completed |
AuthController.verifyEmail (GET /api/auth/verify-email?token=…) + VerificationToken (Flyway V2); login rejected until verified. |
| 1.2.3.5 | Users shall be able to log in using their registered email address and password. | ✅ Completed |
AuthController.login (POST /api/auth/login); returns JWT issued by JwtService. |
| 1.2.3.6 | The system shall verify the user's credentials (email and password) during login. | ✅ Completed |
AuthService.login re-hashes with BCryptPasswordEncoder and compares against users.password_hash. |
| 1.2.3.7 | The system shall display an error message when invalid credentials are provided. | ✅ Completed | 401 with a generic message returned from AuthService.login (prevents account enumeration); rendered by web + mobile login forms. |
| 1.2.3.8 | Users shall be able to log out of the system. | ✅ Completed | Client-side JWT discard (no server-side session); both clients drop the token from secure storage. Documented in frontend/src/ + mobile-app/api/. |
| 1.2.3.9 | Users shall be able to reset their password via their registered email address. | ✅ Completed |
AuthController.forgotPassword + AuthController.resetPassword + AuthController.validateResetToken; PasswordResetToken (Flyway V3); rate-limited 5/h. |
| 2.1.1 | The system shall be available 24/7 except during maintenance periods. | ✅ Completed | Production stack runs on a managed Linux VM via docker-compose.prod.yml (Postgres + Spring Boot + Caddy), redeployed by .github/workflows/deploy.yml. Backend container declares healthcheck on /actuator/health; web container declares healthcheck on /. URL: https://mymentornet.org/. |
| 2.1.2 | The system shall support web and mobile access. | ✅ Completed | React web client at frontend/ (Vite) + Expo / React Native at mobile-app/; both consume the same OpenAPI surface. |
| 2.2.1 | User passwords shall be stored as hashed in the database. | ✅ Completed |
SecurityConfig.passwordEncoder() = BCryptPasswordEncoder; users.password_hash only — no plaintext column. |
| 2.2.2 | Communication between users shall be encrypted. | ✅ Completed | Production reverse-proxy terminates TLS (Caddy auto-HTTPS on mymentornet.org); JWT cookie marked Secure; STOMP runs over WSS. |
| 2.2.4 | The system shall enforce temporary bans for mentees who trigger frequent relationship cancellations. | ✅ Completed |
BanService.recordCancellation counts cancellations in a rolling window; once threshold crossed creates a Ban row with escalating duration; expiry swept by BanExpiryScheduler. Flyway V32. |
| 2.2.5 | The system shall detect spam bots. | ✅ Completed |
SpamDetectionService.validateRegistration (honeypot, timing too fast, email rate) + onRegistrationCommitted post-commit signal accumulation; BotSignalCleanupScheduler self-expires the audit table (Flyway V36). |
| 2.3.2 | The system shall support concurrent mentor-mentee sessions without performance degradation. | ✅ Completed | Stateless backend with JWT auth, Hikari pool, optimistic locking via @Version (Flyway V11); STOMP fans out via Spring's in-memory broker. Postgres tsvector + tagged-term indexes (Flyway V19, V48, V49) keep query plans linear. |
| 2.3.3 | The recommendation system shall utilize data processing to analyze user profiles and generate relevant and diverse mentor suggestions. | ✅ Completed |
MentorScoringPipeline composes 6 signals (interest overlap, major match, skill overlap, availability, location, embedding similarity); diverse slot powered by MmrReranker and global-centroid distance over OpenAI embeddings cached in service/embedding/. |
| 2.3.4 | Social feed updates shall be reflected to users within 5 seconds of post creation, matching the notification delivery budget in 2.3.1. | ✅ Completed | Following feed: post writes synchronously to feed_posts; clients see it on next pull (median <1s in manual QA). For-You feed: FeedPostEventPublisher fires FeedPostCreatedEvent; FeedEngagementBanditListener updates engagement weights AFTER_COMMIT (background). New posts surface on the next /api/feed/for-you pull. |
| # | Requirement (verbatim from SRS) | Status | Evidence / Notes |
|---|---|---|---|
| 1.1.1.2.7 | Mentors shall be able to schedule recurring weekly meetings. | 🟡 In Progress |
MeetingCreateRequest.recurring + recurrenceRule (RRULE) accepted by MeetingService.createMeetings; MeetingService.parseWeeklyInterval understands FREQ=WEEKLY;INTERVAL=N. Backend creates the recurrence series, but only weekly cadence is supported and the web UI exposes the recurring toggle while the mobile client still surfaces single-meeting creation only. |
| 1.1.4.2 | Mentors shall be able to create recurring weekly meetings. | 🟡 In Progress | Same as 1.1.1.2.7 — backend complete, mobile client UI gap. |
| 1.1.5.6 | Mentors and mentees shall define a goal together after matching and acceptance. | 🟡 In Progress |
MentorshipController.setSharedGoal (PUT /api/mentorships/{id}/goal) accepts the goal from either party; MentorshipService.setSharedGoal does not enforce two-party agreement (either side can overwrite). Functionally allows the joint workflow but does not gate on the counterpart's confirmation. |
| 2.2.3 | The system shall comply with GDPR and KVKK regulations. | 🟡 In Progress | Mechanisms in place: account-deletion endpoint (DELETE /api/users/{id}), profile-visibility toggle (1.2.2.3), password hashing (2.2.1), audit logs for moderation actions, no third-party trackers. No published privacy notice / DPO contact / data-processing register yet — compliance is a documentation gap, not a software gap. |
| 2.3.1 | The system shall deliver notifications within 5 seconds of triggering events. | 🟡 In Progress | In-app notification persistence is synchronous (<1s). FCM fan-out is async via AsyncConfig thread pool; medium FCM delivery in manual QA hits within 5s for ~95% of sends, but tail latencies depend on the FCM transport and are not formally measured. No load test confirming P95. |
| 1.2.1.1 (in-app vs push parity) | Push notifications for new recommendations — daily cadence vs "push" expectation. | 🟡 In Progress |
MatchNotificationScheduler is wired and fires (see Completed entry), but the cadence is daily (09:00 UTC) by default — not "immediately as a new top match emerges". Sufficient for the demo, but a near-real-time push on graph change is not implemented. |
| 1.1.1.2.7 (mobile UI) | Mentor recurring-meeting scheduling on the mobile client. | ❌ Not Started |
mobile-app/app/(mentor)/meetings/new.tsx collects a single start / end pair; no recurrence toggle. (Backend is ready — see In Progress row above.) |
| 2.3.1 (formal load test) | 5-second SLA confirmed by a load test. | ❌ Not Started | No JMeter / k6 / Gatling run committed to the repo. Manual smoke tests only. |
| 2.3.4 (formal latency measurement) | Feed 5-second SLA confirmed by a load test. | ❌ Not Started | Same gap — no automated measurement; manual QA only. |
| 1.1.7.4 (real-time fanout) | "Following" feed real-time fanout to active viewers. | ❌ Not Started | Feed is pull-based (HTTP GET on tab open / scroll); no STOMP fanout to subscribed followers on post creation. Spec is satisfied within the 5s budget by polling, but the /topic/feed/... channel mentioned in the design docs is not wired. |
| # | Requirement (verbatim from SRS) | Status | Evidence / Notes |
|---|---|---|---|
| 1.1.5.3 (rubric-based) | Mentors shall be able to provide structured feedback. | ⏸ Out of Scope | Implemented as free-text feedback + APPROVED / NEEDS_REVISION status (see Completed row 1.1.5.3). A formal rubric / structured-question variant ("structured" interpreted strictly) was descoped after the Customer Milestone — the freetext form was accepted as sufficient by the product owner. Listed here for transparency. |
| 2.x (HA / multi-region) | High availability beyond single-VM deployment. | ⏸ Out of Scope | The SRS allows for maintenance periods; single-instance deploy with daily snapshots was accepted. Multi-AZ / hot-standby was descoped from the start (university-project scope). Not a wiki line item but called out to head off marker confusion. |
| 1.2.3 (OAuth / SSO) | Third-party sign-in (Google, Apple). | ⏸ Out of Scope | Not in the SRS; descoped early. Mentioned here only because the demo audience occasionally asks. |
- Live Swagger UI: https://mymentornet.org/swagger-ui/index.html
- Live OpenAPI 3.1 specification (raw JSON): https://mymentornet.org/v3/api-docs
The OpenAPI specification is generated at runtime from springdoc-openapi-starter-webmvc-ui and covers every endpoint shipped in the final release (129 paths / 156 operations). The only endpoints absent from the spec are profile-gated test-support routes under /api/test/*, which are wired in by @ConditionalOnProperty(name="app.test-endpoints.enabled") and are intentionally off in production. No deprecated endpoints are surfaced — grep -rn "@Deprecated" backend/.../controller/ returns zero hits.
All scenarios below were verified against the live spec; the <token> placeholder in every curl is the value of the sessionToken field returned by POST /api/auth/login. Where a response exceeds 20 lines, the middle has been truncated with // … truncated … and the surrounding structure preserved, as the deliverable spec requires.
Scenario 1: Mentee discovers a mentor via the matching recommender, mentor accepts, shared goal is set, mentor creates the first milestone
This scenario exercises the entire mentor-matching → onboarding loop. It runs the recommendation algorithm (post-MVP), creates the mentorship, sets the precondition for milestone creation (the shared goal), and creates the first milestone. The GOAL_REQUIRED 409 guard is in MilestoneService.createMilestone.
Step 1 — Mentee fetches ranked mentor recommendations (matching algorithm).
-
Endpoint:
GET /api/matching/mentors -
Scenario Description: The
MatchingServiceranks every active mentor by a compatibility score combining shared interests, expertise overlap, preferred-major match, availability density, and great-circle distance. Each result carries afactorsarray of human-readable contributors and an optional LLM-generatedexplanation(returned when the advanced ranker is enabled). - The Request:
curl -G "https://mymentornet.org/api/matching/mentors" \
--data-urlencode "keyword=machine learning" \
--data-urlencode "minMatchScore=60" \
--data-urlencode "page=0" \
--data-urlencode "size=10" \
-H "Authorization: Bearer <mentee-token>"- The Response:
{
"content": [
{
"id": 42,
"firstName": "Ahmet",
"field": "Computer Science",
"expertise": "Backend Development",
"interests": ["AI", "Systems"],
"preferredMenteeSkills": ["Java", "Python"],
"mentorshipDuration": 3,
"matchScore": 87,
"factors": ["interest-match:AI", "major-exact", "availability:6h", "nearby:23km"],
"distanceKm": 23.4,
"explanation": "Ahmet's applied-ML expertise aligns with your portfolio-project goal."
}
// … truncated …
],
"totalElements": 4, "totalPages": 1, "number": 0, "size": 10
}Step 2 — Mentor accepts the pending request.
-
Endpoint:
PUT /api/mentorship-requests/{id}/accept -
Scenario Description: Accepting flips the request to
ACCEPTED, creates an active mentorship row with the chosen duration, increments the mentor's mentee count, and cancels every other pending request from the same mentee. - The Request:
curl -X PUT "https://mymentornet.org/api/mentorship-requests/318/accept" \
-H "Authorization: Bearer <mentor-token>" \
-H "Content-Type: application/json" \
-d '{ "duration": 3 }'- The Response:
{
"id": 124, "mentorId": 42, "mentorFirstName": "Ahmet",
"menteeId": 7, "menteeFirstName": "Elif",
"startDate": "2026-05-16T09:14:22Z",
"endDate": "2026-08-16T09:14:22Z",
"duration": 3, "status": "ACTIVE",
"sharedGoal": null, "goalDefined": false,
"terminatedAt": null, "cancellationReason": null
}Step 3 — Either party sets the shared goal (unlocks milestone creation).
-
Endpoint:
PUT /api/mentorships/{id}/goal -
Scenario Description: Setting a non-blank goal flips
goalDefinedtotrue. Until this is done,POST /api/mentorships/{id}/milestonesreturns409 GOAL_REQUIRED. - The Request:
curl -X PUT "https://mymentornet.org/api/mentorships/124/goal" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "sharedGoal": "Build a machine-learning portfolio project by mid-August." }'- The Response:
{
"id": 124, "status": "ACTIVE",
"sharedGoal": "Build a machine-learning portfolio project by mid-August.",
"goalDefined": true,
"startDate": "2026-05-16T09:14:22Z",
"endDate": "2026-08-16T09:14:22Z"
}Step 4 — Mentor creates the first milestone.
-
Endpoint:
POST /api/mentorships/{id}/milestones -
Scenario Description: The
targetDatemust fall inside the mentorship window. The created milestone starts atPENDINGand accepts action items viaPOST /api/milestones/{id}/action-items. - The Request:
curl -X POST "https://mymentornet.org/api/mentorships/124/milestones" \
-H "Authorization: Bearer <mentor-token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Ship the EDA notebook",
"description": "Exploratory data analysis on the Kaggle credit-card dataset.",
"targetDate": "2026-06-15T17:00:00Z",
"orderIndex": 0
}'- The Response:
{
"id": 57, "mentorshipId": 124,
"title": "Ship the EDA notebook",
"description": "Exploratory data analysis on the Kaggle credit-card dataset.",
"targetDate": "2026-06-15T17:00:00Z",
"status": "PENDING", "orderIndex": 0,
"completedAt": null,
"createdAt": "2026-05-16T09:18:05Z",
"actionItems": []
}Scenario 2: Mentee cancels a pending request enough times to cross the auto-ban threshold, admin lifts the ban
This scenario exercises the cancellation counter / ban gate / admin override loop (post-MVP). The 403 envelope carries the stable code=BANNED_UNTIL so clients can branch without parsing the message string.
Step 1 — Mentee cancels their own pending request.
-
Endpoint:
DELETE /api/mentorship-requests/{id} -
Scenario Description: Below the threshold this returns
204silently; above the threshold the cancellation is recorded byBanService.recordCancellationwhich writes a freshBanrow. - The Request:
curl -X DELETE "https://mymentornet.org/api/mentorship-requests/411" \
-H "Authorization: Bearer <mentee-token>"- The Response:
HTTP/1.1 204 No Content
Step 2 — After the threshold is crossed, the next POST /api/mentorship-requests is short-circuited by the ban gate.
-
Endpoint:
POST /api/mentorship-requests -
Scenario Description:
MentorshipRequestService.createRequestrunsBanService.getActiveBan(menteeId)first; if present, throwsUserBannedExceptionandGlobalExceptionHandler.handleUserBannedreturns the structured 403 below. - The Request:
curl -X POST "https://mymentornet.org/api/mentorship-requests" \
-H "Authorization: Bearer <mentee-token>" \
-H "Content-Type: application/json" \
-d '{ "mentorId": 42, "message": "I would love to learn from you." }'- The Response:
{
"error": "Forbidden",
"code": "BANNED_UNTIL",
"message": "User is temporarily banned for excessive cancellations.",
"reason": "Exceeded mentorship-request cancellation threshold",
"expiresAt": "2026-05-23T09:21:00Z",
"banCount": 1
}Step 3 — Admin lifts the ban.
-
Endpoint:
DELETE /api/admin/bans/{banId} -
Scenario Description:
BanService.liftBanstampsliftedAt+liftedByAdminId, emits aUSER_BAN_LIFTEDnotification, and is idempotent. The companionGET /api/admin/bans/users/{userId}lists the user's ban history. - The Request:
curl -X DELETE "https://mymentornet.org/api/admin/bans/88" \
-H "Authorization: Bearer <admin-token>"- The Response:
{
"id": 88, "userId": 7,
"reason": "Exceeded mentorship-request cancellation threshold",
"banCount": 1,
"expiresAt": "2026-05-23T09:21:00Z",
"liftedAt": "2026-05-16T09:25:12Z",
"liftedByAdminId": 1,
"createdAt": "2026-05-16T09:21:00Z"
}Scenario 3: User receives follow recommendations, browses the algorithmic For-You feed, likes and comments on a post
This scenario exercises two of the three production recommendation algorithms (the follow-recommendation ranker and the For-You feed ranker) plus the engagement surface. The For-You ranker emits an AFTER_COMMIT listener on every like/comment that feeds the Thompson-sampling bandit (FeedEngagementBanditListener).
Step 1 — Viewer fetches follow recommendations (follow-recommendation algorithm).
-
Endpoint:
GET /api/users/me/follow-recommendations -
Scenario Description:
FollowRecommendationServicescores candidates by shared-interest overlap and follow-graph proximity ("followed by N of your follows"). Admins and already-followed users are excluded. - The Request:
curl -X GET "https://mymentornet.org/api/users/me/follow-recommendations?page=0&size=10" \
-H "Authorization: Bearer <token>"- The Response:
{
"content": [
{ "id": 22, "firstName": "Esra", "lastName": "Yıldız", "role": "MENTOR",
"score": 11, "factors": ["shared-interest:ml", "followed-by-2-of-your-follows"] },
{ "id": 17, "firstName": "Ada", "lastName": "Demir", "role": "MENTOR",
"score": 7, "factors": ["shared-interest:clinical", "followed-by-1-of-your-follows"] }
],
"totalElements": 2, "totalPages": 1, "number": 0, "size": 10
}Step 2 — Viewer fetches the algorithmic For-You feed (For-You ranker).
-
Endpoint:
GET /api/feed/for-you -
Scenario Description:
FeedReadService.forYouFeedreturns posts ranked by interest overlap, time decay, and follow-graph proximity over a rolling candidate window (app.feed.forYou.candidate-window, default 200). The viewer's own posts and soft-deleted posts are excluded. - The Request:
curl -X GET "https://mymentornet.org/api/feed/for-you?page=0&size=20" \
-H "Authorization: Bearer <token>"- The Response:
{
"content": [
{ "id": 42, "authorId": 17, "authorFirstName": "Ada",
"body": "Just wrapped a clinical-research methods workshop — slides in the comments.",
"hashtags": ["clinical", "research"],
"createdAt": "2026-05-09T10:15:00Z",
"likeCount": 12, "commentCount": 3 },
{ "id": 41, "authorId": 22, "authorFirstName": "Esra",
"body": "Embedding-based mentor search beats keyword matching on cold-start queries.",
"hashtags": ["ml", "recommendations"],
"createdAt": "2026-05-09T09:48:11Z",
"likeCount": 7, "commentCount": 1 },
{ "id": 39, "authorId": 22, "authorFirstName": "Esra",
"body": "Looking for a mentee interested in graph-based recommenders. DM me.",
"hashtags": ["graphs", "recommendations"],
"createdAt": "2026-05-09T08:02:43Z",
"likeCount": 4, "commentCount": 2 },
{ "id": 38, "authorId": 17, "authorFirstName": "Ada",
"body": "Reviewing manuscripts for the systematic-review track.",
"hashtags": ["clinical"],
"createdAt": "2026-05-07T13:21:08Z",
"likeCount": 2, "commentCount": 0 },
{ "id": 35, "authorId": 14, "authorFirstName": "Selin",
"body": "Quick tip: pin the JVM heap when you run Testcontainers on a constrained CI runner.",
"hashtags": ["testing", "ci"],
"createdAt": "2026-05-07T11:05:00Z",
"likeCount": 9, "commentCount": 4 }
],
"pageable": { "pageNumber": 0, "pageSize": 20, "offset": 0, "paged": true, "unpaged": false },
"totalElements": 42, "totalPages": 3, "first": true, "last": false,
"number": 0, "size": 20, "numberOfElements": 5, "empty": false
}Step 3 — Viewer likes the post (idempotent toggle).
-
Endpoint:
POST /api/feed/posts/{id}/like -
Scenario Description:
FeedInteractionService.toggleLikeis idempotent and returns the aggregate counts plus viewer-relative flags so the UI re-renders without a follow-up call. The AFTER_COMMIT bandit listener updates the For-You scoring. - The Request:
curl -X POST "https://mymentornet.org/api/feed/posts/42/like" \
-H "Authorization: Bearer <token>"- The Response:
{
"likeCount": 13, "commentCount": 3, "shareCount": 1, "bookmarkCount": 2,
"viewerHasLiked": true, "viewerHasBookmarked": false
}Step 4 — Viewer adds a comment.
-
Endpoint:
POST /api/feed/posts/{id}/comments -
Scenario Description: Persists the comment and returns the canonical row including
isEdited,isAuthor, andisDeletedflags so the UI can render the soft-delete placeholder consistently. - The Request:
curl -X POST "https://mymentornet.org/api/feed/posts/42/comments" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "body": "Great session! Sharing the slides with my cohort, hope that'\''s OK." }'- The Response:
{
"id": 101, "postId": 42, "authorId": 7, "authorFirstName": "Elif",
"body": "Great session! Sharing the slides with my cohort, hope that's OK.",
"createdAt": "2026-05-16T12:00:00Z",
"updatedAt": "2026-05-16T12:00:00Z",
"isEdited": false, "isAuthor": true, "isDeleted": false,
"likeCount": 0, "viewerHasLiked": false
}This scenario exercises FeedReadService.search, the combined keyword + hashtag search. Filters are ANDed. The keyword uses pg_trgm-accelerated LIKE on the post body, escaped at the service boundary so % and _ cannot act as wildcards. Viewer keyword-mutes are applied after the SQL fetch, so the visible page may surface fewer than size items.
-
Endpoint:
GET /api/feed/search -
Scenario Description: Returns posts whose body contains the keyword
researchAND that are tagged#clinical. At least one ofq,hashtag,since,until, orlangmust be supplied (all-null returns 400). - The Request:
curl -G "https://mymentornet.org/api/feed/search" \
--data-urlencode "q=research" \
--data-urlencode "hashtag=clinical" \
--data-urlencode "page=0" \
--data-urlencode "size=20" \
-H "Authorization: Bearer <token>"- The Response:
{
"content": [
{ "id": 42, "authorId": 17, "authorFirstName": "Ada",
"body": "Just wrapped a clinical-research methods workshop — slides in the comments.",
"hashtags": ["clinical", "research"],
"createdAt": "2026-05-09T10:15:00Z",
"likeCount": 12, "commentCount": 3 }
],
"totalElements": 1, "totalPages": 1, "number": 0, "size": 20
}-
Web Frontend code:
frontend/src/ -
Mobile Frontend code:
mobile-app/app/
Mentor-discovery surface as seen by a mentee. The first screen shows the full mentor catalogue with filter sidebar (availability days, mentorship duration, minimum match-score) and category tabs (All / Backend / Mobile / AI-ML / DevOps / Frontend / Data). The second shows the "Top 5 matches" view with each mentor card carrying a match-score badge, factor chips (e.g. "Strong content match", "Same major", "X km away"), and Send Request / View Profile actions. This is the user-visible output of the mentor-matching ranker described in §4.2 row 1.1.2.1.

Three angles on the social-feed surface: the post composer with an Add image attachment button and hashtag-typing (e.g. #myfirstpost); the For-You feed showing a post card with image attachment, interaction counters and hashtag chips; and the Bookmarks page (Posts you saved for later) where saved posts retain their full interaction-counter row.

Post-MVP profile-editor surface for the mentee: full-name + interests chips (with ESCO / Wikidata URIs persisted server-side), free-text background + goals, taxonomy-tagged skills, ISCED-F major, and the hybrid "Use current location" toggle for location entry. Privacy footnote on the location field is part of the WCAG 2.1 compliance described in §4.5.

The mentor-side active-mentorship surface, end-to-end. First: the dashboard with active-mentees / capacity / available-slots / pending-requests headline counts. Second: the mentorship detail page with the shared-goal banner, mentorship-progress timeline (with Today marker and milestone chips), and the 3/5 tasks · 1/5 milestones · 27 meetings rollup. Then the per-tab views: Milestones (status badges, overdue surfacing, + Add milestone), Schedule (confirmed and pending meetings with reschedule / cancel actions), Tasks (Pending / Awaiting Feedback / Completed three-column layout). The Extend mentorship modal shows the duration-extension flow with calculated new end date. The Edit Availability page shows the weekly-grid editor where adjacent cells merge into one time range on save.

In-app mentorship chat between mentor and mentee with read-receipt timestamps and an attachment paperclip in the composer (used for chat file shares). Real-time delivery is via STOMP fanout on /topic/conversation/{id} (see §5 of the Final Milestone Report).

Free-text report modal opened from another user's public profile. Problem category dropdown (e.g. "Inappropriate behavior") and a 1000-character description textarea. Submits to POST /api/reports with targetType=USER.

Admin-only /admin surface (the side-nav shows the Admin entry only for admin users). The Users tab lists all platform users with per-row Ban action (the second screenshot shows the modal: required reason textarea + duration-in-hours field, default 168 hours = 7 days). The Reports tab is the moderation queue with status filter and the three-state-machine transitions (Mark Under Review / Resolve / Dismiss) on each report card. The Messages tab is the admin-direct + admin-broadcast surface.

The mobile client mirrors the major surfaces shown above. The six screenshots below were captured by Burak Ögüt during mobile-final QA and originally attached to issue #418.
-
— Social feed with reposts, bookmarks, comment likes (mobile) -
— AI mentor match with explanation and factor chips (mobile) -
— User profile with report flow (mobile)
-
— Meetings & sessions with join link (mobile) -
— Mentorship chat with shared post attachments (mobile) -
— Mentor profile editor: skills, interests, location, capacity (mobile)
The Final Milestone codebase adopts ten open standards spanning W3C, IETF, UNESCO, the OpenAPI Initiative, and the Wikimedia Foundation. Each is annotated below with its issuing body, formal version, and the surface it covers in the platform.
-
Activity Streams 2.0 (W3C Recommendation, 23 May 2017) — vocabulary types (
Notefor posts,Likefor interactions,Personfor authors) attached to every feed response so that external Fediverse-compatible consumers can ingest the social graph. -
JSON-LD 1.1 (W3C Recommendation, 16 July 2020) —
@context/@type/@idenvelope wrapping every feed entity for machine-readable, link-resolvable semantics. -
Schema.org (community-maintained vocabulary, encoded in JSON-LD) —
author,dateCreated,textterms used alongside the AS 2.0 vocabulary to maximise interoperability with search engines and social-graph crawlers. -
WCAG 2.1 Level AA (W3C Recommendation, 5 June 2018) — semantic HTML,
aria-labelattributes on icon-only controls, ≥ 4.5 : 1 colour-contrast minimums, full keyboard navigation, preserved focus indicators, and respect forprefers-reduced-motionon animated components. - ESCO (European Skills, Competences, Qualifications and Occupations — EU / CEDEFOP) — canonical URIs persisted alongside human-readable labels for mentor expertise and mentee skills.
- ISCED-F 2013 (International Standard Classification of Education — Fields, UNESCO) — canonical codes for educational field / major on user profiles.
- Wikidata (Wikimedia Foundation) — entity IDs for location names and institutional affiliations.
-
iCalendar / RFC 5545 (IETF) —
.icsexport endpoint for mentor availability and scheduled meetings (VEVENTwithDTSTART,DTEND,SUMMARY,DESCRIPTION,UID) so calendar clients like Google Calendar and Outlook can subscribe. -
OpenAPI 3.0 (OpenAPI Initiative — Linux Foundation) — the full REST surface is annotated via
springdoc-openapi; the live Swagger UI is served at https://mymentornet.org/swagger-ui/index.html and the raw spec at https://mymentornet.org/v3/api-docs. -
JWT / RFC 7519 (IETF) — HS256-signed bearer tokens carrying
sub,iat,expstandard claims, validated on every request by a Spring Security filter; mobile stores them inexpo-secure-store, web inlocalStorage.
- Evidence: PR #536 (feed JSON-LD coverage) · Issue #490
-
Where in the code: Dedicated JSON-LD package at
backend/src/main/java/com/group7/backend/config/jsonld/— most importantly-
JsonLdResponseBodyAdvice.java— SpringResponseBodyAdvicethat wraps every feed / profile / availability response with the@contextenvelope when the client negotiatesapplication/ld+json. -
JsonLdContext.java— holds the canonical@contextarray["https://www.w3.org/ns/activitystreams", "https://schema.org/"]. -
NoteMapping.java— mapsFeedPost→ AS 2.0Notewith Schema.org fields (author,dateCreated,text); class javadoc citeshttps://www.w3.org/TR/activitystreams-core/. -
PersonMapping.java— mapsUser→ AS 2.0Person+schema:Personwithdescription,name,image. -
ScheduleMapping.java— emits Schema.orgbyDayURIs (https://schema.org/Monday, …) on availability slots. -
config/jsonld/feed/— per-entity mappings forOrderedCollectionPage(feed lists) andComment(feed comments) on top of the same context. - Verified by
JsonLdContentNegotiationTest+ per-mapping unit tests (NoteMappingTest,FeedPostJsonLdMappingTest,OrderedCollectionPageJsonLdAdviceTestinbackend/src/test/.../config/jsonld/).
-
-
Reasoning: Every feed and profile response carries an explicit JSON-LD 1.1 envelope (
@context,@type,@id) so that external Fediverse-compatible consumers and search-engine crawlers can ingest the social graph using a standard vocabulary. The@contextdeclares both Activity Streams 2.0 (the dominant social-graph vocabulary; typesNote,Like,Person,OrderedCollectionPage) and Schema.org (the dominant SEO vocabulary; termsauthor,dateCreated,text,byDay,image). The envelope is opt-in via theAccept: application/ld+jsoncontent-negotiation header — plainapplication/jsonclients get the un-decorated payload, so the standard doesn't bloat normal API consumption.
- Evidence: PR #581 (taxonomy URIs on profile dropdowns) · Issue #448
-
Where in the code:
- Backend service:
backend/src/main/java/com/group7/backend/service/TaxonomyService.java— wraps the external ESCO / ISCED / Wikidata HTTP APIs. - Controller surface:
backend/src/main/java/com/group7/backend/controller/TaxonomyController.java—GET /api/taxonomies/skills(ESCO),GET /api/taxonomies/fields(ISCED-F),GET /api/taxonomies/hobbies(Wikidata). - HTTP clients config:
config/TaxonomyClientsConfig.java. - Persistence shape: the migration that adds the canonical URI columns lives at
db/migration/V16__add_taxonomy_uri_columns.sql; theTaggedTermembeddable carries bothdisplayLabelandidentifierUri. - Web frontend autocomplete:
frontend/src/components/TaxonomyAutocomplete.tsx. - Backend integration test:
ProfileTaxonomyIntegrationTest.
- Backend service:
-
Reasoning: Profile fields for expertise / skills use the ESCO skill URI (e.g.
http://data.europa.eu/esco/skill/<id>); educational field / major use the ISCED-F code; location and institutional affiliation resolve against Wikidata entity IDs (e.g.http://www.wikidata.org/entity/Q<id>). For every taxonomy term the backend stores both the human-readable label AND the canonical URI side-by-side (TaggedTerm.displayLabel+TaggedTerm.identifierUri), so the profile data is simultaneously human-readable and machine-resolvable — a recommender or search engine can dereference the URI to a stable concept rather than guessing at free-text strings.
- Evidence: PR #352 · Issue #131
-
Where in the code:
- Generator:
backend/src/main/java/com/group7/backend/service/CalendarExportService.java— emitsBEGIN:VCALENDARenvelope and oneVEVENTper availability slot / scheduled meeting. - Exposed endpoint:
backend/src/main/java/com/group7/backend/controller/AvailabilityController.java—@GetMapping(value = "/{mentorId}/ical", produces = "text/calendar;charset=UTF-8")serves the.icspayload. - Integration test:
AvailabilityIcalIntegrationTest— asserts the response shape (BEGIN:VCALENDAR,VEVENT,DTSTART,DTEND,SUMMARY,UID,END:VEVENT,END:VCALENDAR) and theContent-Type: text/calendarheader.
- Generator:
-
Reasoning: A mentor's availability and scheduled meetings are exported as a single iCalendar
.icspayload conformant with RFC 5545. Each event uses the required core properties (UIDfor stable identity across re-exports,DTSTAMP,DTSTART,DTEND,SUMMARY) so external calendar clients (Google Calendar, Outlook, Apple Calendar, Thunderbird) can subscribe via thewebcal://protocol and receive automatic updates. The endpoint is intentionally anonymous-readable because calendar clients can't sendAuthorizationheaders; the per-mentor URL is the access control (it's effectively a public read with an unguessable hint).
- Evidence: PR #536 (feed examples added)
-
Where in the code:
- Maven dependency:
backend/pom.xml—springdoc-openapi-starter-webmvc-ui(which transitively bundles Swagger UI). - OpenAPI bean config:
backend/src/main/java/com/group7/backend/config/OpenApiConfig.java— declares theOpenAPIbean (title, version, description, contact) and thebearerAuthsecurity scheme (HTTP / Bearer / JWT) for the entire API. - Per-endpoint annotations: every file under
backend/src/main/java/com/group7/backend/controller/uses@Tag,@Operation,@ApiResponses,@ApiResponse,@Parameter, and@Schema. - Reusable example payloads:
backend/src/main/java/com/group7/backend/docs/feed/FeedApiExamples.java— centralised JSON example strings referenced from controller@ExampleObjectannotations so the rendered Swagger UI shows real request / response shapes. - Live UI: https://mymentornet.org/swagger-ui/index.html (interactive)
- Raw spec: https://mymentornet.org/v3/api-docs (OpenAPI 3.1.0 JSON; 129 paths, 156 operations)
- Maven dependency:
-
Reasoning: Every endpoint that ships in the final release is annotated with
springdoc-openapiso a single canonical OpenAPI spec is generated from the running bytecode (no separate hand-written YAML to drift). The live spec covers 129 paths and 156 operations; the only endpoints absent are the profile-gated/api/test/*routes intentionally hidden behind@ConditionalOnProperty("app.test-endpoints.enabled")andspringdoc.swagger-ui.enabled=trueis set inapplication-prod.propertiesso the UI is publicly reachable for graders without authentication.grep -rn "@Deprecated" backend/.../controller/returns zero — no MVP-era endpoints are still surfaced unflagged.
-
Evidence: PR #1 (auth foundation) · subsequent hardening: PR #300 (reject JWTs with missing
userId/roleclaims) · ban-gate: PR #280 (banned users denied at login) -
Where in the code:
- Token mint + parse:
backend/src/main/java/com/group7/backend/service/JwtService.java— HS256 signing viajjwt, withsub,iat,exp, plus customuserIdandroleclaims; rejects tokens missing any of these. - Per-request validation:
backend/src/main/java/com/group7/backend/config/JwtAuthenticationFilter.java— aOncePerRequestFilterthat extracts theAuthorization: Bearer <token>header, validates the signature + expiry + ban-state, and populates the SpringSecurityContext. - WebSocket parallel:
backend/src/main/java/com/group7/backend/config/websocket/JwtChannelInterceptor.java— same validation on STOMPCONNECTframes so chat / feed real-time fanout is gated on the same JWT. - Tests:
JwtAuthenticationFilterTestcovers missing-header / malformed / expired / missing-claim cases. - Client storage: mobile uses
expo-secure-store; web useslocalStorage(auth_token); both attachAuthorization: Bearer <token>on every API call.
- Token mint + parse:
-
Reasoning: Stateless authentication; no server-side session state to invalidate. Tokens are signed with HS256 using a configurable
jwt.secret(defaulted in dev, env-injected in prod), carry only the three RFC 7519 registered claims (sub,iat,exp) plus the two custom claims the authorization rules need (userId,role). Validation is per-request, signature + expiry + ban-state gate together; a banned user's existing JWT is rejected at filter time even if the signature is still valid, so revocation is bounded by the ban check rather than the token's natural expiry. Logout is a client-sidelocalStorage.removeItem— the spec considers this the canonical pattern for stateless JWT (there's nothing on the server to invalidate before natural expiry).
-
Evidence: Issue #305 (accessibility audit + reduced-motion compliance) · commit
91bd792(reduced-motion fix on Playwright + production) -
Where in the code:
- Reduced-motion global handler:
frontend/src/main.jsx— respectsprefers-reduced-motion: reducefor framer-motion-driven entrance animations. -
aria-labelon every icon-only control:frontend/src/components/— e.g.TaxonomyChipPicker.jsx(chip remove buttons),EditHistoryModal.jsx(close button),MessageAttachment.jsx(download icon),AvailabilityGrid.jsx(slot toggles),MentorshipMilestones.jsx,MutedKeywords.jsx,ReportModal.jsx,MentorFilterSidebar.jsx. - Colour contrast: site palette is defined in
frontend/src/styles/main.css— primary text on the brand-green / brand-cream pairing measures 7.4 : 1, well above the AA minimum of 4.5 : 1 for normal text. - Mobile parallel: the Expo client uses the OS-level reduced-motion preference automatically via React Native's
AccessibilityInfoAPI. - Playwright enforcement: every test context sets
reducedMotion: 'reduce'infrontend/playwright.config.jsso the test fixture exercises the exact accessibility codepath production users with the OS preference will see.
- Reduced-motion global handler:
-
Reasoning: The web frontend targets WCAG 2.1 Level AA across all four POUR principles: (Perceivable) ≥ 4.5 : 1 contrast on primary text + meaningful
alttext + icon-only controls carryaria-label; (Operable) full keyboard navigation across all primary flows, preserved focus indicators, no time-limited interactions, andprefers-reduced-motionrespect on every animated transition; (Understandable) consistent navigation across pages, plain-language form validation messages, predictable submit behaviour; (Robust) semantic HTML5 elements (<button>,<nav>,<main>,<form>instead of<div>clickables) so assistive tech can parse the page structure correctly.
All reports live in the wiki repo at reports/final-milestone/ (the README mirroring the headline summary is reports/final-milestone/README.md, or clone via git clone https://github.com/bounswe/bounswe2026group7.wiki.git to browse the whole tree). Headline counts:
Per the report rubric, every layer is published in both JUnit XML (machine-readable) and HTML (human-readable) form. Both formats live in the wiki repo and are linked directly from this section.
| Layer | Runner | Total | Passing | Failing | JUnit XML | HTML report |
|---|---|---|---|---|---|---|
| Backend | Maven Surefire 3.5.3 (mvn surefire-report:report-only) |
2,442 | 2,442 | 0 (1 flake auto-recovered by surefire.rerunFailingTestsCount=2) |
240 per-class XMLs — see "Direct JUnit XML downloads" below | surefire.html (raw) |
| Web (unit) | Vitest 4.1 (xunit-viewer-rendered HTML) |
84 | 84 | 0 | vitest-junit.xml | vitest-report.html (raw) |
| Web (E2E) | Playwright 1.55 × chromium / firefox / webkit | 69 | 37 local · 46 CI (Run 25793439063) | 3 same rate-limit flake × 3 browsers locally · 0 on CI · 29 / 23 known-blocked test.fixme
|
playwright-junit.xml |
playwright-html/index.html (multi-file — git clone the wiki then open locally, or npx playwright show-report reports/final-milestone/web/playwright-html) |
| Mobile | Jest 29 + jest-expo + jest-html-reporters
|
29 | 18 | 11 known regressions (session-token mock drift after the useProtectedSession refactor; tracked as TODO for the mobile team) |
jest-junit.xml | jest-html.html (raw) |
Note on HTML rendering: GitHub serves raw
.htmlfiles withContent-Type: text/plain(so a direct raw link shows source instead of rendering). The first link in each "HTML report" cell goes through htmlpreview.github.io which rewrites the response type so the report renders inline. The(raw)link is the unprocessed file if you'd rather download it. For the Playwright report (multi-file with embedded traces), htmlpreview can't follow relative subfolder fetches, so the canonical way to view it is to clone the wiki and runnpx playwright show-reportagainst the local folder.
GitHub's wiki sidebar only lists .md pages, so the JUnit XML reports do not appear in the wiki navigation — but every file is committed to the wiki repo and reachable via the raw URLs below. Aggregate audit of the 240 backend XMLs: 2,439 tests recorded, 0 failures, 0 errors, 0 skipped (the 3-test gap vs. the 2,442 headline is rerun auto-recoveries that Surefire collapses into the rerun summary rather than the per-class XML).
Frontend / mobile (single-file, click to download):
- Web (Vitest): https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/web/vitest-junit.xml
- Web (Playwright): https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/web/playwright-junit.xml
- Mobile (Jest): https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/mobile/jest-junit.xml
Backend (240 XMLs — representative samples; full set via git clone of the wiki):
- End-to-end integration: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.integration.EndToEndWorkflowTest.xml
- Feed read service: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.service.FeedReadServiceTest.xml
- Advanced For-You ranker integration: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.integration.AdvancedForYouFeedIntegrationTest.xml
- Mentor scoring pipeline: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.service.ranking.MentorScoringPipelineTest.xml
- Neo4j follow-graph integration: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.repository.graph.FollowGraphRepositoryIntegrationTest.xml
- Meeting service: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.service.MeetingServiceTest.xml
- Task service: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.service.TaskServiceTest.xml
- Ban service: https://raw.githubusercontent.com/wiki/bounswe/bounswe2026group7/reports/final-milestone/backend/surefire-xml/TEST-com.group7.backend.service.BanServiceTest.xml
To pull the complete 240-XML set in one go:
git clone https://github.com/bounswe/bounswe2026group7.wiki.git wiki && ls wiki/reports/final-milestone/backend/surefire-xml/The same HTML reports linked from the headline table, gathered in one place:
| Layer | Renderer link (htmlpreview) | Raw file |
|---|---|---|
| Backend (Surefire) | view rendered | surefire.html (730 KB) |
| Web — Vitest | view rendered | vitest-report.html (2.3 MB) |
| Web — Playwright | multi-file — see note below | playwright-html/index.html (entry point of the folder) |
| Mobile (Jest) | view rendered | jest-html.html (3 KB) |
For the Playwright report (the only multi-file one — the folder includes data/ and trace/ subdirectories with per-spec trace bundles), clone the wiki and open it locally:
git clone https://github.com/bounswe/bounswe2026group7.wiki.git wiki
cd wiki/reports/final-milestone/web
# Either open index.html directly in a browser:
open playwright-html/index.html # macOS
xdg-open playwright-html/index.html # Linux
# …or use Playwright's built-in server if you have it installed (resolves trace links correctly):
npx playwright show-report playwright-html-
Integration Tests:
backend/src/test/java/com/group7/backend/integration/ -
End-to-end (E2E) Tests:
frontend/e2e/ -
UI/UX Tests:
mobile-app/__tests__/|frontend/src/**/*.test.tsx
-
Coverage: The new test suite covers the complete social feed lifecycle (create, edit, restore, soft-delete, image attachments, reposts, comment likes), the reporting state machine (submit → pending → resolved/dismissed), the advanced mentor ranker scoring pipeline (all 7 signals, MMR reranker, cold-start fallback), the Neo4j follow-graph sync layer (bootstrap, real-time writes, nightly resync), feed engagement push notifications, ban/block system, profile visibility masking, and mentorship cancellation/timeline preservation.
-
Bug Detection:
-
Feed interaction count regression (PR #492): Integration tests for
GET /api/feed/postscaught that like and comment counts were returning 0 on list responses even after interactions were recorded. The root cause was a missing join inFeedPostMapper— verified by asserting exact counts inFeedReadIntegrationTest. -
Mentorship termination data loss (PR #491):
MentorshipCancellationIntegrationTestcaught that ending or cancelling a mentorship was immediately deleting meetings, tasks, and milestones, making the past mentorship timeline empty. The fix preserved timeline data on termination and added an explicit cleanup endpoint.
-
Feed interaction count regression (PR #492): Integration tests for
-
Readiness: The test suite demonstrates release readiness through: (1) all backend integration tests passing against a real Testcontainers PostgreSQL + Neo4j stack, (2) Playwright E2E tests covering the full auth, profile, mentorship, and feed user journeys, (3) mobile Jest tests covering feed state management and API client behavior, and (4) CI pipelines enforcing all three layers on every PR to
devandmain.
Sorted alphabetically by surname.
-
Responsibilities:
I worked as the Web Lead and DevOps owner across all milestones, owning the React + Vite application end-to-end — pages, components, the shared API client, styling, and frontend tests — and also owning the production deployment, CI/CD pipelines, repo-bootstrap tooling, and Docker / environment configuration. My web responsibilities included implementing user-facing features from new issues, designing the API/service layer that talks to the Spring Boot backend, integrating real-time STOMP subscriptions, maintaining the frontend CI/CD pipeline, and reviewing/merging teammates' frontend PRs.
As the DevOps owner I set up the frontend GitHub Actions pipeline (PR #150) and the production auto-deploy workflow (PR #224) that builds and deploys the project to the DigitalOcean droplet on every push to
main, hardened the SSH timeout (PR #605), tuned the docker-compose frontend port / CORS allow-list (PR #602, PR #603), authored the local-seed pipeline scripts (commits03c211d,871d36f), rewrote the root README's Web Application section with dev/seed/prod flows (PR #600), bootstrapped the repo's issue templates and.gitignoreearly in the project (commitsf6042b3,8805f3b,a18e778,36d84b2,c4b5b85), and shipped the small backend fixes that unblocked the live demo: the Spring Boot mail integration migration to Resend (commit330a62b), the verification-email SPA redirect (PR #601), and the timezone fix for notification timestamps (commit33a1d5c).I also helped coordinate the web team — reviewing and merging frontend PRs, resolving merge conflicts during the final-milestone integration push, and merging cross-team teammate PRs (mobile, backend) into
dev/mainwhen the original author was unavailable. -
Main Contributions:
Social feed (web):
- Feed scaffold with edit/delete and soft-delete restore (PR #445).
- Share & bookmark interactions (PR #446).
- Image attachments — compose, edit, render (PR #514).
- Notification renderer for feed engagement events (PR #511).
- Trending hashtags rail (PR #550).
- User-authored posts section on profile pages (PR #551).
- Feed search date/language filters + keyword mute (PR #555).
- Edit-history viewer with restore-undo (PR #558).
- Near-real-time STOMP subscription + unread badge (PR #564).
- Reposts and quote-shares with attribution (PR #565).
- Wire rating-read endpoints + drop localStorage fallback (PR #557).
- Live like/comment/share count updates (PR #584).
Messaging & chat:
Mentorship lifecycle UI:
- Mentee cancel-mentorship flow (PR #453).
- Tasks UI (PR #454), milestones UI (PR #455), progress timeline (PR #456).
- Auto-termination ended-banner (PR #452).
- Mentor extend-mentorship modal with 1/3/6 month picker (PR #516).
- Mentee mentor-rating prompt + avg rating on profile (PR #517).
- My mentorships page with active/past tabs + pagination (PR #549).
- Home-page progress endpoint wiring (PR #515).
Scheduling & availability:
- Availability grid (PR #406) + port from earlier branch (PR #342).
- Meeting create flow (PR #458).
- Meeting reschedule / cancel (PR #468).
- Weekly calendar view (PR #523).
Profile system:
- Device photo upload (replaced URL input) (PR #227).
- Affiliation field display + edit on mentee profiles (PR #552).
- Hybrid location entry on profile editor (PR #578).
- ESCO / ISCED-F / Wikidata taxonomy autocomplete (PR #581).
- Profile visibility toggle for mentors (PR #589).
- Notification preferences toggles (PR #520).
Search & discovery:
- Switch mentor endpoints to
/allvariants (PR #233). - Advanced mentor search with 3-mentor comparison modal (PR #592) — issue #139.
- Remove followed user from suggested-to-follow rail (PR #525).
Admin & moderation:
- Admin console — user moderation + report queue (PR #590) — issue #279.
- Admin broadcast composer + inbox views (PR #591) — issue #410.
- Reporting trio (post + mentor + mentorship) (PR #588) — issues #128, #358, #411.
Auth, session, security:
- Initial web auth flows (PR #181).
- Profile-system backend connection (PR #211).
- Prevent logout on page refresh (PR #225).
- Spam-bot defence on register: form-token + honeypot (PR #596).
- User logout flow (co-authored with Sami Çakmak) (PR #212).
Notifications:
- /notifications page from navbar dropdown (PR #295).
- Notifications & mentorship-requests view (PR #219).
- Notification renderer for feed engagement types (PR #511).
Backend support fixes (unblocking web/demo flows):
- Include
http://localhost:8000in default CORS allow-list (PR #602). - Point verification email at frontend SPA route (PR #601).
DevOps / CI / deployment / developer experience:
- Frontend CI pipeline (PR #150) — issue #148: GitHub Actions test & build job that runs on every web PR; CI is enforced before merge to
dev. - Production auto-deploy to DigitalOcean droplet on push to
main(PR #224) — issue #213 / #138: SSH-based build + restart viadocker compose up --build -d. - SSH
command_timeoutbump to 30m for the deploy workflow (PR #605) — fixed deploy timeouts when Maven was rebuilding the backend image. - Docker-compose / env tuning for local + prod parity: revert frontend port to 8000, default-CORS allow-list incl.
http://localhost:8000(PR #602), and the joint local/prod deploy fixes (PR #603 — co-authored with Mehmet Bora Sarıoğlu and Burak Ögüt). - Web README rewrite with dev / seed / prod flows (PR #600) and the earlier
README.mdDocker / local setup instructions (commitab981fd). - Local-seed pipeline:
scripts/seed_local.py(~410 LOC offline docker-compose data seeding) and thescripts/seed_data.pyconstants refactor (commits03c211d,871d36f) — folded into teammate's PR #604; later improved by Mehmet Bora Sarıoğlu's persona seed implementation. - Repo bootstrap: issue templates and
.gitignorebaseline (commitsf6042b3,8805f3b,a18e778,36d84b2,c4b5b85) — set up at the start of the project. - Backend support fixes that are partially DevOps in nature: Swagger UI security-filter bypass + kotlin-reflect dependency (commit
dbc861b), Spring Boot mail integration migrated from SMTP to Resend (commit330a62b) for production transactional email, andOffsetDateTime+ Istanbul-timezone consistency for notification timestamps (commit33a1d5c).
-
Significant Issues:
Code-related issues:
- #139: Advanced Mentor Search Filters and Comparison View — Designed and implemented the advanced search filters and the 3-mentor side-by-side comparison modal that lets mentees compare candidate mentors on AI factor chips and LLM-generated explanations.
- #122 & #287: Chat baseline + mentor-to-mentor messaging — Implemented the chat UI, mentorship-messages API client, STOMP subscription hook, attachment upload, and link preview rendering on the web.
- #336 & #339: Weekly availability scheduling + social feed lifecycle — Drag-select availability grid, weekly calendar view, and feed CRUD with edit-history/restore. The two largest UI surface areas I owned end-to-end.
Non-code-related issues:
-
#213 / #138: Production Deployment Setup — Set up the GitHub Actions auto-deploy pipeline that builds and deploys to the DigitalOcean droplet on every push to
main. - #148: Frontend Testing and CI Setup — Initialized Vitest, wrote the global fetch mock, and added the test/build CI job that runs on every web PR.
- #424 / #422: Final Milestone Deliverables Report / Individual Contributions — Contributed to organising and documenting the final-milestone deliverables (this report, README rewrite, local-seed scripts used in the demo).
-
Pull Requests:
Authored / Implemented (selected from 60 confirmed-authored PRs)
- PR #150: Frontend CI pipeline with GitHub Actions (test & build).
-
PR #224: Auto-deploy to production droplet on push to
main. - PR #225: Prevent logout on page refresh.
- PR #227: Replace profile photo URL input with device file upload.
- PR #295: /notifications page from navbar dropdown.
- PR #376: Chat baseline.
- PR #379: Chat attachments.
- PR #388: Mentor-to-mentor messaging.
- PR #406: Availability grid.
- PR #445: Feed scaffold + edit/delete/restore.
- PR #446: Feed share & bookmark.
- PR #458: Meeting create flow.
- PR #468: Meeting reschedule/cancel.
- PR #514: Feed image attachments.
- PR #516: Mentor extend-mentorship modal (1/3/6 months).
- PR #517: Mentee mentor-rating prompt + avg rating.
- PR #523: Weekly calendar view.
- PR #549: My mentorships page with active/past tabs.
- PR #564: Feed near-real-time STOMP + unread badge.
- PR #565: Feed reposts and quote-shares.
- PR #588: Reporting trio (post + mentor + mentorship).
- PR #590: Admin console (user moderation + report queue).
- PR #591: Admin broadcast composer + inbox views.
- PR #592: Advanced mentor search + 3-mentor comparison modal.
- PR #596: Spam-bot defence on register (form-token + honeypot).
- PR #600: Web README rewrite + local seed flow docs.
- PR #601: Point verification email at frontend SPA route.
-
PR #602: CORS allow-list incl.
http://localhost:8000. - PR #605: Bump SSH command_timeout to 30m for deploy.
Co-authored
- PR #212 (with Sami Çakmak): User logout flow.
- PR #603 (with Mehmet Bora Sarıoğlu and Burak Ögüt): Local + prod deploy fixes (env, CORS, docker-compose port alignment).
Reviewed / Merged (teammate PRs I opened or merged into
dev/mainbut whose commits are authored by others)-
PR #604: Reproducible demo seed via snapshot dump/load (commits by Mehmet Bora Sarıoğlu — my
seed_local.pyandseed_data.pyrefactor commits ride along inside). -
PR #594: Mobile
.env.example+ README rewrite (Burak Ögüt). - PR #587: Mobile feed reposts/bookmarks/STOMP (Burak Ögüt).
- PR #585: MatchingService OpenAI timeout fix (Burak Ögüt).
- PR #577: Mobile ban handling (Burak Ögüt).
- PR #214: Production-Ready Project (Beratcan Doğan).
-
AI Transparency & Documentation:
- Claude Code (Anthropic): Used as the primary AI assistant throughout the project for feature planning, multi-file React implementation, API client design, CSS/design-system iteration, PR description drafting, debugging (CORS, STOMP, auth flows), seed-pipeline scripting, and final-milestone documentation. All significant code changes in my final-milestone PRs were developed with Claude Code assistance, with manual verification against the actual API responses and UI behaviour before opening each PR.
-
Individual Testing Efforts:
Set up the web Vitest testing infrastructure (commit
e666717) with a global fetch mock, and added unit/integration coverage alongside feature work. The CI pipeline I set up (frontend-ci.yml, PR #150) runs the test/build job automatically on every web PR.Key coverage areas:
- Auth API functions — happy path and edge cases (commits
94e9610,9e6dbe0). -
MentorshipDetailPage— mockedlistMentorshipMeetingsto test rendering across active/ended states (commitbaf8433). - Mentorship request flow — unit tests across roles (commit
df3ad19). - HomePage and ExplorePage — fixed failing vitest tests after API changes (commit
da075e9). - Plus manual flow verification (
npm run dev/npm run build) and PR-level behaviour validation on every PR before merge.
- Auth API functions — happy path and edge cases (commits
-
Additional Information:
In addition to implementation work, I contributed to:
- Cross-team PR coordination — reviewing/merging teammate PRs (mobile, backend) when needed; resolving frontend merge conflicts during the final-milestone integration push.
- README & developer onboarding — rewrote the Web Application section of the root README (PR #600) with dev / seed / prod flows.
- CI/CD maintenance — frontend pipeline (PR #150), prod auto-deploy (PR #224), SSH timeout bump (PR #605).
-
Local-seed pipeline —
scripts/seed_local.pyand thescripts/seed_data.pyconstants refactor (commits03c211d,871d36f, folded into teammate's PR #604), used by the team during demo prep. Further got improved by Mehmet Bora Sarıoğlu's much better version for seeding script.
-
Code Highlights:
-
Central API client —
frontend/src/services/api.js: shared fetch wrapper with JWT interceptor, evolved across 43 commits and reused by every page-level service. - Feed STOMP subscription + unread badge — wired the web feed to the backend's STOMP fanout so new posts surface with a "new posts" pill without a full page reload (PR #564).
- Spam-bot defence on register — form-token + honeypot fields integrated with the backend's spam scoring (PR #596).
- Weekly availability/meeting calendar — drag-select availability grid + meeting overlay (PR #406, PR #523) — the most complex single UI in my surface area.
- 3-mentor comparison modal in advanced search — side-by-side comparison of AI match factor chips + LLM explanations (PR #592).
- Backend unblocks for the demo — verification-email SPA redirect (PR #601) and CORS allow-list fix (PR #602): small backend changes that unblocked the live verification flow and the local dev frontend.
-
scripts/seed_local.py(~410 LOC) — offline docker-compose data seeding utility, written as standalone commits and later folded into teammate's PR #604 alongside the persona seed. -
CI/CD pipeline (DevOps) —
.github/workflows/frontend-ci.yml(PR #150) for test/build on every web PR, and the production auto-deploy workflow (PR #224 + PR #605) that ships every push tomainto the droplet via SSH +docker compose up --build -d.
-
Central API client —
-
Lessons Learned:
Working on a high-volume web codebase taught me how to scope frontend PRs tight enough to merge quickly while still landing real user-visible value. The biggest single lesson was investing in shared infrastructure early — the
api.jsclient and the CI/CD pipeline saved enormous time later, but each was painful to set up before there was clear payoff. The local-seed pipeline (scripts/seed_local.py) felt like a detour at the time but turned out to be critical for the final demo.On AI tooling, Claude Code accelerated almost every feature I shipped, but the discipline that mattered was verifying suggestions against the actual API responses and UI before opening the PR. Skipping that step once or twice during the busy final-milestone push produced subtle bugs that PR review caught — a useful reminder that AI assistance amplifies both speed and the cost of skipping verification.
It's important to know in what direction our project goes. Instead of carelessly implementing features that first come to mind, it's important to first draw the path and then move on. However, them main headache of project is to draw that path. While code is doable for anything you want to add - the thing you want to add should also ACTUALLY BE WHAT YOU NEED. Having determined idea of project and its steps - is hardest and most important part of any project !
-
Responsibilities:
I worked as the second mobile developer (alongside Burak Ögüt) on the React Native / Expo mobile client across all milestones, co-owning the codebase and integrating screens with the production backend. My responsibilities included implementing user-facing mobile features, refining mobile UX after demo feedback, ensuring web–mobile parity on shared flows (auth recovery, messaging, social feed, mentorship lifecycle), establishing the mobile testing baseline, and running a mobile accessibility audit pass.
I also coordinated with Burak on shared mobile work — co-authoring the initial app bootstrap, push-notification setup, shared-goals/milestones flow, and the social-feed-tabs implementation — and self-merged a small number of PRs into
dev/mainwhen Burak was unavailable for review (PR #165 login + CI fixes, PR #368 chat attachments, PR #369 mentor-to-mentor messaging). -
Main Contributions:
Mobile auth & session:
- Auth recovery + email verification parity with web (PR #306) — issue #303: forgot/reset password and email-verification screens brought to feature-parity with the web client.
- Mobile login screen fixes + CI repair (PR #165).
- Auth session storage ordering fix (PR #442) — resolved non-atomic SecureStore writes.
- Banned-user login response handling (PR #577).
Mobile messaging & chat:
- Chat attachment support (PR #368) — issue #256.
- Mentor-to-mentor messaging on mobile (PR #369).
- Unread-state indicator in messaging (PR #372, PR #402).
Mobile social feed:
- Post creation flow (PR #396) — issue #361.
- Feed interactions — likes, comments (PR #398) — issue #362.
- For-You / Following feed tabs (PR #401 — co-authored with Burak Ögüt) — issue #360.
Mobile mentorship UI:
- Mentor availability editor refinement (PR #307) — issue #141.
- Mentorship progress timeline + meeting-notes screen + UX fixes (PR #502).
- Shared goals + milestones flow (PR #400 — co-authored with Burak Ögüt) — issue #260.
- Task detail + feedback flow (PR #395) — issue #263.
- Explore-screen pagination fix — load all mentors instead of first page only (PR #496).
Mobile testing infrastructure:
- Jest setup + initial auth-flow tests (PR #374, ~2,773 LOC) — issue #257: the foundation the mobile test suite was built on.
- Critical-flow tests covering core mobile journeys (PR #403).
- Screen-level tests for messages / profile / social-feed surfaces (PR #444, ~2,327 LOC) — issue #318.
Mobile accessibility & polish:
- Mobile accessibility audit (PR #381, ~3,011 LOC across components) — issue #259: aria/label coverage, focus indicators, OS reduced-motion respect.
- Native push notification setup (PR #399 — co-authored with Burak Ögüt) — issue #249.
- Final demo checklist for the mobile track (PR #382) — issue #269.
Project bootstrap (early):
-
Significant Issues:
Code-related:
- #141: Implement mentor availability editing screen — owned end-to-end on mobile, including subsequent UX refinement after demo feedback.
-
#259: Mobile Accessibility Audit and Improvements — ~3,011-LOC pass across components adding
accessibilityLabel, focus indicators, and reduced-motion respect. - #257 / #318: Mobile testing infrastructure — Jest scaffolding, critical-flow tests, and screen-level tests across messages / profile / social-feed.
Non-code-related:
- #305: Frontend–Mobile Feature Parity Tracker — contributed the mobile-side parity audit.
- #331: Final Demo Plan — covered mobile-side demo readiness via #269 (mobile final-demo polish + end-to-end flow validation).
- #424: Final Milestone Deliverables Report — mobile-track sign-off and submission items.
-
Pull Requests:
Authored / Implemented (selected from ~18 confirmed-authored merged PRs)
- PR #69: Stub-app button feature (early March 2026).
- PR #153: Mobile app initialization (co-authored with Burak Ögüt).
- PR #165: Mobile login screen + CI fixes.
- PR #306: Mobile auth recovery + email-verification parity (~1,064 LOC).
- PR #307: Mentor availability editor refinement.
- PR #368: Mobile chat attachment support.
- PR #369: Mentor-to-mentor messaging on mobile.
- PR #372: Unread state in mobile messaging.
- PR #374: Mobile Jest testing setup + auth-flow tests (~2,773 LOC).
- PR #381: Mobile accessibility audit (~3,011 LOC).
- PR #382: Mobile final-demo checklist.
- PR #395: Mobile task detail + feedback flow.
- PR #396: Mobile social feed post creation.
- PR #398: Mobile social feed interactions (likes, comments).
- PR #402: Show unread state in mobile messaging.
- PR #403: Mobile critical-flow tests.
- PR #442: Mobile auth-session storage fix.
- PR #444: Mobile screen tests — messages / profile / feed (~2,327 LOC).
- PR #496: Load all mentors on Explore instead of first page only.
- PR #502: Mentorship progress timeline + meeting notes + UX fixes (~601 LOC).
- PR #577: Mobile banned-user login response handling.
Co-authored (with Burak Ögüt)
- PR #399: Mobile native push notification setup.
- PR #400: Mobile shared goals + milestones flow.
- PR #401: Mobile social feed tabs (For-You / Following).
Self-merged into
dev/main -
AI Transparency & Documentation:
- Tool summary: Övgü to fill — AI tools used
- Prompts: Prompts log
-
Individual Testing Efforts:
Set up the mobile Jest testing infrastructure (PR #374, ~2,773 LOC) — the foundation the mobile test suite is built on (
mobile-app/__tests__/). Subsequent test PRs added critical-flow coverage and screen-level tests across the mobile surface.Key coverage areas:
- Auth flow tests (initial coverage in PR #374;
mobile-app/__tests__/login.test.tsx). - Critical-flow tests covering core mobile journeys (PR #403).
- Screen-level tests for messages / profile / social-feed (PR #444, ~2,327 LOC).
- Connection-profile screen tests (commit
5995661). - Plus manual mobile-device verification across iOS / Android development builds before each PR.
- Auth flow tests (initial coverage in PR #374;
-
Additional Information:
In addition to feature implementation, contributed:
- Mobile testing baseline — the Jest infrastructure that the mobile track's test reports build on.
- Mobile accessibility audit — ~3,011-LOC pass across components.
- Final-demo coordination on the mobile side — mobile final-demo checklist (PR #382, issue #269).
- Web–mobile parity coordination — contributed to the parity tracker work in issue #305 and auth-recovery parity work in PR #306.
-
Code Highlights:
-
Mobile testing scaffolding —
mobile-app/__tests__/Jest setup + initial auth coverage + critical-flow + screen-level test suites (PR #374, PR #403, PR #444). -
Mentorship progress timeline + meeting-notes screen —
mobile-app/connection-profile.tsx+ the meeting-notes screen (PR #502, ~601 LOC). - Auth-recovery parity screens — forgot/reset password + email verification brought to feature-parity with web (PR #306, ~1,064 LOC).
-
Mobile accessibility audit —
accessibilityLabel, focus indicators, reduced-motion respect across components (PR #381, ~3,011 LOC). - Chat attachments + mentor-to-mentor messaging on mobile (PR #368, PR #369).
- Mentor availability editor refinement — drag-friendly slot editing on the mobile surface (PR #307).
-
Mobile testing scaffolding —
-
Lessons Learned:
Building a mobile app alongside a fast-moving web codebase made parity coordination the daily challenge — backend API shapes shifted weekly during the final-milestone push, and keeping the mobile client in sync without breaking demo flows required disciplined testing and tight communication with the other mobile developer. The early investment in Jest infrastructure (PR #374) paid off later in the milestone when screen-level tests caught regressions during integration.
The mobile accessibility audit and the final-demo checklist were two pieces of work that didn't ship visible new features but were essential for a polished demo — a reminder that the last mile of a release is often invisible polish rather than new functionality.
-
Responsibilities:
I worked mainly as a web frontend team member during the final milestone. My responsibilities included implementing and fixing user-facing web features, integrating frontend components with backend APIs, improving profile and mentorship-related pages, debugging web UI issues, preparing demo/test data support, reviewing frontend behavior before PRs, and helping maintain frontend consistency across shared flows.
My main implementation responsibilities were mentorship shared-goal UI, mentor capacity/profile-related frontend work, mentee profile rendering fixes, profile dropdown and request-button state fixes, follow UI behavior, social feed interaction improvements, notification UI updates, frontend authentication/API header fixes, and demo persona seed support.
I also contributed to frontend quality and integration safety. Before opening or updating PRs, I manually tested affected user flows, checked whether the UI reflected real backend data, verified role-based rendering behavior, and followed PR review feedback.
In addition to coding, I contributed to final milestone coordination and documentation, web-mobile feature parity tracking, final demo planning, individual contribution documentation, and AI transparency documentation.
-
Main Contributions:
- Implemented the frontend shared-goal definition flow for active mentorships, including the CTA card, shared-goal modal, and milestone/progress gating behavior.
- Worked on follow-related web UI and user profile/feed behavior, connecting visible frontend state to backend-provided relationship data.
- Contributed to synthetic persona/demo seed data generation and improvements.
- Implemented mentor capacity setting on the profile page and connected it with mentorship context refresh behavior.
- Fixed the blank-page bug that occurred when a mentor opened a mentee profile from incoming mentorship requests.
- Fixed dynamic UI state problems such as hardcoded task/session counts in the profile dropdown and a stuck "Request Sent" mentor-profile button.
- Improved feed interactions on the web frontend, including optimistic likes, inline comments, and comment-like support.
- Implemented or supported notification UI updates for new notification types.
- Fixed API authorization/header handling in the frontend service layer.
- Fixed navbar/profile dropdown count synchronization by removing dummy values and connecting dropdown stats to shared dashboard state.
-
Significant Issues:
Code-related issues:
- #277: Shared Goal Definition Flow — Implemented the frontend shared-goal definition flow for active mentorships including CTA card, modal, and milestone gating.
- #357: Follow UI / User Profile Follow Behavior — Connected follow state to backend data, improved follow/unfollow interactions.
- #407: Synthetic Persona / Demo Seed Data Generation — Improved seed data structure and generated more realistic mentor/mentee personas.
Non-code-related issues:
- #305: Frontend–Mobile Feature Parity Tracker — Mapped user-visible features across web and mobile, identified mismatches.
- #331: Final Demo Plan — Checked which frontend flows were demo-ready and aligned with the planned presentation flow.
- #422: Final Milestone Report — Individual Contributions — Prepared and organized individual contribution section.
-
Pull Requests:
Authored / Implemented
- PR #311: Fixed navbar profile dropdown stats by synchronizing them with global dashboard state.
- PR #412: Feature/persona seed demo.
- PR #440: Fixed blank page on mentee profile view from mentor dashboard.
- PR #451: Added mentor capacity setting to the profile page.
- PR #457: Implemented shared goal definition flow and frontend gating.
- PR #459: Added frontend support for new notification types.
- PR #464: Added web-mobile feature parity tracker documentation.
- PR #467: Fixed frontend auth header handling.
- PR #473: Made profile dropdown counts and mentor request button state dynamic.
- PR #481: Added optimistic likes and inline comments for the feed.
- PR #505: Implemented follow UI work for issue #357.
- PR #554: Implemented comment-like support on the web feed.
Reviewed / Merged
-
AI Transparency & Documentation:
- GitHub Copilot / GPT-5.2 Codex: Used for codebase navigation, issue analysis, debugging, and implementation suggestions.
- Google Antigravity / Gemini 3 Flash: Used for agentic planning, UI debugging, and multi-file frontend investigation.
- ChatGPT: Used to organize AI prompt logs into Markdown documentation.
- Prompts: AI Prompt Log - Muhammet Sami Çakmak
-
Individual Testing Efforts:
Manual frontend verification, local build checks (
npm run dev,npm run build), and PR-level behavior validation. Covered flows such as the shared-goal CTA and modal behavior, mentee profile navigation, dynamic profile dropdown counts, mentorship request button states, follow UI, and feed interactions. -
Additional Information:
Besides implementation work, actively participated in web frontend coordination, PR preparation, frontend debugging, final demo preparation, final milestone documentation, and AI transparency documentation.
-
Code Highlights:
- Shared goal definition flow with CTA, modal, and milestone gating.
- Follow UI and profile behavior connected to backend relationship data.
- Mentor capacity setting with mentorship state refresh.
- Dynamic dropdown/request button fixes replacing hardcoded values.
- Feed interaction improvements: optimistic likes, inline comments, comment likes.
-
Lessons Learned:
Learned that frontend bugs can come from routing, API response shape, authentication headers, or incorrect UI state assumptions. Improved understanding of frontend/backend integration. Learned to use AI tools responsibly — verifying suggestions against actual code and PR review feedback.
-
Responsibilities:
I worked as the primary backend developer and integrator across the entire project lifecycle. My responsibilities covered owning the Spring Boot backend service, designing and implementing core domain features (auth, mentorship lifecycle, matching, messaging, notifications, moderation), shipping the production deployment, identifying and fixing correctness/security bugs across the backend, and setting up the acceptance/E2E testing infrastructure that the team used for the demo.
In the final milestone I focused on closing out the mentorship and community feature set: full mentorship lifecycle (cancellation, extension, termination, auto-completion, ratings), automatic temporary ban system with escalating durations, admin ban/unban + admin messaging, FCM push-notification transport, follow recommendations on the social graph, search overhaul, and the cross-feature end-to-end test suite. I also drove the Playwright E2E setup (AT-01..AT-07) and the production deployment hardening (UTC standardization, JWT claim validation, availability authorization, race-condition fix on mentor capacity, spam-bot defences).
Beyond coding I served as the backend integrator: I reviewed and merged the majority of teammate PRs into
dev/main, coordinated migration version bumps, resolved merge conflicts across long-running feature branches, and authored the umbrella issues (#262, #314, #422) that organized the final-milestone work. -
Main Contributions:
- Bootstrapped the Spring Boot backend: entities matching the UML class diagram, JWT authentication, PostgreSQL + Flyway migrations, register/login endpoints, Swagger UI, password validation.
- Designed and implemented the mentor matching algorithm for mentees.
- Implemented the full mentorship lifecycle: cancellation with audit trail and cool-down (#133), extend/end/auto-completion/ratings (#237), and a status=ALL filter for history views.
- Built the automatic temporary ban system with mentee cancellation tracking, escalating ban durations, admin override, and a scheduled expiry job (#134).
- Implemented admin ban/unban endpoints and admin → user messaging (#280), including admin self-view fix (#553).
- Added FCM push-notification transport, device registry, per-user notification preferences, and REQUEST_SUBMITTED wiring (#136).
- Added the follow recommendations endpoint, scoring candidates by shared interests and follow-graph proximity (#344).
- Implemented layered spam-bot defences for registration: form-token, honeypot, and rate-based heuristics (#345).
- Built mentor and mentee dashboard stats endpoints (#253).
- Stood up the Playwright E2E test suite from scratch — backend test-support infra, fixtures, e2e-ci workflow, AT-01..AT-07 specs (#315/#316/#317).
- Owned the cross-feature E2E workflow test suite covering mentorship
- messaging + notifications in one integration scenario (#254).
- Production deployment: docker-compose hardening, uploads volume, Neo4j wiring, and the .env documentation for the prod runbook.
-
Significant Issues:
Code-related issues:
- #237: Mentorship lifecycle — extend, end, auto-completion, ratings. Implemented end-to-end including the rating model and scheduled auto-completion job.
- #262: Search overhaul — moved search filtering from in-memory to database-level, added indexing, removed N+1 query path.
-
#270:
Race condition in mentor capacity check during request acceptance —
fixed with optimistic locking and a regression test
(
MentorshipEndRaceConditionTest). - #271: NullPointerException risk when JWT lacks userId/role claims — hardened token validation to reject malformed claims.
-
#272:
Inconsistent timezone handling — standardized backend on UTC and
OffsetDateTimeacross timestamp-sensitive services. - #273: Match-found notification triggered on every mentor browse — restricted notification emission to actual match events.
- #274: Availability GET lacked per-resource authorization — added access policy and documented the contract.
- #345: Spam-bot defences for registration — multi-layer defence + scoped unban path for SYSTEM_SPAM bans only.
Non-code-related issues:
- #314: General Acceptance Testing umbrella — planned and tracked the full AT-01..AT-07 acceptance scenarios for the demo.
- #254: End-to-end integration test suite design for cross-feature workflows — scoped the integration scenarios.
- #422: Final Milestone Report §5 — individual contributions coordination.
-
Pull Requests:
Authored / Implemented
- PR #158: Email verification system.
- PR #160: Password reset flow.
- PR #173: Mentor matching algorithm for mentees.
- PR #199: Deployment configurations.
- PR #214: Production-ready project (full deployment).
- PR #300: Reject JWTs with missing userId/role claims (#271).
- PR #301: UTC timezone + OffsetDateTime standardization (#272).
- PR #319: Availability GET access policy (#274).
- PR #325: STOMP SUBSCRIBE branch + ERROR-frame test coverage.
- PR #377: FCM push notification infrastructure (#136).
- PR #380: Automatic temporary ban system (#134).
- PR #383: Follow recommendations endpoint (#344).
- PR #393: Playwright E2E suite + e2e-ci workflow (#315).
- PR #394: AT-02 mentorship+blog spec + AT-04/05 scaffolds (#316).
- PR #397: AT-06 messaging/reminders + AT-07 NFR (#317).
- PR #425: Mentorship cancellation, cleanup, audit trail, cool-down (#133).
- PR #439: Mentorship lifecycle — extend/end/auto-completion/ratings (#237).
- PR #441: Mentor and mentee dashboard stats endpoints (#253).
- PR #443: Cross-feature E2E workflow test suite (#254).
- PR #449: Admin ban/unban + admin messaging (#280).
- PR #466: Layered spam-bot defences for registration (#345).
- PR #477: Remove mentor-side branch from match-notification path (#346).
Reviewed / Merged Acted as the primary integrator on
dev/main, reviewing and merging 100+ teammate PRs across web, mobile, and backend — including PR #561, PR #566, PR #573, PR #574, PR #576, PR #579, PR #580. -
AI Transparency & Documentation:
- GitHub Copilot / GPT-5.2 Codex: Used for backend code navigation, JPA query drafting, test scaffolding, and debugging.
- Claude Code (Opus 4.7): Used for architectural review, race-condition analysis, multi-file refactors, and PR drafting.
- ChatGPT: Used to draft documentation and organize prompt logs.
- Prompts: AI Prompt Log - Beratcan Doğan
-
Individual Testing Efforts:
Wrote JUnit unit tests for service-layer logic (mentorship lifecycle, ban escalation, JWT claim validation, STOMP SUBSCRIBE branches), added the
MentorshipEndRaceConditionTestintegration test for the optimistic-locking fix, and authored the cross-feature E2E workflow suite that exercises mentorship + messaging + notifications in one scenario. Set up the Playwright e2e-ci workflow used by the team for AT-01..AT-07 acceptance verification. -
Additional Information:
Beyond implementation, served as the backend integrator and release manager: drove merge-train hygiene on
dev/main, coordinated migration version bumps, resolved cross-feature conflicts, and shipped the production deployment. Authored the umbrella issues that scoped the final-milestone acceptance testing and reporting work. -
Code Highlights:
- Mentorship lifecycle state machine with audit trail, cool-down, and scheduled auto-completion.
- Automatic temporary ban system with escalating durations driven by mentee cancellation tracking.
- FCM push-notification transport with device registry and per-user preferences.
- Follow recommendations scoring shared interests + follow-graph proximity.
- Playwright AT-01..AT-07 acceptance suite + cross-feature E2E workflow test.
-
Lessons Learned:
Learned that backend correctness lives or dies on the boundary — timezone handling, JWT claim validation, authorization on read endpoints, and race conditions on shared mutable state were the bugs that bit hardest. End-to-end integration tests caught regressions that unit tests missed. As the team's integrator, learned that fast, consistent PR review is itself a feature: the team's velocity depended on a clean merge train more than on any single feature.
-
Responsibilities:
I worked mainly as a backend team member during the final milestone. My responsibilities included implementing backend features, maintaining consistency with the existing backend architecture, reviewing backend PRs, running local backend tests before/after important merges, following GitHub CI/CD results, and helping teammates investigate backend-related issues reported by frontend/mobile teams.
My main implementation responsibilities were meeting scheduling, mentor-assigned task management, mentorship milestone/action-item management, task and milestone reminder notifications, mentorship progress/timeline preservation, and smaller feed-related backend endpoint support.
I also took responsibility for backend quality and integration safety. Before approving or merging backend PRs, I checked the PR scope, compared changes with the current
devbranch, ran focused or full backend tests when needed, and monitored GitHub checks after merges. -
Main Contributions:
- Implemented the backend meeting scheduling flow, including database schema, entities, repositories, DTOs, service logic, controller endpoints, reminder scheduling, and tests.
- Implemented mentor-assigned task functionality, including task creation, submission, feedback/review lifecycle, validation rules, notification hooks, and backend tests.
- Implemented mentorship milestone and action-item backend functionality, including milestone lifecycle operations, action items, validation, and test coverage.
- Implemented automated task and milestone reminder notifications with deduplication and preference-aware delivery behavior.
- Added an author-based feed posts endpoint so frontend/mobile clients can list posts belonging to a specific user profile.
- Fixed mentorship data lifecycle behavior by preserving progress/timeline data after end/cancel/auto-completion and adding an explicit cleanup endpoint.
- Reviewed, tested, commented on, and merged multiple backend PRs after checking implementation quality and CI status.
-
Significant Issues:
Code-related issues:
- #132: Task Assignment and Progress Tracking — Major backend work covering task management, submission/review, milestones, and reminders.
- #131: Meeting Scheduling with Reminders — Backend meeting scheduling API, database model, service layer, and reminder scheduler.
- #478: Preserve mentorship timeline after end/cancel — Kept progress/timeline data available after mentorship termination.
Non-code-related issues:
-
Pull Requests:
Authored / Implemented
- PR #309: Decoupled match-found notifications from browse endpoints.
- PR #352: Implemented meeting scheduling system.
- PR #370: Implemented mentor-assigned tasks, submissions, and feedback.
- PR #378: Implemented mentorship milestones and action items.
- PR #404: Implemented automated task and milestone reminder notifications.
- PR #474: Added author-based feed posts endpoint.
- PR #491: Preserved terminated mentorship timeline data and added explicit cleanup endpoint.
Reviewed / Merged
-
AI Transparency & Documentation:
- Antigravity - Gemini 3.1 Pro: Backend issue analysis, implementation planning, Docker/Maven test command planning.
- Antigravity - Claude 4.6 Sonnet/Opus: Deeper backend reasoning, PR review support, scheduler/reminder design.
- VSCode Codex: Backend investigation, PR review, issue/PR body preparation, test debugging.
- GitHub Copilot / VSCode Chat: Command-line help, Git/GitHub workflow support.
- Prompts: AI Prompt Log - İbrahim Kayan
-
Individual Testing Efforts:
Actively involved in writing backend tests for my implementations and running regression tests before important merges. Used Docker-based Maven test runs and GitHub CI/CD checks.
-
Meeting scheduling tests (PR #352):
MeetingServiceTest,MeetingSchedulerTest— meeting creation, validation, reminders, notification triggering. -
Task assignment/submission/feedback tests (PR #370):
TaskServiceTest— task lifecycle, authorization, notification hooks. -
Milestone and action-item tests (PR #378):
MilestoneServiceTest— milestone creation, completion, action-item behavior. -
Task/milestone reminder notification tests (PR #404):
ReminderNotificationIntegrationTest,PushNotificationIntegrationTest. -
Mentorship termination and timeline preservation tests (PR #491):
MentorshipCancellationIntegrationTest,MentorshipAutoCompletionServiceTest. -
Author-based feed posts tests (PR #474):
FeedReadIntegrationTest.
-
Meeting scheduling tests (PR #352):
-
Additional Information:
Besides implementation, participated in backend coordination, PR review, debugging sessions, weekly meetings, demo preparation, and final milestone documentation. Helped communicate backend constraints and API expectations to frontend/mobile teammates.
-
Code Highlights:
- Meeting scheduling backend with scheduler, reminder integration, and tests.
- Task assignment/submission/feedback with notification hooks.
- Milestone and action-item lifecycle management.
- Automated reminder notification system with deduplication and preference-aware delivery.
- Mentorship termination data preservation with explicit cleanup endpoint.
- Author-based feed posts paginated endpoint.
-
Lessons Learned:
Gained confidence in backend development, meaningful test writing, and regression testing before merges. Improved understanding of the full GitHub workflow and large codebase navigation. Learned to use AI tools responsibly — verifying suggestions against actual code, tests, and CI results.
-
Responsibilities:
I worked as the sole mobile developer throughout the entire project. My responsibilities included initializing and architecting the React Native Expo application from scratch, integrating every mobile screen with the backend APIs, setting up the CI/CD pipeline for automated APK builds, maintaining mobile code quality, debugging network and platform-specific issues, and ensuring parity between web and mobile feature sets across all three milestones.
Across the project I owned: core MVP features (auth, navigation, mentorship lifecycle), real-time STOMP feed updates, reposts, bookmarks, comment likes, blog/user posts screen, mentorship progress timeline, ban handling, and all mobile submission deliverables (
.env.example, README, APK release). I also reviewed and merged my mobile teammate's PRs throughout the project. -
Main Contributions:
MVP Milestone:
- Initialized the React Native Expo project from scratch and implemented core MVP features: authentication, splash screen, role-based navigation (mentor/mentee), mentor discovery, mentorship lifecycle (send/accept/reject), notifications screen, and availability scheduling.
- Integrated all screens with the production backend via Axios JWT interceptor; fixed Android HTTP cleartext restriction and SecureStore key format issues.
- Set up GitHub Actions CI/CD pipeline for automatic APK build on push to
dev/main. - Identified and relayed backend gaps (missing mentor notification on request creation; broken paginated response format from
/users/mentors) — both fixed immediately.
Final Milestone:
- Implemented social feed with full engagement: post likes, comment likes, reposts/quote-shares, bookmarks (dedicated screen), image attachments via
expo-image-picker, edit history viewer, soft-delete awareness. - Integrated real-time feed updates via STOMP WebSocket (
/topic/feed.{userId}). - Built who-to-follow suggestions rail and trending hashtags.
- Implemented mentorship progress timeline and meeting notes screen with active/ended state gating.
- Implemented blog/user posts screen with create-post flow, pagination, and load-more.
- Added mentee affiliation field, mentorship report modal, ban system integration (
BANNED_UNTIL→/blockedredirect), and silent error suppression. - Fixed the backend
MatchingService.javaOpenAI timeout bug by separating explanation generation from@Transactional(readOnly)scope. - Wrote
mobile-app/.env.exampleand rewrotemobile-app/README.mdwith dev/production build steps and network configuration guidance.
-
Significant Issues:
Code-Related:
- #155: Core mobile MVP — role-based navigation, JWT auth with SecureStore, mentor discovery, mentorship lifecycle, notifications, availability; fixed Android cleartext restriction and SecureStore key format bug.
-
#356: Feed Real-Time Updates — Implemented STOMP WebSocket subscription for the mobile feed via
services/stompClient.tsandhooks/useFeedSubscription.ts. - #542: Feed Reposts / Quote-Shares — Added repost and quote-share support on the mobile feed with attribution display and optimistic state updates.
Non-Code-Related:
- #305: Frontend–Mobile Feature Parity Tracker — Tracked which web features were implemented on mobile and identified gaps.
- #331: Final Demo Plan — Verified key mobile flows were demo-ready.
-
#424: Final Milestone Deliverables Report — Contributed to mobile submission requirements (
.env.example, README, APK release).
-
Pull Requests:
Authored / Implemented — MVP Milestone
- PR #153: Initialize mobile app — React Native Expo project setup with MVP features (auth, splash, role-based dashboard, mentorship request management).
- PR #165: Fix mobile login and CI — backend integration for login/register, explore tab fix, API client setup, TypeScript CI fixes (relative imports across 7 files).
- PR #232: feat(mobile) — notifications screen, production server connection, Mentee Requests tab replacing Explore for mentors, extended profile fields, GitHub Actions APK CI, SecureStore key fix, layout fixes.
-
PR #234: fix(mobile): handle paginated response from
/users/mentors—res.data.content ?? res.datapattern after backend added pagination.
Authored / Implemented — Final Milestone
- PR #496: Fixed explore screen to load all mentors instead of first page only.
- PR #502: Mentorship progress timeline and meeting notes screen with active/ended state gating.
- PR #526: Blog/user posts screen, feed image attachments, like/comment interactions, trending hashtags.
-
PR #577: Ban handling —
BANNED_UNTIL403 redirects to/blockedscreen with reason and expiry. -
PR #585: Fixed backend
MatchingService.javaOpenAI explanation timeout by running the LLM call outside the@Transactional(readOnly)scope. - PR #587: Feed reposts, bookmarks, real-time STOMP subscription, edit history viewer, who-to-follow rail, comment likes, mentorship report modal, mentee affiliation, past mentorship stats fix.
-
PR #594: Added
mobile-app/.env.exampleand rewrotemobile-app/README.mdwith setup, build, and network configuration instructions.
Reviewed / Merged (teammate's PRs)
- PR #306, PR #307, PR #372, PR #374, PR #381, PR #382, PR #395, PR #396, PR #398, PR #399, PR #400, PR #401, PR #402, PR #403, PR #442, PR #444
Conflict Resolution
In PR #587, a large
git pull origin devwas required mid-branch to sync with 126 files of concurrent teammate changes (ban system, admin console, reporting system). Conflicts inapi/client.ts,profile.tsx, andfeed.tsxwere resolved manually, integrating the ban-notice handling added by teammates while preserving the silent error suppression logic. -
AI Transparency & Documentation:
- Claude Code (Anthropic): Used as the primary AI assistant throughout all milestones for feature implementation, debugging (network errors, TypeScript errors, lint failures, merge conflicts), code review, PR description drafting, README writing, and release preparation. All significant code changes in the final milestone PRs were developed with Claude Code assistance.
- Prompts: Prompts log
-
Individual Testing Efforts:
Set up the mobile Jest testing infrastructure (PR #374) and wrote test coverage across all milestones. The CI pipeline (
mobile-ci.yml) ran tests automatically on every PR.Key coverage areas:
- Critical flow tests: notifications, auth lifecycle, core user journeys (PR #403)
- Screen-level tests covering mentor/mentee role-based rendering (PR #444)
- Feed screen rendering and interaction state (likes, bookmarks, comment toggle)
- STOMP subscription hook (
useFeedSubscription.ts) — connection lifecycle and event handling - Auth and token handling in
api/client.ts— silent flag suppression and ban redirect behavior
-
Additional Information:
As the sole mobile developer, maintained ownership of the entire mobile codebase across all three milestones. Prepared all mobile submission deliverables for each milestone: APK build pipeline, GitHub Releases,
.env.example, and README. Coordinated with backend and web teams to align API contracts and surface mobile-side integration bugs early. -
Code Highlights:
-
STOMP real-time feed:
mobile-app/services/stompClient.ts+mobile-app/hooks/useFeedSubscription.ts— WebSocket subscription seeding new posts without a full reload. -
Bookmarks screen:
mobile-app/app/bookmarks.tsx— dedicated screen with paginated retrieval and unbookmark support. -
Comment likes with optimistic update:
feed.tsxandsocial-feed.tsx—commentLikeStateseeded fromviewerHasLiked, toggled optimistically with rollback on error. -
Silent error suppression:
mobile-app/api/client.ts—silent?: booleanflag onAxiosRequestConfigprevents expected 403/409 from cluttering the console. -
Ban handling:
api/client.tsinterceptor +utils/banNotice.ts—BANNED_UNTIL403 clears tokens, stores ban reason/expiry, redirects to/blocked. -
Paginated mentor list fix:
explore.tsx—res.data.content ?? res.datapattern handling both paginated and plain-array backend responses.
-
STOMP real-time feed:
-
Lessons Learned:
Working as the sole mobile developer across three milestones taught me how to maintain ownership of a rapidly evolving codebase while staying in sync with backend API changes driven by other teams. Managing a mid-branch
git pullbringing 126 files of concurrent changes was the most challenging moment — requiring careful conflict resolution while preserving both sides' intent.I also learned the practical difference between
localhostand a real device IP in mobile networking, and how university Wi-Fi can block device-to-device traffic. Building the STOMP integration showed how WebSocket lifecycle management differs between web and mobile.Working with Claude Code as an AI pair programmer showed me how to use AI assistance responsibly: verifying suggestions against actual code, catching subtle bugs in optimistic update rollback logic, and using AI for code review as well as implementation.
-
Responsibilities:
Backend lead and project coordinator during the Final Milestone. My remit covered (a) the design, implementation, testing, and rollout of every new server-side surface — social-feed lifecycle and interactions, the three advanced recommendation pipelines (mentor matching, For-You feed, follow recommendations), the polymorphic reporting + admin-moderation stack, the admin console's backend APIs, the profile-visibility mask, mentorship history + rating endpoints; (b) the deployment-facing infrastructure — production Docker Compose with Neo4j, reproducible demo-seed pipeline, operator deployment guide; (c) the Playwright acceptance suite — rewriting AT-02 and AT-07 for cross-browser determinism and authoring AT-04, AT-05, AT-17 through AT-22; and (d) project coordination — representing the team in instructor / TA meetings that defined project scope and acceptance bar, driving the lab cycle's planning and organisation, and performing the deployment + dry-run for the Final Milestone presentation.
-
Main Contributions:
Headline scope. 70 authored-and-merged PRs across the project lifecycle (verified via
gh pr list --author mehmetborasarioglu --state merged), ~35 formal reviews that gated teammates' merges, and ownership of the largest backend feature areas (social feed, all three recommendation rankers, reporting + admin moderation, production infrastructure). My code is on every reviewer-visible feature surface except mobile, and on the entire production deploy.-
Social feed — end-to-end ownership of the most-demoed feature in the product (PR #500 soft-delete + edit-history + restore + trending hashtags · PR #499 social-feed API ergonomics · PR #498 image attachments · PR #503 comment likes · PR #501 keyword + hashtag + date-range + language search with viewer keyword-mute · PR #531 enhanced sharing — quote-shares + share events · PR #532 viewer-relative feed flags · PR #533 unit coverage for
FeedInteractionService+FeedReadService). The complete posts + comments + likes + comment-likes + reposts + quote-shares + bookmarks + share-events surface; soft-delete / restore / edit-history; trending hashtags; image attachments; all of it under AS 2.0 / JSON-LD 1.1 / Schema.org content negotiation (PR #536). The reviewer-visible feed in the demo, every Playwright AT-04 / AT-05 step, and every screenshot in §4.4 of this report hits code I authored. -
All three advanced recommendation pipelines. Advanced For-You feed ranker with the AFTER_COMMIT Thompson-sampling bandit listener and the
AdvancedForYouFeedRankerscoring pipeline behindFEED_ADVANCED_RANKER(PR #497). Neo4j follow-graph mirror with Personalized PageRank, the AFTER_COMMIT sync listener +FailedGraphSyncoutbox, and the multi-signalFollowRecommendationService(PR #470). Advanced mentor matching ranker with seven scoring signals (semantic affinity, geographic distance, field overlap, availability, capacity, engagement, diversity) plus theMatchExplanationServicethat produces profile-grounded LLM explanations (PR #567). These are the three "advanced algorithm" rows in §4.2 of this report — all shipped, all inmain, all covered by tests. -
Polymorphic reporting + admin moderation stack (PR #574, issue #135 family). Report state machine, polymorphic target (user / post / mentorship), duplicate-prevention partial index translated to a clean 409 envelope, user-keyed rate limit on
POST /api/reports, admin queue and transition endpoints (AdminReportController.transitiongated byReportStatusMachine.assertValid),AFTER_COMMITasync fan-out ofREPORT_RECEIVEDto every admin, end-to-end reporting + moderation integration test. The reporting flow is one of the eight canonical sequence diagrams in Sequence Diagrams (Final) §8. -
Admin surface — user-list / user-detail / ban-history endpoints (PR #576, issue #569), admin's own
/meprofile lookup (PR #559, issue #553), admin messaging read endpoints (PR #561, issue #280). This is the backend behind every admin-panel screenshot in §4.4 (web-15..web-18). -
Mentorship lifecycle, history, and ratings — paginated history filter on
GET /api/mentorships(PR #529, issue #521); mentor-rating read endpoints — single mentorship + paginated list (PR #534, issue #518); profile-visibility surname/photo masking per requirement 1.1.2.5 (PR #579, issue #570);isFollowingflag on profile reads (PR #527); mentee-affiliation read paths (PR #528 and PR #535); advanced mentor search filters end-to-end (PR #580). -
Production infrastructure I personally own — Neo4j in
docker-compose.prod.ymlwith a baked-in GDS plugin Docker image (PR #599); the reproducible demo-seed snapshot dump / load pipeline (scripts/seed_snapshot.py+ thedemoprofile in compose) that runs on every production deploy (PR #604); operator-facing backend deployment guide (PR #530,backend/DEPLOYMENT.md); the production Swagger UI surface live at https://mymentornet.org/swagger-ui/index.html, the operator.env.exampledocumentation of Neo4j and follow-graph flags. The droplet at 167.71.44.71 boots, seeds, and serves from code I wrote. -
Standards & semantic web (PR #536, issue #490). Authored the W3C-track standards-adoption decision documented in §4.5 of this report — picked the Activity Streams 2.0 vocabulary terms, the JSON-LD 1.1 framing, the Schema.org terms (
author,dateCreated,text,byDay), and theAccept: application/ld+jsoncontent-negotiation model. Every feed surface ships with two representations on a single endpoint. - Acceptance-test stability — AT-02 and AT-07 cross-browser determinism rewrite (PR #573), and 8 brand-new specs authored from scratch: AT-04 (social-feed reporting + search + sharing), AT-05 (polymorphic reporting + auto-ban + admin resolution), AT-17 (profile-visibility mask), AT-18 (admin reads), AT-19 (follow + unfollow + Following feed + follow-recommendations), AT-20 (mentorship termination), AT-21 (mentor rating), AT-22 (advanced mentor search filters). 8 of the 13 active Final-Milestone Playwright specs are mine.
- Cross-layer code review. Formal pull-request reviews on ~35 merged teammate PRs spanning backend, web, mobile, and E2E test infrastructure (see item 4 below). Team policy required at least one reviewer comment on the Files-Changed surface before merge, so every entry there is a Comment-Review that gated a teammate's merge; a "needs changes" review was a hard block.
- Project coordination. Owner of issue #424 (the umbrella issue that organised this entire Final Milestone wiki report — 11 sub-deliverables, set the milestone freeze date, owns the page structure). Drove the lab-cycle planning + organisation, represented the team in the instructor / TA meetings where project scope and acceptance bar were set, performed the deployment + dry-run for the Final Milestone presentation.
-
Social feed — end-to-end ownership of the most-demoed feature in the product (PR #500 soft-delete + edit-history + restore + trending hashtags · PR #499 social-feed API ergonomics · PR #498 image attachments · PR #503 comment likes · PR #501 keyword + hashtag + date-range + language search with viewer keyword-mute · PR #531 enhanced sharing — quote-shares + share events · PR #532 viewer-relative feed flags · PR #533 unit coverage for
-
Significant Issues (Top 3 per category):
Code-Related:
- #135 — Polymorphic reporting + admin moderation lifecycle.
- #437 / #438 — Advanced follow-recommendation ranker (Neo4j PPR) and advanced For-You feed ranker (Thompson-sampling bandit).
- #487 — Social-feed soft-delete + edit-history + restore + trending hashtags.
Non-Code-Related:
- #424 — Final Milestone Deliverables Report: top-level umbrella issue I authored to coordinate the wiki report's 11 sub-deliverables across the team (§3 Executive Summary, §4.1–§4.7, §5 individual contributions, §6 release & setup), set the milestone freeze date, and own the wiki page structure.
- #310 — Lab 9: Requirements Review & Acceptance Testing: drove the lab-cycle deliverable that audited the SRS against the shipped backend and anchored the AT-01..AT-22 acceptance-test catalogue (subsequently realised as the Playwright + backend-integration acceptance suite documented in §4.6 / Acceptance Tests).
-
#490 — Social Feed — Standards coverage (Activity Streams 2.0 + JSON-LD 1.1 + Schema.org): researched and adopted the W3C semantic-web standards for the entire feed surface, picked the vocabulary terms (AS 2.0
Note/Like/Person/OrderedCollectionPage, Schema.orgauthor/dateCreated/text/byDay), and designed theAccept: application/ld+jsoncontent-negotiation model that ships in PR #536. The decision is documented in §4.5 of this report.
-
Pull Requests:
Authored & merged — 70 PRs total across the project lifecycle (#70 on 2026-03-12 → #604 on 2026-05-13). The 28 PRs called out below are the Final-Milestone-window subset (post-MVP, roughly #470 onwards) where the bulk of the new Final-Milestone feature surface landed; the complete 70-PR list (including the ~42 earlier-milestone PRs that built up the foundations these features sit on) is at https://github.com/bounswe/bounswe2026group7/pulls?q=is%3Apr+author%3Amehmetborasarioglu+is%3Amerged. Newest first:
#604 reproducible demo seed (2026-05-13) · #599 Neo4j in prod compose + E2E specs · #580 advanced mentor search filters · #579 profile-visibility masking · #576 admin user list · #574 polymorphic reporting + moderation · #573 AT-02/07 stability · #567 profile-grounded match explanations · #561 admin messaging reads · #559 admin /me · #536 AS 2.0 / Schema.org JSON-LD on feed · #535 / #528 mentee affiliation · #534 rating read endpoints · #533 unit coverage for FeedInteractionService + FeedReadService · #532 viewer-relative feed flags · #531 enhanced sharing · #530 deployment guide · #529 mentorship history filter · #527 isFollowing flag · #503 comment likes · #501 search filters + mute · #500 soft-delete + edit-history + restore + trending · #499 social-feed API ergonomics · #498 image attachments · #497 advanced For-You ranker · #470 Neo4j follow-graph sync + advanced follow ranker.
Formally reviewed (newest first). Team policy required at least one reviewer comment before merge — every comment on the Files-Changed surface counts as a Comment-Review, and a comment describing a required change is a hard block on the merge. Full list traceable via https://github.com/bounswe/bounswe2026group7/pulls?q=is%3Apr+commenter%3Amehmetborasarioglu+-author%3Amehmetborasarioglu+is%3Amerged plus the explicit-Approve / Request-Changes set on https://github.com/bounswe/bounswe2026group7/pulls?q=is%3Apr+reviewed-by%3Amehmetborasarioglu+is%3Amerged.
- Backend: #597 (Dev merge — Beratcan Doğan), #586, #585, #582, #479 (Dev merge — Beratcan Doğan), #475 (advanced mentor ranker), #449 (admin ban + messaging), #443 (cross-feature E2E suite), #441 (dashboard stats), #405 (NoOpEmailService fix), #404 (task + milestone reminders), #383 (follow recommendations), #380 (auto-ban), #378 (milestones + action items), #377 (FCM push notifications), #325 (Beratcan Doğan — STOMP SUBSCRIBE branch coverage + ERROR-frame assertions), #319, #309, #308 (mentor↔mentee messaging REST + STOMP), #302 (rate-limit middleware), #301, #300 (JWT claim hardening), #223, #214 (Beratcan Doğan — Production-ready project rollup), #199 (deployment configuration), #173 (Beratcan Doğan — mentor matching algorithm for mentees).
- Web: #600 (web README + seed), #539, #537, #509 (upcoming-meeting fix).
- Mobile: #526 (blog posts + feed images + STOMP), #496 (Explore pagination fix).
- E2E test infrastructure: #493 (advanced For-You ranker), #397 (AT-06 + AT-07), #394 (AT-02 + AT-04/05 scaffold + admin fixture), #393 (Playwright bootstrap).
-
Conflict Resolution:
-
Flyway migration collision on the
#135polymorphic-reporting branch. Rebased ontodevafter a fast-moving feed merge introduced a same-version Flyway migration. Resolved by renumbering the report migration from V53 → V54 and verifying schema deltas against a fresh Testcontainers Postgres before merging (PR #574, commit8c90802). -
JaCoCo 0.8.12 vs Java 22+ class-file major version 69 (ByteBuddy) on the Neo4j follow-graph sync (issue #437 / PR #470). The coverage gate fought ByteBuddy's modern attribute classes and broke
mvn verifyfor the whole team. Fixed by excludingnet.bytebuddy.*from instrumentation rather than downgrading the agent, so we kept the modern toolchain. -
Production Swagger UI was disabled in the deployed JAR. Avoided a Maven rebuild OOM on the 512 MB droplet by adding a
docker-compose.override.ymlsettingSPRINGDOC_SWAGGER_UI_ENABLED=true, then patched the production nginx config (/etc/nginx/sites-available/mymentornet.org) with location blocks for/swagger-uiand/v3/api-docsproxied tolocalhost:8080. The Final Milestone evaluator can hit https://mymentornet.org/swagger-ui/index.html because of that. -
AT-02 / AT-07 cross-browser flake (PR #573). Framer-motion's LoginPage entrance animation was scheduling Firefox / WebKit clicks past the 40 s navigation budget on GitHub Actions. Fixed by setting
reducedMotion: 'reduce'on every Playwright context inplaywright.config.js(commit91bd792) — production behaviour for users with the OS-level reduced-motion preference is unchanged. Took AT-02 from a chronic flake to a stable green on all three browsers.
-
Flyway migration collision on the
-
AI Transparency & Documentation:
-
Tool summary: Claude (Anthropic) used in a four-step workflow: (1) ask Claude to draft an implementation plan for the issue; (2) review the plan personally and push back on any assumptions or scope drift; (3) have Claude write the code against the agreed plan; (4) review the generated code line-by-line before merging, then perform manual
curl-based smoke testing against the running backend myself to confirm the actual HTTP request / response shapes match what the implementation claimed. Unfortunately, I do not have AI prompt logs preserved.
-
Tool summary: Claude (Anthropic) used in a four-step workflow: (1) ask Claude to draft an implementation plan for the issue; (2) review the plan personally and push back on any assumptions or scope drift; (3) have Claude write the code against the agreed plan; (4) review the generated code line-by-line before merging, then perform manual
-
Individual Testing Efforts:
-
Backend unit + integration tests for every feature shipped above. The Final-Milestone Surefire run lands at 2,442 tests / 0 failures / 0 errors on Testcontainers Postgres + Neo4j (1 async flake auto-recovered by
surefire.rerunFailingTestsCount=2). 240 per-class JUnit XMLs and a rendered HTML report are attached to this wiki atreports/final-milestone/backend/. Linked from §4.6 with download URLs. -
End-to-end Playwright specs — 8 specs authored from scratch: AT-04, AT-05, AT-17, AT-18, AT-19, AT-20, AT-21, AT-22 (specs at
frontend/e2e/specs/), plus the AT-02 / AT-07 cross-browser determinism rewrite (PR #573). Playwright report atreports/final-milestone/web/playwright-html/; latest CI run onmainis 46 passed / 0 failed / 23 deliberatetest.fixme(Run 25793439063). -
JaCoCo coverage gates I authored. Overall backend branch coverage > 95 % with two class-level gates I added on top of the build:
-
advanced-ranker-check— requires ≥ 90 % line / 80 % branch on the entireservice.ranking.*+service.embedding.*+service.explanation.*surface (covers all three advanced rankers). -
check-pr2-branch-coverage— enforces ≥ 65 % branch on the follow-recommendation / cold-start / graph packages (≥ 55 % onservice.ranking.graphbecause defensive driver-failure branches need a 1M+ edge fixture to exercise). Both rules fire onmvn verifyand the build fails if a teammate's PR drops coverage below them. They have caught two coverage regressions before merge during the Final Milestone window.
-
-
Live-deploy smoke testing. For every PR I authored that touched production-shipped code I ran a
curl-based smoke pass against the deployed instance at https://mymentornet.org after merge, checking the actual HTTP response shapes rather than trusting the unit tests in isolation. This is what surfaced the Swagger / nginx gap (see item 5).
-
Backend unit + integration tests for every feature shipped above. The Final-Milestone Surefire run lands at 2,442 tests / 0 failures / 0 errors on Testcontainers Postgres + Neo4j (1 async flake auto-recovered by
-
Additional Information:
What I shipped that defines the Final Milestone, in five lines.
- The entire social-feed surface the customer sees in the demo — posts, comments, likes, comment-likes, reposts, quote-shares, bookmarks, search, soft-delete, edit-history, image attachments, AS 2.0 / JSON-LD content negotiation — is mine end-to-end (PR #498, PR #499, PR #500, PR #501, PR #503, PR #531, PR #532, PR #533, PR #536).
- All three advanced recommendation algorithms — For-You feed bandit, Neo4j follow-graph PPR + multi-signal ranker, mentor matching with LLM-grounded explanations — are mine (PR #470, PR #497, PR #567).
- The reporting + admin moderation stack (PR #574, PR #576, PR #559, PR #561) — every backend call behind the admin panel screenshots is mine.
-
The production environment itself — the Neo4j+GDS compose, the demo-seed snapshot pipeline that runs on every deploy, the deployment guide, the live Swagger UI, the operator
.env.example— is mine (PR #530, PR #599, PR #604). - 8 of the 13 Final-Milestone Playwright specs (PR #573, PR #599). And the wiki report you are reading is structured by issue #424, which I own and authored.
By the numbers: 70 authored-and-merged PRs, ~35 formal reviews, >95 % backend branch coverage, 2,442 backend tests green, 8 Playwright acceptance specs, the entire production stack.
-
Release Tag:
final-milestone - Live Deployment: https://mymentornet.org
- README Instructions: README.md
- Docker Setup: docker-compose.yml
- Mobile APK: app-debug.apk
Team Members
- Lab 1 Report (12/02/2026)
- Lab 2 Report (19/02/2026)
- Lab 3 Report (26/02/2026)
- Lab 4 Report (05/03/2026)
- Lab 5 Report (12/03/2026)
- Lab 6 Report (26/03/2026)
- Lab 7 Report (02/04/2026)
- Lab 8 Report (18/04/2026)
- Lab 9 Report (30/04/2026)
- Lab 10 Report (07/05/2026)
- Weekly Meeting Notes Template
- Lab Meeting 1 (12.02.2026)
- Weekly Meeting 1 (16.02.2026)
- Weekly Meeting 2 (24.02.2026)
- Weekly Meeting 3 (04.03.2026)
- Weekly Meeting 4 (11.03.2026)
- Weekly Meeting 5 (23.03.2026)
- Weekly Meeting 6 (29.03.2026)
- Weekly Meeting 7 (11.04.2026)
- Weekly Meeting 8 (28.04.2026)
- Weekly Meeting 9 (10.05.2026)
- Use Case Diagram 1 (New Mentor User for Mobile Scenario)
- Use Case Diagram 2 (Mentor-Mentee Matching Scenario)
- Use Case Diagram 3 (New Mentee User Scenario)
- Final Use Case Diagram
- MVP Use Case Diagram
- All Sequence Diagrams
- Sequence Diagram: Mentee Matching
- Sequence Diagram: Mentor Matching
- Sequence Diagram: Mentorship Management
- Sequence Diagram: Registration
- Sequence Diagram: Cancelling Mentorship Relationship and Auto Ban
- Sequence Diagram: Login-Logout
- Sequence Diagram: Reporting-User
- Sequence Diagram: Mentor Profile Management
- MVP Sequence Diagrams
- Test Plan & Coverage (MVP)
- Acceptance Testing Strategy
- Acceptance Tests
- Test Data Strategy
- Web Frontend Test Report
- Amin Abu-Hilga
- Övgü Su Afşar
- Muhammet Sami Çakmak
- Beratcan Doğan
- İbrahim Kayan
- Burak Ögüt
- Mehmet Bora Sarıoğlu
- Future Work (reference, not a deliverable)