SuperCoolJobs
SuperCoolJobs is a full-stack job recruitment application built on a classic Client-Server architecture serving two distinct user personas: Recruits (job seekers) and Recruiters. The platform features advanced job discovery with multi-axis filtering (profession, type, frequency), a complete application lifecycle management system, and a highly relational MySQL schema comprising 12 rigorously constrained tables paired with 12 pre-defined SQL views for complex, instant multi-table queries. Authentication is handled via client-side bcrypt hashing with server-side verification.
Architecture & How It Works
The system follows a three-tier architecture: a React SPA frontend communicates with an Express REST API backend, which queries a MySQL relational database. The frontend handles routing and UI via React Router v6 and Bootstrap 5, while the backend centralizes all business logic in Api.js—managing authentication, job CRUD, application workflows, and profile operations. The database enforces referential integrity across all entities, with pre-built SQL views eliminating the need for complex JOIN queries at the application layer.
1. Dual-Persona Authentication & Routing
The platform serves two fundamentally different user types—Recruits and Recruiters—each with isolated dashboards, data views, and permissions. Authentication uses bcryptjs for client-side password hashing before transmission, with the backend verifying against stored hashes. React Router v6 conditionally renders role-specific route trees based on the authenticated user type.
// Authentication flow
async function handleLogin(username, password) {
// Client-side: hash password before sending
const hashedPassword = await bcrypt.hash(password, salt);
const response = await fetch("/login", {
method: "POST",
body: JSON.stringify({ username, password: hashedPassword })
});
const user = await response.json();
// Route to Recruit or Recruiter dashboard based on role
if (user.role === "recruit") navigate("/recruit/dashboard");
else navigate("/recruiter/dashboard");
}2. Multi-Axis Job Discovery & Filtering
Job seekers can browse and filter postings across three independent axes, enabling precise job matching:
- ●Profession: Software Engineering, Data Science, Marketing, Design, etc.—mapped to the
professioncolumn on thejob_postingtable. - ●Job Type: Remote, Hybrid, or In-Person—allowing seekers to filter by their preferred work arrangement.
- ●Frequency: Full-Time, Part-Time, or Contract—providing flexibility for different employment needs.GET /jobs?profession=SE&type=Remote&frequency=Full-Time
3. Relational Schema & Application Lifecycle
The MySQL database implements a 12-table relational schema with strict foreign key constraints ensuring data integrity across users, companies, job postings, and applications. When a recruit applies to a job, a row is created in the job_application junction table with a default status of “Pending.” Recruiters can then transition each application through a defined state machine: Pending → Accepted or Pending → Rejected. Additionally, 12 pre-defined SQL views encapsulate complex multi-table JOINs, allowing the API to query denormalized data sets with simple SELECT * FROM view_name calls—eliminating repetitive JOIN logic from the application layer.
Tech Stack & Tools Used
Frontend & UI
- React 18: Component-based SPA with hooks-driven state management (useState, useEffect).
- React Router v6: Client-side routing with role-based conditional rendering for Recruit vs. Recruiter dashboards.
- Bootstrap 5 & React-Bootstrap: Responsive UI framework providing pre-styled components and grid layout.
- bcryptjs: Client-side password hashing before transmission to the backend for secure authentication.
Backend & Data Layer
- Node.js & Express: RESTful API framework handling authentication, business logic, and data routing.
- mysql2: MySQL driver for Node.js with prepared statements and connection pooling.
- MySQL 8.0+: Relational database with 12 tables, 12 views, and strict foreign key constraints.
- dotenv & cors: Environment variable management and cross-origin resource sharing middleware.
Architecture Diagram
📐Three-Tier Client-Server Architecture
[ ARCHITECTURE OVERVIEW ]
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (SPA) │
│ React 18 + React Router v6 │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Landing │ │ Recruit │ │ Recruiter │ │
│ │ Pages │ │ Dashboard │ │ Dashboard │ │
│ │ │ │ │ │ │ │
│ │ Login │ │ Browse Jobs │ │ Post Jobs │ │
│ │ Register │ │ Apply │ │ View Applicants │ │
│ │ About │ │ Profile │ │ Update Status │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Bootstrap 5 + React-Bootstrap + bcryptjs │ │
│ └────────────────────────┬────────────────────────────┘ │
└───────────────────────────┼─────────────────────────────────┘
│
HTTP (REST API)
Port 3000 -> 3001
│
┌───────────────────────────┼─────────────────────────────────┐
│ BACKEND (API) │
│ Node.js + Express │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Api.js │ │
│ │ │ │
│ │ Auth Routes: │ │
│ │ POST /login -> Validate credentials │ │
│ │ POST /register -> Create user account │ │
│ │ │ │
│ │ Recruit Routes: │ │
│ │ GET /recruits -> List all job seekers │ │
│ │ GET /jobs -> Browse job postings │ │
│ │ POST /apply -> Submit application │ │
│ │ GET /applications -> View my applications │ │
│ │ │ │
│ │ Recruiter Routes: │ │
│ │ POST /jobs -> Create job posting │ │
│ │ GET /applicants -> View applications │ │
│ │ PUT /applications -> Update status │ │
│ │ │ │
│ │ Profile Routes: │ │
│ │ GET /profile -> Fetch user profile │ │
│ │ PUT /profile -> Update profile data │ │
│ └─────────────────────────┬───────────────────────────┘ │
│ │ │
│ dotenv + cors middleware │ mysql2 driver │
└─────────────────────────────┼───────────────────────────────┘
│
SQL Queries
│
┌─────────────────────────────┼───────────────────────────────┐
│ MySQL 8.0+ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Schema: supercooljobs │ │
│ │ │ │
│ │ 12 Tables: │ │
│ │ ┌──────────┐ ┌───────────┐ ┌────────────────┐ │ │
│ │ │ user │ │ recruit │ │ recruiter │ │ │
│ │ │ account │ │ profile │ │ profile │ │ │
│ │ └────┬─────┘ └─────┬─────┘ └───────┬────────┘ │ │
│ │ │ │ │ │ │
│ │ └──────┬──────┴───────┬───────┘ │ │
│ │ │ │ │ │
│ │ ┌───────────┴──┐ ┌───────┴────────┐ │ │
│ │ │ job_posting │ │ job_application │ │ │
│ │ │ │ │ │ │ │
│ │ │ profession │ │ status: │ │ │
│ │ │ type │ │ Pending │ │ │
│ │ │ frequency │ │ Accepted │ │ │
│ │ │ company_id │ │ Rejected │ │ │
│ │ └──────────────┘ └────────────────┘ │ │
│ │ │ │
│ │ 12 SQL Views (pre-defined multi-table queries) │ │
│ │ restart_everything.sql (schema + seed data) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Application Flow:
[Recruit Logs In] -> POST /login -> bcrypt verify
│
▼
[Browse Jobs] -> GET /jobs?profession=SE&type=Remote
│
├─ Filter: profession (Software Engineering, etc.)
├─ Filter: type (Remote, Hybrid, In-Person)
└─ Filter: frequency (Full-Time, Part-Time, Contract)
│
▼
[Apply to Job] -> POST /apply
│
▼
job_application row created (status: "Pending")
│
▼
[Recruiter Views] -> GET /applicants
│
▼
[Update Status] -> PUT /applications (Accepted / Rejected)Local Execution & Testing
This project requires a running MySQL server, the backend API, and the React frontend. The database must be initialized first using the provided SQL script. You'll need a .env file in the api/ directory with your MySQL credentials:
# 1. Initialize the MySQL Databasemysql -u your_username -p supercooljobs < sql/restart_everything.sql# 2. Configure Environment (api/.env)DB_HOST=localhostDB_USER=your_mysql_userDB_PASSWORD=your_mysql_passwordDB_DATABASE=supercooljobsDB_PORT=3306# 3. Start the Backend API (Terminal 1)cd apinpm installnpm start # Runs on http://localhost:3001# 4. Start the Frontend (Terminal 2)cd webnpm installnpm start # Opens http://localhost:3000Testing Strategy
- ●Recruit Flow: Log in with test credentials (e.g.,
neh2332 / 123), browse jobs, apply to a posting, and verify the application appears in the dashboard. - ●Recruiter Flow: Log in as a recruiter (e.g.,
recruiter1 / 123), view incoming applications, and update status to Accepted or Rejected. - ●API Testing: Use Postman or
curlagainst endpoints defined inapi/Api.js(e.g.,GET http://localhost:3001/recruits).