A web application for running peer feedback cycles. Managers and employees create feedback requests, invite reviewers via email, and view aggregated results. Reviewers receive a unique email link and fill out a feedback form — no login required.
- Managers create feedback requests for any employee, manage invitations (resend, cancel), and view aggregated feedback results.
- Employees initiate feedback requests about themselves and track their cycles.
- Reviewers receive an email with a one-time link, rate 5 competencies (1–5 stars), add optional comments, and submit — no account needed.
Phase 1 uses a user-selector dropdown (no real authentication). The selected user's ID is sent as an X-User-Id header; the backend enforces role-based access.
| Language | Java 21 |
| Framework | Spring Boot 3.4.3 |
| ORM | Spring Data JPA + Hibernate |
| Database (dev) | H2 in-memory |
| Database (prod) | PostgreSQL 16 |
| Migrations | Flyway |
| Spring Mail + JavaMailSender | |
| Email (dev) | MailHog |
| Validation | Jakarta Bean Validation |
| API Docs | Springdoc OpenAPI (Swagger UI at /swagger-ui) |
| Testing | JUnit 5, Mockito, Spring Boot Test |
| Framework | React 19 + TypeScript |
| Build | Vite |
| Routing | React Router v7 |
| HTTP | Axios |
| UI | Tailwind CSS v4 |
| State / Data | TanStack Query v5 |
| Testing | Vitest + React Testing Library |
| Build system | Maven |
| Frontend bundling | frontend-maven-plugin (Node v24.0.0) |
| Local infra | Docker Compose (PostgreSQL + MailHog) |
| Output | Single fat JAR |
people/
├── src/
│ ├── main/
│ │ ├── java/com/example/feedback/
│ │ │ ├── controller/ REST controllers
│ │ │ ├── service/ Business logic + role enforcement
│ │ │ ├── repository/ Spring Data JPA repositories
│ │ │ ├── model/ JPA entities + enums
│ │ │ ├── dto/ Request/response DTOs
│ │ │ ├── exception/ Custom exception classes
│ │ │ └── config/ Spring config (CORS, exception handler)
│ │ └── resources/
│ │ ├── application.yml
│ │ ├── application-dev.yml H2 + MailHog
│ │ ├── application-prod.yml PostgreSQL + SMTP
│ │ └── db/migration/ Flyway SQL scripts
│ └── test/
│ └── java/com/example/feedback/
├── frontend/ React project (Vite)
│ └── src/
│ ├── pages/ Screen components
│ ├── components/ Shared UI components (StarRating, Layout, etc.)
│ ├── api/ Axios API functions
│ ├── hooks/ TanStack Query hooks
│ └── types/ TypeScript interfaces
├── docker-compose.yml PostgreSQL + MailHog
└── pom.xml Maven + frontend-maven-plugin
- Java 21 (Temurin)
- Maven 3.9+
- Docker + Docker Compose (for local PostgreSQL and MailHog)
- Node.js 24+ (only needed if running the frontend dev server separately)
docker-compose up -dThis starts:
- PostgreSQL on
localhost:5432(db:feedbackdb, user:feedback, password:secret) - MailHog SMTP on
localhost:1025, web UI athttp://localhost:8025
mvn package -DskipTests
java -jar target/feedback-0.0.1-SNAPSHOT.jar --spring.profiles.active=devThe app starts on http://localhost:8080.
The
devprofile uses H2 in-memory (not the Docker PostgreSQL). To use PostgreSQL locally, set theprodprofile and provide env vars (see Production).
| URL | Description |
|---|---|
| http://localhost:8080 | React SPA |
| http://localhost:8080/swagger-ui | API documentation |
| http://localhost:8080/h2-console | H2 database console (dev only) |
| http://localhost:8025 | MailHog — view sent emails |
For hot-reloading during frontend development:
# Terminal 1: run the backend
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# Terminal 2: run the Vite dev server
cd frontend
npm install
npm run devThe Vite dev server runs on http://localhost:5173 and proxies /api requests to the backend on port 8080.
mvn packageThis will:
- Download Node.js and npm (first run only)
- Run
npm installinfrontend/ - Run
npm run build— outputs React assets tosrc/main/resources/static/ - Compile Java and run tests
- Package a single fat JAR at
target/feedback-0.0.1-SNAPSHOT.jar
mvn package -DskipTestsmvn package -DskipTests -Dfrontend.skip=trueNote: if
src/main/resources/static/is empty (no prior frontend build), the app will still start but the SPA won't load.
mvn testmvn test -Dtest=FeedbackRequestServiceTestcd frontend
npx vitest runcd frontend
npx vitestExpected output: 24 Java tests, 3 frontend tests — all passing.
Swagger UI is available at http://localhost:8080/swagger-ui when the app is running.
| Method | Path | Description |
|---|---|---|
GET |
/api/users |
List all users |
POST |
/api/requests |
Create feedback request |
GET |
/api/requests |
List requests (filtered by role) |
GET |
/api/requests/{id} |
Get request with invitations |
PATCH |
/api/requests/{id}/cancel |
Cancel request |
GET |
/api/requests/{id}/results |
Aggregated results (MANAGER only) |
POST |
/api/invitations/{id}/resend |
Resend invitation email |
PATCH |
/api/invitations/{id}/cancel |
Cancel invitation |
GET |
/api/feedback/{token} |
Load public feedback form |
POST |
/api/feedback/{token} |
Submit feedback |
GET |
/api/feedback/{token}/decline |
Decline invitation (redirects) |
All authenticated endpoints require the X-User-Id: <uuid> header.
The dev database is seeded with:
Users:
| ID | Name | Role |
|---|---|---|
11111111-1111-1111-1111-111111111111 |
Jane Smith | MANAGER |
22222222-2222-2222-2222-222222222222 |
Bob Jones | EMPLOYEE |
33333333-3333-3333-3333-333333333333 |
Alice Chen | EMPLOYEE |
Competencies: Communication, Collaboration, Technical Skills, Ownership, Reliability
Set the following environment variables and run with the prod profile:
export SPRING_DATASOURCE_URL=jdbc:postgresql://host:5432/feedbackdb
export SPRING_DATASOURCE_USERNAME=feedback
export SPRING_DATASOURCE_PASSWORD=secret
export MAIL_HOST=smtp.sendgrid.net
export MAIL_PORT=587
export MAIL_USERNAME=apikey
export MAIL_PASSWORD=your-api-key
export APP_BASE_URL=https://your-domain.com
java -jar target/feedback-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod