The Expense Reimbursement System is a Java Full Stack application that allows employees to submit reimbursement requests and managers to review and resolve them. Built with Spring Boot and React + TypeScript, it features secure session-based authentication, role-based access control, and a responsive Material UI interface.
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, Material UI 6 |
| Backend | Spring Boot 3.4, Java 17 |
| Database | PostgreSQL |
| Testing | JUnit 5, jqwik (property-based), Vitest, fast-check |
| Auth | Session-based with BCrypt password hashing |
- Register and log in with hashed credentials
- Submit reimbursement requests with validated description and amount
- View all or pending reimbursements
- Edit the description of pending reimbursements
- Everything an employee can do, plus:
- View and resolve (approve/deny) all reimbursements
- View, delete, and update roles for all users
- Delete confirmation dialog prevents accidental removals
- BCrypt password hashing — plaintext passwords never stored or logged
- Passwords excluded from all API responses via
@JsonProperty(WRITE_ONLY) - Structured JSON error responses with proper HTTP status codes (401 vs 403)
- Bean Validation on all request bodies
BigDecimalfor monetary amounts (no floating-point rounding)@Transactionalon multi-step database operations- SLF4J logging throughout (no
System.out.println) - Centralized CORS configuration, DTO mapping, and session utilities
- Axios 401 interceptor for automatic session-expiry handling
- Role-based route protection on the frontend
- Client-side form validation with accessibility (
aria-describedby, semantic HTML) - Responsive layout with MUI breakpoints and hamburger nav on mobile
P1Backend/ Spring Boot backend
├── src/main/java/com/revature/
│ ├── config/ CorsConfiguration
│ ├── controllers/ Auth, User, Reimbursement controllers
│ ├── aspects/ AOP auth checks (@AdminOnly)
│ ├── exceptions/ Global exception handler, ErrorResponse, custom exceptions
│ ├── models/ JPA entities, DTOs, DTOMapper
│ ├── repository/ Spring Data JPA repositories
│ ├── services/ Business logic with BCrypt and @Transactional
│ └── util/ SessionUtil
└── src/test/java/ Property-based tests (jqwik)
p1frontend/ React + TypeScript frontend
├── src/
│ ├── Components/ Navbar, Auth, Reimbursements, Users, DashboardLayout
│ ├── contexts/ AuthContext (userId, username, role, logout)
│ ├── hooks/ useApiQuery (loading, error, refetch)
│ ├── pages/ Employee and Manager dashboards
│ ├── services/ Axios API service with 401 interceptor
│ ├── types/ TypeScript interfaces
│ └── __tests__/ Property-based tests (fast-check + Vitest)
└── .env.example Environment variable template
- Java 17+
- Node.js 18+
- PostgreSQL running on
localhost:5432 - A database named
postgreswith a schema namedproject1
cd P1Backend
./mvnw spring-boot:runThe API starts on http://localhost:4444. Configure the database connection in src/main/resources/application.properties.
cd p1frontend
npm install
npm run devThe dev server starts on http://localhost:5173. To point at a different backend, create a .env file:
VITE_API_BASE_URL=http://localhost:4444
Backend (excludes the context-load test that requires a live DB):
cd P1Backend
./mvnw test -Dtest='!P1BackendApplicationTests'Frontend:
cd p1frontend
npm test| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /auth/login |
No | Log in, creates session |
| POST | /auth/logout |
Yes | Invalidate session |
| POST | /users/register |
No | Register new user |
| GET | /users |
Manager | List all users (DTOs) |
| DELETE | /users/delete/{id} |
Yes | Delete a user |
| PATCH | /users/update-role |
Manager | Change user role |
| POST | /reimbursements/create |
Yes | Submit reimbursement |
| GET | /reimbursements/my-reimbursements |
Yes | Current user's reimbursements |
| GET | /reimbursements/my-pending |
Yes | Current user's pending |
| GET | /reimbursements |
Manager | All reimbursements |
| GET | /reimbursements/pending |
Manager | All pending |
| PATCH | /reimbursements/resolve/{id} |
Manager | Approve or deny |
| PATCH | /reimbursements/update/{id} |
Yes | Update description |
Adam Abdulkadir