ApplyDrive is a high-performance, enterprise-grade job aggregator and off-campus recruitment platform designed to curate, organize, and streamline off-campus hiring opportunities. The application is built using a highly secure decoupled architecture featuring React SPA client portals and a robust Spring Boot REST API backend.
- Key Features
- Architecture Overview
- Technology Stack
- Project Directory Map
- Local Development Setup
- Environment Configurations
- Dockerization Guide
- Production Deployment Topologies
- API Endpoint Specifications
- Secure Sessions & Authentication: JWT authentication utilizing secure, stateless HTTP-Only cookies (
accessTokenandrefreshToken) for robust mitigation of Cross-Site Scripting (XSS) and Session hijacking risks. - Double Portal Architecture: Decoupled interface supporting both a Student Public Portal (for searching jobs, uploading resumes, tracking applications) and a comprehensive Admin Console.
- Dynamic Job Ingestion: Custom scraper and importer service to ingest off-campus job drives dynamically from external feeds and listings.
- Admin Command & Analytics: Admin dashboard for toggling user active status, registering partner companies, and monitoring candidate metrics.
- Cloud Image/Resume Hosting: High-speed resume uploads and company logo mapping integrated directly with Cloudinary APIs.
- Real-time Synchronization: Robust caching and synchronization services for efficient data fetching and minimal database load.
The following diagram illustrates the network flow, security boundary, and service communication of the ApplyDrive platform:
graph TD
subgraph ClientTier [Client Tier]
PublicClient["Student Portal - React SPA"]
AdminClient["Admin Portal - React SPA"]
end
subgraph RouterTier [Nginx Router]
Router{"Nginx Proxy / Docker"}
PublicClient -->|"Path: /portal"| Router
AdminClient -->|"Path: /admin"| Router
end
subgraph BackendTier [Spring Boot Backend]
API["Spring Boot REST Controllers"]
SecurityChain["Spring Security & JWT Filters"]
Services["Job, Company, User & Sync Services"]
Router -->|"API Proxy: /api/v1/**"| API
API <--> SecurityChain
API <--> Services
end
subgraph InfrastructureTier [External Services]
DB[("MySQL Relational DB")]
Cloudinary["Cloudinary CDN Store"]
SMTP["Brevo SMTP Server"]
Scraper["External Off-Campus Feeds"]
Services <-->|"Spring Data JPA / Hikari"| DB
Services --->|"Upload API / SDK"| Cloudinary
Services -.->|"Transaction Mails"| SMTP
Services --->|"Ingestion Job"| Scraper
end
style Router fill:#646CFF,stroke:#fff,stroke-width:2px,color:#fff
style ClientTier fill:#1b1b1f,stroke:#333,stroke-width:1px,color:#fff
style BackendTier fill:#222,stroke:#6DB33F,stroke-width:2px,color:#fff
style InfrastructureTier fill:#1b1b1f,stroke:#333,stroke-width:1px,color:#fff
This repository is optimized for API development. Git tracking is strictly restricted to protect sensitive workspace configurations and isolate frontend UI code:
├── frontend/ # React Frontend Applications
│ ├── public-portal/ # Student portal files
│ │ └── src/services/ # HTTP client API Integrations (staged)
│ ├── admin-portal/ # Admin portal files
│ │ └── src/services/ # Admin client API Integrations (staged)
│ ├── package.json # Frontend dependency manifest
│ ├── tailwind.config.js # Styles design token configuration
│ └── Dockerfile # Multi-stage production Nginx serve file
│
└── spring-backend/ # Spring Boot Backend REST Service
├── src/main/java/com/jobportal/
│ ├── config/ # CORS configuration, database seeder config
│ ├── controller/ # REST Controllers (Auth, Jobs, Company)
│ ├── dto/ # Request & Response Data Transfer Objects
│ ├── entity/ # Hibernate Entity Definitions
│ ├── mapper/ # ModelMapper conversions
│ ├── repository/ # Spring Data JPA Repository interfaces
│ ├── security/ # Spring Security, JWT validation and cookie parsers
│ └── service/ # Service interfaces & implementations
├── src/main/resources/
│ ├── application.yml # Main environment configurations
│ └── application.yml.example # Template environment config placeholders
├── Dockerfile # Multi-stage containerization build file
└── pom.xml # Maven build dependencies config
- Java: JDK 17 installed
- NodeJS: Version 18 or higher (along with npm)
- Database: MySQL Server instance running locally
- Create a MySQL database instance named
job_aggregator_db:CREATE DATABASE job_aggregator_db;
- Navigate to
spring-backend/src/main/resources. - Copy
application.yml.exampletoapplication.yml:cp application.yml.example application.yml
- Fill in your credentials inside
application.yml(database user/pass, Cloudinary credentials, and Brevo SMTP details). - Start the Spring Boot application using Maven:
cd spring-backend mvn clean compile mvn spring-boot:run
The backend server starts by default on port 8080 with context path /.
- Navigate to the
frontendfolder:cd frontend - Install npm dependencies:
npm install
- Run the Student Public Portal (accessible at
http://localhost:5173):npm run dev:portal
- Run the Admin Portal (accessible at
http://localhost:5174):npm run dev:admin
Both ports are configured to proxy API requests to your local backend on port 8080.
For deployments or container overrides, configure the variables listed below inside your environment or docker container configurations:
| Variable Name | Description | Default / Example |
|---|---|---|
SPRING_DATASOURCE_URL |
MySQL Database Connection URL | jdbc:mysql://localhost:3306/job_aggregator_db |
SPRING_DATASOURCE_USERNAME |
Database Username | root |
SPRING_DATASOURCE_PASSWORD |
Database Password | your_mysql_password |
SPRING_MAIL_HOST |
SMTP Server Host Address | smtp-relay.brevo.com |
SPRING_MAIL_PORT |
SMTP Server Connection Port | 587 |
SPRING_MAIL_USERNAME |
SMTP Mail Account Username | your_brevo_mail_username |
SPRING_MAIL_PASSWORD |
SMTP Mail Account Password | your_brevo_mail_password |
CLOUDINARY_CLOUD_NAME |
Cloudinary Account Cloud Name | your_cloudinary_cloud_name |
CLOUDINARY_API_KEY |
Cloudinary API Key | your_api_key |
CLOUDINARY_API_SECRET |
Cloudinary API Secret Key | your_api_secret |
CLOUDINARY_FOLDER |
Cloudinary Uploads Folder | job-app/images |
JWT_SECRET |
Base64 JWT Secret Key | Generate a secure Base64 256-bit string |
PUBLIC_PORTAL_URL |
CORS Allowed Origin - Public Portal | http://localhost:5173 |
ADMIN_PORTAL_URL |
CORS Allowed Origin - Admin Portal | http://localhost:5174 |
Navigate to the root directory and build the multi-stage images:
Backend Image:
cd spring-backend
docker build -t job-backend:latest .Frontend Image (combines public and admin portals served by Nginx):
cd ../frontend
docker build -t job-frontend:latest .- Map Host Port
8080to Container Port8080for the backend. - Supply environment variables like
SPRING_DATASOURCE_URL,SPRING_DATASOURCE_USERNAME, andSPRING_DATASOURCE_PASSWORD. - Map Host Port
80to Container Port80for the Nginx frontend. Access the public portal athttp://localhost/portaland the admin portal athttp://localhost/admin.
To host both portals directly inside the backend JAR for a single-port deployment:
- Navigate to the frontend directory and build the assets:
cd frontend npm run build:portal npm run build:admin - Copy the production output assets into the Spring Boot resource folders:
cp -r public-portal/dist/* ../spring-backend/src/main/resources/static/portal/ cp -r admin-portal/dist/* ../spring-backend/src/main/resources/static/admin/
- Build the unified JAR:
cd ../spring-backend mvn clean package -DskipTests - Run the JAR:
java -jar target/spring-backend-0.0.1-SNAPSHOT.jar
Access the portals at http://localhost:8080/portal/index.html and http://localhost:8080/admin/index.html.
Run the Frontend container served by Nginx alongside the Backend container, mapping backend CORS policies to allow the production Nginx domain names.
| HTTP Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/auth/register |
Create student account. |
POST |
/api/v1/auth/login |
Authenticate student user, returns stateless JWT HttpOnly cookies (accessToken, refreshToken). |
POST |
/api/v1/auth/refresh-token |
Request new accessToken using refreshToken cookie. |
POST |
/api/v1/auth/logout |
Evict client auth cookies and terminate session. |
| HTTP Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/users/me |
Fetch currently logged-in student profile details. |
PUT |
/api/v1/users/me |
Update candidate profile metadata. |
| HTTP Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/companies |
Retrieve listing of partner employers. |
POST |
/api/v1/companies |
Register a partner employer. |
| HTTP Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/public/jobs |
Paginated job listings search. |
GET |
/api/v1/jobs/{id} |
Fetch detailed job specification page. |
POST |
/api/v1/jobs/import |
Trigger the job scraper and ingestion feed engine. |
| HTTP Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/upload/resume |
Process resume PDF uploads directly to Cloudinary. |
POST |
/api/v1/upload/image |
Handle avatar and company brand logo uploads to Cloudinary. |
| HTTP Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/admin/auth/login |
Authenticate administrative dashboard privileges. |
GET |
/api/v1/admin/dashboard/analytics |
Fetch aggregated metrics (sign-up trends, active counts, jobs categories). |
PATCH |
/api/v1/admin/users/{id}/status |
Toggle student account activation status (active vs. blocked). |