Full-Stack Job Board Application Development

Ravi

Ravi Mahawar

Full-Stack Job Board Application

This is a complete full-stack job board application built with a modern tech stack, featuring distinct user roles, a comprehensive API, and a seamless authentication system that supports both local email/password and SSO logins via Auth0.

Local Development Instructions

Follow these steps to set up and run both the frontend and backend components of the application on your local machine.

Prerequisites

Node.js (v18 or later recommended)
npm or a compatible package manager
PostgreSQL: A running instance of a PostgreSQL database.

Backend Setup

Navigate to the backend directory:
cd backend
Install dependencies:
npm install
Set up environment variables: Create a .env file in the backend directory root and add the following variables.
# Replace with your PostgreSQL connection string
DATABASE_URL="postgresql://YOUR_USER:YOUR_PASSWORD@localhost:5432/job_board_db"

# A strong, secret key for signing JWTs
JWT_SECRET="your-super-secret-key-that-is-at-least-32-characters-long"

# The base URL of your backend server
BACKEND_URL="http://localhost:4000"
Set up the PostgreSQL database:
Make sure your PostgreSQL server is running.
Create a new database with the name you specified in your DATABASE_URL (e.g., job_board_db). You can do this using a GUI tool like Postico or via the command line:
CREATE DATABASE job_board_db;
Run database migrations: This command will sync your database schema with the Prisma schema file and apply any pending changes.
npx prisma migrate dev
Run the backend server:
npm run dev or npm start
The backend API will now be running, typically at http://localhost:4000.

Frontend Setup

Navigate to the client directory:
cd client
Install dependencies:
npm install
Set up environment variables: Create a .env file in the client directory root and add your Auth0 application credentials.
VITE_AUTH0_DOMAIN=your-auth0-domain.us.auth0.com
VITE_AUTH0_CLIENT_ID=your-auth0-client-id
VITE_AUTH0_CALLBACK_URL=http://localhost:5173/auth/callback
Run the frontend development server:
npm run dev
The frontend application will now be running, typically at http://localhost:5173.

Design Explanations

Database Schema

The database schema is designed to be both robust and flexible, centered around a few key relationships:
User Roles: The User model has an enum Role that clearly separates users into JOB_SEEKER and EMPLOYER. This is the foundation for all role-based access control in the application.
Employer-Company Relationship: The relationship between an Employer and a Company is managed through a dedicated EmployerProfile model. The key design choice here is the @unique constraint on the userId field in the EmployerProfile. This enforces a one-to-one relationship, meaning an employer can only be associated with one company at a time. This was chosen for simplicity in this version of the application, as it streamlines the logic for job posting and company management.
Cascading Deletes: The schema uses onDelete: Cascade for critical relationships. For example, if a User is deleted, their associated EmployerProfile or JobSeekerProfile is also automatically deleted, ensuring data integrity.

Authentication Strategy

The application uses a powerful hybrid authentication strategy to provide a seamless experience for all users:
Local Authentication: For email and password logins, passwords are never stored directly. They are securely hashed using bcryptjs. Upon successful login, the backend generates a JSON Web Token (JWT) containing the user's ID and role.
SSO Authentication (Auth0): For social logins, the authentication is handled on the frontend by the Auth0 React SDK. After a user authenticates with a provider (like Google), the frontend sends the user's details to our backend.
Unified Session Management: This is the most critical part of the strategy. Whether a user logs in locally or via SSO, the backend's final step is to issue the same type of JWT. This token is stored in a secure, httpOnly cookie. This means that the rest of our application—from protected routes on the backend to conditional UI on the frontend—doesn't need to care how a user logged in. It only needs to verify the single, unified JWT, which creates a very clean and decoupled system.

OAuth2 Provider: Auth0

Auth0 was chosen as the OAuth2 provider for several key reasons:
Universal Login Page: Auth0 provides a hosted, customizable login page that can handle multiple social connections (Google, GitHub, etc.) out of the box, reducing the amount of frontend code we need to write.
Security: It handles the complexities of the OAuth2 flow securely, reducing the risk of implementation errors.
Developer Experience: The Auth0 React SDK is well-documented and makes the frontend integration very straightforward.
Scalability: It's easy to add new social providers or enterprise connections in the future without changing our application's core logic.

Architectural Choices

Backend: The backend is built using a three-layer architecture (Routers -> Controllers -> Services). This provides a clear separation of concerns:
Routers handle the HTTP routing and request validation.
Controllers parse the request and manage the HTTP response.
Services contain all the core business logic and database interactions, keeping them completely separate from the web layer.
Frontend:
Feature-Based Structure: The code is organized into folders based on features (e.g., auth, jobs, profile), which makes it easier to navigate and maintain as the application grows.
Global State with Zustand: Instead of a more complex library like Redux, Zustand was chosen for its simplicity and minimal boilerplate. It provides a lightweight way to manage the global authentication state, which is all the global state this application needs.
Unified Profile Component: A single, role-aware ProfilePage.jsx component is used for both job seekers and employers. It conditionally renders different sections based on the user's role, which significantly reduces code duplication.
Like this project

Posted Oct 3, 2025

Developed a full-stack job board app with user roles and Auth0 authentication.