Back to selected work
3Full Stack

Job Portal

A full-stack hiring platform where employers post jobs and move applicants through interview stages, built on a stateless JWT-secured Spring Boot API, MongoDB, and a React + Redux client.

Stack
  • React
  • Redux Toolkit
  • Mantine
  • Spring Boot
  • Spring Security
  • JWT
  • MongoDB
  1. React client — Redux state and role-based routes
  2. Axios interceptor — Adds Bearer JWT; 401 returns to login
  3. JWT filter — Stateless Spring Security
  4. REST API — Auth, users, profiles, jobs, notifications
  5. User service — Registration and BCrypt passwords
  6. Users and profiles — MongoDB collections
  7. Job service — Post, apply, and change application status
  8. Jobs and applicants — Applicants embedded in each job
  9. Notification service — Unread and read in-app notifications
  10. Notifications — MongoDB collection
A React client sends Bearer-token requests through a stateless JWT filter to Spring Boot services; applications move through status changes stored with each job in MongoDB, and key events create in-app notifications.
I

Overview

Applicants find and apply to jobs; employers post jobs, review applicants, and move each application through interview stages.

II

Architecture

A React client with Redux Toolkit state calls a Spring Boot REST API through an Axios instance that attaches the Bearer token and returns the user to login on a 401.

Spring Security runs a stateless JWT filter before every protected endpoint; user, job, profile, and notification services persist to MongoDB.

III

Decisions

Store applicants inside each job document, and query a user’s history with a MongoDB $elemMatch on applicant and status.

Generate readable sequential IDs with an atomic findAndModify $inc counter per collection.

Hash passwords with BCrypt and keep sessions stateless, with the JWT carried on each request.

IV

Implementation

Applying sets the status to applied and rejects a second application to the same job.

Moving an applicant to interviewing records the interview time and creates an in-app notification; posting a job notifies the employer.

Notifications are stored as unread and marked read from the header menu.

Routes are guarded by account type in the React client, and validation and domain errors are returned through a global exception handler.