<Chandan />
Back to projects

Case study

Credify

Recruitment workflows without the usual friction

A full-stack recruitment platform for candidates and recruiters, with secure authentication, role-aware workflows, resume handling, and job applications.

Credify project preview
Next.jsTypeScriptNode.jsExpressMongoDBMongooseTailwind CSSCloudinaryResend

01

Overview

Credify is a recruitment platform designed around two primary users: candidates looking for opportunities and recruiters managing hiring workflows. The project focuses on the practical engineering behind authentication, authorization, profile management, job publishing, applications, file uploads, email flows, and production deployment.

02

The problem

Hiring workflows are often fragmented across forms, email threads, files, and disconnected dashboards. Candidates need a clear way to manage their profile and applications, while recruiters need reliable controls for posting jobs and reviewing candidates.

03

The solution

Credify brings those workflows into one role-aware application. Candidates can manage their profile, resume, and applications while recruiters work with company and job data through protected APIs. The backend separates authentication, authorization, policy checks, storage, and domain logic so each part can evolve independently.

04

Key features

Candidate and recruiter registration/login flows
Refresh-token rotation and session restoration
Role-based authorization and policy checks
Candidate and recruiter profile management
Job creation and application workflows
Resume upload and replacement flow
Email verification and password reset
Production frontend/backend deployment

05

Architecture

Next.js client
REST API
Express + TypeScript
Authentication / policies
MongoDB + Mongoose
Cloudinary file storage
Resend transactional email

06

Technical decisions

Short-lived access tokens + refresh sessions

The access token stays short-lived while refresh-token handling is isolated behind the auth flow. This keeps normal API authorization simple without forcing long-lived access credentials into the browser.

Authorization beyond route guards

Role checks protect broad capabilities, while policy-level checks handle resource-specific rules such as whether a recruiter can act on a particular company.

Storage separated from business logic

Resume upload behavior is kept behind a storage service so controllers do not need to know Cloudinary-specific details and old files can be cleaned up as part of replacement flows.

07

Challenges

01

Restoring authentication without unsafe persistence

Problem

A page refresh clears in-memory access state, but storing a long-lived access token in localStorage would increase exposure to client-side script attacks.

Approach

The application restores the session through the refresh flow and keeps the active access token in memory, with loading states preventing protected UI from making assumptions before restoration completes.

02

Keeping role rules maintainable

Problem

As candidate, recruiter, company, job, and application rules grow, putting every rule directly inside controllers makes behavior difficult to reason about.

Approach

Authentication, broad role authorization, and resource-level policy checks are separated so each layer answers a narrower question.

03

Deploying a split frontend/backend application

Problem

The frontend and API are deployed separately, so API paths, cookies, origins, and production environment variables have to remain consistent between local and hosted environments.

Approach

Environment-driven proxy configuration and explicit production settings keep the client and API decoupled while preserving a stable application-facing API path.

08

What I learned

  • Authentication is a system, not just a login endpoint.
  • Resource policies become valuable as soon as roles interact with owned data.
  • Loading and session-restoration UX matters as much as the auth API itself.
  • Production deployment exposes assumptions that local development can hide.

09

Next improvements

  • Expand recruiter analytics and application review tools
  • Add stronger end-to-end coverage for critical hiring flows
  • Improve observability for production API failures
  • Continue accessibility and loading-performance refinements

Want to talk about this project?

I'm happy to walk through the architecture, trade-offs and implementation decisions in more depth.

Contact me