-
Notifications
You must be signed in to change notification settings - Fork 0
Sequence Diagrams (Final)
Mentee browses ranked mentors via MatchingController.getTopMentors, sends a request via MentorshipRequestController.createRequest, the mentor accepts via MentorshipService.acceptRequest (which cancels every other pending request from this mentee), either party sets the shared goal, and the mentor creates the first milestone. MentorshipPreconditions.requireSharedGoal throws GoalRequiredException (HTTP 409 GOAL_REQUIRED) when a milestone is created before the shared goal is set.

Cancellation flips the request to CANCELLED and records the violation via BanService.recordCancellation. Once the threshold is crossed, the next POST /api/mentorship-requests is short-circuited with the structured 403 BANNED_UNTIL envelope. The admin lifts the ban via BanAdminController.liftBan.

FeedPostController.create is rate-limited (USER-keyed bucket feed-post-create, 30/h), normalises hashtags via HashtagNormalizer, links pre-uploaded attachments, persists the post, and emits a FeedPostCreatedEvent. The FeedFanoutListener (@Async, @TransactionalEventListener(AFTER_COMMIT)) fans out STOMP frames to every follower of the author on /topic/feed.{followerId}.

FeedReadService.forYouFeed loads a rolling candidate window (default 200 posts) and hands it to the FeedRanker (either the baseline InterestOverlapFeedRanker or the advanced ForYouScoringPipeline behind FEED_ADVANCED_RANKER). On every engagement (POST /api/feed/posts/{id}/like), the FeedEngagementBanditListener fires AFTER_COMMIT in a REQUIRES_NEW transaction on a second Hikari connection — the reason the prod pool was bumped from 10 → 20 in application-prod.properties.

FeedReadController.search requires at least one of q / hashtag / since / until / lang. The keyword path uses pg_trgm-accelerated LIKE on the post body with % and _ escaped at the service boundary so they cannot act as wildcards. Hashtag matching normalises via HashtagNormalizer. Viewer keyword-mutes are applied after the SQL fetch, so the visible page may surface fewer than size items.

Optional attachment upload via AttachmentController.upload (with per-user-hourly quota), then MentorPairMessageController.send (rate-limited 60/min), then MessageBroadcastListener (@Async, AFTER_COMMIT) STOMP-broadcasts on /topic/mentor-pair.{convId} and publishes a NEW_MESSAGE notification. The recipient marks-read via PATCH …/messages/read.

MentorshipAutoCompletionScheduler (cron-driven via @Scheduled) sweeps Mentorship rows where endDate < now AND status=ACTIVE. Each row's status flip runs in its own REQUIRES_NEW transaction so a single per-row failure doesn't abort the sweep. Both mentor and mentee receive a MENTORSHIP_AUTO_COMPLETED notification.

ReportController.createReport validates the target type (POST / USER / MENTORSHIP), enforces the target's existence + visibility, rejects self-reports, prevents duplicates via a Postgres partial-unique-index translation in ReportService, and emits a ReportSubmittedEvent. The ReportFanoutListener (@Async, AFTER_COMMIT) fans out REPORT_RECEIVED notifications to every admin. Admin transitions the report via AdminReportController.transition gated by ReportStatusMachine.assertValid. Optional follow-up: admin bans the reported user via AdminController.banUser.

MeetingController.createMeetings stores meetings as PENDING_CONFIRMATION with a confirmationDeadline; the mentee confirms via POST /confirm or declines via POST /decline. Either party can open a reschedule request which the counterpart approves or rejects through MeetingService.approveReschedule (which may auto-flip a still-pending meeting straight to CONFIRMED). MeetingScheduler.run() (cron 0 */5 * * * *) sweeps in per-row REQUIRES_NEW transactions: it fires 24h / 1h reminders for CONFIRMED meetings inside the configured window and auto-expires PENDING_CONFIRMATION rows whose deadline has passed, publishing a MEETING_AUTO_DECLINED notification.

MentorshipService.endMentorship (mentor only, mentorship must be ACTIVE) flips status to COMPLETED, writes a MentorshipAuditLog row for the ACTIVE → COMPLETED transition, and publishes MENTORSHIP_ENDED. The mentee can then POST /api/mentorships/{id}/rating once; MentorRatingService.createRating enforces the gate (mentorship in COMPLETED or CANCELLED) and idempotency (existsByMentorshipId check plus a UNIQUE(mentorship_id) backstop translated to 409 ALREADY_RATED). Aggregate stars and rating count are computed on profile read via MentorRatingRepository.aggregateForMentor — they are not stored on the user row.

TaskService.createTask gates on MentorshipPreconditions.requireSharedGoal (409 GOAL_REQUIRED if the shared goal has not been set yet) and saves the task as PENDING. The mentee submits via POST /api/tasks/{id}/submission (appends a TaskSubmission row and flips the task to SUBMITTED); the mentor reviews via PATCH /api/tasks/{id}/feedback which sets feedback / reviewedAt / reviewedBy on the latest submission and transitions the task to either COMPLETED or REVISION_REQUESTED. A REVISION_REQUESTED task can be re-submitted — submissions are append-only and surfaced in submittedAt DESC order. ReminderNotificationScheduler.processTaskReminders (cron 0 0/30 * * * *) emits 24h-before-due reminders for tasks in PENDING or REVISION_REQUESTED.

FollowService.follow uses a native INSERT … ON CONFLICT DO NOTHING (FollowRepository.upsertFollow) so re-follow returns 200 idempotently while a fresh edge returns 201 and publishes a FollowChangedEvent. FollowGraphSyncListener (@TransactionalEventListener(AFTER_COMMIT)) retries FollowGraphWriter.apply up to 3 times — failures land in the FailedGraphSync outbox swept nightly by FollowGraphResyncJob. In parallel, NotificationEventListener (@Async, AFTER_COMMIT, REQUIRES_NEW) persists the in-app NEW_FOLLOWER row and dispatches FCM push via FcmPushDeliveryService, pruning rejected tokens through UserDeviceRepository.deleteByToken. The prod Hikari pool was bumped 10 → 20 to keep this second Neo4j transaction from starving the request-path connection.

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)