Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
plugins {
java
application
id("org.springframework.boot") version "4.0.2"
id("io.spring.dependency-management") version "1.1.7"
}

// Use build directory outside OneDrive to avoid file locking issues
layout.buildDirectory = file("C:/Temp/gradle-build/java-bootcamp")

group = "com.wcc.bootcamp.java"
version = "0.0.1-SNAPSHOT"
description = "Java Bootcamp "

application {
mainClass.set("com.wcc.bootcamp.java.mentorship.MentorshipWebApplication")
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
languageVersion = JavaLanguageVersion.of(23)
}
sourceSets {
main {
java {
srcDirs("src/main/java", "participants/victoria/project/src/main/java")
}
resources {
srcDirs("src/main/resources", "participants/victoria/project/src/main/resources")
}
}
test {
java {
srcDirs("src/test/java", "participants/victoria/project/src/test/java")
}
resources {
srcDirs("src/test/resources", "participants/victoria/project/src/test/resources")
}
}
}
}

Expand All @@ -20,10 +46,21 @@ repositories {

dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-mail")
runtimeOnly("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

tasks.withType<Test> {
useJUnitPlatform()
}

tasks.withType<Copy> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
4 changes: 4 additions & 0 deletions data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore H2 database files - they're binary and locked while app runs
*.db
*.mv.db
*.trace.db
9 changes: 9 additions & 0 deletions demo_matches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Mentorship Matches Export
# Format: ID|MentorID|MentorName|MenteeID|MenteeName|Score|Skills|Status
# Generated: 2026-02-12T09:57:52.794171700

20debd80-561c-48b5-930c-e2e2789ee22c|39c08197-46da-486b-9e32-9d6672350f79|Alice Johnson|adc4df88-00d2-437d-9803-afe6464429e7|Frank Lee|1.00|java,spring|ACTIVE
6e6397b4-00e3-4c28-8de6-384ebd08b28a|5da8777d-50ad-4310-ab3c-0ea39e0905a7|Bob Smith|2b7ed551-81fb-4211-ad73-48f9db1895f3|Grace Chen|1.00|machine learning,python,data analysis|ACTIVE
ffd0ed61-c0b6-4809-b54f-8def82637b1e|48c73e56-5ec6-442e-b0fe-fc52e2d59e3b|Carol Williams|f91b4463-30fc-4555-9f1e-97bad00a0b38|Henry Wilson|0.67|react,javascript|ACTIVE
7c8c24d8-580f-4d61-81b5-93442df7fe12|39c08197-46da-486b-9e32-9d6672350f79|Alice Johnson|877835a9-ae4c-4a47-b4a3-314e26b49a01|Karen Davis|0.67|sql,java|CANCELLED
0fd92fa0-0619-4ded-af6f-ccc62eb0cc9b|adc6819c-3e20-4bdb-a861-2a26b42a1ec9|David Brown|877835a9-ae4c-4a47-b4a3-314e26b49a01|Karen Davis|0.33|java|ACTIVE
43 changes: 43 additions & 0 deletions demo_report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
╔══════════════════════════════════════════════════════════════╗
║ MENTORSHIP MATCHER - DETAILED REPORT ║
╚══════════════════════════════════════════════════════════════╝

Generated: 2026-02-12T09:57:52.799727300

── SUMMARY ─────────────────────────────────────────────────────
Total Mentors: 5
Total Mentees: 6
Total Matches: 5
Active Matches: 4

── MENTORS ─────────────────────────────────────────────────────
• Mentor{name='Alice Johnson', email='alice@example.com', expertise=[java, spring boot, microservices, sql], mentees=1/3}
• Mentor{name='Bob Smith', email='bob@example.com', expertise=[python, machine learning, data science, tensorflow], mentees=1/3}
• Mentor{name='Carol Williams', email='carol@example.com', expertise=[javascript, react, node.js, typescript, css], mentees=1/3}
• Mentor{name='David Brown', email='david@example.com', expertise=[java, kotlin, android, mobile development], mentees=1/3}
• Mentor{name='Eva Martinez', email='eva@example.com', expertise=[devops, docker, kubernetes, aws, ci/cd], mentees=0/3}

── MENTEES ─────────────────────────────────────────────────────
• Mentee{name='Frank Lee', email='frank@example.com', goals=[java, spring], level='beginner', matched=true}
• Mentee{name='Grace Chen', email='grace@example.com', goals=[machine learning, python, data analysis], level='intermediate', matched=true}
• Mentee{name='Henry Wilson', email='henry@example.com', goals=[react, javascript, frontend development], level='beginner', matched=true}
• Mentee{name='Ivy Taylor', email='ivy@example.com', goals=[android, mobile apps, kotlin], level='intermediate', matched=false}
• Mentee{name='Jack Anderson', email='jack@example.com', goals=[docker, cloud computing, aws], level='advanced', matched=false}
• Mentee{name='Karen Davis', email='karen@example.com', goals=[sql, database design, java], level='beginner', matched=true}

── MATCHES ─────────────────────────────────────────────────────
• Match{mentor='Alice Johnson', mentee='Frank Lee', skills=[java, spring], score=100.00%, status=ACTIVE}
Date: 2026-02-12T09:57:52.771063

• Match{mentor='Bob Smith', mentee='Grace Chen', skills=[machine learning, python, data analysis], score=100.00%, status=ACTIVE}
Date: 2026-02-12T09:57:52.781737700

• Match{mentor='Carol Williams', mentee='Henry Wilson', skills=[react, javascript], score=66.67%, status=ACTIVE}
Date: 2026-02-12T09:57:52.782841500

• Match{mentor='Alice Johnson', mentee='Karen Davis', skills=[sql, java], score=66.67%, status=CANCELLED}
Date: 2026-02-12T09:57:52.785653600

• Match{mentor='David Brown', mentee='Karen Davis', skills=[java], score=33.33%, status=ACTIVE}
Date: 2026-02-12T09:57:52.789334800

1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
buildDir=C:/Temp/gradle-build
192 changes: 192 additions & 0 deletions participants/victoria/project/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Mentorship Matcher

A Spring Boot web application that matches mentors with mentees based on skills and learning goals. Built as part of the WCC Java Bootcamp.

## Features

- **Mentor Registration**: Register mentors with their expertise areas and maximum mentee capacity
- **Mentee Registration**: Register mentees with their learning goals and experience level
- **Smart Matching**: Algorithm matches mentees to mentors based on skill compatibility
- **Match Management**: View, activate, and manage mentor-mentee relationships
- **Data Persistence**: H2 file-based database ensures data survives server restarts
- **Email Notifications**: Automatic email alerts to mentor and mentee when a match is created

## Email Notifications (MailHog)

The application sends email notifications when a match is created. For local development, use **MailHog** - a local SMTP server that captures emails for viewing.

### Setting Up MailHog

**Windows (download executable):**
```powershell
# Download MailHog
Invoke-WebRequest -Uri "https://github.com/mailhog/MailHog/releases/download/v1.0.1/MailHog_windows_amd64.exe" -OutFile "MailHog.exe"

# Run MailHog
.\MailHog.exe
```

**Mac (Homebrew):**
```bash
brew install mailhog
mailhog
```

**Docker:**
```bash
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
```

### Accessing MailHog

| Service | URL |
|---------|-----|
| SMTP Server | `localhost:1025` |
| Web UI | http://localhost:8025 |

When a match is created, both the mentor and mentee receive emails. View captured emails at [http://localhost:8025](http://localhost:8025).

### Disabling Email

To disable email notifications, set in `application.properties`:
```properties
spring.mail.enabled=false
```

## Tech Stack

- **Java 23** - Language
- **Spring Boot 4.0.2** - Web framework
- **Spring Data JPA** - Database access
- **H2 Database** - Embedded file-based persistence
- **Thymeleaf** - Server-side templating
- **Bootstrap 5.3.2** - UI styling
- **Gradle** - Build tool

## Prerequisites

- Java 23 (Eclipse Adoptium recommended)
- Gradle 9.x (or use the included Gradle wrapper)

## Running the Application

### From the project root directory:

```powershell
# Set JAVA_HOME (Windows PowerShell)
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-23.0.2.7-hotspot"

# Run the application
.\gradlew.bat bootRun
```

### From terminal (Unix/Mac):

```bash
export JAVA_HOME=/path/to/jdk-23
./gradlew bootRun
```

The application will start at **http://localhost:8080**

## Running Tests

```powershell
# Set JAVA_HOME (Windows PowerShell)
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-23.0.2.7-hotspot"

# Run all tests
.\gradlew.bat test --no-daemon
```

Test results are generated at `C:\Temp\gradle-build\java-bootcamp\reports\tests\test\index.html`

### Test Coverage

| Test Class | Tests | Description |
|------------|-------|-------------|
| `MentorTest` | 16 | Model tests: constructor, equality, expertise matching, mentee capacity |
| `MenteeTest` | 15 | Model tests: constructor, equality, learning goals, match status |
| `MatchTest` | 17 | Model tests: constructor, equality, lifecycle (activate/cancel/complete), file format |
| `MentorshipServiceTest` | 18 | Service tests: mentor/mentee/match CRUD operations, statistics |
| `DtoValidationTest` | 22 | Validation tests: registration form input validation |
| **Total** | **88** | |

### Test Structure

```
participants/victoria/project/src/test/java/com/wcc/bootcamp/java/mentorship/
├── model/
│ ├── MentorTest.java # Mentor entity tests
│ ├── MenteeTest.java # Mentee entity tests
│ └── MatchTest.java # Match entity tests
├── service/
│ └── MentorshipServiceTest.java # Business logic tests (with Mockito)
└── dto/
└── DtoValidationTest.java # Form validation tests
```

> **Note**: Controller tests are not included because `@WebMvcTest` and `@AutoConfigureMockMvc` are not available in Spring Boot 4.0.2's `spring-boot-starter-test`.

## Application Pages

| URL | Description |
|-----|-------------|
| `/` | Home page with navigation |
| `/mentors` | List all registered mentors |
| `/mentors/register` | Register a new mentor |
| `/mentors/{id}` | View mentor profile |
| `/mentees` | List all registered mentees |
| `/mentees/register` | Register a new mentee |
| `/mentees/{id}` | View mentee profile |
| `/matches` | View active matches |
| `/matches/find` | Find potential matches |

## Database

The application uses H2 database with file-based persistence:

- **Location**: `./data/mentorship-db.mv.db`
- **Console**: http://localhost:8080/h2-console
- **JDBC URL**: `jdbc:h2:file:./data/mentorship-db`
- **Username**: `sa`
- **Password**: *(empty)*

Data persists between server restarts. To reset the database, delete the `data/` folder.

## Project Structure

```
participants/victoria/project/src/main/java/com/wcc/bootcamp/java/mentorship/
├── MentorshipWebApplication.java # Main Spring Boot application
├── controller/
│ ├── HomeController.java # Home page
│ ├── MentorController.java # Mentor CRUD operations
│ ├── MenteeController.java # Mentee CRUD operations
│ └── MatchController.java # Matching operations
├── model/
│ ├── Mentor.java # Mentor entity
│ ├── Mentee.java # Mentee entity
│ └── Match.java # Match entity
├── repository/
│ ├── MentorRepository.java # Mentor data access
│ ├── MenteeRepository.java # Mentee data access
│ └── MatchRepository.java # Match data access
├── service/
│ └── MentorshipService.java # Business logic
└── dto/
├── MentorRegistrationForm.java # Form binding for mentors
└── MenteeRegistrationForm.java # Form binding for mentees
```

## How Matching Works

1. The algorithm compares each mentee's learning goals against each mentor's expertise areas
2. Skills are matched using case-insensitive partial matching (e.g., "java" matches "Java programming")
3. A compatibility score (0-100%) is calculated based on the percentage of mentee goals that match mentor expertise
4. Matches are ranked by compatibility score
5. Only mentors with available capacity are shown as potential matches

## Author

Victoria - WCC Java Bootcamp Participant
Loading