Job Tracker is a full-stack application for managing job applications, built with a Spring Boot backend and a React + Vite frontend. The goal of the project is to help users keep track of submitted applications, monitor their status, and manage their job search data through a simple and clean interface.
- allows users to register and log in
- allows users to add, edit, and delete job applications
- displays a dashboard with general statistics
- provides a simple and modern user experience for career management
The project is divided into two main parts:
- backend: a Spring Boot application exposing a REST API
- frontend: a React application communicating with the backend through Axios
Watch the application in action:
jobtracker/
├── backend/
│ ├── src/main/java/com/toni/jobtracker
│ │ ├── config/
│ │ ├── controller/
│ │ ├── dto/
│ │ ├── entity/
│ │ ├── exception/
│ │ ├── mapper/
│ │ ├── repository/
│ │ ├── service/
│ │ └── util/
│ ├── src/main/resources/
│ └── src/test/java/
├── frontend/
│ ├── src/
│ │ ├── api/
│ │ ├── components/
│ │ ├── layouts/
│ │ ├── pages/
│ │ ├── services/
│ │ └── styles.css
│ └── cypress/
└── .github/workflows/
- Java 25
- Spring Boot 4.1.0
- Spring Web MVC
- Spring Data JPA
- Validation
- Maven
- PostgreSQL
The backend follows a typical layered structure:
- controller: handles HTTP requests
- service: contains the business logic
- repository: manages database access
- entity: JPA data models
- dto: objects used for data transfer
- mapper: transforms between entities and DTOs
- exception: handles application errors
- AuthController: handles login and registration
- DashboardController: exposes dashboard data
- JobApplicationController: manages job applications
- AuthService: authentication and registration logic
- DashboardService: aggregates data for the dashboard
- JobApplicationService: CRUD operations for applications
- User: represents a user account
- JobApplication: represents a job application entry
- request/: objects received from the client
- response/: objects returned in API responses
- UserMapper: transforms between User entities and DTOs
- JobApplicationMapper: transforms between JobApplication entities and DTOs
A user can have multiple job applications. The relationship is:
- User 1 -> N JobApplication
- Layered Architecture
- DTO pattern to separate the internal model from the API contract
- Mapper pattern for entity/DTO transformations
- Repository pattern through Spring Data JPA
- Centralized exception handling through GlobalExceptionHandler
- React 19
- Vite
- React Router DOM
- Axios
- Custom CSS
- Cypress for end-to-end testing
The frontend is built modularly, with separate pages, reusable components, and services for communicating with the API.
- Login: authentication form
- Register: registration form
- Dashboard: displays summary statistics
- Applications: lists existing applications
- CreateApplication: adds a new application
- EditApplication: edits an existing application
- NotFound: fallback page for invalid routes
- Navbar: main application navigation
- MainLayout: shared app shell with navbar, content area, and footer
- authService: authentication API calls
- applicationService: job application API calls
- axios.js: centralized Axios instance for all backend requests
- Component-based architecture
- Route-based navigation
- Service layer for API calls
- Separation of concerns between pages, layout, and services
- the user opens the registration page
- fills in their name, email, and password
- the frontend sends the data to /auth/register
- the backend creates the user account
- the user is redirected to the login page
- the user opens the login page
- submits their email and password
- the backend validates the credentials
- on success, the user is redirected to the dashboard
- the user views the list of applications
- can add, edit, or delete an application
- the data is synchronized with the backend through REST endpoints
Backend tests are located in:
- src/test/java/com/toni/jobtracker/service
- src/test/java/com/toni/jobtracker/mapper
End-to-end tests are located in:
- cypress/e2e/app-flow.cy.js
The project includes a GitHub Actions workflow in .github/workflows/ci.yml that:
- runs backend tests
- builds the backend application
- installs frontend dependencies
- builds the frontend application
- Java 25
- Maven
- Node.js 22+
- PostgreSQL
cd backend
./mvnw spring-boot:runcd frontend
npm install
npm run devcd backend
./mvnw testcd frontend
npx cypress runThe project includes Docker support for the frontend, backend, and PostgreSQL database.
- Docker
- Docker Compose
From the project root directory, run:
docker compose up --buildThis command will:
- build the backend image
- build the frontend image
- start a PostgreSQL container
- create the required Docker network
- start all services
Once the containers are running, the application will be available at:
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:8080 |
| PostgreSQL | localhost:5432 |
To stop all running containers:
docker compose downTo stop the containers and remove the database volume:
docker compose down -v +------------------+
| Frontend |
| React + Vite |
+--------+---------+
|
HTTP REST
|
▼
+------------------+
| Backend |
| Spring Boot |
+--------+---------+
|
Spring Data JPA
|
▼
+------------------+
| PostgreSQL |
+------------------+
Application configuration is stored in:
- backend/src/main/resources/application.properties
- frontend/src/api/axios.js
A local PostgreSQL server is recommended, and the backend database URL should be updated accordingly.
- the application is built to be easy to understand and extend
- it clearly separates business logic from presentation logic
- it uses a simple but modular frontend structure
- it is ready for future enhancements such as stronger authentication, pagination, or filtering
Job Tracker is a full-stack example project with a clear architecture, separation between frontend and backend, automated testing, and CI workflow support. It is suitable for learning, demos, and future extensions.